{"version":3,"file":"kendo.dataviz.diagram.min.js","names":["factory","define","amd","$","undefined$1","kendo","window","diagram","dataviz","deepExtend","isArray","Array","Utils","isNearZero","num","Math","abs","isDefined","obj","isUndefined","isObject","Object","has","key","hasOwnProperty","call","isString","prototype","toString","isBoolean","isType","type","isNumber","isNaN","parseFloat","isFinite","isEmpty","length","simpleExtend","destination","source","name","initArray","size","value","array","i","serializePoints","points","res","p","push","x","y","join","deserializePoints","s","v","split","Point","parseInt","randomInteger","lower","upper","floor","random","DFT","el","func","childNodes","item","this","getMatrixAngle","m","d","atan2","b","PI","getMatrixScaling","sqrt","a","c","sign","number","findAngle","center","end","start","sngXComp","sngYComp","atan","findRadian","forEach","arr","iterator","thisRef","any","predicate","remove","what","ax","indexOf","splice","contains","inArray","fold","list","acc","context","initial","arguments","find","result","index","first","constraint","insert","element","position","all","clear","bisort","sortfunc","sort","n","addRange","range","apply","Easing","pos","cos","Ticker","Class","extend","init","adapters","target","tick","interval","duration","lastTime","handlers","_this","transition","timerDelegate","onTimerEvent","addAdapter","onComplete","handler","removeHandler","grep","h","trigger","caller","onStep","seekTo","to","seekFromTo","from","max","min","Date","getTime","intervalId","setInterval","stop","clearInterval","play","origin","initState","reverse","propagate","update","now","timePassed","movement","ui","Range","step","Infinity","j","k","rangeIntegerScale","jQuery","Point2D","isFunction","map","fn","plus","minus","offset","times","normalize","lengthSquared","middleOf","q","toPolar","useDegrees","factor","halfpi","len","Polar","isOnLine","temp","o1","u1","r1","Rect","inflate","r2","union","height","width","parse","str","xy","slice","PathDefiner","left","right","point","dx","dy","r","x1","y1","x2","y2","top","bottom","topLeft","topRight","bottomLeft","bottomRight","clone","equals","rect","rotatedBounds","angle","rotatedPoints","tl","tr","br","bl","rotate","delimiter","scale","scaleX","scaleY","staicPoint","adornerCenter","thisCenter","delta","scaled","zoom","overlaps","rectBottomRight","Size","intersectLine","start1","end1","start2","end2","isSegment","tangensdiff","Empty","toRect","empty","fromPoints","Intersect","lines","segments","rectWithLine","rects","rect1","rect2","intersect","reverseAngle","RectAlign","container","align","content","alignment","alignValues","toLowerCase","_singleAlign","_align","_left","_center","_right","stretch","_stretch","_top","middle","_middle","_bottom","alignCalc","Matrix","e","f","applyRect","fromSVGMatrix","vm","fromMatrixVector","fromList","translation","unit","rotation","sin","scaling","parts","nums","trim","substr","MatrixVector","fromMatrix","randomId","chars","charAt","round","Geometry","_distanceToLineSquared","d2","pt1","pt2","vx","vy","dot","distanceToLine","distanceToPolyline","minimum","Number","MAX_VALUE","p1","p2","HashTable","_buckets","add","_createGetBucket","get","_bucketExists","set","containsKey","hashId","_hash","hashes","_hashes","hash","bucket","ht","_hashString","_objectHashId","charCodeAt","id","_hashId","Dictionary","Observable","dictionary","_hashTable","entry","Error","forEachValue","forEachKey","keys","Queue","_tail","_head","enqueue","next","dequeue","current","Set","resource","kv","toArray","Node","shape","links","outgoing","incoming","weight","associatedShape","bounds","data","shortForm","isVirtual","isIsolated","isLinkedTo","node","that","link","getComplement","getChildren","children","getParents","parents","copy","balance","owner","adjacentTo","removeLink","hasLinkTo","degree","incidentWith","getLinksWith","getNeighbors","neighbors","Link","connection","sourceFound","targetFound","associatedConnection","getCommonNode","isBridging","v1","v2","getNodes","changeSource","changeTarget","changesNodes","w","oldSource","oldTarget","directTo","createReverseEdge","reversed","Graph","idOrDiagram","nodes","_nodeMap","_root","_hasCachedRelationships","cacheRelationships","forceRebuild","assignLevels","startNode","visited","level","child","root","found","getConnectedComponents","componentIndex","setItemIndices","componentId","_collectConnectedNodes","components","addNodeAndOutgoings","setIds","nodeIndex","nextId","calcBounds","getSpanningTree","tree","remaining","_addNode","levelCount","pop","ni","cn","newLink","addLink","treeLevels","takeRandomNode","excludedNodes","incidenceLessThan","pool","isHealthy","hasNode","sourceOrLink","addExistingLink","foundSource","getNode","addNode","foundTarget","removeAllLinks","hasLink","t","linkOrId","nodeOrId","_removeNode","removeNode","areConnected","n1","n2","layoutRect","newNode","newLinks","saveMapping","save","nodeMap","linkMap","nOriginal","nCopy","linkOriginal","linkCopy","linearize","addIds","depthFirstTraversal","action","foundNode","_dftIterator","breadthFirstTraversal","queue","_stronglyConnectedComponents","excludeSingleItems","indices","lowLinks","connected","stack","component","findCycles","isAcyclic","isSubGraph","other","otherArray","thisArray","makeAcyclic","oneNode","rev","N","intensityCatalog","flowIntensity","catalogEqualIntensity","intensity","sourceStack","targetStack","targets","li","targetLink","unshift","sources","si","sourceLink","ri","ril","u","concat","vertexOrder","kk","reversedEdges","Predefined","EightGraph","Mindmap","ThreeGraph","BinaryTree","levels","createBalancedTree","Linear","Tree","siblingsCount","Forest","trees","createBalancedForest","Workflow","Grid","g","previous","graphString","previousLink","graph","part","lin","_addShape","kendoDiagram","shapeDefaults","radius","fill","undoable","addShape","_addConnection","options","connect","createDiagramFromGraph","doLayout","randomSize","clientWidth","clientHeight","opt","color","gli","sourceShape","targetShape","SpringLayout","layoutGraph","limitToView","shi","news","counter","lastAdded","parent","treeCount","createRandomConnectedGraph","nodeCount","maxIncidence","isTree","poolNode","randomAdditions","randomDiagram","shapeCount","normalVariable","mean","deviation","log","geometry","drawing","defined","util","TRANSPARENT","Markers","none","arrowStart","filledCircle","arrowEnd","START","END","WIDTH","HEIGHT","diffNumericOptions","fields","field","elementOptions","hasChanges","Scale","toMatrix","format","invert","Translation","toMatrixVector","Length","Rotation","ZERO","create","values","CompositeTransform","translate","transform","render","visual","_transform","_renderTransform","rotateMatrix","scaleMatrix","translatePoint","AutoSizeableMixin","_setScale","originWidth","_originWidth","originHeight","_originHeight","_setTranslate","_initSize","autoSize","_measure","_updateSize","_diffNumericOptions","Element","_originSize","visible","drawingContainer","redraw","drawingElement","matrix","_hover","force","_measured","box","_boundingBox","startPoint","rawBBox","VisualBase","normalizeDrawingOptions","stroke","opacity","_fill","getColor","_stroke","show","hover","strokeOptions","dashType","fillOptions","gradient","GradientClass","RadialGradient","LinearGradient","TextBlock","_textColor","_font","_initText","fontSize","fontFamily","Text","text","font","fontOptions","fontStyle","fontWeight","sizeChanged","textOptions","Rectangle","_initPath","_setPosition","_drawPath","Path","closed","sizeOptions","sizeOptionsOrDefault","elements","createSegment","MarkerBase","anchor","createElement","_transformToPath","path","transformCopy","CircleMarker","Circle","positionMarker","targetSegment","ArrowMarker","xDiff","yDiff","_linePoints","deg","endPoint","controlOut","nextSegment","controlIn","prevSegment","MarkerPathMixin","_getPath","MultiPath","paths","_normalizeMarkerOptions","startCap","endCap","_removeMarker","marker","_markers","_createMarkers","_createMarker","markerType","append","_positionMarker","_capMap","_redrawMarker","pathChange","pathOptions","cap","pathCapType","optionsCap","created","_redrawMarkers","Group","_createElements","_setData","multipath","Line","Polyline","_updatePath","_pointsDiffer","currentPoints","differ","Image","_initImage","src","_rect","_childrenChange","_remove","removeAt","toFront","visuals","toBack","_reorderChildren","toIndex","group","drawingChildren","fixedPosition","boundingBox","childBoundingBox","_includeInBBox","clippedBBox","Layout","toDrawingRect","drawingRect","reflow","_initCircle","circleOptions","move","_circle","setRadius","Canvas","surface","Surface","_translate","_viewBox","viewBox","setSize","draw","insertBefore","destroy","clearHtml","drawingOptions","Color","toHex","Segment","Movable","Cursors","arrow","grip","cross","select","south","east","west","north","rowresize","colresize","HIT_TEST_DISTANCE","AUTO","TOP","RIGHT","LEFT","BOTTOM","DRAG_START","DRAG","DRAG_END","ITEMBOUNDSCHANGE","ROTATED","TARGET","HANDLE_NAMES","PositionAdapter","layoutState","froms","tos","subjects","getShapeById","LayoutUndoUnit","initialState","finalState","animate","_initialState","_finalState","title","undo","setState","redo","state","conn","ticker","CompositeUnit","units","undoUnit","ConnectionEditUnit","redoSource","redoTarget","_redoSource","_redoTarget","_undoSource","_undoTarget","_updateConnector","updateModel","ConnectionEditUndoUnit","undoSource","undoTarget","DeleteConnectionUnit","targetConnector","DeleteShapeUnit","TransformUnit","shapes","undoStates","adorner","redoStates","layout","refreshBounds","refresh","AddConnectionUnit","AddShapeUnit","deselect","PanUndoUnit","initialPosition","finalPosition","finalPos","pan","RotateUnit","undoRotates","redoRotates","redoAngle","_angle","_innerBounds","_initialize","ToFrontUnit","items","initialIndices","_toIndex","ToBackUnit","UndoRedoService","bind","events","capacity","begin","composite","cancel","commit","execute","_restart","addCompositeItem","count","EmptyTool","toolService","tryActivate","getCursor","ScrollerTool","tool","friction","support","mobileOS","canvas","scroller","scrollable","kendoMobileScroller","velocityMultiplier","mousewheelScrolling","scroll","_move","movableCanvas","virtualScroll","dimension","makeVirtual","virtualSize","dimensions","disable","meta","pannable","enabled","ctrlKey","noMeta","hoveredItem","hoveredAdorner","_hoveredConnector","enable","args","scrollPos","scrollLeft","scrollTop","_storePan","moveTo","_pan","PointerTool","selectSingle","handle","_hitTest","_resizingAdorner","isDragHandle","connections","undoRedoService","_getCursor","SelectionTool","selectable","multiple","selector","isSelected","selectArea","ConnectionTool","connector","_createConnection","_c","canDrag","connectionHandle","_connectionManipulation","_removeHover","activeConnection","_cachedTouchTarget","cachedTouchTarget","sourceConnector","Shape","getConnector","_syncConnectionChanges","_connectorsAdorner","ConnectionEditTool","isActive","handleName","testKey","toUpperCase","ToolService","tools","activeTool","_updateHoveredItem","_activateTool","_updateCursor","focus","suspendTracking","updateHovered","resumeTracking","keyDown","metaKey","altKey","toRemove","_triggerRemove","_syncChanges","_destroyToolBar","_discardNewConnection","selectAll","cut","paste","wheel","z","zoomRate","zoomOptions","zoomMin","zoomMax","setTool","addToSelection","newConnection","cursor","css","disabledShape","isNew","hit","_visible","selectedConnections","_selectedItems","Connection","_hitTestItems","_hitTestElements","shapeHit","connectionHit","idx","connectors","hitTestShapeConnectors","mainLayer","ConnectionRouterBase","LinearConnectionRouter","hitTest","getBounds","allPoints","PolylineRouter","route","CascadingRouter","SAME_SIDE_DISTANCE_RATIO","routePoints","_connectorPoints","_floatingPoints","_resolvedSourceConnector","_resolvedTargetConnector","sourcePoint","targetPoint","_connectorSides","axis","boundsPoint","secondarySign","_connectorSide","sideDistance","minSide","side","shapeBounds","sides","MAX_NUM","_sameSideDistance","pointX","pointY","sourceConnectorSide","targetConnectorSide","deltaX","deltaY","sameSideDistance","shiftX","shiftY","cascadeStartHorizontal","_startHorizontal","sourceSide","AdornerBase","_adorners","ConnectionEditAdorner","_ts","sp","tp","spVisual","handles","epVisual","_initialSource","_initialTarget","ts","radiusX","radiusY","sourcePointDistance","distanceTo","targetPointDistance","sourceHandle","targetHandle","modelToLayer","ConnectorsAdorner","_refreshHandler","ctr","_clearVisual","ConnectorVisual","_keepCachedTouchTarget","visualChildren","childrenCount","unbind","each","ResizingAdorner","_manipulating","_initSelection","_createHandles","selected","_internalChange","_rotatedHandler","_resizable","editable","resize","_handleOptions","_bounds","handleBounds","handlesCount","_getHandleBounds","_rotationOffset","_startAngle","_rotates","_positions","initialRotates","initialStates","handleOptions","_sp","_cp","_lp","shapeStates","visibleHandles","currentAngle","dragging","newBounds","staticPoint","dtl","dbr","changed","_truncateAngle","_rotating","shouldSnap","thr","_truncateDistance","hitToOppositeSide","_displaceBounds","newCenter","minWidth","minHeight","oldBounds","states","_truncatePositionToGuides","ruler","truncatePositionToGuides","_truncateSizeToGuides","truncateSizeToGuides","snap","snapOptions","snapAngle","snapSize","drag","_diffStates","_syncShapeChanges","rotationThumb","thumb","_rotationThumbBounds","Selector","_ep","_adorn","visualBounds","modelToView","relative","_visualBounds","shiftKey","HyperTree","EPSILON","DEG_TO_RAD","LayoutBase","defaultOptions","subtype","roots","nodeDistance","iterations","horizontalSeparation","verticalSeparation","underneathVerticalTopOffset","underneathHorizontalOffset","underneathVerticalSeparation","grid","offsetX","offsetY","componentSpacingX","componentSpacingY","layerSeparation","layeredIterations","startRadialAngle","endRadialAngle","radialSeparation","radialFirstLevelSeparation","keepComponentsInOneRadialLayout","ignoreContainers","layoutContainerChildren","ignoreInvisible","animateTransitions","gridLayoutComponents","maxWidth","startX","resultLinkSet","resultNodeSet","moveToOffset","boundingRect","currentHeight","currentWidth","deltax","deltay","nodeBounds","newpoints","pt","currentHorizontalOffset","transferOptions","DiagramToHyperTreeAdapter","shapeMap","edges","edgeMap","finalNodes","finalLinks","ignoredConnections","ignoredShapes","hyperMap","hyperTree","finalGraph","convert","_renormalizeShapes","_renormalizeConnections","l","mapConnection","mapShape","getEdge","listToRoot","containerGraph","parentContainer","firstNonIgnorableContainer","isContainer","_isIgnorableItem","isContainerConnection","isDescendantOf","scope","containers","isIgnorableItem","isCollapsed","_isVisible","_isTop","isShapeMapped","leastCommonAncestor","al","xa","xb","_isCollapsed","sink","sourceNode","sinkNode","areConnectedAlready","newEdge","finalNodeSet","LayoutState","initialTemperature","temperature","guessBounds","_expectedBounds","refineStage","_repulsion","_attraction","_shake","rho","alpha","_InverseSquareForce","wn","hn","wm","hm","pow","_SquareForce","distance","squareSize","area","ceil","TreeLayoutProcessor","treeGraph","layoutSwitch","layoutLeft","setChildrenDirection","setChildrenLayout","TreeDirection","measure","Width","arrange","layoutRight","layoutUp","up","layoutDown","down","treeDirection","layoutRadialTree","previousRoot","startAngle","endAngle","maxDepth","calculateAngularWidth","radialLayout","Angle","tipOverTree","startFromLevel","aw","diameter","sectorAngle","sortChildren","basevalue","pl","nl","normalizeAngle","col","deltaTheta","deltaThetaHalf","parentSector","fraction","sorted","childNode","cp","childAngleFraction","setPolarLocation","BoundingRectangle","direction","includeStart","rootDirection","rootLayout","childrenLayout","givenSize","shapeWidth","shapeHeight","AngleToParent","SectorAngle","pp","childrenwidth","selfLocation","single","male","female","leftcount","tipOverTreeStartLevel","TreeLayout","adapter","layoutComponents","getTree","getTreeForRoot","LayeredLayout","_initRuntimeProperties","layer","downstreamLinkCount","upstreamLinkCount","uBaryCenter","dBaryCenter","upstreamPriority","downstreamPriority","gridPosition","_prepare","targetLayer","layerMap","layerCount","shift","sortedNodes","o2","o1layer","o2layer","minLayer","layers","linksTo","_dummify","_optimizeCrossings","_swapPairs","arrangeNodes","_moveThingsAround","_dedummify","setMinDist","minDist","layerIndex","minDistances","getMinDist","dist","i1","i2","placeLeftToRight","leftClasses","leftPos","classNodes","placeLeft","POSITIVE_INFINITY","rightSibling","nodeLeftClass","D","upNodes","downNodes","neighbor","intDiv","placeRightToLeft","rightClasses","rightPos","placeRight","NEGATIVE_INFINITY","leftSibling","nodeRightClass","_getLeftWing","leftWing","computeClasses","_getRightWing","rightWing","wingPair","currentWing","wing","ndsinl","_nodesInLink","vnode","wings","classIndex","_isVerticalLayout","_isHorizontalLayout","_isIncreasingLayout","_gridPositionComparer","dest","currentNode","currDown","downNode","order","placed","sequenceStart","virtualStartIndex","_firstVirtualNode","virtualStart","sequence","_sequencer","virtualEnd","nextVirtualNode","virtualEndIndex","adjustDirections","ctx","fromLayerIndex","layerIncrement","maximumHeight","MIN_VALUE","prevBridge","prevBridgeTarget","nextBridge","nextBridgeTarget","getNeighborOnLayer","clayer","j1","j2","dir","_sequenceSingle","combineSequences","pair","leftHeap","_positionDescendingComparer","rightHeap","_positionAscendingComparer","leftRes","rightRes","leftClass","_getComposite","rightClass","it","layoutLayer","gridPos","iconsidered","considered","n1Priority","n2Priority","nodeGridPos","nodeBaryCenter","calcBaryCenter","nodePriority","moveRight","moveLeft","calcDownData","calcUpData","priority","rightNode","rightNodePriority","leftNode","leftNodePriority","mapVirtualNode","nodeToLinkMap","linkToNodeMap","addLinkBetweenLayers","upLayer","downLayer","o","oLayer","dLayer","oPos","dPos","depthOfDumminess","dedum","prevLink","moves","iter","optimizeLayerCrossings","sum","total","presorted","n1BaryCenter","n2BaryCenter","compareByIndex","compareValue","inode","maxIterations","downwards","secondPass","hasSwapped","calcCrossings","memCrossings","crossBefore","countLinksCrossingBetweenTwoLayers","node1","node2","node1GridPos","node2GridPos","crossAfter","ulayer","dlayer","link1","link2","n11","n12","n21","n22","l1","l2","crossings","n11gp","n12gp","numerator","denominator","graphOrNodes","capture","diagramOrGraphOrNodes","GraphAdapter","geom","Widget","outerWidth","_outerWidth","outerHeight","_outerHeight","HierarchicalDataSource","isPlainObject","math","NS","CASCADING","CHANGE","CLICK","ERROR","MAXINT","SELECT","ITEMROTATE","PAN","ZOOM_START","ZOOM_END","NONE","TRANSFORMED","DefaultConnectors","getPosition","defaultButtons","imageClass","className","iconClass","isAutoConnector","closestConnector","resCtr","minimumDistance","indicesOfItems","extra","defaults","DiagramElement","dataItem","_template","serializable","serialize","json","_content","contentOptions","_contentVisual","_updateContentVisual","_createContentVisual","template","elementTemplate","paramName","_canSelect","toJSON","Connector","shapeId","tempStr","updateOptionsFromModel","createShapeVisual","updateBounds","_createConnectors","_setOptionsFromModel","model","modelOptions","filterShapeDataItem","redrawVisual","_isEditable","_redrawVisual","syncChanges","_suspendModelRefresh","_resumeModelRefresh","_rotate","_alignContent","contentVisual","containerRect","aligner","contentBounds","bbox","contentRect","alignedBounds","connectorDefaults","_transformedBounds","_rotatedBounds","_setBounds","_triggerBoundsChange","_layouting","refreshConnections","cloneDataItem","deselected","_internalSelection","_selectionChanged","deltaAngle","newPosition","sc","con","cons","nameOrPoint","toLocaleLowerCase","fnName","_transformPoint","boundsChange","shapeOptions","shapeVisual","_visualOptions","_updateConnectors","_showConnectors","rotatedPoint","visualOptions","visualTemplate","_initRouter","_sourcePoint","_targetPoint","_setSource","_setTarget","definers","fromConnector","toConnector","dataMap","_dataMap","fromX","fromY","toX","toY","filterConnectionDataItem","connectionsDataSource","getByUid","uid","clearField","shapeSource","defaultConnector","_removeFromSourceConnector","_clearSourceConnector","_setFromOptions","fromPoint","sourceDefiner","_sourceDefiner","shapeTarget","_removeFromTargetConnector","_clearTargetConnector","_setToOptions","toPoint","targetDefiner","_targetDefiner","instance","connectorName","setNewTarget","inactiveItem","_inactiveShapeItems","_deferredConnectionUpdates","onActivate","endIdx","startIdx","alignToPath","midIdx","selection","_router","pts","definition","_resolveConnectors","_refreshPath","sourceConnectors","targetConnectors","_resolveAutoConnectors","minNonConflictSource","minNonConflictTarget","minSource","minTarget","sourceIdx","targetIdx","minNonConflict","_testRoutePoints","router","passRoute","exclude","_getRouteExclude","_shapesQuadTree","hitTestRect","_isPointInsideShape","boundsX","boundsY","Diagram","userOptions","_initTheme","_initElements","_extendLayoutOptions","_initDefaults","_interactionDefaults","_initCanvas","ShapesQuadTree","adornerLayer","_createHandlers","_clipboard","pauseMouseHandlers","_fetchFreshData","_createGlobalToolBar","_createOptionElements","theme","dataSource","draggable","autoBind","tooltip","connectionDefaults","toolBar","DiagramToolBar","click","_toolBarClick","modal","textAlign","prepend","_resize","createShape","editor","view","createModel","_createShape","edit","createConnection","_connectionsDataMap","addConnection","editModel","editorType","editors","cancelEdit","shapeEditors","shapeTemplate","connectionSelectorHandler","connectionSelector","connectionEditors","connectionTemplate","PopupEditor","_update","_cancel","_editArgs","_getEditDataSource","cancelChanges","_destroyEditor","saveEdit","sync","wrapper","close","attr","addClass","appendTo","userShapeDefaults","copyDefaultOptions","mobile","canvasContainer","viewPort","viewport","on","_wheel","_keydown","_userEvents","UserEvents","multiTouch","fastTap","tap","_tap","_dragStart","_drag","_dragEnd","gesturestart","_gestureStart","gesturechange","_gestureChange","gestureend","_gestureEnd","doubleTap","_doubleTap","supportDoubleTap","_mouseover","_mouseout","_mouseMove","_mouseDown","_mouseUp","_syncHandler","_resizeHandler","onResize","_pauseMouseHandlers","_eventPositions","event","_meta","preventDefault","_createToolBar","focused","ctrlPressed","keyCode","origEvent","originalEvent","wheelDelta","detail","mwDelta","touch","pageX","pageY","documentToModel","initialCenter","eventArgs","_gesture","_initialCenter","previousGesture","documentToView","scaleDelta","_zoom","updateZoom","_getValidZoom","zoomedPoint","_panTransform","_updateAdorners","pointPosition","_kendoNode","srcElement","themeOptions","themeName","themes","SASS_THEMES","autoTheme","shapesLength","_createShapes","_createConnections","_findConnectionTarget","unbindResize","off","destroyScroller","_destroyGlobalToolBar","is","_activeElement","scrollContainer","offsets","documentElement","document","parentNode","scrollHeight","load","setOptions","added","removed","_parseBounds","splitDiagramElements","_removeItem","_removeShapeDataItem","_removeConnectionDataItem","_getDiagramItems","_fixOrdering","bringIntoView","original","newPan","_zoomMainLayer","alignShapes","val","raw","hideTooltip","_getPan","animatedScrollTo","scrollTo","_copyOffset","copied","mapping","_updateCopiedConnection","sourceConnection","di","_containerOffset","containerOffset","viewToDocument","viewToModel","_transformWithMatrix","_matrixInvert","_matrix","_layerMatrix","layerToModel","_layerMatrixInvert","viewPoint","modelToDocument","setDataSource","_dataSource","fetch","setConnectionsDataSource","_connectionDataSource","_redrawConnections","getShapeByModelId","getShapeByModelUid","getConnectionByModelId","getConnectionByModelUid","_transformMainLayer","_finishPan","NaN","_storeViewMatrix","_storeLayerMatrix","canvasTransform","shapePos","conPos","removedConnections","_removeShape","_removeConnection","_removeDataItems","recursive","_removeShapeConnections","hasChildren","loaded","_addDataItem","_addDataItemByUid","_addDataItems","parentShape","_refreshSource","dataBound","_bindingRoots","_addItem","preventClosing","singleToolBar","popupZIndex","closest","popupWidth","_popup","popupHeight","connectionBounds","showAt","one","_normalizePointZoom","InactiveItemsCollection","undone","redone","_loadingShapes","_loadingConnections","dsOptions","ds","_shapesRefreshHandler","_shapesRequestStartHandler","_shapesErrorHandler","_refreshShapes","_shapesRequestStart","_error","DataSource","_treeDataSource","_connectionsRefreshHandler","_connectionsRequestStartHandler","_connectionsErrorHandler","_refreshConnections","_connectionsRequestStart","_connectionsError","_shouldRefresh","_removeShapes","_updateShapes","_syncShapes","_suspended","_rebindShapesAndConnections","_addShapes","_addConnections","inactiveItems","activate","dataItems","_removeConnections","_updateConnections","_addConnectionDataItem","_validateConnector","_unbindDataSource","_errorHandler","adorners","_refresh","hide","exportDOMVisual","scrollOffset","viewRect","clipPath","fromRect","wrap","clipWrap","clip","exportVisual","when","then","deferredConnectionUpdates","ExportMixin","PDFMixin","_tools","createToolBar","createTools","appendTools","createPopup","kendoPopup","getKendoPopup","buttons","_toolBar","kendoToolBar","resizable","getKendoToolBar","createTool","toolName","attributes","_setAttributes","open","newGroup","editTool","icon","showText","deleteTool","rotateAnticlockwiseTool","_appendGroup","_rotateGroup","rotateClockwiseTool","createShapeTool","_createGroup","createConnectionTool","undoTool","_historyGroup","redoTool","prop","_getAttributes","eventData","selectedElements","delete","selectedElemens","rotateClockwise","rotateAnticlockwise","Editor","_getFields","_initContainer","createEditable","Editable","clearContainer","modelFields","columns","formContent","_renderTemplate","_renderFields","_renderButtons","Window","userTriggered","sender","_cancelClick","_attachButtonEvents","unescape","form","_createButton","_cancelClickHandler","_updateClickHandler","_updateClick","_editUpdateClickHandler","reader","textField","idField","kendoDropDownList","dataValueField","dataTextField","optionLabel","valuePrimitive","InactiveItem","callbacks","callback","deffered","Deferred","deferred","resolve","QuadRoot","_add","_quadNode","_testRect","QuadNode","inBounds","nodeRect","nodeBottomRight","overlapsBounds","inserted","_initChildren","childIdx","shapeIdx","halfWidth","halfHeight","ROOT_SIZE","boundsChangeHandler","_boundsChange","initRoots","rootMap","rootSize","sectors","getSectors","inRoot","bottomX","bottomY","xIdx","yIdx","Model","_defaultId","ObservableObject","mainOptions","plugin"],"sources":["kendo.dataviz.diagram.js"],"mappings":"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","sourcesContent":["(function (factory) {\n typeof define === 'function' && define.amd ? define(['kendo.data', 'kendo.draganddrop', 'kendo.userevents', 'kendo.mobile.scroller', 'kendo.drawing', 'kendo.core', 'kendo.dataviz.core', 'kendo.toolbar', 'kendo.editable', 'kendo.window', 'kendo.dropdownlist', 'kendo.dataviz.themes'], factory) :\n factory();\n})((function () {\n (function($, undefined$1) {\n var kendo = window.kendo,\n diagram = kendo.dataviz.diagram = {},\n deepExtend = kendo.deepExtend,\n isArray = Array.isArray,\n EPSILON = 1e-06;\n\n /*-------------------Diverse utilities----------------------------*/\n var Utils = {\n };\n\n deepExtend(Utils, {\n isNearZero: function(num) {\n return Math.abs(num) < EPSILON;\n },\n isDefined: function(obj) {\n return typeof obj !== 'undefined';\n },\n\n isUndefined: function(obj) {\n return (typeof obj === 'undefined') || obj === null;\n },\n /**\n * Returns whether the given object is an object or a value.\n */\n isObject: function(obj) {\n return obj === Object(obj);\n },\n /**\n * Returns whether the object has a property with the given name.\n */\n has: function(obj, key) {\n return Object.hasOwnProperty.call(obj, key);\n },\n /**\n * Returns whether the given object is a string.\n */\n isString: function(obj) {\n return Object.prototype.toString.call(obj) == '[object String]';\n },\n isBoolean: function(obj) {\n return Object.prototype.toString.call(obj) == '[object Boolean]';\n },\n isType: function(obj, type) {\n return Object.prototype.toString.call(obj) == '[object ' + type + ']';\n },\n /**\n * Returns whether the given object is a number.\n */\n isNumber: function(obj) {\n return !isNaN(parseFloat(obj)) && isFinite(obj);\n },\n /**\n * Return whether the given object (array or dictionary).\n */\n isEmpty: function(obj) {\n if (obj === null) {\n return true;\n }\n if (isArray(obj) || Utils.isString(obj)) {\n return obj.length === 0;\n }\n for (var key in obj) {\n if (Utils.has(obj, key)) {\n return false;\n }\n }\n return true;\n },\n simpleExtend: function(destination, source) {\n if (!Utils.isObject(source)) {\n return;\n }\n\n for (var name in source) {\n destination[name] = source[name];\n }\n },\n /**\n * Returns an array of the specified size and with each entry set to the given value.\n * @param size\n * @param value\n * @returns {Array}\n */\n initArray: function createIdArray(size, value) {\n var array = [];\n for (var i = 0; i < size; ++i) {\n array[i] = value;\n }\n return array;\n },\n serializePoints: function(points) {\n var res = [];\n for (var i = 0; i < points.length; i++) {\n var p = points[i];\n res.push(p.x + \";\" + p.y);\n }\n return res.join(\";\");\n },\n deserializePoints: function(s) {\n var v = s.split(\";\"), points = [];\n if (v.length % 2 !== 0) {\n throw \"Not an array of points.\";\n }\n for (var i = 0; i < v.length; i += 2) {\n points.push(new diagram.Point(\n parseInt(v[i], 10),\n parseInt(v[i + 1], 10)\n ));\n }\n return points;\n },\n /**\n * Returns an integer within the given bounds.\n * @param lower The inclusive lower bound.\n * @param upper The exclusive upper bound.\n * @returns {number}\n */\n randomInteger: function(lower, upper) {\n return parseInt(Math.floor(Math.random() * upper) + lower, 10);\n } ,\n /*\n Depth-first traversal of the given node.\n */\n DFT: function(el, func) {\n func(el);\n if (el.childNodes) {\n for (var i = 0; i < el.childNodes.length; i++) {\n var item = el.childNodes[i];\n this.DFT(item, func);\n }\n }\n },\n /*\n Returns the angle in degrees for the given matrix\n */\n getMatrixAngle: function(m) {\n if (m === null || m.d === 0) {\n return 0;\n }\n return Math.atan2(m.b, m.d) * 180 / Math.PI;\n },\n\n /*\n Returns the scaling factors for the given matrix.\n */\n getMatrixScaling: function(m) {\n var sX = Math.sqrt(m.a * m.a + m.c * m.c);\n var sY = Math.sqrt(m.b * m.b + m.d * m.d);\n return [sX, sY];\n }\n\n });\n\n /**\n * The Range defines an array of equally separated numbers.\n * @param start The start-value of the Range.\n * @param stop The end-value of the Range.\n * @param step The separation between the values (default:1).\n * @returns {Array}\n */\n function Range(start, stop, step) {\n if (typeof start == 'undefined' || typeof stop == 'undefined') {\n return [];\n }\n if (step && Utils.sign(stop - start) != Utils.sign(step)) {\n throw \"The sign of the increment should allow to reach the stop-value.\";\n }\n step = step || 1;\n start = start || 0;\n stop = stop || start;\n if ((stop - start) / step === Infinity) {\n throw \"Infinite range defined.\";\n }\n var range = [], i = -1, j;\n\n function rangeIntegerScale(x) {\n var k = 1;\n while (x * k % 1) {\n k *= 10;\n }\n return k;\n }\n\n var k = rangeIntegerScale(Math.abs(step));\n start *= k;\n stop *= k;\n step *= k;\n if (start > stop && step > 0) {\n step = -step;\n }\n if (step < 0) {\n while ((j = start + step * ++i) >= stop) {\n range.push(j / k);\n }\n }\n else {\n while ((j = start + step * ++i) <= stop) {\n range.push(j / k);\n }\n }\n return range;\n }\n\n /*-------------------Diverse math functions----------------------------*/\n\n function findRadian(start, end) {\n if (start == end) {\n return 0;\n }\n var sngXComp = end.x - start.x,\n sngYComp = start.y - end.y,\n atan = Math.atan(sngXComp / sngYComp);\n if (sngYComp >= 0) {\n return sngXComp < 0 ? atan + (2 * Math.PI) : atan;\n }\n return atan + Math.PI;\n }\n\n Utils.sign = function(number) {\n return number ? number < 0 ? -1 : 1 : 0;\n };\n\n Utils.findAngle = function(center, end) {\n return findRadian(center, end) * 180 / Math.PI;\n };\n\n /*-------------------Array Helpers ----------------------------*/\n\n Utils.forEach = function(arr, iterator, thisRef) {\n for (var i = 0; i < arr.length; i++) {\n iterator.call(thisRef, arr[i], i, arr);\n }\n };\n\n Utils.any = function(arr, predicate) {\n for (var i = 0; i < arr.length; ++i) {\n if (predicate(arr[i])) {\n return arr[i];\n }\n }\n return null;\n };\n\n Utils.remove = function(arr, what) {\n var ax;\n while ((ax = Utils.indexOf(arr, what)) !== -1) {\n arr.splice(ax, 1);\n }\n return arr;\n };\n\n Utils.contains = function(arr, obj) {\n return Utils.indexOf(arr, obj) !== -1;\n };\n\n Utils.indexOf = function(arr, what) {\n return $.inArray(what, arr);\n };\n\n Utils.fold = function(list, iterator, acc, context) {\n var initial = arguments.length > 2;\n\n for (var i = 0; i < list.length; i++) {\n var value = list[i];\n if (!initial) {\n acc = value;\n initial = true;\n }\n else {\n acc = iterator.call(context, acc, value, i, list);\n }\n }\n\n if (!initial) {\n throw 'Reduce of empty array with no initial value';\n }\n\n return acc;\n };\n\n Utils.find = function(arr, iterator, context) {\n var result;\n Utils.any(arr, function(value, index, list) {\n if (iterator.call(context, value, index, list)) {\n result = value;\n return true;\n }\n return false;\n });\n return result;\n };\n\n Utils.first = function(arr, constraint, context) {\n if (arr.length === 0) {\n return null;\n }\n if (Utils.isUndefined(constraint)) {\n return arr[0];\n }\n\n return Utils.find(arr, constraint, context);\n };\n\n /**\n * Inserts the given element at the specified position and returns the result.\n */\n Utils.insert = function(arr, element, position) {\n arr.splice(position, 0, element);\n return arr;\n };\n\n Utils.all = function(arr, iterator, context) {\n var result = true;\n var value;\n\n for (var i = 0; i < arr.length; i++) {\n value = arr[i];\n result = result && iterator.call(context, value, i, arr);\n\n if (!result) {\n break;\n }\n }\n\n return result;\n };\n\n Utils.clear = function(arr) {\n arr.splice(0, arr.length);\n };\n\n /**\n * Sort the arrays on the basis of the first one (considered as keys and the other array as values).\n * @param a\n * @param b\n * @param sortfunc (optiona) sorting function for the values in the first array\n */\n Utils.bisort = function(a, b, sortfunc) {\n if (Utils.isUndefined(a)) {\n throw \"First array is not specified.\";\n }\n if (Utils.isUndefined(b)) {\n throw \"Second array is not specified.\";\n }\n if (a.length != b.length) {\n throw \"The two arrays should have equal length\";\n }\n\n var all = [], i;\n\n for (i = 0; i < a.length; i++) {\n all.push({ 'x': a[i], 'y': b[i] });\n }\n if (Utils.isUndefined(sortfunc)) {\n all.sort(function(m, n) {\n return m.x - n.x;\n });\n }\n else {\n all.sort(function(m, n) {\n return sortfunc(m.x, n.x);\n });\n }\n\n Utils.clear(a);\n Utils.clear(b);\n\n for (i = 0; i < all.length; i++) {\n a.push(all[i].x);\n b.push(all[i].y);\n }\n };\n\n Utils.addRange = function(arr, range) {\n arr.push.apply(arr, range);\n };\n\n var Easing = {\n easeInOut: function(pos) {\n return ((-Math.cos(pos * Math.PI) / 2) + 0.5);\n }\n };\n\n /**\n * An animation ticker driving an adapter which sets a particular\n * property in function of the tick.\n * @type {*}\n */\n var Ticker = kendo.Class.extend({\n init: function() {\n this.adapters = [];\n this.target = 0;\n this.tick = 0;\n this.interval = 20;\n this.duration = 800;\n this.lastTime = null;\n this.handlers = [];\n var _this = this;\n this.transition = Easing.easeInOut;\n this.timerDelegate = function() {\n _this.onTimerEvent();\n };\n },\n addAdapter: function(a) {\n this.adapters.push(a);\n },\n onComplete: function(handler) {\n this.handlers.push(handler);\n },\n removeHandler: function(handler) {\n this.handlers = $.grep(this.handlers, function(h) {\n return h !== handler;\n });\n },\n trigger: function() {\n var _this = this;\n if (this.handlers) {\n Utils.forEach(this.handlers, function(h) {\n return h.call(_this.caller !== null ? _this.caller : _this);\n });\n }\n },\n onStep: function() {\n },\n seekTo: function(to) {\n this.seekFromTo(this.tick, to);\n },\n seekFromTo: function(from, to) {\n this.target = Math.max(0, Math.min(1, to));\n this.tick = Math.max(0, Math.min(1, from));\n this.lastTime = new Date().getTime();\n if (!this.intervalId) {\n this.intervalId = window.setInterval(this.timerDelegate, this.interval);\n }\n },\n stop: function() {\n if (this.intervalId) {\n window.clearInterval(this.intervalId);\n this.intervalId = null;\n\n //this.trigger.call(this);\n this.trigger();\n // this.next();\n }\n },\n play: function(origin) {\n if (this.adapters.length === 0) {\n return;\n }\n if (origin !== null) {\n this.caller = origin;\n }\n this.initState();\n this.seekFromTo(0, 1);\n },\n reverse: function() {\n this.seekFromTo(1, 0);\n },\n initState: function() {\n if (this.adapters.length === 0) {\n return;\n }\n for (var i = 0; i < this.adapters.length; i++) {\n this.adapters[i].initState();\n }\n },\n propagate: function() {\n var value = this.transition(this.tick);\n\n for (var i = 0; i < this.adapters.length; i++) {\n this.adapters[i].update(value);\n }\n },\n onTimerEvent: function() {\n var now = new Date().getTime();\n var timePassed = now - this.lastTime;\n this.lastTime = now;\n var movement = (timePassed / this.duration) * (this.tick < this.target ? 1 : -1);\n if (Math.abs(movement) >= Math.abs(this.tick - this.target)) {\n this.tick = this.target;\n } else {\n this.tick += movement;\n }\n\n try {\n this.propagate();\n } finally {\n this.onStep.call(this);\n if (this.target == this.tick) {\n this.stop();\n }\n }\n }\n });\n\n kendo.deepExtend(diagram, {\n init: function(element) {\n kendo.init(element, diagram.ui);\n },\n\n Utils: Utils,\n Range: Range,\n Ticker: Ticker\n });\n })(window.kendo.jQuery);\n\n (function($, undefined$1) {\n // Imports ================================================================\n var kendo = window.kendo,\n diagram = kendo.dataviz.diagram,\n Class = kendo.Class,\n deepExtend = kendo.deepExtend,\n dataviz = kendo.dataviz,\n Utils = diagram.Utils,\n Point = dataviz.Point2D,\n isFunction = kendo.isFunction,\n contains = Utils.contains,\n map = $.map;\n\n // Constants ==============================================================\n var HITTESTAREA = 3,\n EPSILON = 1e-06;\n\n deepExtend(Point.fn, {\n plus: function(p) {\n return new Point(this.x + p.x, this.y + p.y);\n },\n minus: function(p) {\n return new Point(this.x - p.x, this.y - p.y);\n },\n offset: function(value) {\n return new Point(this.x - value, this.y - value);\n },\n times: function(s) {\n return new Point(this.x * s, this.y * s);\n },\n normalize: function() {\n if (this.length() === 0) {\n return new Point();\n }\n return this.times(1 / this.length());\n },\n length: function() {\n return Math.sqrt(this.x * this.x + this.y * this.y);\n },\n toString: function() {\n return \"(\" + this.x + \",\" + this.y + \")\";\n },\n lengthSquared: function() {\n return (this.x * this.x + this.y * this.y);\n },\n middleOf: function MiddleOf(p, q) {\n return new Point(q.x - p.x, q.y - p.y).times(0.5).plus(p);\n },\n toPolar: function(useDegrees) {\n var factor = 1;\n if (useDegrees) {\n factor = 180 / Math.PI;\n }\n var a = Math.atan2(Math.abs(this.y), Math.abs(this.x));\n var halfpi = Math.PI / 2;\n var len = this.length();\n if (this.x === 0) {\n // note that the angle goes down and not the usual mathematical convention\n\n if (this.y === 0) {\n return new Polar(0, 0);\n }\n if (this.y > 0) {\n return new Polar(len, factor * halfpi);\n }\n if (this.y < 0) {\n return new Polar(len, factor * 3 * halfpi);\n }\n }\n else if (this.x > 0) {\n if (this.y === 0) {\n return new Polar(len, 0);\n }\n if (this.y > 0) {\n return new Polar(len, factor * a);\n }\n if (this.y < 0) {\n return new Polar(len, factor * (4 * halfpi - a));\n }\n }\n else {\n if (this.y === 0) {\n return new Polar(len, 2 * halfpi);\n }\n if (this.y > 0) {\n return new Polar(len, factor * (2 * halfpi - a));\n }\n if (this.y < 0) {\n return new Polar(len, factor * (2 * halfpi + a));\n }\n }\n },\n isOnLine: function(from, to) {\n if (from.x > to.x) { // from must be the leftmost point\n var temp = to;\n to = from;\n from = temp;\n }\n var r1 = new Rect(from.x, from.y).inflate(HITTESTAREA, HITTESTAREA),\n r2 = new Rect(to.x, to.y).inflate(HITTESTAREA, HITTESTAREA), o1, u1;\n if (r1.union(r2).contains(this)) {\n if (from.x === to.x || from.y === to.y) {\n return true;\n }\n else if (from.y < to.y) {\n o1 = r1.x + (((r2.x - r1.x) * (this.y - (r1.y + r1.height))) / ((r2.y + r2.height) - (r1.y + r1.height)));\n u1 = (r1.x + r1.width) + ((((r2.x + r2.width) - (r1.x + r1.width)) * (this.y - r1.y)) / (r2.y - r1.y));\n }\n else {\n o1 = r1.x + (((r2.x - r1.x) * (this.y - r1.y)) / (r2.y - r1.y));\n u1 = (r1.x + r1.width) + ((((r2.x + r2.width) - (r1.x + r1.width)) * (this.y - (r1.y + r1.height))) / ((r2.y + r2.height) - (r1.y + r1.height)));\n }\n return (this.x > o1 && this.x < u1);\n }\n return false;\n }\n });\n\n deepExtend(Point, {\n parse: function(str) {\n var tempStr = str.slice(1, str.length - 1),\n xy = tempStr.split(\",\"),\n x = parseInt(xy[0], 10),\n y = parseInt(xy[1], 10);\n if (!isNaN(x) && !isNaN(y)) {\n return new Point(x, y);\n }\n }\n });\n\n /**\n * Structure combining a Point with two additional points representing the handles or tangents attached to the first point.\n * If the additional points are null or equal to the first point the path will be sharp.\n * Left and right correspond to the direction of the underlying path.\n */\n var PathDefiner = Class.extend(\n {\n init: function(p, left, right) {\n this.point = p;\n this.left = left;\n this.right = right;\n }\n }\n );\n\n /**\n * Defines a rectangular region.\n */\n var Rect = Class.extend({\n init: function(x, y, width, height) {\n this.x = x || 0;\n this.y = y || 0;\n this.width = width || 0;\n this.height = height || 0;\n },\n contains: function(point) {\n return ((point.x >= this.x) && (point.x <= (this.x + this.width)) && (point.y >= this.y) && (point.y <= (this.y + this.height)));\n },\n inflate: function(dx, dy) {\n if (dy === undefined$1) {\n dy = dx;\n }\n\n this.x -= dx;\n this.y -= dy;\n this.width += 2 * dx + 1;\n this.height += 2 * dy + 1;\n return this;\n },\n offset: function(dx, dy) {\n var x = dx, y = dy;\n if (dx instanceof Point) {\n x = dx.x;\n y = dx.y;\n }\n this.x += x;\n this.y += y;\n return this;\n },\n union: function(r) {\n var x1 = Math.min(this.x, r.x);\n var y1 = Math.min(this.y, r.y);\n var x2 = Math.max((this.x + this.width), (r.x + r.width));\n var y2 = Math.max((this.y + this.height), (r.y + r.height));\n return new Rect(x1, y1, x2 - x1, y2 - y1);\n },\n center: function() {\n return new Point(this.x + this.width / 2, this.y + this.height / 2);\n },\n top: function() {\n return new Point(this.x + this.width / 2, this.y);\n },\n right: function() {\n return new Point(this.x + this.width, this.y + this.height / 2);\n },\n bottom: function() {\n return new Point(this.x + this.width / 2, this.y + this.height);\n },\n left: function() {\n return new Point(this.x, this.y + this.height / 2);\n },\n topLeft: function() {\n return new Point(this.x, this.y);\n },\n topRight: function() {\n return new Point(this.x + this.width, this.y);\n },\n bottomLeft: function() {\n return new Point(this.x, this.y + this.height);\n },\n bottomRight: function() {\n return new Point(this.x + this.width, this.y + this.height);\n },\n clone: function() {\n return new Rect(this.x, this.y, this.width, this.height);\n },\n isEmpty: function() {\n return !this.width && !this.height;\n },\n equals: function(rect) {\n return this.x === rect.x && this.y === rect.y && this.width === rect.width && this.height === rect.height;\n },\n rotatedBounds: function(angle) {\n var rect = this.clone(),\n points = this.rotatedPoints(angle),\n tl = points[0],\n tr = points[1],\n br = points[2],\n bl = points[3];\n\n rect.x = Math.min(br.x, tl.x, tr.x, bl.x);\n rect.y = Math.min(br.y, tl.y, tr.y, bl.y);\n rect.width = Math.max(br.x, tl.x, tr.x, bl.x) - rect.x;\n rect.height = Math.max(br.y, tl.y, tr.y, bl.y) - rect.y;\n\n return rect;\n },\n rotatedPoints: function(angle) {\n var rect = this,\n c = rect.center(),\n br = rect.bottomRight().rotate(c, 360 - angle),\n tl = rect.topLeft().rotate(c, 360 - angle),\n tr = rect.topRight().rotate(c, 360 - angle),\n bl = rect.bottomLeft().rotate(c, 360 - angle);\n\n return [tl, tr, br, bl];\n },\n toString: function(delimiter) {\n delimiter = delimiter || \" \";\n\n return this.x + delimiter + this.y + delimiter + this.width + delimiter + this.height;\n },\n scale: function(scaleX, scaleY, staicPoint, adornerCenter, angle) {\n var tl = this.topLeft();\n var thisCenter = this.center();\n tl.rotate(thisCenter, 360 - angle).rotate(adornerCenter, angle);\n\n var delta = staicPoint.minus(tl);\n var scaled = new Point(delta.x * scaleX, delta.y * scaleY);\n var position = delta.minus(scaled);\n tl = tl.plus(position);\n tl.rotate(adornerCenter, 360 - angle).rotate(thisCenter, angle);\n\n this.x = tl.x;\n this.y = tl.y;\n\n this.width *= scaleX;\n this.height *= scaleY;\n },\n\n zoom: function(zoom) {\n this.x *= zoom;\n this.y *= zoom;\n this.width *= zoom;\n this.height *= zoom;\n return this;\n },\n\n overlaps: function(rect) {\n var bottomRight = this.bottomRight();\n var rectBottomRight = rect.bottomRight();\n var overlaps = !(bottomRight.x < rect.x || bottomRight.y < rect.y ||\n rectBottomRight.x < this.x || rectBottomRight.y < this.y);\n return overlaps;\n }\n });\n\n var Size = Class.extend({\n init: function(width, height) {\n this.width = width;\n this.height = height;\n }\n });\n\n Size.prototype.Empty = new Size(0, 0);\n\n Rect.toRect = function(rect) {\n if (!(rect instanceof Rect)) {\n rect = new Rect(rect.x, rect.y, rect.width, rect.height);\n }\n\n return rect;\n };\n\n Rect.empty = function() {\n return new Rect(0, 0, 0, 0);\n };\n\n Rect.fromPoints = function(p, q) {\n if (isNaN(p.x) || isNaN(p.y) || isNaN(q.x) || isNaN(q.y)) {\n throw \"Some values are NaN.\";\n }\n return new Rect(Math.min(p.x, q.x), Math.min(p.y, q.y), Math.abs(p.x - q.x), Math.abs(p.y - q.y));\n };\n\n function isNearZero(num) {\n return Math.abs(num) < EPSILON;\n }\n\n function intersectLine(start1, end1, start2, end2, isSegment) {\n var tangensdiff = ((end1.x - start1.x) * (end2.y - start2.y)) - ((end1.y - start1.y) * (end2.x - start2.x));\n if (isNearZero(tangensdiff)) {\n //parallel lines\n return;\n }\n\n var num1 = ((start1.y - start2.y) * (end2.x - start2.x)) - ((start1.x - start2.x) * (end2.y - start2.y));\n var num2 = ((start1.y - start2.y) * (end1.x - start1.x)) - ((start1.x - start2.x) * (end1.y - start1.y));\n var r = num1 / tangensdiff;\n var s = num2 / tangensdiff;\n\n if (isSegment && (r < 0 || r > 1 || s < 0 || s > 1)) {\n //r < 0 => line 1 is below line 2\n //r > 1 => line 1 is above line 2\n //s < 0 => line 2 is below line 1\n //s > 1 => line 2 is above line 1\n return;\n }\n\n return new Point(start1.x + (r * (end1.x - start1.x)), start1.y + (r * (end1.y - start1.y)));\n }\n\n var Intersect = {\n lines: function(start1, end1, start2, end2) {\n return intersectLine(start1, end1, start2, end2);\n },\n segments: function(start1, end1, start2, end2) {\n return intersectLine(start1, end1, start2, end2, true);\n },\n rectWithLine: function(rect, start, end) {\n return Intersect.segments(start, end, rect.topLeft(), rect.topRight()) ||\n Intersect.segments(start, end, rect.topRight(), rect.bottomRight()) ||\n Intersect.segments(start, end, rect.bottomLeft(), rect.bottomRight()) ||\n Intersect.segments(start, end, rect.topLeft(), rect.bottomLeft());\n },\n rects: function(rect1, rect2, angle) {\n var tl = rect2.topLeft(),\n tr = rect2.topRight(),\n bl = rect2.bottomLeft(),\n br = rect2.bottomRight();\n var center = rect2.center();\n if (angle) {\n tl = tl.rotate(center, angle);\n tr = tr.rotate(center, angle);\n bl = bl.rotate(center, angle);\n br = br.rotate(center, angle);\n }\n\n var intersect = rect1.contains(tl) ||\n rect1.contains(tr) ||\n rect1.contains(bl) ||\n rect1.contains(br) ||\n Intersect.rectWithLine(rect1, tl, tr) ||\n Intersect.rectWithLine(rect1, tl, bl) ||\n Intersect.rectWithLine(rect1, tr, br) ||\n Intersect.rectWithLine(rect1, bl, br);\n\n if (!intersect) {//last possible case is rect1 to be completely within rect2\n tl = rect1.topLeft();\n tr = rect1.topRight();\n bl = rect1.bottomLeft();\n br = rect1.bottomRight();\n\n if (angle) {\n var reverseAngle = 360 - angle;\n tl = tl.rotate(center, reverseAngle);\n tr = tr.rotate(center, reverseAngle);\n bl = bl.rotate(center, reverseAngle);\n br = br.rotate(center, reverseAngle);\n }\n\n intersect = rect2.contains(tl) ||\n rect2.contains(tr) ||\n rect2.contains(bl) ||\n rect2.contains(br);\n }\n\n return intersect;\n }\n };\n\n /**\n * Aligns two rectangles, where one is the container and the other is content.\n */\n var RectAlign = Class.extend({\n init: function(container) {\n this.container = Rect.toRect(container);\n },\n\n align: function(content, alignment) {\n var alignValues = alignment.toLowerCase().split(\" \");\n\n for (var i = 0; i < alignValues.length; i++) {\n content = this._singleAlign(content, alignValues[i]);\n }\n\n return content;\n },\n _singleAlign: function(content, alignment) {\n if (isFunction(this[alignment])) {\n return this[alignment](content);\n }\n else {\n return content;\n }\n },\n\n left: function(content) {\n return this._align(content, this._left);\n },\n center: function(content) {\n return this._align(content, this._center);\n },\n right: function(content) {\n return this._align(content, this._right);\n },\n stretch: function(content) {\n return this._align(content, this._stretch);\n },\n top: function(content) {\n return this._align(content, this._top);\n },\n middle: function(content) {\n return this._align(content, this._middle);\n },\n bottom: function(content) {\n return this._align(content, this._bottom);\n },\n\n _left: function(container, content) {\n content.x = container.x;\n },\n _center: function(container, content) {\n content.x = ((container.width - content.width) / 2) || 0;\n },\n _right: function(container, content) {\n content.x = container.width - content.width;\n },\n _top: function(container, content) {\n content.y = container.y;\n },\n _middle: function(container, content) {\n content.y = ((container.height - content.height) / 2) || 0;\n },\n _bottom: function(container, content) {\n content.y = container.height - content.height;\n },\n _stretch: function(container, content) {\n content.x = 0;\n content.y = 0;\n content.height = container.height;\n content.width = container.width;\n },\n _align: function(content, alignCalc) {\n content = Rect.toRect(content);\n alignCalc(this.container, content);\n\n return content;\n }\n });\n\n var Polar = Class.extend({\n init: function(r, a) {\n this.r = r;\n this.angle = a;\n }\n });\n\n /**\n * SVG transformation matrix.\n */\n var Matrix = Class.extend({\n init: function(a, b, c, d, e, f) {\n this.a = a || 0;\n this.b = b || 0;\n this.c = c || 0;\n this.d = d || 0;\n this.e = e || 0;\n this.f = f || 0;\n },\n plus: function(m) {\n this.a += m.a;\n this.b += m.b;\n this.c += m.c;\n this.d += m.d;\n this.e += m.e;\n this.f += m.f;\n },\n minus: function(m) {\n this.a -= m.a;\n this.b -= m.b;\n this.c -= m.c;\n this.d -= m.d;\n this.e -= m.e;\n this.f -= m.f;\n },\n times: function(m) {\n return new Matrix(\n this.a * m.a + this.c * m.b,\n this.b * m.a + this.d * m.b,\n this.a * m.c + this.c * m.d,\n this.b * m.c + this.d * m.d,\n this.a * m.e + this.c * m.f + this.e,\n this.b * m.e + this.d * m.f + this.f\n );\n },\n apply: function(p) {\n return new Point(this.a * p.x + this.c * p.y + this.e, this.b * p.x + this.d * p.y + this.f);\n },\n applyRect: function(r) {\n return Rect.fromPoints(this.apply(r.topLeft()), this.apply(r.bottomRight()));\n },\n toString: function() {\n return \"matrix(\" + this.a + \" \" + this.b + \" \" + this.c + \" \" + this.d + \" \" + this.e + \" \" + this.f + \")\";\n }\n });\n\n deepExtend(Matrix, {\n fromSVGMatrix: function(vm) {\n var m = new Matrix();\n m.a = vm.a;\n m.b = vm.b;\n m.c = vm.c;\n m.d = vm.d;\n m.e = vm.e;\n m.f = vm.f;\n return m;\n },\n fromMatrixVector: function(v) {\n var m = new Matrix();\n m.a = v.a;\n m.b = v.b;\n m.c = v.c;\n m.d = v.d;\n m.e = v.e;\n m.f = v.f;\n return m;\n },\n fromList: function(v) {\n if (v.length !== 6) {\n throw \"The given list should consist of six elements.\";\n }\n var m = new Matrix();\n m.a = v[0];\n m.b = v[1];\n m.c = v[2];\n m.d = v[3];\n m.e = v[4];\n m.f = v[5];\n return m;\n },\n translation: function(x, y) {\n var m = new Matrix();\n m.a = 1;\n m.b = 0;\n m.c = 0;\n m.d = 1;\n m.e = x;\n m.f = y;\n return m;\n },\n unit: function() {\n return new Matrix(1, 0, 0, 1, 0, 0);\n },\n rotation: function(angle, x, y) {\n var m = new Matrix();\n m.a = Math.cos(angle * Math.PI / 180);\n m.b = Math.sin(angle * Math.PI / 180);\n m.c = -m.b;\n m.d = m.a;\n m.e = (x - x * m.a + y * m.b) || 0;\n m.f = (y - y * m.a - x * m.b) || 0;\n return m;\n },\n scaling: function(scaleX, scaleY) {\n var m = new Matrix();\n m.a = scaleX;\n m.b = 0;\n m.c = 0;\n m.d = scaleY;\n m.e = 0;\n m.f = 0;\n return m;\n },\n parse: function(v) {\n var parts, nums;\n if (v) {\n v = v.trim();\n // of the form \"matrix(...)\"\n if (v.slice(0, 6).toLowerCase() === \"matrix\") {\n nums = v.slice(7, v.length - 1).trim();\n parts = nums.split(\",\");\n if (parts.length === 6) {\n return Matrix.fromList(map(parts, function(p) {\n return parseFloat(p);\n }));\n }\n parts = nums.split(\" \");\n if (parts.length === 6) {\n return Matrix.fromList(map(parts, function(p) {\n return parseFloat(p);\n }));\n }\n }\n // of the form \"(...)\"\n if (v.slice(0, 1) === \"(\" && v.slice(v.length - 1) === \")\") {\n v = v.substr(1, v.length - 1);\n }\n if (v.indexOf(\",\") > 0) {\n parts = v.split(\",\");\n if (parts.length === 6) {\n return Matrix.fromList(map(parts, function(p) {\n return parseFloat(p);\n }));\n }\n }\n if (v.indexOf(\" \") > 0) {\n parts = v.split(\" \");\n if (parts.length === 6) {\n return Matrix.fromList(map(parts, function(p) {\n return parseFloat(p);\n }));\n }\n }\n }\n return parts;\n }\n });\n\n /**\n * SVG transformation represented as a vector.\n */\n var MatrixVector = Class.extend({\n init: function(a, b, c, d, e, f) {\n this.a = a || 0;\n this.b = b || 0;\n this.c = c || 0;\n this.d = d || 0;\n this.e = e || 0;\n this.f = f || 0;\n },\n fromMatrix: function FromMatrix(m) {\n var v = new MatrixVector();\n v.a = m.a;\n v.b = m.b;\n v.c = m.c;\n v.d = m.d;\n v.e = m.e;\n v.f = m.f;\n return v;\n }\n });\n\n /**\n * Returns a value with Gaussian (normal) distribution.\n * @param mean The mean value of the distribution.\n * @param deviation The deviation (spreading at half-height) of the distribution.\n * @returns {number}\n */\n function normalVariable(mean, deviation) {\n var x, y, r;\n do {\n x = Math.random() * 2 - 1;\n y = Math.random() * 2 - 1;\n r = x * x + y * y;\n }\n while (!r || r > 1);\n return mean + deviation * x * Math.sqrt(-2 * Math.log(r) / r);\n }\n\n /**\n * Returns a random identifier which can be used as an ID of objects, eventually augmented with a prefix.\n * @returns {string}\n */\n function randomId(length) {\n if (Utils.isUndefined(length)) {\n length = 10;\n }\n // old version return Math.floor((1 + Math.random()) * 0x1000000).toString(16).substring(1);\n var result = '';\n var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n for (var i = length; i > 0; --i) {\n result += chars.charAt(Math.round(Math.random() * (chars.length - 1)));\n }\n return result;\n }\n\n var Geometry = {\n\n /**\n * Returns the squared distance to the line defined by the two given Points.\n * @param p An arbitrary Point.\n * @param a An endpoint of the line or segment.\n * @param b The complementary endpoint of the line or segment.\n */\n _distanceToLineSquared: function(p, a, b) {\n function d2(pt1, pt2) {\n return (pt1.x - pt2.x) * (pt1.x - pt2.x) + (pt1.y - pt2.y) * (pt1.y - pt2.y);\n }\n\n if (a === b) { // returns the distance of p to a\n return d2(p, a);\n }\n\n var vx = b.x - a.x,\n vy = b.y - a.y,\n dot = (p.x - a.x) * vx + (p.y - a.y) * vy;\n if (dot < 0) {\n return d2(a, p); // sits on side of a\n }\n\n dot = (b.x - p.x) * vx + (b.y - p.y) * vy;\n if (dot < 0) {\n return d2(b, p); // sits on side of b\n }\n // regular case, use crossproduct to get the sine out\n dot = (b.x - p.x) * vy - (b.y - p.y) * vx;\n return dot * dot / (vx * vx + vy * vy);\n },\n\n /**\n * Returns the distance to the line defined by the two given Points.\n * @param p An arbitrary Point.\n * @param a An endpoint of the line or segment.\n * @param b The complementary endpoint of the line or segment.\n */\n distanceToLine: function(p, a, b) {\n return Math.sqrt(this._distanceToLineSquared(p, a, b));\n },\n\n /**\n * Returns the distance of the given points to the polyline defined by the points.\n * @param p An arbitrary point.\n * @param points The points defining the polyline.\n * @returns {Number}\n */\n distanceToPolyline: function(p, points) {\n var minimum = Number.MAX_VALUE;\n if (Utils.isUndefined(points) || points.length === 0) {\n return Number.MAX_VALUE;\n }\n for (var s = 0; s < points.length - 1; s++) {\n var p1 = points[s];\n var p2 = points[s + 1];\n\n var d = this._distanceToLineSquared(p, p1, p2);\n if (d < minimum) {\n minimum = d;\n }\n }\n return Math.sqrt(minimum);\n }\n };\n\n /*---------------The HashTable structure--------------------------------*/\n\n /**\n * Represents a collection of key-value pairs that are organized based on the hash code of the key.\n * _buckets[hashId] = {key: key, value:...}\n * Important: do not use the standard Array access method, use the get/set methods instead.\n * See http://en.wikipedia.org/wiki/Hash_table\n */\n var HashTable = kendo.Class.extend({\n init: function() {\n this._buckets = [];\n this.length = 0;\n },\n\n /**\n * Adds the literal object with the given key (of the form {key: key,....}).\n */\n add: function(key, value) {\n\n var obj = this._createGetBucket(key);\n if (Utils.isDefined(value)) {\n obj.value = value;\n }\n return obj;\n },\n\n /**\n * Gets the literal object with the given key.\n */\n get: function(key) {\n if (this._bucketExists(key)) {\n return this._createGetBucket(key);\n }\n return null;\n },\n\n /**\n * Set the key-value pair.\n * @param key The key of the entry.\n * @param value The value to set. If the key already exists the value will be overwritten.\n */\n set: function(key, value) {\n this.add(key, value);\n },\n\n /**\n * Determines whether the HashTable contains a specific key.\n */\n containsKey: function(key) {\n return this._bucketExists(key);\n },\n\n /**\n * Removes the element with the specified key from the hashtable.\n * Returns the removed bucket.\n */\n remove: function(key) {\n if (this._bucketExists(key)) {\n var hashId = this._hash(key);\n delete this._buckets[hashId];\n this.length--;\n return key;\n }\n },\n\n /**\n * Foreach with an iterator working on the key-value pairs.\n * @param func\n */\n forEach: function(func) {\n var hashes = this._hashes();\n for (var i = 0, len = hashes.length; i < len; i++) {\n var hash = hashes[i];\n var bucket = this._buckets[hash];\n if (Utils.isUndefined(bucket)) {\n continue;\n }\n func(bucket);\n }\n },\n\n /**\n * Returns a (shallow) clone of the current HashTable.\n * @returns {HashTable}\n */\n clone: function() {\n var ht = new HashTable();\n var hashes = this._hashes();\n for (var i = 0, len = hashes.length; i < len; i++) {\n var hash = hashes[i];\n var bucket = this._buckets[hash];\n if (Utils.isUndefined(bucket)) {\n continue;\n }\n ht.add(bucket.key, bucket.value);\n }\n return ht;\n },\n\n /**\n * Returns the hashes of the buckets.\n * @returns {Array}\n * @private\n */\n _hashes: function() {\n var hashes = [];\n for (var hash in this._buckets) {\n if (this._buckets.hasOwnProperty(hash)) {\n hashes.push(hash);\n }\n }\n return hashes;\n },\n\n _bucketExists: function(key) {\n var hashId = this._hash(key);\n return Utils.isDefined(this._buckets[hashId]);\n },\n\n /**\n * Returns-adds the createGetBucket with the given key. If not present it will\n * be created and returned.\n * A createGetBucket is a literal object of the form {key: key, ...}.\n */\n _createGetBucket: function(key) {\n var hashId = this._hash(key);\n var bucket = this._buckets[hashId];\n if (Utils.isUndefined(bucket)) {\n bucket = { key: key };\n this._buckets[hashId] = bucket;\n this.length++;\n }\n return bucket;\n },\n\n /**\n * Hashing of the given key.\n */\n _hash: function(key) {\n if (Utils.isNumber(key)) {\n return key;\n }\n if (Utils.isString(key)) {\n return this._hashString(key);\n }\n if (Utils.isObject(key)) {\n return this._objectHashId(key);\n }\n throw \"Unsupported key type.\";\n },\n\n /**\n * Hashing of a string.\n */\n _hashString: function(s) {\n // see for example http://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript-jquery\n var result = 0;\n if (s.length === 0) {\n return result;\n }\n for (var i = 0; i < s.length; i++) {\n var ch = s.charCodeAt(i);\n result = ((result * 32) - result) + ch;\n }\n return result;\n },\n\n /**\n * Returns the unique identifier for an object. This is automatically assigned and add on the object.\n */\n _objectHashId: function(key) {\n var id = key._hashId;\n if (Utils.isUndefined(id)) {\n id = randomId();\n key._hashId = id;\n }\n return id;\n }\n });\n\n /*---------------The Dictionary structure--------------------------------*/\n\n /**\n * Represents a collection of key-value pairs.\n * Important: do not use the standard Array access method, use the get/Set methods instead.\n */\n var Dictionary = kendo.Observable.extend({\n /**\n * Initializes a new instance of the Dictionary class.\n * @param dictionary Loads the content of the given dictionary into this new one.\n */\n init: function(dictionary) {\n var that = this;\n kendo.Observable.fn.init.call(that);\n this._hashTable = new HashTable();\n this.length = 0;\n if (Utils.isDefined(dictionary)) {\n if (Array.isArray(dictionary)) {\n for (var i = 0; i < dictionary.length; i++) {\n this.add(dictionary[i]);\n }\n } else {\n dictionary.forEach(function(k, v) {\n this.add(k, v);\n }, this);\n }\n }\n },\n\n /**\n * Adds a key-value to the dictionary.\n * If the key already exists this will assign the given value to the existing entry.\n */\n add: function(key, value) {\n var entry = this._hashTable.get(key);\n if (!entry) {\n entry = this._hashTable.add(key);\n this.length++;\n this.trigger('changed');\n }\n entry.value = value;\n },\n\n /**\n * Set the key-value pair.\n * @param key The key of the entry.\n * @param value The value to set. If the key already exists the value will be overwritten.\n */\n set: function(key, value) {\n this.add(key, value);\n },\n\n /**\n * Gets the value associated with the given key in the dictionary.\n */\n get: function(key) {\n var entry = this._hashTable.get(key);\n if (entry) {\n return entry.value;\n }\n throw new Error(\"Cannot find key \" + key);\n },\n\n /**\n * Returns whether the dictionary contains the given key.\n */\n containsKey: function(key) {\n return this._hashTable.containsKey(key);\n },\n\n /**\n * Removes the element with the specified key from the dictionary.\n */\n remove: function(key) {\n if (this.containsKey(key)) {\n this.trigger(\"changed\");\n this.length--;\n return this._hashTable.remove(key);\n }\n },\n\n /**\n * The functional gets the key and value as parameters.\n */\n forEach: function(func, thisRef) {\n this._hashTable.forEach(function(entry) {\n func.call(thisRef, entry.key, entry.value);\n });\n },\n\n /**\n * Same as forEach except that only the value is passed to the functional.\n */\n forEachValue: function(func, thisRef) {\n this._hashTable.forEach(function(entry) {\n func.call(thisRef, entry.value);\n });\n },\n\n /**\n * Calls a defined callback function for each key in the dictionary.\n */\n forEachKey: function(func, thisRef) {\n this._hashTable.forEach(function(entry) {\n func.call(thisRef, entry.key);\n });\n },\n\n /**\n * Gets an array with all keys in the dictionary.\n */\n keys: function() {\n var keys = [];\n this.forEachKey(function(key) {\n keys.push(key);\n });\n return keys;\n }\n });\n\n /*---------------Queue structure--------------------------------*/\n\n var Queue = kendo.Class.extend({\n\n init: function() {\n this._tail = null;\n this._head = null;\n this.length = 0;\n },\n\n /**\n * Enqueues an object to the end of the queue.\n */\n enqueue: function(value) {\n var entry = { value: value, next: null };\n if (!this._head) {\n this._head = entry;\n this._tail = this._head;\n }\n else {\n this._tail.next = entry;\n this._tail = this._tail.next;\n }\n this.length++;\n },\n\n /**\n * Removes and returns the object at top of the queue.\n */\n dequeue: function() {\n if (this.length < 1) {\n throw new Error(\"The queue is empty.\");\n }\n var value = this._head.value;\n this._head = this._head.next;\n this.length--;\n return value;\n },\n\n contains: function(item) {\n var current = this._head;\n while (current) {\n if (current.value === item) {\n return true;\n }\n current = current.next;\n }\n return false;\n }\n });\n\n\n /**\n * While other data structures can have multiple times the same item a Set owns only\n * once a particular item.\n * @type {*}\n */\n var Set = kendo.Observable.extend({\n init: function(resource) {\n var that = this;\n kendo.Observable.fn.init.call(that);\n this._hashTable = new HashTable();\n this.length = 0;\n if (Utils.isDefined(resource)) {\n if (resource instanceof HashTable) {\n resource.forEach(function(d) {\n this.add(d);\n });\n }\n else if (resource instanceof Dictionary) {\n resource.forEach(function(k, v) {\n this.add({ key: k, value: v });\n }, this);\n }\n }\n },\n\n contains: function(item) {\n return this._hashTable.containsKey(item);\n },\n\n add: function(item) {\n var entry = this._hashTable.get(item);\n if (!entry) {\n this._hashTable.add(item, item);\n this.length++;\n this.trigger('changed');\n }\n },\n\n get: function(item) {\n if (this.contains(item)) {\n return this._hashTable.get(item).value;\n }\n else {\n return null;\n }\n },\n\n /**\n * Returns the hash of the item.\n * @param item\n * @returns {*}\n */\n hash: function(item) {\n return this._hashTable._hash(item);\n },\n\n /**\n * Removes the given item from the set. No exception is thrown if the item is not in the Set.\n * @param item\n */\n remove: function(item) {\n if (this.contains(item)) {\n this._hashTable.remove(item);\n this.length--;\n this.trigger('changed');\n }\n },\n /**\n * Foreach with an iterator working on the key-value pairs.\n * @param func\n */\n forEach: function(func, context) {\n this._hashTable.forEach(function(kv) {\n func(kv.value);\n }, context);\n },\n toArray: function() {\n var r = [];\n this.forEach(function(d) {\n r.push(d);\n });\n return r;\n }\n });\n\n /*----------------Node-------------------------------*/\n\n /**\n * Defines the node (vertex) of a Graph.\n */\n var Node = kendo.Class.extend({\n\n init: function(id, shape) {\n\n /**\n * Holds all the links incident with the current node.\n * Do not use this property to manage the incoming links, use the appropriate add/remove methods instead.\n */\n this.links = [];\n\n /**\n * Holds the links from the current one to another Node .\n * Do not use this property to manage the incoming links, use the appropriate add/remove methods instead.\n */\n this.outgoing = [];\n\n /**\n * Holds the links from another Node to the current one.\n * Do not use this property to manage the incoming links, use the appropriate add/remove methods instead.\n */\n this.incoming = [];\n\n /**\n * Holds the weight of this Node.\n */\n this.weight = 1;\n\n if (Utils.isDefined(id)) {\n this.id = id;\n }\n else {\n this.id = randomId();\n }\n if (Utils.isDefined(shape)) {\n this.associatedShape = shape;\n // transfer the shape's bounds to the runtime props\n var b = shape.bounds();\n this.width = b.width;\n this.height = b.height;\n this.x = b.x;\n this.y = b.y;\n }\n else {\n this.associatedShape = null;\n }\n /**\n * The payload of the node.\n * @type {null}\n */\n this.data = null;\n this.type = \"Node\";\n this.shortForm = \"Node '\" + this.id + \"'\";\n /**\n * Whether this is an injected node during the analysis or layout process.\n * @type {boolean}\n */\n this.isVirtual = false;\n },\n\n /**\n * Returns whether this node has no links attached.\n */\n isIsolated: function() {\n return Utils.isEmpty(this.links);\n },\n\n /**\n * Gets or sets the bounding rectangle of this node.\n * This should be considered as runtime data, the property is not hotlinked to a SVG item.\n */\n bounds: function(r) {\n if (!Utils.isDefined(r)) {\n return new diagram.Rect(this.x, this.y, this.width, this.height);\n }\n\n this.x = r.x;\n this.y = r.y;\n this.width = r.width;\n this.height = r.height;\n },\n\n /**\n * Returns whether there is at least one link with the given (complementary) node. This can be either an\n * incoming or outgoing link.\n */\n isLinkedTo: function(node) {\n var that = this;\n return Utils.any(that.links, function(link) {\n return link.getComplement(that) === node;\n });\n },\n\n /**\n * Gets the children of this node, defined as the adjacent nodes with a link from this node to the adjacent one.\n * @returns {Array}\n */\n getChildren: function() {\n if (this.outgoing.length === 0) {\n return [];\n }\n var children = [];\n for (var i = 0, len = this.outgoing.length; i < len; i++) {\n var link = this.outgoing[i];\n children.push(link.getComplement(this));\n }\n return children;\n },\n\n /**\n * Gets the parents of this node, defined as the adjacent nodes with a link from the adjacent node to this one.\n * @returns {Array}\n */\n getParents: function() {\n if (this.incoming.length === 0) {\n return [];\n }\n var parents = [];\n for (var i = 0, len = this.incoming.length; i < len; i++) {\n var link = this.incoming[i];\n parents.push(link.getComplement(this));\n }\n return parents;\n },\n\n /**\n * Returns a clone of the Node. Note that the identifier is not cloned since it's a different Node instance.\n * @returns {Node}\n */\n clone: function() {\n var copy = new Node();\n if (Utils.isDefined(this.weight)) {\n copy.weight = this.weight;\n }\n if (Utils.isDefined(this.balance)) {\n copy.balance = this.balance;\n }\n if (Utils.isDefined(this.owner)) {\n copy.owner = this.owner;\n }\n copy.associatedShape = this.associatedShape;\n copy.x = this.x;\n copy.y = this.y;\n copy.width = this.width;\n copy.height = this.height;\n return copy;\n },\n\n /**\n * Returns whether there is a link from the current node to the given node.\n */\n adjacentTo: function(node) {\n return this.isLinkedTo(node) !== null;\n },\n\n /**\n * Removes the given link from the link collection this node owns.\n * @param link\n */\n removeLink: function(link) {\n if (link.source === this) {\n Utils.remove(this.links, link);\n Utils.remove(this.outgoing, link);\n link.source = null;\n }\n\n if (link.target === this) {\n Utils.remove(this.links, link);\n Utils.remove(this.incoming, link);\n link.target = null;\n }\n },\n\n /**\n * Returns whether there is a (outgoing) link from the current node to the given one.\n */\n hasLinkTo: function(node) {\n return Utils.any(this.outgoing, function(link) {\n return link.target === node;\n });\n },\n\n /**\n * Returns the degree of this node, i.e. the sum of incoming and outgoing links.\n */\n degree: function() {\n return this.links.length;\n },\n\n /**\n * Returns whether this node is either the source or the target of the given link.\n */\n incidentWith: function(link) {\n return contains(this.links, link);\n },\n\n /**\n * Returns the links between this node and the given one.\n */\n getLinksWith: function(node) {\n return Utils.all(this.links, function(link) {\n return link.getComplement(this) === node;\n }, this);\n },\n\n /**\n * Returns the nodes (either parent or child) which are linked to the current one.\n */\n getNeighbors: function() {\n var neighbors = [];\n Utils.forEach(this.incoming, function(e) {\n neighbors.push(e.getComplement(this));\n }, this);\n Utils.forEach(this.outgoing, function(e) {\n neighbors.push(e.getComplement(this));\n }, this);\n return neighbors;\n }\n });\n\n /**\n * Defines a directed link (edge, connection) of a Graph.\n */\n var Link = kendo.Class.extend({\n\n init: function(source, target, id, connection) {\n if (Utils.isUndefined(source)) {\n throw \"The source of the new link is not set.\";\n }\n if (Utils.isUndefined(target)) {\n throw \"The target of the new link is not set.\";\n }\n var sourceFound, targetFound;\n if (Utils.isString(source)) {\n sourceFound = new Node(source);\n }\n else {\n sourceFound = source;\n }\n if (Utils.isString(target)) {\n targetFound = new Node(target);\n }\n else {\n targetFound = target;\n }\n\n this.source = sourceFound;\n this.target = targetFound;\n this.source.links.push(this);\n this.target.links.push(this);\n this.source.outgoing.push(this);\n this.target.incoming.push(this);\n if (Utils.isDefined(id)) {\n this.id = id;\n }\n else {\n this.id = randomId();\n }\n if (Utils.isDefined(connection)) {\n this.associatedConnection = connection;\n }\n else {\n this.associatedConnection = null;\n }\n this.type = \"Link\";\n this.shortForm = \"Link '\" + this.source.id + \"->\" + this.target.id + \"'\";\n },\n\n /**\n * Returns the complementary node of the given one, if any.\n */\n getComplement: function(node) {\n if (this.source !== node && this.target !== node) {\n throw \"The given node is not incident with this link.\";\n }\n return this.source === node ? this.target : this.source;\n },\n\n /**\n * Returns the overlap of the current link with the given one, if any.\n */\n getCommonNode: function(link) {\n if (this.source === link.source || this.source === link.target) {\n return this.source;\n }\n if (this.target === link.source || this.target === link.target) {\n return this.target;\n }\n return null;\n },\n\n /**\n * Returns whether the current link is bridging the given nodes.\n */\n isBridging: function(v1, v2) {\n return this.source === v1 && this.target === v2 || this.source === v2 && this.target === v1;\n },\n\n /**\n * Returns the source and target of this link as a tuple.\n */\n getNodes: function() {\n return [this.source, this.target];\n },\n\n /**\n * Returns whether the given node is either the source or the target of the current link.\n */\n incidentWith: function(node) {\n return this.source === node || this.target === node;\n },\n\n /**\n * Returns whether the given link is a continuation of the current one. This can be both\n * via an incoming or outgoing link.\n */\n adjacentTo: function(link) {\n return contains(this.source.links, link) || contains(this.target.links, link);\n },\n\n /**\n * Changes the source-node of this link.\n */\n changeSource: function(node) {\n Utils.remove(this.source.links, this);\n Utils.remove(this.source.outgoing, this);\n\n node.links.push(this);\n node.outgoing.push(this);\n\n this.source = node;\n },\n\n /**\n * Changes the target-node of this link.\n * @param node\n */\n changeTarget: function(node) {\n Utils.remove(this.target.links, this);\n Utils.remove(this.target.incoming, this);\n\n node.links.push(this);\n node.incoming.push(this);\n\n this.target = node;\n },\n\n /**\n * Changes both the source and the target nodes of this link.\n */\n changesNodes: function(v, w) {\n if (this.source === v) {\n this.changeSource(w);\n }\n else if (this.target === v) {\n this.changeTarget(w);\n }\n },\n\n /**\n * Reverses the direction of this link.\n */\n reverse: function() {\n var oldSource = this.source;\n var oldTarget = this.target;\n\n this.source = oldTarget;\n Utils.remove(oldSource.outgoing, this);\n this.source.outgoing.push(this);\n\n this.target = oldSource;\n Utils.remove(oldTarget.incoming, this);\n this.target.incoming.push(this);\n return this;\n },\n\n /**\n * Ensures that the given target defines the endpoint of this link.\n */\n directTo: function(target) {\n if (this.source !== target && this.target !== target) {\n throw \"The given node is not incident with this link.\";\n }\n if (this.target !== target) {\n this.reverse();\n }\n },\n\n /**\n * Returns a reversed clone of this link.\n */\n createReverseEdge: function() {\n var r = this.clone();\n r.reverse();\n r.reversed = true;\n return r;\n },\n\n /**\n * Returns a clone of this link.\n */\n clone: function() {\n var clone = new Link(this.source, this.target);\n return clone;\n }\n });\n\n /*--------------Graph structure---------------------------------*/\n /**\n * Defines a directed graph structure.\n * Note that the incidence structure resides in the nodes through the incoming and outgoing links collection, rahter than\n * inside the Graph.\n */\n var Graph = kendo.Class.extend({\n init: function(idOrDiagram) {\n /**\n * The links or edge collection of this Graph.\n * @type {Array}\n */\n this.links = [];\n /**\n * The node or vertex collection of this Graph.\n * @type {Array}\n */\n this.nodes = [];\n\n this._nodeMap = new Dictionary();\n /**\n * The optional reference to the Diagram on which this Graph is based.\n * @type {null}\n */\n this.diagram = null;\n\n /**\n * The root of this Graph. If not set explicitly the first Node with zero incoming links will be taken.\n * @type {null}\n * @private\n */\n this._root = null;\n if (Utils.isDefined(idOrDiagram)) {\n if (Utils.isString(idOrDiagram)) {\n this.id = idOrDiagram;\n }\n else {\n this.diagram = idOrDiagram;\n this.id = idOrDiagram.id;\n }\n }\n else {\n this.id = randomId();\n }\n\n /**\n * The bounds of this graph if the nodes have spatial extension defined.\n * @type {Rect}\n */\n this.bounds = new Rect();\n // keeps track whether the children & parents have been created\n this._hasCachedRelationships = false;\n this.type = \"Graph\";\n },\n /**\n * Caches the relational information of parents and children in the 'parents' and 'children'\n * properties.\n * @param forceRebuild If set to true the relational info will be rebuild even if already present.\n */\n cacheRelationships: function(forceRebuild) {\n if (Utils.isUndefined(forceRebuild)) {\n forceRebuild = false;\n }\n if (this._hasCachedRelationships && !forceRebuild) {\n return;\n }\n for (var i = 0, len = this.nodes.length; i < len; i++) {\n var node = this.nodes[i];\n node.children = this.getChildren(node);\n node.parents = this.getParents(node);\n }\n this._hasCachedRelationships = true;\n },\n\n /**\n * Assigns tree-levels to the nodes assuming this is a tree graph.\n * If not connected or not a tree the process will succeed but\n * will have little meaning.\n * @param startNode The node from where the level numbering starts, usually the root of the tree.\n * @param visited The collection of visited nodes.\n * @param offset The offset or starting counter of the level info.\n */\n assignLevels: function(startNode, offset, visited) {\n if (!startNode) {\n throw \"Start node not specified.\";\n }\n if (Utils.isUndefined(offset)) {\n offset = 0;\n }\n // if not done before, cache the parents and children\n this.cacheRelationships();\n if (Utils.isUndefined(visited)) {\n visited = new Dictionary();\n Utils.forEach(this.nodes, function(n) {\n visited.add(n, false);\n });\n }\n visited.set(startNode, true);\n startNode.level = offset;\n var children = startNode.children;\n for (var i = 0, len = children.length; i < len; i++) {\n var child = children[i];\n if (!child || visited.get(child)) {\n continue;\n }\n this.assignLevels(child, offset + 1, visited);\n }\n },\n\n /**\n * Gets or set the root of this graph.\n * If not set explicitly the first Node with zero incoming links will be taken.\n * @param value\n * @returns {*}\n */\n root: function(value) {\n if (Utils.isUndefined(value)) {\n if (!this._root) {\n // TODO: better to use the longest path for the most probable root?\n var found = Utils.first(this.nodes, function(n) {\n return n.incoming.length === 0;\n });\n if (found) {\n return found;\n }\n return Utils.first(this.nodes);\n }\n else {\n return this._root;\n }\n }\n else {\n this._root = value;\n }\n },\n\n /**\n * Returns the connected components of this graph.\n * Note that the returned graphs are made up of the nodes and links of this graph, i.e. a pointer to the items of this graph.\n * If you alter the items of the components you'll alter the original graph and vice versa.\n * @returns {Array}\n */\n getConnectedComponents: function() {\n this.componentIndex = 0;\n this.setItemIndices();\n var componentId = Utils.initArray(this.nodes.length, -1);\n\n for (var v = 0; v < this.nodes.length; v++) {\n if (componentId[v] === -1) {\n this._collectConnectedNodes(componentId, v);\n this.componentIndex++;\n }\n }\n\n var components = [], i;\n for (i = 0; i < this.componentIndex; ++i) {\n components[i] = new Graph();\n }\n for (i = 0; i < componentId.length; ++i) {\n var graph = components[componentId[i]];\n graph.addNodeAndOutgoings(this.nodes[i]);\n }\n // sorting the components in decreasing order of node count\n components.sort(function(a, b) {\n return b.nodes.length - a.nodes.length;\n });\n return components;\n },\n\n _collectConnectedNodes: function(setIds, nodeIndex) {\n setIds[nodeIndex] = this.componentIndex; // part of the current component\n var node = this.nodes[nodeIndex];\n Utils.forEach(node.links,\n function(link) {\n var next = link.getComplement(node);\n var nextId = next.index;\n if (setIds[nextId] === -1) {\n this._collectConnectedNodes(setIds, nextId);\n }\n }, this);\n },\n\n /**\n * Calculates the bounds of this Graph if the Nodes have spatial dimensions defined.\n * @returns {Rect}\n */\n calcBounds: function() {\n if (this.isEmpty()) {\n this.bounds = new Rect();\n return this.bounds;\n }\n var b = null;\n for (var i = 0, len = this.nodes.length; i < len; i++) {\n var node = this.nodes[i];\n if (!b) {\n b = node.bounds();\n }\n else {\n b = b.union(node.bounds());\n }\n }\n this.bounds = b;\n return this.bounds;\n },\n\n /**\n * Creates a spanning tree for the current graph.\n * Important: this will not return a spanning forest if the graph is disconnected.\n * Prim's algorithm finds a minimum-cost spanning tree of an edge-weighted, connected, undirected graph;\n * see http://en.wikipedia.org/wiki/Prim%27s_algorithm .\n * @param root The root of the spanning tree.\n * @returns {Graph}\n */\n getSpanningTree: function(root) {\n var tree = new Graph();\n var map = new Dictionary(), source, target;\n tree.root = root.clone();\n tree.root.level = 0;\n tree.root.id = root.id;\n map.add(root, tree.root);\n root.level = 0;\n\n var visited = [];\n var remaining = [];\n tree._addNode(tree.root);\n visited.push(root);\n remaining.push(root);\n\n var levelCount = 1;\n while (remaining.length > 0) {\n var next = remaining.pop();\n for (var ni = 0; ni < next.links.length; ni++) {\n var link = next.links[ni];\n var cn = link.getComplement(next);\n if (contains(visited, cn)) {\n continue;\n }\n\n cn.level = next.level + 1;\n if (levelCount < cn.level + 1) {\n levelCount = cn.level + 1;\n }\n if (!contains(remaining, cn)) {\n remaining.push(cn);\n }\n if (!contains(visited, cn)) {\n visited.push(cn);\n }\n if (map.containsKey(next)) {\n source = map.get(next);\n }\n else {\n source = next.clone();\n source.level = next.level;\n source.id = next.id;\n map.add(next, source);\n }\n if (map.containsKey(cn)) {\n target = map.get(cn);\n }\n else {\n target = cn.clone();\n target.level = cn.level;\n target.id = cn.id;\n map.add(cn, target);\n }\n var newLink = new Link(source, target);\n tree.addLink(newLink);\n }\n\n }\n\n var treeLevels = [];\n for (var i = 0; i < levelCount; i++) {\n treeLevels.push([]);\n }\n\n Utils.forEach(tree.nodes, function(node) {\n treeLevels[node.level].push(node);\n });\n\n tree.treeLevels = treeLevels;\n tree.cacheRelationships();\n return tree;\n },\n\n /**\n * Returns a random node in this graph.\n * @param excludedNodes The collection of nodes which should not be considered.\n * @param incidenceLessThan The maximum degree or incidence the random node should have.\n * @returns {*}\n */\n takeRandomNode: function(excludedNodes, incidenceLessThan) {\n if (Utils.isUndefined(excludedNodes)) {\n excludedNodes = [];\n }\n if (Utils.isUndefined(incidenceLessThan)) {\n incidenceLessThan = 4;\n }\n if (this.nodes.length === 0) {\n return null;\n }\n if (this.nodes.length === 1) {\n return contains(excludedNodes, this.nodes[0]) ? null : this.nodes[0];\n }\n var pool = $.grep(this.nodes, function(node) {\n return !contains(excludedNodes, node) && node.degree() <= incidenceLessThan;\n });\n if (Utils.isEmpty(pool)) {\n return null;\n }\n return pool[Utils.randomInteger(0, pool.length)];\n },\n\n /**\n * Returns whether this is an empty graph.\n */\n isEmpty: function() {\n return Utils.isEmpty(this.nodes);\n },\n\n /**\n * Checks whether the endpoints of the links are all in the nodes collection.\n */\n isHealthy: function() {\n return Utils.all(this.links, function(link) {\n return contains(this.nodes, link.source) && contains(this.nodes, link.target);\n }, this);\n },\n\n /**\n * Gets the parents of this node, defined as the adjacent nodes with a link from the adjacent node to this one.\n * @returns {Array}\n */\n getParents: function(n) {\n if (!this.hasNode(n)) {\n throw \"The given node is not part of this graph.\";\n }\n return n.getParents();\n },\n\n /**\n * Gets the children of this node, defined as the adjacent nodes with a link from this node to the adjacent one.\n * @returns {Array}\n */\n getChildren: function(n) {\n if (!this.hasNode(n)) {\n throw \"The given node is not part of this graph.\";\n }\n return n.getChildren();\n },\n\n /**\n * Adds a new link to the graph between the given nodes.\n */\n addLink: function(sourceOrLink, target, owner) {\n\n if (Utils.isUndefined(sourceOrLink)) {\n throw \"The source of the link is not defined.\";\n }\n if (Utils.isUndefined(target)) {\n // can only be undefined if the first one is a Link\n if (Utils.isDefined(sourceOrLink.type) && sourceOrLink.type === \"Link\") {\n this.addExistingLink(sourceOrLink);\n return;\n }\n else {\n throw \"The target of the link is not defined.\";\n }\n }\n\n var foundSource = this.getNode(sourceOrLink);\n if (Utils.isUndefined(foundSource)) {\n foundSource = this.addNode(sourceOrLink);\n }\n var foundTarget = this.getNode(target);\n if (Utils.isUndefined(foundTarget)) {\n foundTarget = this.addNode(target);\n }\n\n var newLink = new Link(foundSource, foundTarget);\n\n if (Utils.isDefined(owner)) {\n newLink.owner = owner;\n }\n\n /*newLink.source.outgoing.push(newLink);\n newLink.source.links.push(newLink);\n newLink.target.incoming.push(newLink);\n newLink.target.links.push(newLink);*/\n\n this.links.push(newLink);\n\n return newLink;\n },\n\n /**\n * Removes all the links in this graph.\n */\n removeAllLinks: function() {\n while (this.links.length > 0) {\n var link = this.links[0];\n this.removeLink(link);\n }\n },\n\n /**\n * Adds the given link to the current graph.\n */\n addExistingLink: function(link) {\n\n if (this.hasLink(link)) {\n return;\n }\n this.links.push(link);\n if (this.hasNode(link.source.id)) {\n // priority to the existing node with the id even if other props are different\n var s = this.getNode(link.source.id);\n link.changeSource(s);\n }\n else {\n this.addNode(link.source);\n }\n\n if (this.hasNode(link.target.id)) {\n var t = this.getNode(link.target.id);\n link.changeTarget(t);\n }\n else {\n this.addNode(link.target);\n }\n\n /* if (!link.source.outgoing.contains(link)) {\n link.source.outgoing.push(link);\n }\n if (!link.source.links.contains(link)) {\n link.source.links.push(link);\n }\n if (!link.target.incoming.contains(link)) {\n link.target.incoming.push(link);\n }\n if (!link.target.links.contains(link)) {\n link.target.links.push(link);\n }*/\n },\n\n /**\n * Returns whether the given identifier or Link is part of this graph.\n * @param linkOrId An identifier or a Link object.\n * @returns {*}\n */\n hasLink: function(linkOrId) {\n if (Utils.isString(linkOrId)) {\n return Utils.any(this.links, function(link) {\n return link.id === linkOrId;\n });\n }\n if (linkOrId.type === \"Link\") {\n return contains(this.links, linkOrId);\n }\n throw \"The given object is neither an identifier nor a Link.\";\n },\n /**\n * Gets the node with the specified Id or null if not part of this graph.\n */\n getNode: function(nodeOrId) {\n var id = nodeOrId.id || nodeOrId;\n if (this._nodeMap.containsKey(id)) {\n return this._nodeMap.get(id);\n }\n },\n\n /**\n * Returns whether the given node or node Id is part of this graph.\n */\n hasNode: function(nodeOrId) {\n var id = nodeOrId.id || nodeOrId;\n return this._nodeMap.containsKey(id);\n },\n\n _addNode: function(node) {\n this.nodes.push(node);\n this._nodeMap.add(node.id, node);\n },\n\n _removeNode: function(node) {\n Utils.remove(this.nodes, node);\n this._nodeMap.remove(node.id);\n },\n\n /**\n * Removes the given node from this graph.\n * The node can be specified as an object or as an identifier (string).\n */\n removeNode: function(nodeOrId) {\n var n = nodeOrId;\n if (Utils.isString(nodeOrId)) {\n n = this.getNode(nodeOrId);\n }\n\n if (Utils.isDefined(n)) {\n var links = n.links;\n n.links = [];\n for (var i = 0, len = links.length; i < len; i++) {\n var link = links[i];\n this.removeLink(link);\n }\n this._removeNode(n);\n }\n else {\n throw \"The identifier should be a Node or the Id (string) of a node.\";\n }\n },\n\n /**\n * Returns whether the given nodes are connected with a least one link independently of the direction.\n */\n areConnected: function(n1, n2) {\n return Utils.any(this.links, function(link) {\n return link.source == n1 && link.target == n2 || link.source == n2 && link.target == n1;\n });\n },\n\n /**\n * Removes the given link from this graph.\n */\n removeLink: function(link) {\n /* if (!this.links.contains(link)) {\n throw \"The given link is not part of the Graph.\";\n }\n */\n Utils.remove(this.links, link);\n\n Utils.remove(link.source.outgoing, link);\n Utils.remove(link.source.links, link);\n Utils.remove(link.target.incoming, link);\n Utils.remove(link.target.links, link);\n },\n\n /**\n * Adds a new node to this graph, if not already present.\n * The node can be an existing Node or the identifier of a new node.\n * No error is thrown if the node is already there and the existing one is returned.\n */\n addNode: function(nodeOrId, layoutRect, owner) {\n\n var newNode = null;\n\n if (!Utils.isDefined(nodeOrId)) {\n throw \"No Node or identifier for a new Node is given.\";\n }\n\n if (Utils.isString(nodeOrId)) {\n if (this.hasNode(nodeOrId)) {\n return this.getNode(nodeOrId);\n }\n newNode = new Node(nodeOrId);\n }\n else {\n if (this.hasNode(nodeOrId)) {\n return this.getNode(nodeOrId);\n }\n // todo: ensure that the param is a Node?\n newNode = nodeOrId;\n }\n\n if (Utils.isDefined(layoutRect)) {\n newNode.bounds(layoutRect);\n }\n\n if (Utils.isDefined(owner)) {\n newNode.owner = owner;\n }\n this._addNode(newNode);\n return newNode;\n },\n\n /**\n * Adds the given Node and its outgoing links.\n */\n addNodeAndOutgoings: function(node) {\n if (!this.hasNode(node)) {\n this._addNode(node);\n }\n\n var newLinks = node.outgoing;\n node.outgoing = [];\n Utils.forEach(newLinks, function(link) {\n this.addExistingLink(link);\n }, this);\n },\n\n /**\n * Sets the 'index' property on the links and nodes of this graph.\n */\n setItemIndices: function() {\n var i;\n for (i = 0; i < this.nodes.length; ++i) {\n this.nodes[i].index = i;\n }\n\n for (i = 0; i < this.links.length; ++i) {\n this.links[i].index = i;\n }\n },\n\n /**\n * Returns a clone of this graph.\n */\n clone: function(saveMapping) {\n var copy = new Graph();\n var save = Utils.isDefined(saveMapping) && saveMapping === true;\n if (save) {\n copy.nodeMap = new Dictionary();\n copy.linkMap = new Dictionary();\n }\n // we need a map even if the saveMapping is not set\n var map = new Dictionary();\n Utils.forEach(this.nodes, function(nOriginal) {\n var nCopy = nOriginal.clone();\n map.set(nOriginal, nCopy);\n copy._addNode(nCopy);\n\n if (save) {\n copy.nodeMap.set(nCopy, nOriginal);\n }\n });\n\n Utils.forEach(this.links, function(linkOriginal) {\n if (map.containsKey(linkOriginal.source) && map.containsKey(linkOriginal.target)) {\n var linkCopy = copy.addLink(map.get(linkOriginal.source), map.get(linkOriginal.target));\n if (save) {\n copy.linkMap.set(linkCopy, linkOriginal);\n }\n }\n });\n\n return copy;\n },\n\n /**\n * The parsing allows a quick way to create graphs.\n * - [\"n1->n2\", \"n2->n3\"]: creates the three nodes and adds the links\n * - [\"n1->n2\", {id: \"QSDF\"}, \"n2->n3\"]: same as previous but also performs a deep extend of the link between n1 and n2 with the given object.\n */\n linearize: function(addIds) {\n return Graph.Utils.linearize(this, addIds);\n },\n\n /**\n * Performs a depth-first traversal starting at the given node.\n * @param startNode a node or id of a node in this graph\n * @param action\n */\n depthFirstTraversal: function(startNode, action) {\n if (Utils.isUndefined(startNode)) {\n throw \"You need to supply a starting node.\";\n }\n if (Utils.isUndefined(action)) {\n throw \"You need to supply an action.\";\n }\n if (!this.hasNode(startNode)) {\n throw \"The given start-node is not part of this graph\";\n }\n var foundNode = this.getNode(startNode);// case the given one is an Id\n var visited = [];\n this._dftIterator(foundNode, action, visited);\n },\n\n _dftIterator: function(node, action, visited) {\n\n action(node);\n visited.push(node);\n var children = node.getChildren();\n for (var i = 0, len = children.length; i < len; i++) {\n var child = children[i];\n if (contains(visited, child)) {\n continue;\n }\n this._dftIterator(child, action, visited);\n }\n },\n\n /**\n * Performs a breadth-first traversal starting at the given node.\n * @param startNode a node or id of a node in this graph\n * @param action\n */\n breadthFirstTraversal: function(startNode, action) {\n\n if (Utils.isUndefined(startNode)) {\n throw \"You need to supply a starting node.\";\n }\n if (Utils.isUndefined(action)) {\n throw \"You need to supply an action.\";\n }\n\n if (!this.hasNode(startNode)) {\n throw \"The given start-node is not part of this graph\";\n }\n var foundNode = this.getNode(startNode);// case the given one is an Id\n var queue = new Queue();\n var visited = [];\n queue.enqueue(foundNode);\n\n while (queue.length > 0) {\n var node = queue.dequeue();\n action(node);\n visited.push(node);\n var children = node.getChildren();\n for (var i = 0, len = children.length; i < len; i++) {\n var child = children[i];\n if (contains(visited, child) || contains(queue, child)) {\n continue;\n }\n queue.enqueue(child);\n }\n }\n },\n\n /**\n * This is the classic Tarjan algorithm for strongly connected components.\n * See e.g. http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm\n * @param excludeSingleItems Whether isolated nodes should be excluded from the analysis.\n * @param node The start node from which the analysis starts.\n * @param indices Numbers the nodes consecutively in the order in which they are discovered.\n * @param lowLinks The smallest index of any node known to be reachable from the node, including the node itself\n * @param connected The current component.\n * @param stack The bookkeeping stack of things to visit.\n * @param index The counter of visited nodes used to assign the indices.\n * @private\n */\n _stronglyConnectedComponents: function(excludeSingleItems, node, indices, lowLinks, connected, stack, index) {\n indices.add(node, index);\n lowLinks.add(node, index);\n index++;\n\n stack.push(node);\n\n var children = node.getChildren(), next;\n for (var i = 0, len = children.length; i < len; i++) {\n next = children[i];\n if (!indices.containsKey(next)) {\n this._stronglyConnectedComponents(excludeSingleItems, next, indices, lowLinks, connected, stack, index);\n lowLinks.add(node, Math.min(lowLinks.get(node), lowLinks.get(next)));\n }\n else if (contains(stack, next)) {\n lowLinks.add(node, Math.min(lowLinks.get(node), indices.get(next)));\n }\n }\n // If v is a root node, pop the stack and generate a strong component\n if (lowLinks.get(node) === indices.get(node)) {\n var component = [];\n do {\n next = stack.pop();\n component.push(next);\n }\n while (next !== node);\n if (!excludeSingleItems || (component.length > 1)) {\n connected.push(component);\n }\n }\n },\n\n /**\n * Returns the cycles found in this graph.\n * The returned arrays consist of the nodes which are strongly coupled.\n * @param excludeSingleItems Whether isolated nodes should be excluded.\n * @returns {Array} The array of cycles found.\n */\n findCycles: function(excludeSingleItems) {\n if (Utils.isUndefined(excludeSingleItems)) {\n excludeSingleItems = true;\n }\n var indices = new Dictionary();\n var lowLinks = new Dictionary();\n var connected = [];\n var stack = [];\n for (var i = 0, len = this.nodes.length; i < len; i++) {\n var node = this.nodes[i];\n if (indices.containsKey(node)) {\n continue;\n }\n this._stronglyConnectedComponents(excludeSingleItems, node, indices, lowLinks, connected, stack, 0);\n }\n return connected;\n },\n\n /**\n * Returns whether this graph is acyclic.\n * @returns {*}\n */\n isAcyclic: function() {\n return Utils.isEmpty(this.findCycles());\n },\n\n /**\n * Returns whether the given graph is a subgraph of this one.\n * @param other Another graph instance.\n */\n isSubGraph: function(other) {\n var otherArray = other.linearize();\n var thisArray = this.linearize();\n return Utils.all(otherArray, function(s) {\n return contains(thisArray, s);\n });\n },\n\n /**\n * Makes an acyclic graph from the current (connected) one.\n * * @returns {Array} The reversed links.\n */\n makeAcyclic: function() {\n // if empty or almost empty\n if (this.isEmpty() || this.nodes.length <= 1 || this.links.length <= 1) {\n return [];\n }\n // singular case of just two nodes\n if (this.nodes.length == 2) {\n var result = [];\n if (this.links.length > 1) {\n var oneLink = this.links[0];\n var oneNode = oneLink.source;\n for (var i = 0, len = this.links.length; i < len; i++) {\n var link = this.links[i];\n if (link.source == oneNode) {\n continue;\n }\n var rev = link.reverse();\n result.push(rev);\n }\n }\n return result;\n }\n\n var copy = this.clone(true); // copy.nodeMap tells you the mapping\n var N = this.nodes.length;\n\n var intensityCatalog = new Dictionary();\n\n /**\n * If there are both incoming and outgoing links this will return the flow intensity (out-in).\n * Otherwise the node acts as a flow source with N specifying the (equal) intensity.\n * @param node\n * @returns {number}\n */\n var flowIntensity = function(node) {\n if (node.outgoing.length === 0) {\n return (2 - N);\n }\n else if (node.incoming.length === 0) {\n return (N - 2);\n }\n else {\n return node.outgoing.length - node.incoming.length;\n }\n };\n\n /**\n * Collects the nodes with the same intensity.\n * @param node\n * @param intensityCatalog\n */\n var catalogEqualIntensity = function(node, intensityCatalog) {\n var intensity = flowIntensity(node, N);\n if (!intensityCatalog.containsKey(intensity)) {\n intensityCatalog.set(intensity, []);\n }\n intensityCatalog.get(intensity).push(node);\n };\n\n Utils.forEach(copy.nodes, function(v) {\n catalogEqualIntensity(v, intensityCatalog);\n });\n\n var sourceStack = [];\n var targetStack = [];\n\n while (copy.nodes.length > 0) {\n var source, target, intensity;\n if (intensityCatalog.containsKey(2 - N)) {\n var targets = intensityCatalog.get(2 - N); // nodes without outgoings\n while (targets.length > 0) {\n target = targets.pop();\n for (var li = 0; li < target.links.length; li++) {\n var targetLink = target.links[li];\n source = targetLink.getComplement(target);\n intensity = flowIntensity(source, N);\n Utils.remove(intensityCatalog.get(intensity), source);\n source.removeLink(targetLink);\n catalogEqualIntensity(source, intensityCatalog);\n }\n copy._removeNode(target);\n targetStack.unshift(target);\n }\n }\n\n // move sources to sourceStack\n if (intensityCatalog.containsKey(N - 2)) {\n var sources = intensityCatalog.get(N - 2); // nodes without incomings\n while (sources.length > 0) {\n source = sources.pop();\n for (var si = 0; si < source.links.length; si++) {\n var sourceLink = source.links[si];\n target = sourceLink.getComplement(source);\n intensity = flowIntensity(target, N);\n Utils.remove(intensityCatalog.get(intensity), target);\n target.removeLink(sourceLink);\n catalogEqualIntensity(target, intensityCatalog);\n }\n sourceStack.push(source);\n copy._removeNode(source);\n }\n }\n\n if (copy.nodes.length > 0) {\n for (var k = N - 3; k > 2 - N; k--) {\n if (intensityCatalog.containsKey(k) &&\n intensityCatalog.get(k).length > 0) {\n var maxdiff = intensityCatalog.get(k);\n var v = maxdiff.pop();\n for (var ri = 0; ri < v.links.length; ri++) {\n var ril = v.links[ri];\n var u = ril.getComplement(v);\n intensity = flowIntensity(u, N);\n Utils.remove(intensityCatalog.get(intensity), u);\n u.removeLink(ril);\n catalogEqualIntensity(u, intensityCatalog);\n }\n sourceStack.push(v);\n copy._removeNode(v);\n break;\n }\n }\n }\n }\n\n sourceStack = sourceStack.concat(targetStack);\n\n var vertexOrder = new Dictionary();\n for (var kk = 0; kk < this.nodes.length; kk++) {\n vertexOrder.set(copy.nodeMap.get(sourceStack[kk]), kk);\n }\n\n var reversedEdges = [];\n Utils.forEach(this.links, function(link) {\n if (vertexOrder.get(link.source) > vertexOrder.get(link.target)) {\n link.reverse();\n reversedEdges.push(link);\n }\n });\n return reversedEdges;\n }\n });\n\n /**\n * A collection of predefined graphs for demo and testing purposes.\n */\n Graph.Predefined = {\n /**\n * Eight-shapes graph all connected in a cycle.\n * @returns {*}\n * @constructor\n */\n EightGraph: function() {\n return Graph.Utils.parse([ \"1->2\", \"2->3\", \"3->4\", \"4->1\", \"3->5\", \"5->6\", \"6->7\", \"7->3\"]);\n },\n\n /**\n * Creates a typical mindmap diagram.\n * @returns {*}\n * @constructor\n */\n Mindmap: function() {\n return Graph.Utils.parse([\"0->1\", \"0->2\", \"0->3\", \"0->4\", \"0->5\", \"1->6\", \"1->7\", \"7->8\", \"2->9\", \"9->10\", \"9->11\", \"3->12\",\n \"12->13\", \"13->14\", \"4->15\", \"4->16\", \"15->17\", \"15->18\", \"18->19\", \"18->20\", \"14->21\", \"14->22\", \"5->23\", \"23->24\", \"23->25\", \"6->26\"]);\n },\n\n /**\n * Three nodes connected in a cycle.\n * @returns {*}\n * @constructor\n */\n ThreeGraph: function() {\n return Graph.Utils.parse([ \"1->2\", \"2->3\", \"3->1\"]);\n },\n\n /**\n * A tree with each node having two children.\n * @param levels How many levels the binary tree should have.\n * @returns {diagram.Graph}\n * @constructor\n */\n BinaryTree: function(levels) {\n if (Utils.isUndefined(levels)) {\n levels = 5;\n }\n return Graph.Utils.createBalancedTree(levels, 2);\n },\n\n /**\n * A linear graph (discrete line segment).\n * @param length How many segments (the node count is hence (length+1)).\n * @returns {diagram.Graph}\n * @constructor\n */\n Linear: function(length) {\n if (Utils.isUndefined(length)) {\n length = 10;\n }\n return Graph.Utils.createBalancedTree(length, 1);\n },\n\n /**\n * A standard tree-graph with the specified levels and children (siblings) count.\n * Note that for a balanced tree of level N and sibling count s, counting the root as level zero:\n * - NodeCount = (1-s^(N+1))/(1-s)]\n * - LinkCount = s.(1-s^N)/(1-s)\n * @param levels How many levels the tree should have.\n * @param siblingsCount How many siblings each level should have.\n * @returns {diagram.Graph}\n * @constructor\n */\n Tree: function(levels, siblingsCount) {\n return Graph.Utils.createBalancedTree(levels, siblingsCount);\n },\n\n /**\n * Creates a forest.\n * Note that for a balanced forest of level N, sibling count s and tree count t, counting the root as level zero:\n * - NodeCount = t.(1-s^(N+1))/(1-s)]\n * - LinkCount = t.s.(1-s^N)/(1-s)\n * @param levels How many levels the tree should have.\n * @param siblingsCount How many siblings each level should have.\n * @param trees The amount of trees the forest should have.\n * @returns {diagram.Graph}\n * @constructor\n */\n Forest: function(levels, siblingsCount, trees) {\n return Graph.Utils.createBalancedForest(levels, siblingsCount, trees);\n },\n\n /**\n * A workflow-like graph with cycles.\n * @returns {*}\n * @constructor\n */\n Workflow: function() {\n return Graph.Utils.parse(\n [\"0->1\", \"1->2\", \"2->3\", \"1->4\", \"4->3\", \"3->5\", \"5->6\", \"6->3\", \"6->7\", \"5->4\"]\n );\n },\n\n /**\n * A grid graph with the direction of the links avoiding cycles.\n * Node count: (n+1).(m+1)\n * Link count: n.(m+1) + m.(n+1)\n * @param n Horizontal count of grid cells. If zero this will result in a linear graph.\n * @param m Vertical count of grid cells. If zero this will result in a linear graph.\n * @constructor\n */\n Grid: function(n, m) {\n var g = new diagram.Graph();\n if (n <= 0 && m <= 0) {\n return g;\n }\n\n for (var i = 0; i < n + 1; i++) {\n var previous = null;\n for (var j = 0; j < m + 1; j++) {\n // using x-y coordinates to name the nodes\n var node = new Node(i.toString() + \".\" + j.toString());\n g.addNode(node);\n if (previous) {\n g.addLink(previous, node);\n }\n if (i > 0) {\n var left = g.getNode((i - 1).toString() + \".\" + j.toString());\n g.addLink(left, node);\n }\n previous = node;\n }\n }\n return g;\n }\n\n };\n\n /**\n * Graph generation and other utilities.\n */\n Graph.Utils = {\n /**\n * The parsing allows a quick way to create graphs.\n * - [\"n1->n2\", \"n2->n3\"]: creates the three nodes and adds the links\n * - [\"n1->n2\", {id: \"id177\"}, \"n2->n3\"]: same as previous but also performs a deep extend of the link between n1 and n2 with the given object.\n */\n parse: function(graphString) {\n\n var previousLink, graph = new diagram.Graph(), parts = graphString.slice();\n for (var i = 0, len = parts.length; i < len; i++) {\n var part = parts[i];\n if (Utils.isString(part)) // link spec\n {\n if (part.indexOf(\"->\") < 0) {\n throw \"The link should be specified as 'a->b'.\";\n }\n var p = part.split(\"->\");\n if (p.length != 2) {\n throw \"The link should be specified as 'a->b'.\";\n }\n previousLink = new Link(p[0], p[1]);\n graph.addLink(previousLink);\n }\n if (Utils.isObject(part)) {\n if (!previousLink) {\n throw \"Specification found before Link definition.\";\n }\n kendo.deepExtend(previousLink, part);\n }\n }\n return graph;\n },\n\n /**\n * Returns a linearized representation of the given Graph.\n * See also the Graph.Utils.parse method for the inverse operation.\n */\n linearize: function(graph, addIds) {\n if (Utils.isUndefined(graph)) {\n throw \"Expected an instance of a Graph object in slot one.\";\n }\n if (Utils.isUndefined(addIds)) {\n addIds = false;\n }\n var lin = [];\n for (var i = 0, len = graph.links.length; i < len; i++) {\n var link = graph.links[i];\n lin.push(link.source.id + \"->\" + link.target.id);\n if (addIds) {\n lin.push({ id: link.id });\n }\n }\n return lin;\n },\n\n /**\n * The method used by the diagram creation to instantiate a shape.\n * @param kendoDiagram The Kendo diagram where the diagram will be created.\n * @param p The position at which to place the shape.\n * @param shapeDefaults Optional Shape options.\n * @param id Optional identifier of the shape.\n * @returns {*}\n * @private\n */\n _addShape: function(kendoDiagram, p, id, shapeDefaults) {\n if (Utils.isUndefined(p)) {\n p = new diagram.Point(0, 0);\n }\n\n if (Utils.isUndefined(id)) {\n id = randomId();\n }\n\n shapeDefaults = kendo.deepExtend({\n width: 20,\n height: 20,\n id: id,\n radius: 10,\n fill: \"#778899\",\n data: \"circle\",\n undoable: false,\n x: p.x,\n y: p.y\n }, shapeDefaults);\n\n return kendoDiagram.addShape(shapeDefaults);\n },\n /**\n * The method used by the diagram creation to instantiate a connection.\n * @param diagram he Kendo diagram where the diagram will be created.\n * @param from The source shape.\n * @param to The target shape.\n * @param options Optional Connection options.\n * @returns {*}\n * @private\n */\n _addConnection: function(diagram, from, to, options) {\n return diagram.connect(from, to, options);\n },\n\n /**\n * Creates a diagram from the given Graph.\n * @param diagram The Kendo diagram where the diagram will be created.\n * @param graph The graph structure defining the diagram.\n */\n createDiagramFromGraph: function(diagram, graph, doLayout, randomSize) {\n\n if (Utils.isUndefined(diagram)) {\n throw \"The diagram surface is undefined.\";\n }\n if (Utils.isUndefined(graph)) {\n throw \"No graph specification defined.\";\n }\n if (Utils.isUndefined(doLayout)) {\n doLayout = true;\n }\n if (Utils.isUndefined(randomSize)) {\n randomSize = false;\n }\n\n var width = diagram.element.clientWidth || 200;\n var height = diagram.element.clientHeight || 200;\n var map = [], node, shape;\n for (var i = 0, len = graph.nodes.length; i < len; i++) {\n node = graph.nodes[i];\n var p = node.position;\n if (Utils.isUndefined(p)) {\n if (Utils.isDefined(node.x) && Utils.isDefined(node.y)) {\n p = new Point(node.x, node.y);\n }\n else {\n p = new Point(Utils.randomInteger(10, width - 20), Utils.randomInteger(10, height - 20));\n }\n }\n var opt = {};\n\n if (node.id === \"0\") {\n /* kendo.deepExtend(opt,\n {\n fill: \"Orange\",\n data: 'circle',\n width: 100,\n height: 100,\n center: new Point(50, 50)\n });*/\n }\n else if (randomSize) {\n kendo.deepExtend(opt, {\n width: Math.random() * 150 + 20,\n height: Math.random() * 80 + 50,\n data: 'rectangle',\n fill: {\n color: \"#778899\"\n }\n });\n }\n\n shape = this._addShape(diagram, p, node.id, opt);\n //shape.content(node.id);\n\n var bounds = shape.bounds();\n if (Utils.isDefined(bounds)) {\n node.x = bounds.x;\n node.y = bounds.y;\n node.width = bounds.width;\n node.height = bounds.height;\n }\n map[node.id] = shape;\n }\n for (var gli = 0; gli < graph.links.length; gli++) {\n var link = graph.links[gli];\n var sourceShape = map[link.source.id];\n if (Utils.isUndefined(sourceShape)) {\n continue;\n }\n var targetShape = map[link.target.id];\n if (Utils.isUndefined(targetShape)) {\n continue;\n }\n this._addConnection(diagram, sourceShape, targetShape, { id: link.id });\n\n }\n if (doLayout) {\n var l = new diagram.SpringLayout(diagram);\n l.layoutGraph(graph, { limitToView: false });\n for (var shi = 0; shi < graph.nodes.length; shi++) {\n node = graph.nodes[shi];\n shape = map[node.id];\n shape.bounds(new Rect(node.x, node.y, node.width, node.height));\n }\n }\n },\n\n /**\n * Creates a balanced tree with the specified number of levels and siblings count.\n * Note that for a balanced tree of level N and sibling count s, counting the root as level zero:\n * - NodeCount = (1-s^(N+1))/(1-s)]\n * - LinkCount = s.(1-s^N)/(1-s)\n * @param levels How many levels the tree should have.\n * @param siblingsCount How many siblings each level should have.\n * @returns {diagram.Graph}\n */\n createBalancedTree: function(levels, siblingsCount) {\n if (Utils.isUndefined(levels)) {\n levels = 3;\n }\n if (Utils.isUndefined(siblingsCount)) {\n siblingsCount = 3;\n }\n\n var g = new diagram.Graph(), counter = -1, lastAdded = [], news;\n if (levels <= 0 || siblingsCount <= 0) {\n return g;\n }\n var root = new Node((++counter).toString());\n g.addNode(root);\n g.root = root;\n lastAdded.push(root);\n for (var i = 0; i < levels; i++) {\n news = [];\n for (var j = 0; j < lastAdded.length; j++) {\n var parent = lastAdded[j];\n for (var k = 0; k < siblingsCount; k++) {\n var item = new Node((++counter).toString());\n g.addLink(parent, item);\n news.push(item);\n }\n }\n lastAdded = news;\n }\n return g;\n },\n\n /**\n * Creates a balanced tree with the specified number of levels and siblings count.\n * Note that for a balanced forest of level N, sibling count s and tree count t, counting the root as level zero:\n * - NodeCount = t.(1-s^(N+1))/(1-s)]\n * - LinkCount = t.s.(1-s^N)/(1-s)\n * @param levels How many levels the tree should have.\n * @param siblingsCount How many siblings each level should have.\n * @returns {diagram.Graph}\n * @param treeCount The number of trees the forest should have.\n */\n createBalancedForest: function(levels, siblingsCount, treeCount) {\n if (Utils.isUndefined(levels)) {\n levels = 3;\n }\n if (Utils.isUndefined(siblingsCount)) {\n siblingsCount = 3;\n }\n if (Utils.isUndefined(treeCount)) {\n treeCount = 5;\n }\n var g = new diagram.Graph(), counter = -1, lastAdded = [], news;\n if (levels <= 0 || siblingsCount <= 0 || treeCount <= 0) {\n return g;\n }\n\n for (var t = 0; t < treeCount; t++) {\n var root = new Node((++counter).toString());\n g.addNode(root);\n lastAdded = [root];\n for (var i = 0; i < levels; i++) {\n news = [];\n for (var j = 0; j < lastAdded.length; j++) {\n var parent = lastAdded[j];\n for (var k = 0; k < siblingsCount; k++) {\n var item = new Node((++counter).toString());\n g.addLink(parent, item);\n news.push(item);\n }\n }\n lastAdded = news;\n }\n }\n return g;\n },\n\n /**\n * Creates a random graph (uniform distribution) with the specified amount of nodes.\n * @param nodeCount The amount of nodes the random graph should have.\n * @param maxIncidence The maximum allowed degree of the nodes.\n * @param isTree Whether the return graph should be a tree (default: false).\n * @returns {diagram.Graph}\n */\n createRandomConnectedGraph: function(nodeCount, maxIncidence, isTree) {\n\n /* Swa's Mathematica export of random Bernoulli graphs\n gr[n_,p_]:=Module[{g=RandomGraph[BernoulliGraphDistribution[n,p],VertexLabels->\"Name\",DirectedEdges->True]},\n While[Not[ConnectedGraphQ[g]],g=RandomGraph[BernoulliGraphDistribution[n,p],VertexLabels->\"Name\",DirectedEdges->True]];g];\n project[a_]:=(\"\\\"\"<>ToString[Part[#,1]]<>\"->\"<>ToString[Part[#,2]]<>\"\\\"\")& @ a;\n export[g_]:=project/@ EdgeList[g]\n g = gr[12,.1]\n export [g]\n */\n\n if (Utils.isUndefined(nodeCount)) {\n nodeCount = 40;\n }\n if (Utils.isUndefined(maxIncidence)) {\n maxIncidence = 4;\n }\n if (Utils.isUndefined(isTree)) {\n isTree = false;\n }\n\n var g = new diagram.Graph(), counter = -1;\n if (nodeCount <= 0) {\n return g;\n }\n\n var root = new Node((++counter).toString());\n g.addNode(root);\n if (nodeCount === 1) {\n return g;\n }\n if (nodeCount > 1) {\n // random tree\n for (var i = 1; i < nodeCount; i++) {\n var poolNode = g.takeRandomNode([], maxIncidence);\n if (!poolNode) {\n //failed to find one so the graph will have less nodes than specified\n break;\n }\n var newNode = g.addNode(i.toString());\n g.addLink(poolNode, newNode);\n }\n if (!isTree && nodeCount > 1) {\n var randomAdditions = Utils.randomInteger(1, nodeCount);\n for (var ri = 0; ri < randomAdditions; ri++) {\n var n1 = g.takeRandomNode([], maxIncidence);\n var n2 = g.takeRandomNode([], maxIncidence);\n if (n1 && n2 && !g.areConnected(n1, n2)) {\n g.addLink(n1, n2);\n }\n }\n }\n return g;\n }\n },\n\n /**\n * Generates a random diagram.\n * @param diagram The host diagram.\n * @param shapeCount The number of shapes the random diagram should contain.\n * @param maxIncidence The maximum degree the shapes can have.\n * @param isTree Whether the generated diagram should be a tree\n * @param layoutType The optional layout type to apply after the diagram is generated.\n */\n randomDiagram: function(diagram, shapeCount, maxIncidence, isTree, randomSize) {\n var g = kendo.dataviz.diagram.Graph.Utils.createRandomConnectedGraph(shapeCount, maxIncidence, isTree);\n Graph.Utils.createDiagramFromGraph(diagram, g, false, randomSize);\n }\n };\n\n kendo.deepExtend(diagram, {\n init: function(element) {\n kendo.init(element, diagram.ui);\n },\n\n Point: Point,\n Intersect: Intersect,\n Geometry: Geometry,\n Rect: Rect,\n Size: Size,\n RectAlign: RectAlign,\n Matrix: Matrix,\n MatrixVector: MatrixVector,\n normalVariable: normalVariable,\n randomId: randomId,\n Dictionary: Dictionary,\n HashTable: HashTable,\n Queue: Queue,\n Set: Set,\n Node: Node,\n Link: Link,\n Graph: Graph,\n PathDefiner: PathDefiner\n });\n })(window.kendo.jQuery);\n\n (function($, undefined$1) {\n // Imports ================================================================\n var kendo = window.kendo,\n diagram = kendo.dataviz.diagram,\n Class = kendo.Class,\n deepExtend = kendo.deepExtend,\n Point = diagram.Point,\n Rect = diagram.Rect,\n Matrix = diagram.Matrix,\n Utils = diagram.Utils,\n isNumber = Utils.isNumber,\n isString = Utils.isString,\n MatrixVector = diagram.MatrixVector,\n\n g = kendo.geometry,\n d = kendo.drawing,\n\n defined = d.util.defined,\n\n inArray = $.inArray;\n\n // Constants ==============================================================\n var TRANSPARENT = \"transparent\",\n Markers = {\n none: \"none\",\n arrowStart: \"ArrowStart\",\n filledCircle: \"FilledCircle\",\n arrowEnd: \"ArrowEnd\"\n },\n FULL_CIRCLE_ANGLE = 360,\n START = \"start\",\n END = \"end\",\n WIDTH = \"width\",\n HEIGHT = \"height\",\n X = \"x\",\n Y = \"y\";\n\n diagram.Markers = Markers;\n\n function diffNumericOptions(options, fields) {\n var elementOptions = this.options;\n var hasChanges = false;\n var value, field;\n for (var i = 0; i < fields.length; i++) {\n field = fields[i];\n value = options[field];\n if (isNumber(value) && elementOptions[field] !== value) {\n elementOptions[field] = value;\n hasChanges = true;\n }\n }\n\n return hasChanges;\n }\n\n var Scale = Class.extend({\n init: function(x, y) {\n this.x = x;\n this.y = y;\n },\n toMatrix: function() {\n return Matrix.scaling(this.x, this.y);\n },\n toString: function() {\n return kendo.format(\"scale({0},{1})\", this.x, this.y);\n },\n invert: function() {\n return new Scale(1 / this.x, 1 / this.y);\n }\n });\n\n var Translation = Class.extend({\n init: function(x, y) {\n this.x = x;\n this.y = y;\n },\n toMatrixVector: function() {\n return new MatrixVector(0, 0, 0, 0, this.x, this.y);\n },\n toMatrix: function() {\n return Matrix.translation(this.x, this.y);\n },\n toString: function() {\n return kendo.format(\"translate({0},{1})\", this.x, this.y);\n },\n plus: function(delta) {\n this.x += delta.x;\n this.y += delta.y;\n },\n times: function(factor) {\n this.x *= factor;\n this.y *= factor;\n },\n length: function() {\n return Math.sqrt(this.x * this.x + this.y * this.y);\n },\n normalize: function() {\n if (this.Length === 0) {\n return;\n }\n this.times(1 / this.length());\n },\n invert: function() {\n return new Translation(-this.x, -this.y);\n }\n });\n\n var Rotation = Class.extend({\n init: function(angle, x, y) {\n this.x = x || 0;\n this.y = y || 0;\n this.angle = angle;\n },\n toString: function() {\n if (this.x && this.y) {\n return kendo.format(\"rotate({0},{1},{2})\", this.angle, this.x, this.y);\n } else {\n return kendo.format(\"rotate({0})\", this.angle);\n }\n },\n toMatrix: function() {\n return Matrix.rotation(this.angle, this.x, this.y); // T*R*T^-1\n },\n center: function() {\n return new Point(this.x, this.y);\n },\n invert: function() {\n return new Rotation(FULL_CIRCLE_ANGLE - this.angle, this.x, this.y);\n }\n });\n\n Rotation.ZERO = new Rotation(0);\n\n Rotation.create = function(rotation) {\n return new Rotation(rotation.angle, rotation.x, rotation.y);\n };\n\n Rotation.parse = function(str) {\n var values = str.slice(1, str.length - 1).split(\",\"),\n angle = values[0],\n x = values[1],\n y = values[2];\n var rotation = new Rotation(angle, x, y);\n return rotation;\n };\n\n var CompositeTransform = Class.extend({\n init: function(x, y, scaleX, scaleY, angle, center) {\n this.translate = new Translation(x, y);\n if (scaleX !== undefined$1 && scaleY !== undefined$1) {\n this.scale = new Scale(scaleX, scaleY);\n }\n if (angle !== undefined$1) {\n this.rotate = center ? new Rotation(angle, center.x, center.y) : new Rotation(angle);\n }\n },\n toString: function() {\n var toString = function(transform) {\n return transform ? transform.toString() : \"\";\n };\n\n return toString(this.translate) +\n toString(this.rotate) +\n toString(this.scale);\n },\n\n render: function(visual) {\n visual._transform = this;\n visual._renderTransform();\n },\n\n toMatrix: function() {\n var m = Matrix.unit();\n\n if (this.translate) {\n m = m.times(this.translate.toMatrix());\n }\n if (this.rotate) {\n m = m.times(this.rotate.toMatrix());\n }\n if (this.scale) {\n m = m.times(this.scale.toMatrix());\n }\n return m;\n },\n invert: function() {\n var rotate = this.rotate ? this.rotate.invert() : undefined$1,\n rotateMatrix = rotate ? rotate.toMatrix() : Matrix.unit(),\n scale = this.scale ? this.scale.invert() : undefined$1,\n scaleMatrix = scale ? scale.toMatrix() : Matrix.unit();\n\n var translatePoint = new Point(-this.translate.x, -this.translate.y);\n translatePoint = rotateMatrix.times(scaleMatrix).apply(translatePoint);\n var translate = new Translation(translatePoint.x, translatePoint.y);\n\n var transform = new CompositeTransform();\n transform.translate = translate;\n transform.rotate = rotate;\n transform.scale = scale;\n\n return transform;\n }\n });\n\n var AutoSizeableMixin = {\n _setScale: function() {\n var options = this.options;\n var originWidth = this._originWidth;\n var originHeight = this._originHeight;\n var scaleX = options.width / originWidth;\n var scaleY = options.height / originHeight;\n\n if (!isNumber(scaleX)) {\n scaleX = 1;\n }\n if (!isNumber(scaleY)) {\n scaleY = 1;\n }\n\n this._transform.scale = new Scale(scaleX, scaleY);\n },\n\n _setTranslate: function() {\n var options = this.options;\n var x = options.x || 0;\n var y = options.y || 0;\n this._transform.translate = new Translation(x, y);\n },\n\n _initSize: function() {\n var options = this.options;\n var transform = false;\n if (options.autoSize !== false && (defined(options.width) || defined(options.height))) {\n this._measure(true);\n this._setScale();\n transform = true;\n }\n\n if (defined(options.x) || defined(options.y)) {\n this._setTranslate();\n transform = true;\n }\n\n if (transform) {\n this._renderTransform();\n }\n },\n\n _updateSize: function(options) {\n var update = false;\n\n if (this.options.autoSize !== false && this._diffNumericOptions(options, [WIDTH, HEIGHT])) {\n update = true;\n this._measure(true);\n this._setScale();\n }\n\n if (this._diffNumericOptions(options, [X, Y])) {\n update = true;\n this._setTranslate();\n }\n\n if (update) {\n this._renderTransform();\n }\n\n return update;\n }\n };\n\n var Element = Class.extend({\n init: function(options) {\n var element = this;\n element.options = deepExtend({}, element.options, options);\n element.id = element.options.id;\n element._originSize = Rect.empty();\n element._transform = new CompositeTransform();\n },\n\n visible: function(value) {\n return this.drawingContainer().visible(value);\n },\n\n redraw: function(options) {\n if (options && options.id) {\n this.id = options.id;\n }\n },\n\n position: function(x, y) {\n var options = this.options;\n if (!defined(x)) {\n return new Point(options.x, options.y);\n }\n\n if (defined(y)) {\n options.x = x;\n options.y = y;\n } else if (x instanceof Point) {\n options.x = x.x;\n options.y = x.y;\n }\n\n this._transform.translate = new Translation(options.x, options.y);\n this._renderTransform();\n },\n\n rotate: function(angle, center) {\n if (defined(angle)) {\n this._transform.rotate = new Rotation(angle, center.x, center.y);\n this._renderTransform();\n }\n return this._transform.rotate || Rotation.ZERO;\n },\n\n drawingContainer: function() {\n return this.drawingElement;\n },\n\n _renderTransform: function() {\n var matrix = this._transform.toMatrix();\n this.drawingContainer().transform(new g.Matrix(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f));\n },\n\n _hover: function() {},\n\n _diffNumericOptions: diffNumericOptions,\n\n _measure: function(force) {\n var rect;\n if (!this._measured || force) {\n var box = this._boundingBox() || new g.Rect();\n var startPoint = box.topLeft();\n rect = new Rect(startPoint.x, startPoint.y, box.width(), box.height());\n this._originSize = rect;\n this._originWidth = rect.width;\n this._originHeight = rect.height;\n this._measured = true;\n } else {\n rect = this._originSize;\n }\n return rect;\n },\n\n _boundingBox: function() {\n return this.drawingElement.rawBBox();\n }\n });\n\n var VisualBase = Element.extend({\n init: function(options) {\n Element.fn.init.call(this, options);\n\n options = this.options;\n options.fill = normalizeDrawingOptions(options.fill);\n options.stroke = normalizeDrawingOptions(options.stroke);\n },\n\n options: {\n stroke: {\n color: \"gray\",\n width: 1\n },\n fill: {\n color: TRANSPARENT\n }\n },\n\n fill: function(color, opacity) {\n this._fill({\n color: getColor(color),\n opacity: opacity\n });\n },\n\n stroke: function(color, width, opacity) {\n this._stroke({\n color: getColor(color),\n width: width,\n opacity: opacity\n });\n },\n\n redraw: function(options) {\n if (options) {\n var stroke = options.stroke;\n var fill = options.fill;\n if (stroke) {\n this._stroke(normalizeDrawingOptions(stroke));\n }\n if (fill) {\n this._fill(normalizeDrawingOptions(fill));\n }\n\n Element.fn.redraw.call(this, options);\n }\n },\n\n _hover: function(show) {\n var drawingElement = this.drawingElement;\n var options = this.options;\n var hover = options.hover;\n\n if (hover && hover.fill) {\n var fill = show ? normalizeDrawingOptions(hover.fill) : options.fill;\n drawingElement.fill(fill.color, fill.opacity);\n }\n },\n\n _stroke: function(strokeOptions) {\n var options = this.options;\n deepExtend(options, {\n stroke: strokeOptions\n });\n\n strokeOptions = options.stroke;\n\n var stroke = null;\n if (strokeOptions.width > 0) {\n stroke = {\n color: strokeOptions.color,\n width: strokeOptions.width,\n opacity: strokeOptions.opacity,\n dashType: strokeOptions.dashType\n };\n }\n\n this.drawingElement.options.set(\"stroke\", stroke);\n },\n\n _fill: function(fillOptions) {\n var options = this.options;\n deepExtend(options, {\n fill: fillOptions || {}\n });\n var fill = options.fill;\n\n if (fill.gradient) {\n var gradient = fill.gradient;\n var GradientClass = (gradient.type === \"radial\" ? d.RadialGradient : d.LinearGradient);\n this.drawingElement.fill(new GradientClass(gradient));\n } else {\n this.drawingElement.fill(fill.color, fill.opacity);\n }\n }\n });\n\n var TextBlock = VisualBase.extend({\n init: function(options) {\n options = this._textColor(options);\n VisualBase.fn.init.call(this, options);\n\n this._font();\n this._initText();\n this._initSize();\n },\n\n options: {\n fontSize: 15,\n fontFamily: \"sans-serif\",\n stroke: {\n width: 0\n },\n fill: {\n color: \"black\"\n },\n autoSize: true\n },\n\n _initText: function() {\n var options = this.options;\n\n this.drawingElement = new d.Text(defined(options.text) ? options.text : \"\", new g.Point(), {\n font: options.font\n });\n\n this._fill();\n this._stroke();\n },\n\n _textColor: function(options) {\n if (options && options.color) {\n options = deepExtend({}, options, {\n fill: {\n color: options.color\n }\n });\n }\n return options;\n },\n\n _font: function() {\n var options = this.options;\n if (options.fontFamily && defined(options.fontSize)) {\n var fontOptions = [];\n\n if (options.fontStyle) {\n fontOptions.push(options.fontStyle);\n }\n\n if (options.fontWeight) {\n fontOptions.push(options.fontWeight);\n }\n\n fontOptions.push(options.fontSize + (isNumber(options.fontSize) ? \"px\" : \"\"));\n fontOptions.push(options.fontFamily);\n\n options.font = fontOptions.join(\" \");\n } else {\n delete options.font;\n }\n },\n\n content: function(text) {\n return this.drawingElement.content(text);\n },\n\n redraw: function(options) {\n if (options) {\n var sizeChanged = false;\n var textOptions = this.options;\n\n options = this._textColor(options);\n\n VisualBase.fn.redraw.call(this, options);\n\n if (options.fontFamily || defined(options.fontSize) || options.fontStyle || options.fontWeight) {\n deepExtend(textOptions, {\n fontFamily: options.fontFamily,\n fontSize: options.fontSize,\n fontStyle: options.fontStyle,\n fontWeight: options.fontWeight\n });\n this._font();\n this.drawingElement.options.set(\"font\", textOptions.font);\n sizeChanged = true;\n }\n\n if (options.text) {\n this.content(options.text);\n sizeChanged = true;\n }\n\n if (!this._updateSize(options) && sizeChanged) {\n this._initSize();\n }\n }\n }\n });\n\n deepExtend(TextBlock.fn, AutoSizeableMixin);\n\n var Rectangle = VisualBase.extend({\n init: function(options) {\n VisualBase.fn.init.call(this, options);\n this._initPath();\n this._setPosition();\n },\n\n _setPosition: function() {\n var options = this.options;\n var x = options.x;\n var y = options.y;\n if (defined(x) || defined(y)) {\n this.position(x || 0, y || 0);\n }\n },\n\n redraw: function(options) {\n if (options) {\n VisualBase.fn.redraw.call(this, options);\n if (this._diffNumericOptions(options, [WIDTH, HEIGHT])) {\n this._drawPath();\n }\n if (this._diffNumericOptions(options, [X, Y])) {\n this._setPosition();\n }\n }\n },\n\n _initPath: function() {\n var options = this.options;\n this.drawingElement = new d.Path({\n stroke: options.stroke,\n closed: true\n });\n\n this._fill();\n this._drawPath();\n },\n\n _drawPath: function() {\n var drawingElement = this.drawingElement;\n var sizeOptions = sizeOptionsOrDefault(this.options);\n var width = sizeOptions.width;\n var height = sizeOptions.height;\n\n drawingElement.segments.elements([\n createSegment(0, 0),\n createSegment(width, 0),\n createSegment(width, height),\n createSegment(0, height)\n ]);\n }\n });\n\n var MarkerBase = VisualBase.extend({\n init: function(options) {\n VisualBase.fn.init.call(this, options);\n var anchor = this.options.anchor;\n this.anchor = new g.Point(anchor.x, anchor.y);\n this.createElement();\n },\n\n options: {\n stroke: {\n color: TRANSPARENT,\n width: 0\n },\n fill: {\n color: \"black\"\n }\n },\n\n _transformToPath: function(point, path) {\n var transform = path.transform();\n if (point && transform) {\n point = point.transformCopy(transform);\n }\n return point;\n },\n\n redraw: function(options) {\n if (options) {\n if (options.position) {\n this.options.position = options.position;\n }\n\n VisualBase.fn.redraw.call(this, options);\n }\n }\n });\n\n var CircleMarker = MarkerBase.extend({\n options: {\n radius: 4,\n anchor: {\n x: 0,\n y: 0\n }\n },\n\n createElement: function() {\n var options = this.options;\n this.drawingElement = new d.Circle(new g.Circle(this.anchor, options.radius), {\n fill: options.fill,\n stroke: options.stroke\n });\n },\n\n positionMarker: function(path) {\n var options = this.options;\n var position = options.position;\n var segments = path.segments;\n var targetSegment;\n var point;\n\n if (position == START) {\n targetSegment = segments[0];\n } else {\n targetSegment = segments[segments.length - 1];\n }\n if (targetSegment) {\n point = this._transformToPath(targetSegment.anchor(), path);\n this.drawingElement.transform(g.transform().translate(point.x, point.y));\n }\n }\n });\n\n var ArrowMarker = MarkerBase.extend({\n options: {\n path: \"M 0 0 L 10 5 L 0 10 L 3 5 z\" ,\n anchor: {\n x: 10,\n y: 5\n }\n },\n\n createElement: function() {\n var options = this.options;\n this.drawingElement = d.Path.parse(options.path, {\n fill: options.fill,\n stroke: options.stroke\n });\n },\n\n positionMarker: function(path) {\n var points = this._linePoints(path);\n var start = points.start;\n var end = points.end;\n var transform = g.transform();\n if (start) {\n transform.rotate(lineAngle(start, end), end);\n }\n\n if (end) {\n var anchor = this.anchor;\n var translate = end.clone().translate(-anchor.x, -anchor.y);\n transform.translate(translate.x, translate.y);\n }\n this.drawingElement.transform(transform);\n },\n\n _linePoints: function(path) {\n var options = this.options;\n var segments = path.segments;\n var startPoint, endPoint, targetSegment;\n if (options.position == START) {\n targetSegment = segments[0];\n if (targetSegment) {\n endPoint = targetSegment.anchor();\n startPoint = targetSegment.controlOut();\n var nextSegment = segments[1];\n if (!startPoint && nextSegment) {\n startPoint = nextSegment.anchor();\n }\n }\n } else {\n targetSegment = segments[segments.length - 1];\n if (targetSegment) {\n endPoint = targetSegment.anchor();\n startPoint = targetSegment.controlIn();\n var prevSegment = segments[segments.length - 2];\n if (!startPoint && prevSegment) {\n startPoint = prevSegment.anchor();\n }\n }\n }\n if (endPoint) {\n return {\n start: this._transformToPath(startPoint, path),\n end: this._transformToPath(endPoint, path)\n };\n }\n }\n });\n\n var MarkerPathMixin = {\n _getPath: function(position) {\n var path = this.drawingElement;\n if (path instanceof d.MultiPath) {\n if (position == START) {\n path = path.paths[0];\n } else {\n path = path.paths[path.paths.length - 1];\n }\n }\n if (path && path.segments.length) {\n return path;\n }\n },\n\n _normalizeMarkerOptions: function(options) {\n var startCap = options.startCap;\n var endCap = options.endCap;\n\n if (isString(startCap)) {\n options.startCap = {\n type: startCap\n };\n }\n\n if (isString(endCap)) {\n options.endCap = {\n type: endCap\n };\n }\n },\n\n _removeMarker: function(position) {\n var marker = this._markers[position];\n if (marker) {\n this.drawingContainer().remove(marker.drawingElement);\n delete this._markers[position];\n }\n },\n\n _createMarkers: function() {\n var options = this.options;\n this._normalizeMarkerOptions(options);\n\n this._markers = {};\n this._markers[START] = this._createMarker(options.startCap, START);\n this._markers[END] = this._createMarker(options.endCap, END);\n },\n\n _createMarker: function(options, position) {\n var type = (options || {}).type;\n var path = this._getPath(position);\n var markerType, marker;\n if (!path) {\n this._removeMarker(position);\n return;\n }\n\n if (type == Markers.filledCircle) {\n markerType = CircleMarker;\n } else if (type == Markers.arrowStart || type == Markers.arrowEnd) {\n markerType = ArrowMarker;\n } else {\n this._removeMarker(position);\n }\n if (markerType) {\n marker = new markerType(deepExtend({}, options, {\n position: position\n }));\n marker.positionMarker(path);\n this.drawingContainer().append(marker.drawingElement);\n\n return marker;\n }\n },\n\n _positionMarker: function(position) {\n var marker = this._markers[position];\n\n if (marker) {\n var path = this._getPath(position);\n if (path) {\n marker.positionMarker(path);\n } else {\n this._removeMarker(position);\n }\n }\n },\n\n _capMap: {\n start: \"startCap\",\n end: \"endCap\"\n },\n\n _redrawMarker: function(pathChange, position, options) {\n this._normalizeMarkerOptions(options);\n\n var pathOptions = this.options;\n var cap = this._capMap[position];\n var pathCapType = (pathOptions[cap] || {}).type;\n var optionsCap = options[cap];\n var created = false;\n if (optionsCap) {\n pathOptions[cap] = deepExtend({}, pathOptions[cap], optionsCap);\n if (optionsCap.type && pathCapType != optionsCap.type) {\n this._removeMarker(position);\n this._markers[position] = this._createMarker(pathOptions[cap], position);\n created = true;\n } else if (this._markers[position]) {\n this._markers[position].redraw(optionsCap);\n }\n } else if (pathChange && !this._markers[position] && pathOptions[cap]) {\n this._markers[position] = this._createMarker(pathOptions[cap], position);\n created = true;\n }\n return created;\n },\n\n _redrawMarkers: function(pathChange, options) {\n if (!this._redrawMarker(pathChange, START, options) && pathChange) {\n this._positionMarker(START);\n }\n if (!this._redrawMarker(pathChange, END, options) && pathChange) {\n this._positionMarker(END);\n }\n }\n };\n\n var Path = VisualBase.extend({\n init: function(options) {\n VisualBase.fn.init.call(this, options);\n this.container = new d.Group();\n this._createElements();\n this._initSize();\n },\n\n options: {\n autoSize: true\n },\n\n drawingContainer: function() {\n return this.container;\n },\n\n data: function(value) {\n var options = this.options;\n if (value) {\n if (options.data != value) {\n options.data = value;\n this._setData(value);\n this._initSize();\n this._redrawMarkers(true, {});\n }\n } else {\n return options.data;\n }\n },\n\n redraw: function(options) {\n if (options) {\n VisualBase.fn.redraw.call(this, options);\n\n var pathOptions = this.options;\n var data = options.data;\n\n if (defined(data) && pathOptions.data != data) {\n pathOptions.data = data;\n this._setData(data);\n if (!this._updateSize(options)) {\n this._initSize();\n }\n this._redrawMarkers(true, options);\n } else {\n this._updateSize(options);\n this._redrawMarkers(false, options);\n }\n }\n },\n\n _createElements: function() {\n var options = this.options;\n\n this.drawingElement = d.Path.parse(options.data || \"\", {\n stroke: options.stroke\n });\n\n this._fill();\n this.container.append(this.drawingElement);\n this._createMarkers();\n },\n\n _setData: function(data) {\n var drawingElement = this.drawingElement;\n var multipath = d.Path.parse(data || \"\");\n var paths = multipath.paths.slice(0);\n multipath.paths.elements([]);\n drawingElement.paths.elements(paths);\n }\n });\n\n deepExtend(Path.fn, AutoSizeableMixin);\n deepExtend(Path.fn, MarkerPathMixin);\n\n var Line = VisualBase.extend({\n init: function(options) {\n VisualBase.fn.init.call(this, options);\n this.container = new d.Group();\n this._initPath();\n this._createMarkers();\n },\n\n drawingContainer: function() {\n return this.container;\n },\n\n redraw: function(options) {\n if (options) {\n options = options || {};\n var from = options.from;\n var to = options.to;\n if (from) {\n this.options.from = from;\n }\n\n if (to) {\n this.options.to = to;\n }\n\n if (from || to) {\n this._drawPath();\n this._redrawMarkers(true, options);\n } else {\n this._redrawMarkers(false, options);\n }\n\n VisualBase.fn.redraw.call(this, options);\n }\n },\n\n _initPath: function() {\n var options = this.options;\n var drawingElement = this.drawingElement = new d.Path({\n stroke: options.stroke\n });\n\n this._fill();\n this._drawPath();\n this.container.append(drawingElement);\n },\n\n _drawPath: function() {\n var options = this.options;\n var drawingElement = this.drawingElement;\n var from = options.from || new Point();\n var to = options.to || new Point();\n\n drawingElement.segments.elements([\n createSegment(from.x, from.y),\n createSegment(to.x, to.y)\n ]);\n }\n });\n\n deepExtend(Line.fn, MarkerPathMixin);\n\n var Polyline = VisualBase.extend({\n init: function(options) {\n VisualBase.fn.init.call(this, options);\n this.container = new d.Group();\n this._initPath();\n this._createMarkers();\n },\n\n drawingContainer: function() {\n return this.container;\n },\n\n points: function(points) {\n var options = this.options;\n if (points) {\n options.points = points;\n this._updatePath();\n } else {\n return options.points;\n }\n },\n\n redraw: function(options) {\n if (options) {\n var points = options.points;\n VisualBase.fn.redraw.call(this, options);\n\n if (points && this._pointsDiffer(points)) {\n this.points(points);\n this._redrawMarkers(true, options);\n } else {\n this._redrawMarkers(false, options);\n }\n }\n },\n\n _initPath: function() {\n var options = this.options;\n this.drawingElement = new d.Path({\n stroke: options.stroke\n });\n\n this._fill();\n this.container.append(this.drawingElement);\n\n if (options.points) {\n this._updatePath();\n }\n },\n\n _pointsDiffer: function(points) {\n var currentPoints = this.options.points;\n var differ = currentPoints.length !== points.length;\n if (!differ) {\n for (var i = 0; i < points.length; i++) {\n if (currentPoints[i].x !== points[i].x || currentPoints[i].y !== points[i].y) {\n differ = true;\n break;\n }\n }\n }\n\n return differ;\n },\n\n _updatePath: function() {\n var drawingElement = this.drawingElement;\n var options = this.options;\n var points = options.points;\n var segments = [];\n var point;\n for (var i = 0; i < points.length; i++) {\n point = points[i];\n segments.push(createSegment(point.x, point.y));\n }\n\n drawingElement.segments.elements(segments);\n },\n\n options: {\n points: []\n }\n });\n\n deepExtend(Polyline.fn, MarkerPathMixin);\n\n var Image = Element.extend({\n init: function(options) {\n Element.fn.init.call(this, options);\n\n this._initImage();\n },\n\n redraw: function(options) {\n if (options) {\n if (options.source) {\n this.drawingElement.src(options.source);\n }\n\n if (this._diffNumericOptions(options, [WIDTH, HEIGHT, X, Y])) {\n this.drawingElement.rect(this._rect());\n }\n\n Element.fn.redraw.call(this, options);\n }\n },\n\n _initImage: function() {\n var options = this.options;\n var rect = this._rect();\n\n this.drawingElement = new d.Image(options.source, rect, {});\n },\n\n _rect: function() {\n var sizeOptions = sizeOptionsOrDefault(this.options);\n var origin = new g.Point(sizeOptions.x, sizeOptions.y);\n var size = new g.Size(sizeOptions.width, sizeOptions.height);\n\n return new g.Rect(origin, size);\n }\n });\n\n var Group = Element.extend({\n init: function(options) {\n this.children = [];\n Element.fn.init.call(this, options);\n this.drawingElement = new d.Group();\n this._initSize();\n },\n\n options: {\n autoSize: false\n },\n\n append: function(visual) {\n this.drawingElement.append(visual.drawingContainer());\n this.children.push(visual);\n this._childrenChange = true;\n },\n\n remove: function(visual) {\n if (this._remove(visual)) {\n this._childrenChange = true;\n }\n },\n\n _remove: function(visual) {\n var index = inArray(visual, this.children);\n if (index >= 0) {\n this.drawingElement.removeAt(index);\n this.children.splice(index, 1);\n return true;\n }\n },\n\n clear: function() {\n this.drawingElement.clear();\n this.children = [];\n this._childrenChange = true;\n },\n\n toFront: function(visuals) {\n var visual;\n\n for (var i = 0; i < visuals.length; i++) {\n visual = visuals[i];\n if (this._remove(visual)) {\n this.append(visual);\n }\n }\n },\n //TO DO: add drawing group support for moving and inserting children\n toBack: function(visuals) {\n this._reorderChildren(visuals, 0);\n },\n\n toIndex: function(visuals, indices) {\n this._reorderChildren(visuals, indices);\n },\n\n _reorderChildren: function(visuals, indices) {\n var group = this.drawingElement;\n var drawingChildren = group.children.slice(0);\n var children = this.children;\n var fixedPosition = isNumber(indices);\n var i, index, toIndex, drawingElement, visual;\n\n for (i = 0; i < visuals.length; i++) {\n visual = visuals[i];\n drawingElement = visual.drawingContainer();\n\n index = inArray(visual, children);\n if (index >= 0) {\n drawingChildren.splice(index, 1);\n children.splice(index, 1);\n\n toIndex = fixedPosition ? indices : indices[i];\n\n drawingChildren.splice(toIndex, 0, drawingElement);\n children.splice(toIndex, 0, visual);\n }\n }\n group.clear();\n group.append.apply(group, drawingChildren);\n },\n\n redraw: function(options) {\n if (options) {\n if (this._childrenChange) {\n this._childrenChange = false;\n if (!this._updateSize(options)) {\n this._initSize();\n }\n } else {\n this._updateSize(options);\n }\n\n Element.fn.redraw.call(this, options);\n }\n },\n\n _boundingBox: function() {\n var children = this.children;\n var boundingBox;\n var visual, childBoundingBox;\n for (var i = 0; i < children.length; i++) {\n visual = children[i];\n if (visual.visible() && visual._includeInBBox !== false) {\n childBoundingBox = visual.drawingContainer().clippedBBox(null);\n if (childBoundingBox) {\n if (boundingBox) {\n boundingBox = g.Rect.union(boundingBox, childBoundingBox);\n } else {\n boundingBox = childBoundingBox;\n }\n }\n }\n }\n\n return boundingBox;\n }\n });\n\n deepExtend(Group.fn, AutoSizeableMixin);\n\n var Layout = Group.extend({\n init: function(rect, options) {\n this.children = [];\n Element.fn.init.call(this, options);\n this.drawingElement = new d.Layout(toDrawingRect(rect), options);\n this._initSize();\n },\n\n rect: function(rect) {\n if (rect) {\n this.drawingElement.rect(toDrawingRect(rect));\n } else {\n var drawingRect = this.drawingElement.rect();\n if (drawingRect) {\n return new Rect(drawingRect.origin.x, drawingRect.origin.y, drawingRect.size.width, drawingRect.size.height);\n }\n }\n },\n\n reflow: function() {\n this.drawingElement.reflow();\n },\n\n redraw: function(options) {\n kendo.deepExtend(this.drawingElement.options, options);\n Group.fn.redraw.call(this, options);\n }\n });\n\n var Circle = VisualBase.extend({\n init: function(options) {\n VisualBase.fn.init.call(this, options);\n this._initCircle();\n this._initSize();\n },\n\n redraw: function(options) {\n if (options) {\n var circleOptions = this.options;\n\n if (options.center) {\n deepExtend(circleOptions, {\n center: options.center\n });\n this._center.move(circleOptions.center.x, circleOptions.center.y);\n }\n\n if (this._diffNumericOptions(options, [\"radius\"])) {\n this._circle.setRadius(circleOptions.radius);\n }\n\n this._updateSize(options);\n\n VisualBase.fn.redraw.call(this, options);\n }\n },\n\n _initCircle: function() {\n var options = this.options;\n var width = options.width;\n var height = options.height;\n var radius = options.radius;\n if (!defined(radius)) {\n if (!defined(width)) {\n width = height;\n }\n if (!defined(height)) {\n height = width;\n }\n options.radius = radius = Math.min(width, height) / 2;\n }\n\n var center = options.center || { x: radius, y: radius };\n this._center = new g.Point(center.x, center.y);\n this._circle = new g.Circle(this._center, radius);\n this.drawingElement = new d.Circle(this._circle, {\n stroke: options.stroke\n });\n\n this._fill();\n }\n });\n deepExtend(Circle.fn, AutoSizeableMixin);\n\n var Canvas = Class.extend({\n init: function(element, options) {\n options = options || {};\n this.element = element;\n this.surface = d.Surface.create(element, options);\n if (kendo.isFunction(this.surface.translate)) {\n this.translate = this._translate;\n }\n\n this.drawingElement = new d.Group();\n this._viewBox = new Rect(0, 0, options.width, options.height);\n this.size(this._viewBox);\n },\n\n bounds: function() {\n var box = this.drawingElement.clippedBBox();\n return new Rect(0, 0, box.width(), box.height());\n },\n\n size: function(size) {\n var viewBox = this._viewBox;\n if (defined(size)) {\n viewBox.width = size.width;\n viewBox.height = size.height;\n this.surface.setSize(size);\n }\n return {\n width: viewBox.width,\n height: viewBox.height\n };\n },\n\n _translate: function(x, y) {\n var viewBox = this._viewBox;\n if (defined(x) && defined(y)) {\n viewBox.x = x;\n viewBox.y = y;\n this.surface.translate({ x: x, y: y });\n }\n return {\n x: viewBox.x,\n y: viewBox.y\n };\n },\n\n draw: function() {\n this.surface.draw(this.drawingElement);\n },\n\n append: function(visual) {\n this.drawingElement.append(visual.drawingContainer());\n return this;\n },\n\n remove: function(visual) {\n this.drawingElement.remove(visual.drawingContainer());\n },\n\n insertBefore: function() {\n\n },\n\n clear: function() {\n this.drawingElement.clear();\n },\n\n destroy: function(clearHtml) {\n this.surface.destroy();\n if (clearHtml) {\n $(this.element).remove();\n }\n }\n });\n\n // Helper functions ===========================================\n\n function sizeOptionsOrDefault(options) {\n return {\n x: options.x || 0,\n y: options.y || 0,\n width: options.width || 0,\n height: options.height || 0\n };\n }\n\n function normalizeDrawingOptions(options) {\n if (options) {\n var drawingOptions = options;\n\n if (isString(drawingOptions)) {\n drawingOptions = {\n color: drawingOptions\n };\n }\n\n if (drawingOptions.color) {\n drawingOptions.color = getColor(drawingOptions.color);\n }\n return drawingOptions;\n }\n }\n\n function getColor(value) {\n var color;\n if (value != TRANSPARENT) {\n color = new d.Color(value).toHex();\n } else {\n color = value;\n }\n return color;\n }\n\n function lineAngle(p1, p2) {\n var xDiff = p2.x - p1.x;\n var yDiff = p2.y - p1.y;\n var angle = d.util.deg(Math.atan2(yDiff, xDiff));\n return angle;\n }\n\n function createSegment(x, y) {\n return new d.Segment(new g.Point(x, y));\n }\n\n function toDrawingRect(rect) {\n if (rect) {\n return new g.Rect([rect.x, rect.y], [rect.width, rect.height]);\n }\n }\n\n // Exports ================================================================\n kendo.deepExtend(diagram, {\n init: function(element) {\n kendo.init(element, diagram.ui);\n },\n diffNumericOptions: diffNumericOptions,\n Element: Element,\n Scale: Scale,\n Translation: Translation,\n Rotation: Rotation,\n Circle: Circle,\n Group: Group,\n Rectangle: Rectangle,\n Canvas: Canvas,\n Path: Path,\n Layout: Layout,\n Line: Line,\n MarkerBase: MarkerBase,\n ArrowMarker: ArrowMarker,\n CircleMarker: CircleMarker,\n Polyline: Polyline,\n CompositeTransform: CompositeTransform,\n TextBlock: TextBlock,\n Image: Image,\n VisualBase: VisualBase\n });\n })(window.kendo.jQuery);\n\n (function($, undefined$1) {\n // Imports ================================================================\n var kendo = window.kendo,\n dataviz = kendo.dataviz,\n diagram = dataviz.diagram,\n Class = kendo.Class,\n Group = diagram.Group,\n Rect = diagram.Rect,\n Rectangle = diagram.Rectangle,\n Utils = diagram.Utils,\n isUndefined = Utils.isUndefined,\n Point = diagram.Point,\n Circle = diagram.Circle,\n Ticker = diagram.Ticker,\n deepExtend = kendo.deepExtend,\n Movable = kendo.ui.Movable,\n util = kendo.drawing.util,\n defined = util.defined,\n inArray = $.inArray;\n\n // Constants ==============================================================\n var Cursors = {\n arrow: \"default\",\n grip: \"pointer\",\n cross: \"pointer\",\n add: \"pointer\",\n move: \"move\",\n select: \"pointer\",\n south: \"s-resize\",\n east: \"e-resize\",\n west: \"w-resize\",\n north: \"n-resize\",\n rowresize: \"row-resize\",\n colresize: \"col-resize\"\n },\n HIT_TEST_DISTANCE = 10,\n AUTO = \"Auto\",\n TOP = \"Top\",\n RIGHT = \"Right\",\n LEFT = \"Left\",\n BOTTOM = \"Bottom\",\n DEFAULT_SNAP_SIZE = 10,\n DEFAULT_SNAP_ANGLE = 10,\n DRAG_START = \"dragStart\",\n DRAG = \"drag\",\n DRAG_END = \"dragEnd\",\n ITEMROTATE = \"itemRotate\",\n ITEMBOUNDSCHANGE = \"itemBoundsChange\",\n MIN_SNAP_SIZE = 5,\n MIN_SNAP_ANGLE = 5,\n MOUSE_ENTER = \"mouseEnter\",\n MOUSE_LEAVE = \"mouseLeave\",\n ZOOM_START = \"zoomStart\",\n ZOOM_END = \"zoomEnd\",\n SCROLL_MIN = -20000,\n SCROLL_MAX = 20000,\n FRICTION = 0.90,\n FRICTION_MOBILE = 0.93,\n VELOCITY_MULTIPLIER = 5,\n TRANSPARENT = \"transparent\",\n PAN = \"pan\",\n ROTATED = \"rotated\",\n SOURCE = \"source\",\n TARGET = \"target\",\n HANDLE_NAMES = {\n \"-1\": SOURCE,\n \"1\": TARGET\n };\n\n diagram.Cursors = Cursors;\n\n var PositionAdapter = kendo.Class.extend({\n init: function(layoutState) {\n this.layoutState = layoutState;\n this.diagram = layoutState.diagram;\n },\n initState: function() {\n this.froms = [];\n this.tos = [];\n this.subjects = [];\n function pusher(id, bounds) {\n var shape = this.diagram.getShapeById(id);\n if (shape) {\n this.subjects.push(shape);\n this.froms.push(shape.bounds().topLeft());\n this.tos.push(bounds.topLeft());\n }\n }\n\n this.layoutState.nodeMap.forEach(pusher, this);\n },\n update: function(tick) {\n if (this.subjects.length <= 0) {\n return;\n }\n for (var i = 0; i < this.subjects.length; i++) {\n //todo: define a Lerp function instead\n this.subjects[i].position(\n new Point(this.froms[i].x + (this.tos[i].x - this.froms[i].x) * tick, this.froms[i].y + (this.tos[i].y - this.froms[i].y) * tick)\n );\n }\n }\n });\n\n var LayoutUndoUnit = Class.extend({\n init: function(initialState, finalState, animate) {\n if (isUndefined(animate)) {\n this.animate = false;\n }\n else {\n this.animate = animate;\n }\n this._initialState = initialState;\n this._finalState = finalState;\n this.title = \"Diagram layout\";\n },\n undo: function() {\n this.setState(this._initialState);\n },\n redo: function() {\n this.setState(this._finalState);\n },\n setState: function(state) {\n var diagram = state.diagram;\n if (this.animate) {\n state.linkMap.forEach(\n function(id, points) {\n var conn = diagram.getShapeById(id);\n conn.visible(false);\n if (conn) {\n conn.points(points);\n }\n }\n );\n var ticker = new Ticker();\n ticker.addAdapter(new PositionAdapter(state));\n ticker.onComplete(function() {\n state.linkMap.forEach(\n function(id) {\n var conn = diagram.getShapeById(id);\n conn.visible(true);\n }\n );\n });\n ticker.play();\n }\n else {\n state.nodeMap.forEach(function(id, bounds) {\n var shape = diagram.getShapeById(id);\n if (shape) {\n shape.position(bounds.topLeft());\n }\n });\n state.linkMap.forEach(\n function(id, points) {\n var conn = diagram.getShapeById(id);\n if (conn) {\n conn.points(points);\n }\n }\n );\n }\n }\n });\n\n var CompositeUnit = Class.extend({\n init: function(unit) {\n this.units = [];\n this.title = \"Composite unit\";\n if (unit !== undefined$1) {\n this.units.push(unit);\n }\n },\n add: function(undoUnit) {\n this.units.push(undoUnit);\n },\n undo: function() {\n for (var i = 0; i < this.units.length; i++) {\n this.units[i].undo();\n }\n },\n redo: function() {\n for (var i = 0; i < this.units.length; i++) {\n this.units[i].redo();\n }\n }\n });\n\n var ConnectionEditUnit = Class.extend({\n init: function(item, redoSource, redoTarget) {\n this.item = item;\n this._redoSource = redoSource;\n this._redoTarget = redoTarget;\n if (defined(redoSource)) {\n this._undoSource = item.source();\n }\n\n if (defined(redoTarget)) {\n this._undoTarget = item.target();\n }\n this.title = \"Connection Editing\";\n },\n undo: function() {\n if (this._undoSource !== undefined$1) {\n this.item._updateConnector(this._undoSource, \"source\");\n }\n\n if (this._undoTarget !== undefined$1) {\n this.item._updateConnector(this._undoTarget, \"target\");\n }\n\n this.item.updateModel();\n },\n redo: function() {\n if (this._redoSource !== undefined$1) {\n this.item._updateConnector(this._redoSource, \"source\");\n }\n\n if (this._redoTarget !== undefined$1) {\n this.item._updateConnector(this._redoTarget, \"target\");\n }\n\n this.item.updateModel();\n }\n });\n\n var ConnectionEditUndoUnit = Class.extend({\n init: function(item, undoSource, undoTarget) {\n this.item = item;\n this._undoSource = undoSource;\n this._undoTarget = undoTarget;\n this._redoSource = item.source();\n this._redoTarget = item.target();\n this.title = \"Connection Editing\";\n },\n undo: function() {\n this.item._updateConnector(this._undoSource, \"source\");\n this.item._updateConnector(this._undoTarget, \"target\");\n this.item.updateModel();\n },\n redo: function() {\n this.item._updateConnector(this._redoSource, \"source\");\n this.item._updateConnector(this._redoTarget, \"target\");\n this.item.updateModel();\n }\n });\n\n var DeleteConnectionUnit = Class.extend({\n init: function(connection) {\n this.connection = connection;\n this.diagram = connection.diagram;\n this.targetConnector = connection.targetConnector;\n this.title = \"Delete connection\";\n },\n undo: function() {\n this.diagram._addConnection(this.connection, false);\n },\n redo: function() {\n this.diagram.remove(this.connection, false);\n }\n });\n\n var DeleteShapeUnit = Class.extend({\n init: function(shape) {\n this.shape = shape;\n this.diagram = shape.diagram;\n this.title = \"Deletion\";\n },\n undo: function() {\n this.diagram._addShape(this.shape, false);\n this.shape.select(false);\n },\n redo: function() {\n this.shape.select(false);\n this.diagram.remove(this.shape, false);\n }\n });\n /**\n * Holds the undoredo state when performing a rotation, translation or scaling. The adorner is optional.\n * @type {*}\n */\n var TransformUnit = Class.extend({\n init: function(shapes, undoStates, adorner) {\n this.shapes = shapes;\n this.undoStates = undoStates;\n this.title = \"Transformation\";\n this.redoStates = [];\n this.adorner = adorner;\n for (var i = 0; i < this.shapes.length; i++) {\n var shape = this.shapes[i];\n this.redoStates.push(shape.bounds());\n }\n },\n undo: function() {\n for (var i = 0; i < this.shapes.length; i++) {\n var shape = this.shapes[i];\n shape.bounds(this.undoStates[i]);\n if (shape.hasOwnProperty(\"layout\")) {\n shape.layout(shape, this.redoStates[i], this.undoStates[i]);\n }\n shape.updateModel();\n }\n if (this.adorner) {\n this.adorner.refreshBounds();\n this.adorner.refresh();\n }\n },\n redo: function() {\n for (var i = 0; i < this.shapes.length; i++) {\n var shape = this.shapes[i];\n shape.bounds(this.redoStates[i]);\n // the 'layout' property, if implemented, lets the shape itself work out what to do with the new bounds\n if (shape.hasOwnProperty(\"layout\")) {\n shape.layout(shape, this.undoStates[i], this.redoStates[i]);\n }\n shape.updateModel();\n }\n\n if (this.adorner) {\n this.adorner.refreshBounds();\n this.adorner.refresh();\n }\n }\n });\n\n var AddConnectionUnit = Class.extend({\n init: function(connection, diagram) {\n this.connection = connection;\n this.diagram = diagram;\n this.title = \"New connection\";\n },\n\n undo: function() {\n this.diagram.remove(this.connection, false);\n },\n\n redo: function() {\n this.diagram._addConnection(this.connection, false);\n }\n });\n\n var AddShapeUnit = Class.extend({\n init: function(shape, diagram) {\n this.shape = shape;\n this.diagram = diagram;\n this.title = \"New shape\";\n },\n\n undo: function() {\n this.diagram.deselect();\n this.diagram.remove(this.shape, false);\n },\n\n redo: function() {\n this.diagram._addShape(this.shape, false);\n }\n });\n\n var PanUndoUnit = Class.extend({\n init: function(initialPosition, finalPosition, diagram) {\n this.initial = initialPosition;\n this.finalPos = finalPosition;\n this.diagram = diagram;\n this.title = \"Pan Unit\";\n },\n undo: function() {\n this.diagram.pan(this.initial);\n },\n redo: function() {\n this.diagram.pan(this.finalPos);\n }\n });\n\n var RotateUnit = Class.extend({\n init: function(adorner, shapes, undoRotates) {\n this.shapes = shapes;\n this.undoRotates = undoRotates;\n this.title = \"Rotation\";\n this.redoRotates = [];\n this.redoAngle = adorner._angle;\n this.adorner = adorner;\n this.center = adorner._innerBounds.center();\n for (var i = 0; i < this.shapes.length; i++) {\n var shape = this.shapes[i];\n this.redoRotates.push(shape.rotate().angle);\n }\n },\n undo: function() {\n var i, shape;\n for (i = 0; i < this.shapes.length; i++) {\n shape = this.shapes[i];\n shape.rotate(this.undoRotates[i], this.center, false);\n if (shape.hasOwnProperty(\"layout\")) {\n shape.layout(shape);\n }\n shape.updateModel();\n }\n if (this.adorner) {\n this.adorner._initialize();\n this.adorner.refresh();\n }\n },\n redo: function() {\n var i, shape;\n for (i = 0; i < this.shapes.length; i++) {\n shape = this.shapes[i];\n shape.rotate(this.redoRotates[i], this.center, false);\n if (shape.hasOwnProperty(\"layout\")) {\n shape.layout(shape);\n }\n shape.updateModel();\n }\n if (this.adorner) {\n this.adorner._initialize();\n this.adorner.refresh();\n }\n }\n });\n\n var ToFrontUnit = Class.extend({\n init: function(diagram, items, initialIndices) {\n this.diagram = diagram;\n this.indices = initialIndices;\n this.items = items;\n this.title = \"Rotate Unit\";\n },\n undo: function() {\n this.diagram._toIndex(this.items, this.indices);\n },\n redo: function() {\n this.diagram.toFront(this.items, false);\n }\n });\n\n var ToBackUnit = Class.extend({\n init: function(diagram, items, initialIndices) {\n this.diagram = diagram;\n this.indices = initialIndices;\n this.items = items;\n this.title = \"Rotate Unit\";\n },\n undo: function() {\n this.diagram._toIndex(this.items, this.indices);\n },\n redo: function() {\n this.diagram.toBack(this.items, false);\n }\n });\n\n /**\n * Undo-redo service.\n */\n var UndoRedoService = kendo.Observable.extend({\n init: function(options) {\n kendo.Observable.fn.init.call(this, options);\n this.bind(this.events, options);\n this.stack = [];\n this.index = 0;\n this.capacity = 100;\n },\n\n events: [\"undone\", \"redone\"],\n\n /**\n * Starts the collection of units. Add those with\n * the addCompositeItem method and call commit. Or cancel to forget about it.\n */\n begin: function() {\n this.composite = new CompositeUnit();\n },\n\n /**\n * Cancels the collection process of unit started with 'begin'.\n */\n cancel: function() {\n this.composite = undefined$1;\n },\n\n /**\n * Commits a batch of units.\n */\n commit: function(execute) {\n if (this.composite.units.length > 0) {\n this._restart(this.composite, execute);\n }\n this.composite = undefined$1;\n },\n\n /**\n * Adds a unit as part of the begin-commit batch.\n * @param undoUnit\n */\n addCompositeItem: function(undoUnit) {\n if (this.composite) {\n this.composite.add(undoUnit);\n } else {\n this.add(undoUnit);\n }\n },\n\n /**\n * Standard addition of a unit. See also the batch version; begin-addCompositeUnit-commit methods.\n * @param undoUnit The unit to be added.\n * @param execute If false, the unit will be added but not executed.\n */\n add: function(undoUnit, execute) {\n this._restart(undoUnit, execute);\n },\n\n /**\n * Returns the number of undoable unit in the stack.\n * @returns {Number}\n */\n\n pop: function() {\n if (this.index > 0) {\n this.stack.pop();\n this.index--;\n }\n },\n\n count: function() {\n return this.stack.length;\n },\n\n /**\n * Rollback of the unit on top of the stack.\n */\n undo: function() {\n if (this.index > 0) {\n this.index--;\n this.stack[this.index].undo();\n this.trigger(\"undone\");\n }\n },\n\n /**\n * Redo of the last undone action.\n */\n redo: function() {\n if (this.stack.length > 0 && this.index < this.stack.length) {\n this.stack[this.index].redo();\n this.index++;\n this.trigger(\"redone\");\n }\n },\n\n _restart: function(composite, execute) {\n // throw away anything beyond this point if this is a new branch\n this.stack.splice(this.index, this.stack.length - this.index);\n this.stack.push(composite);\n if (execute !== false) {\n this.redo();\n } else {\n this.index++;\n }\n // check the capacity\n if (this.stack.length > this.capacity) {\n this.stack.splice(0, this.stack.length - this.capacity);\n this.index = this.capacity; //points to the end of the stack\n }\n },\n\n /**\n * Clears the stack.\n */\n clear: function() {\n this.stack = [];\n this.index = 0;\n }\n });\n\n // Tools =========================================\n\n var EmptyTool = Class.extend({\n init: function(toolService) {\n this.toolService = toolService;\n },\n start: function() {\n },\n move: function() {\n },\n end: function() {\n },\n tryActivate: function() {\n return false;\n },\n getCursor: function() {\n return Cursors.arrow;\n }\n });\n\n var ScrollerTool = EmptyTool.extend({\n init: function(toolService) {\n var tool = this;\n var friction = kendo.support.mobileOS ? FRICTION_MOBILE : FRICTION;\n EmptyTool.fn.init.call(tool, toolService);\n\n var diagram = tool.toolService.diagram,\n canvas = diagram.canvas;\n\n var scroller = diagram.scroller = tool.scroller = $(diagram.scrollable).kendoMobileScroller({\n friction: friction,\n velocityMultiplier: VELOCITY_MULTIPLIER,\n mousewheelScrolling: false,\n zoom: false,\n scroll: tool._move.bind(tool)\n }).data(\"kendoMobileScroller\");\n\n if (canvas.translate) {\n tool.movableCanvas = new Movable(canvas.element);\n }\n\n var virtualScroll = function(dimension, min, max) {\n dimension.makeVirtual();\n dimension.virtualSize(min || SCROLL_MIN, max || SCROLL_MAX);\n };\n\n virtualScroll(scroller.dimensions.x);\n virtualScroll(scroller.dimensions.y);\n scroller.disable();\n },\n\n tryActivate: function(p, meta) {\n var toolService = this.toolService;\n var options = toolService.diagram.options.pannable;\n var enabled = meta.ctrlKey;\n\n if (defined(options.key)) {\n if (!options.key || options.key == \"none\") {\n enabled = noMeta(meta) && !defined(toolService.hoveredItem);\n } else {\n enabled = meta[options.key + \"Key\"];\n }\n }\n\n return options !== false && enabled && !defined(toolService.hoveredAdorner) && !defined(toolService._hoveredConnector);\n },\n\n start: function() {\n this.scroller.enable();\n },\n move: function() {\n },//the tool itself should not handle the scrolling. Let kendo scroller take care of this part. Check _move\n _move: function(args) {\n var tool = this,\n diagram = tool.toolService.diagram,\n canvas = diagram.canvas,\n scrollPos = new Point(args.scrollLeft, args.scrollTop);\n\n if (canvas.translate) {\n diagram._storePan(scrollPos.times(-1));\n tool.movableCanvas.moveTo(scrollPos);\n canvas.translate(scrollPos.x, scrollPos.y);\n } else {\n scrollPos = scrollPos.plus(diagram._pan.times(-1));\n }\n\n diagram.trigger(PAN, { pan: scrollPos });\n },\n end: function() {\n this.scroller.disable();\n },\n getCursor: function() {\n return Cursors.move;\n }\n });\n\n /**\n * The tool handling the transformations via the adorner.\n * @type {*}\n */\n var PointerTool = Class.extend({\n init: function(toolService) {\n this.toolService = toolService;\n },\n tryActivate: function() {\n return true; // the pointer tool is last and handles all others requests.\n },\n start: function(p, meta) {\n var toolService = this.toolService,\n diagram = toolService.diagram,\n hoveredItem = toolService.hoveredItem;\n\n if (hoveredItem) {\n toolService.selectSingle(hoveredItem, meta);\n if (hoveredItem.adorner) { //connection\n this.adorner = hoveredItem.adorner;\n this.handle = this.adorner._hitTest(p);\n }\n }\n\n if (!this.handle) {\n this.handle = diagram._resizingAdorner._hitTest(p);\n if (this.handle) {\n this.adorner = diagram._resizingAdorner;\n }\n }\n\n if (this.adorner) {\n if (!this.adorner.isDragHandle(this.handle) || !diagram.trigger(DRAG_START, { shapes: this.adorner.shapes, connections: [] })) {\n this.adorner.start(p);\n } else {\n toolService.startPoint = p;\n toolService.end(p);\n }\n }\n },\n\n move: function(p) {\n if (this.adorner) {\n this.adorner.move(this.handle, p);\n if (this.adorner.isDragHandle(this.handle)) {\n this.toolService.diagram.trigger(DRAG, { shapes: this.adorner.shapes, connections: [] });\n }\n }\n },\n\n end: function() {\n var diagram = this.toolService.diagram,\n adorner = this.adorner,\n unit;\n\n if (adorner) {\n if (!adorner.isDragHandle(this.handle) || !diagram.trigger(DRAG_END, { shapes: adorner.shapes, connections: [] })) {\n unit = adorner.stop();\n if (unit) {\n diagram.undoRedoService.add(unit, false);\n }\n } else {\n adorner.cancel();\n }\n }\n\n this.adorner = undefined$1;\n this.handle = undefined$1;\n },\n getCursor: function(p) {\n return this.toolService.hoveredItem ? this.toolService.hoveredItem._getCursor(p) : Cursors.arrow;\n }\n });\n\n var SelectionTool = Class.extend({\n init: function(toolService) {\n this.toolService = toolService;\n },\n tryActivate: function(p, meta) {\n var toolService = this.toolService;\n var selectable = toolService.diagram.options.selectable;\n var enabled = selectable && selectable.multiple !== false;\n\n if (enabled) {\n if (selectable.key && selectable.key != \"none\") {\n enabled = meta[selectable.key + \"Key\"];\n } else {\n enabled = noMeta(meta);\n }\n }\n\n return enabled && !defined(toolService.hoveredItem) && !defined(toolService.hoveredAdorner);\n },\n start: function(p) {\n var diagram = this.toolService.diagram;\n diagram.deselect();\n diagram.selector.start(p);\n },\n move: function(p) {\n var diagram = this.toolService.diagram;\n diagram.selector.move(p);\n },\n end: function(p, meta) {\n var diagram = this.toolService.diagram, hoveredItem = this.toolService.hoveredItem;\n var rect = diagram.selector.bounds();\n if ((!hoveredItem || !hoveredItem.isSelected) && !meta.ctrlKey) {\n diagram.deselect();\n }\n if (!rect.isEmpty()) {\n diagram.selectArea(rect);\n }\n diagram.selector.end();\n },\n getCursor: function() {\n return Cursors.arrow;\n }\n });\n\n var ConnectionTool = Class.extend({\n init: function(toolService) {\n this.toolService = toolService;\n this.type = \"ConnectionTool\";\n },\n tryActivate: function() {\n return this.toolService._hoveredConnector;\n },\n start: function(p, meta) {\n var toolService = this.toolService,\n diagram = toolService.diagram,\n connector = toolService._hoveredConnector,\n connection = diagram._createConnection({}, connector._c, p);\n\n if (canDrag(connection) && !diagram.trigger(DRAG_START, { shapes: [], connections: [connection], connectionHandle: TARGET }) && diagram._addConnection(connection)) {\n toolService._connectionManipulation(connection, connector._c.shape, true);\n toolService._removeHover();\n toolService.selectSingle(toolService.activeConnection, meta);\n if (meta.type == \"touchmove\") {\n diagram._cachedTouchTarget = connector.visual;\n }\n } else {\n connection.source(null);\n toolService.end(p);\n }\n },\n\n move: function(p) {\n var toolService = this.toolService;\n var connection = toolService.activeConnection;\n\n connection.target(p);\n toolService.diagram.trigger(DRAG, { shapes: [], connections: [connection], connectionHandle: TARGET });\n return true;\n },\n\n end: function(p) {\n var toolService = this.toolService,\n d = toolService.diagram,\n connection = toolService.activeConnection,\n hoveredItem = toolService.hoveredItem,\n connector = toolService._hoveredConnector,\n target,\n cachedTouchTarget = d._cachedTouchTarget;\n\n if (!connection) {\n return;\n }\n\n if (connector && connector._c != connection.sourceConnector) {\n target = connector._c;\n } else if (hoveredItem && hoveredItem instanceof diagram.Shape) {\n target = hoveredItem.getConnector(AUTO) || hoveredItem.getConnector(p);\n } else {\n target = p;\n }\n\n connection.target(target);\n\n if (!d.trigger(DRAG_END, { shapes: [], connections: [connection], connectionHandle: TARGET })) {\n connection.updateModel();\n d._syncConnectionChanges();\n } else {\n d.remove(connection, false);\n d.undoRedoService.pop();\n }\n toolService._connectionManipulation();\n\n if (cachedTouchTarget) {\n d._connectorsAdorner.visual.remove(cachedTouchTarget);\n d._cachedTouchTarget = null;\n }\n },\n\n getCursor: function() {\n return Cursors.arrow;\n }\n });\n\n var ConnectionEditTool = Class.extend({\n init: function(toolService) {\n this.toolService = toolService;\n this.type = \"ConnectionTool\";\n },\n\n tryActivate: function(p, meta) {\n var toolService = this.toolService,\n diagram = toolService.diagram,\n selectable = diagram.options.selectable,\n item = toolService.hoveredItem,\n isActive = selectable !== false &&\n item && item.path && !(item.isSelected && meta.ctrlKey);\n\n if (isActive) {\n this._c = item;\n }\n\n return isActive;\n },\n\n start: function(p, meta) {\n var toolService = this.toolService;\n var connection = this._c;\n\n toolService.selectSingle(connection, meta);\n\n var adorner = connection.adorner;\n\n var handle, name;\n if (adorner) {\n handle = adorner._hitTest(p);\n name = HANDLE_NAMES[handle];\n }\n\n if (canDrag(connection) && adorner && !toolService.diagram.trigger(DRAG_START, { shapes: [], connections: [connection], connectionHandle: name })) {\n this.handle = handle;\n this.handleName = name;\n adorner.start(p);\n } else {\n toolService.startPoint = p;\n toolService.end(p);\n }\n },\n\n move: function(p) {\n var adorner = this._c.adorner;\n if (canDrag(this._c) && adorner) {\n adorner.move(this.handle, p);\n this.toolService.diagram.trigger(DRAG, { shapes: [], connections: [this._c], connectionHandle: this.handleName });\n\n return true;\n }\n },\n\n end: function(p) {\n var connection = this._c;\n var adorner = connection.adorner;\n var toolService = this.toolService;\n var diagram = toolService.diagram;\n\n if (adorner) {\n if (canDrag(connection)) {\n var unit = adorner.stop(p);\n if (!diagram.trigger(DRAG_END, { shapes: [], connections: [connection], connectionHandle: this.handleName })) {\n diagram.undoRedoService.add(unit, false);\n connection.updateModel();\n diagram._syncConnectionChanges();\n } else {\n unit.undo();\n }\n }\n }\n },\n\n getCursor: function() {\n return Cursors.move;\n }\n });\n\n function testKey(key, str) {\n return str.charCodeAt(0) == key || str.toUpperCase().charCodeAt(0) == key;\n }\n\n /**\n * The service managing the tools.\n * @type {*}\n */\n var ToolService = Class.extend({\n init: function(diagram) {\n this.diagram = diagram;\n this.tools = [\n new ScrollerTool(this),\n new ConnectionEditTool(this),\n new ConnectionTool(this),\n new SelectionTool(this),\n new PointerTool(this)\n ]; // the order matters.\n\n this.activeTool = undefined$1;\n },\n\n start: function(p, meta) {\n meta = deepExtend({}, meta);\n if (this.activeTool) {\n this.activeTool.end(p, meta);\n }\n this._updateHoveredItem(p);\n this._activateTool(p, meta);\n this.activeTool.start(p, meta);\n this._updateCursor(p);\n this.diagram.focus();\n this.diagram.canvas.surface.suspendTracking();\n this.startPoint = p;\n return true;\n },\n\n move: function(p, meta) {\n meta = deepExtend({}, meta);\n var updateHovered = true;\n if (this.activeTool) {\n updateHovered = this.activeTool.move(p, meta);\n }\n if (updateHovered) {\n this._updateHoveredItem(p);\n }\n this._updateCursor(p);\n return true;\n },\n\n end: function(p, meta) {\n meta = deepExtend({}, meta);\n if (this.activeTool) {\n this.activeTool.end(p, meta);\n }\n this.diagram.canvas.surface.resumeTracking();\n this.activeTool = undefined$1;\n this._updateCursor(p);\n return true;\n },\n\n keyDown: function(key, meta) {\n var diagram = this.diagram;\n meta = deepExtend({ ctrlKey: false, metaKey: false, altKey: false }, meta);\n if ((meta.ctrlKey || meta.metaKey) && !meta.altKey) {// ctrl or option\n if (testKey(key, \"a\")) {// A: select all\n diagram.selectAll();\n diagram._destroyToolBar();\n return true;\n } else if (testKey(key, \"z\")) {// Z: undo\n diagram.undo();\n diagram._destroyToolBar();\n return true;\n } else if (testKey(key, \"y\")) {// y: redo\n diagram.redo();\n diagram._destroyToolBar();\n return true;\n } else if (testKey(key, \"c\")) {\n diagram.copy();\n diagram._destroyToolBar();\n } else if (testKey(key, \"x\")) {\n diagram.cut();\n diagram._destroyToolBar();\n } else if (testKey(key, \"v\")) {\n diagram.paste();\n diagram._destroyToolBar();\n } else if (testKey(key, \"l\")) {\n diagram.layout();\n diagram._destroyToolBar();\n } else if (testKey(key, \"d\")) {\n diagram._destroyToolBar();\n diagram.copy();\n diagram.paste();\n }\n } else if (key === 46 || key === 8) {// del: deletion\n var toRemove = this.diagram._triggerRemove(diagram.select());\n if (toRemove.length) {\n this.diagram.remove(toRemove, true);\n this.diagram._syncChanges();\n this.diagram._destroyToolBar();\n }\n\n return true;\n } else if (key === 27) {// ESC: stop any action\n this._discardNewConnection();\n diagram.deselect();\n diagram._destroyToolBar();\n return true;\n }\n\n },\n wheel: function(p, meta) {\n var diagram = this.diagram,\n delta = meta.delta,\n z = diagram.zoom(),\n options = diagram.options,\n zoomRate = options.zoomRate,\n zoomOptions = { point: p, meta: meta, zoom: z };\n\n if (diagram.trigger(ZOOM_START, zoomOptions)) {\n return;\n }\n\n if (delta < 0) {\n z += zoomRate;\n } else {\n z -= zoomRate;\n }\n\n z = kendo.dataviz.round(Math.max(options.zoomMin, Math.min(options.zoomMax, z)), 2);\n zoomOptions.zoom = z;\n\n diagram.zoom(z, zoomOptions);\n diagram.trigger(ZOOM_END, zoomOptions);\n\n return true;\n },\n setTool: function(tool, index) {\n tool.toolService = this;\n this.tools[index] = tool;\n },\n\n selectSingle: function(item, meta) {\n var diagram = this.diagram;\n var selectable = diagram.options.selectable;\n if (selectable && !item.isSelected && item.options.selectable !== false) {\n var addToSelection = meta.ctrlKey && selectable.multiple !== false;\n diagram.select(item, { addToSelection: addToSelection });\n }\n },\n\n _discardNewConnection: function() {\n if (this.newConnection) {\n this.diagram.remove(this.newConnection);\n this.newConnection = undefined$1;\n }\n },\n _activateTool: function(p, meta) {\n for (var i = 0; i < this.tools.length; i++) {\n var tool = this.tools[i];\n if (tool.tryActivate(p, meta)) {\n this.activeTool = tool;\n break; // activating the first available tool in the loop.\n }\n }\n },\n _updateCursor: function(p) {\n var element = this.diagram.element;\n var cursor = this.activeTool ? this.activeTool.getCursor(p) : (this.hoveredAdorner ? this.hoveredAdorner._getCursor(p) : (this.hoveredItem ? this.hoveredItem._getCursor(p) : Cursors.arrow));\n\n element.css({ cursor: cursor });\n },\n _connectionManipulation: function(connection, disabledShape, isNew) {\n this.activeConnection = connection;\n this.disabledShape = disabledShape;\n if (isNew) {\n this.newConnection = this.activeConnection;\n } else {\n this.newConnection = undefined$1;\n }\n },\n _updateHoveredItem: function(p) {\n var hit = this._hitTest(p);\n var diagram = this.diagram;\n\n if (hit != this.hoveredItem && (!this.disabledShape || hit != this.disabledShape)) {\n if (this.hoveredItem) {\n diagram.trigger(MOUSE_LEAVE, { item: this.hoveredItem });\n this.hoveredItem._hover(false);\n }\n\n if (hit && hit.options.enable) {\n diagram.trigger(MOUSE_ENTER, { item: hit });\n\n this.hoveredItem = hit; // Shape, connection or connector\n this.hoveredItem._hover(true);\n } else {\n this.hoveredItem = undefined$1;\n }\n }\n },\n _removeHover: function() {\n if (this.hoveredItem) {\n this.hoveredItem._hover(false);\n this.hoveredItem = undefined$1;\n }\n },\n _hitTest: function(point) {\n var hit, d = this.diagram, item, i;\n\n // connectors\n if (this._hoveredConnector) {\n this._hoveredConnector._hover(false);\n this._hoveredConnector = undefined$1;\n }\n if (d._connectorsAdorner._visible) {\n hit = d._connectorsAdorner._hitTest(point);\n if (hit) {\n return hit;\n }\n }\n\n hit = this.diagram._resizingAdorner._hitTest(point);\n if (hit) {\n this.hoveredAdorner = d._resizingAdorner;\n if (hit.x !== 0 || hit.y !== 0) { // hit testing for resizers or rotator, otherwise if (0,0) than pass through.\n return;\n }\n hit = undefined$1;\n } else {\n this.hoveredAdorner = undefined$1;\n }\n\n if (!this.activeTool || this.activeTool.type !== \"ConnectionTool\") {\n var selectedConnections = []; // only the connections should have higher presence because the connection edit point is on top of connector.\n // TODO: This should be reworked. The connection adorner should be one for all selected connections and should be hit tested prior the connections and shapes itself.\n for (i = 0; i < d._selectedItems.length; i++) {\n item = d._selectedItems[i];\n if (item instanceof diagram.Connection) {\n selectedConnections.push(item);\n }\n }\n hit = this._hitTestItems(selectedConnections, point);\n }\n\n return hit || this._hitTestElements(point);\n },\n\n _hitTestElements: function(point) {\n var diagram = this.diagram;\n var shapeHit = this._hitTestItems(diagram.shapes, point);\n var connectionHit = this._hitTestItems(diagram.connections, point);\n var hit;\n\n if ((!this.activeTool || this.activeTool.type != \"ConnectionTool\") && shapeHit && connectionHit && !hitTestShapeConnectors(shapeHit, point)) {\n var mainLayer = diagram.mainLayer;\n var shapeIdx = inArray(shapeHit.visual, mainLayer.children);\n var connectionIdx = inArray(connectionHit.visual, mainLayer.children);\n hit = shapeIdx > connectionIdx ? shapeHit : connectionHit;\n }\n return hit || shapeHit || connectionHit;\n },\n\n _hitTestItems: function(array, point) {\n var i, item, hit;\n for (i = array.length - 1; i >= 0; i--) {\n item = array[i];\n hit = item._hitTest(point);\n if (hit) {\n return hit;\n }\n }\n }\n });\n\n // Routing =========================================\n\n /**\n * Base class for connection routers.\n */\n var ConnectionRouterBase = kendo.Class.extend({\n init: function() {\n }\n /*route: function (connection) {\n },\n hitTest: function (p) {\n\n },\n getBounds: function () {\n\n }*/\n });\n\n /**\n * Base class for polyline and cascading routing.\n */\n var LinearConnectionRouter = ConnectionRouterBase.extend({\n init: function(connection) {\n var that = this;\n ConnectionRouterBase.fn.init.call(that);\n this.connection = connection;\n },\n /**\n * Hit testing for polyline paths.\n */\n hitTest: function(p) {\n var rec = this.getBounds().inflate(HIT_TEST_DISTANCE);\n if (!rec.contains(p)) {\n return false;\n }\n return diagram.Geometry.distanceToPolyline(p, this.connection.allPoints()) < HIT_TEST_DISTANCE;\n },\n\n /**\n * Bounds of a polyline.\n * @returns {kendo.dataviz.diagram.Rect}\n */\n getBounds: function() {\n var points = this.connection.allPoints(),\n s = points[0],\n e = points[points.length - 1],\n right = Math.max(s.x, e.x),\n left = Math.min(s.x, e.x),\n top = Math.min(s.y, e.y),\n bottom = Math.max(s.y, e.y);\n\n for (var i = 1; i < points.length - 1; ++i) {\n right = Math.max(right, points[i].x);\n left = Math.min(left, points[i].x);\n top = Math.min(top, points[i].y);\n bottom = Math.max(bottom, points[i].y);\n }\n\n return new Rect(left, top, right - left, bottom - top);\n }\n });\n\n /**\n * A simple poly-linear routing which does not alter the intermediate points.\n * Does hold the underlying hit, bounds....logic.\n * @type {*|Object|void|extend|Zepto.extend|b.extend}\n */\n var PolylineRouter = LinearConnectionRouter.extend({\n init: function(connection) {\n var that = this;\n LinearConnectionRouter.fn.init.call(that);\n this.connection = connection;\n },\n route: function() {\n // just keep the points as is\n }\n });\n\n var CascadingRouter = LinearConnectionRouter.extend({\n SAME_SIDE_DISTANCE_RATIO: 5,\n\n init: function(connection) {\n var that = this;\n LinearConnectionRouter.fn.init.call(that);\n this.connection = connection;\n },\n\n routePoints: function(start, end, sourceConnector, targetConnector) {\n var result;\n\n if (sourceConnector && targetConnector) {\n result = this._connectorPoints(start, end, sourceConnector, targetConnector);\n } else {\n result = this._floatingPoints(start, end, sourceConnector);\n }\n return result;\n },\n\n route: function() {\n var sourceConnector = this.connection._resolvedSourceConnector;\n var targetConnector = this.connection._resolvedTargetConnector;\n var start = this.connection.sourcePoint();\n var end = this.connection.targetPoint();\n var points = this.routePoints(start, end, sourceConnector, targetConnector);\n this.connection.points(points);\n },\n\n _connectorSides: [{\n name: \"Top\",\n axis: \"y\",\n boundsPoint: \"topLeft\",\n secondarySign: 1\n }, {\n name: \"Left\",\n axis: \"x\",\n boundsPoint: \"topLeft\",\n secondarySign: 1\n }, {\n name: \"Bottom\",\n axis: \"y\",\n boundsPoint: \"bottomRight\",\n secondarySign: -1\n }, {\n name: \"Right\",\n axis: \"x\",\n boundsPoint: \"bottomRight\",\n secondarySign: -1\n }],\n\n _connectorSide: function(connector, targetPoint) {\n var position = connector.position();\n var shapeBounds = connector.shape.bounds(ROTATED);\n var bounds = {\n topLeft: shapeBounds.topLeft(),\n bottomRight: shapeBounds.bottomRight()\n };\n var sides = this._connectorSides;\n var min = util.MAX_NUM;\n var sideDistance;\n var minSide;\n var axis;\n var side;\n for (var idx = 0; idx < sides.length; idx++) {\n side = sides[idx];\n axis = side.axis;\n sideDistance = Math.round(Math.abs(position[axis] - bounds[side.boundsPoint][axis]));\n if (sideDistance < min) {\n min = sideDistance;\n minSide = side;\n } else if (sideDistance === min &&\n (position[axis] - targetPoint[axis]) * side.secondarySign > (position[minSide.axis] - targetPoint[minSide.axis]) * minSide.secondarySign) {\n minSide = side;\n }\n }\n return minSide.name;\n },\n\n _sameSideDistance: function(connector) {\n var bounds = connector.shape.bounds(ROTATED);\n return Math.min(bounds.width, bounds.height) / this.SAME_SIDE_DISTANCE_RATIO;\n },\n\n _connectorPoints: function(start, end, sourceConnector, targetConnector) {\n var sourceConnectorSide = this._connectorSide(sourceConnector, end);\n var targetConnectorSide = this._connectorSide(targetConnector, start);\n var deltaX = end.x - start.x;\n var deltaY = end.y - start.y;\n var sameSideDistance = this._sameSideDistance(sourceConnector);\n var result = [];\n var pointX, pointY;\n\n if (sourceConnectorSide === TOP || sourceConnectorSide == BOTTOM) {\n if (targetConnectorSide == TOP || targetConnectorSide == BOTTOM) {\n if (sourceConnectorSide == targetConnectorSide) {\n if (sourceConnectorSide == TOP) {\n pointY = Math.min(start.y, end.y) - sameSideDistance;\n } else {\n pointY = Math.max(start.y, end.y) + sameSideDistance;\n }\n result = [new Point(start.x, pointY), new Point(end.x, pointY)];\n } else {\n result = [new Point(start.x, start.y + deltaY / 2), new Point(end.x, start.y + deltaY / 2)];\n }\n } else {\n result = [new Point(start.x, end.y)];\n }\n } else {\n if (targetConnectorSide == LEFT || targetConnectorSide == RIGHT) {\n if (sourceConnectorSide == targetConnectorSide) {\n if (sourceConnectorSide == LEFT) {\n pointX = Math.min(start.x, end.x) - sameSideDistance;\n } else {\n pointX = Math.max(start.x, end.x) + sameSideDistance;\n }\n result = [new Point(pointX, start.y), new Point(pointX, end.y)];\n } else {\n result = [new Point(start.x + deltaX / 2, start.y), new Point(start.x + deltaX / 2, start.y + deltaY)];\n }\n } else {\n result = [new Point(end.x, start.y)];\n }\n }\n return result;\n },\n\n _floatingPoints: function(start, end, sourceConnector) {\n var sourceConnectorSide = sourceConnector ? this._connectorSide(sourceConnector, end) : null;\n var cascadeStartHorizontal = this._startHorizontal(start, end, sourceConnectorSide);\n var points = [start, start, end, end];\n var deltaX = end.x - start.x;\n var deltaY = end.y - start.y;\n var length = points.length;\n var shiftX;\n var shiftY;\n\n // note that this is more generic than needed for only two intermediate points.\n for (var idx = 1; idx < length - 1; ++idx) {\n if (cascadeStartHorizontal) {\n if (idx % 2 !== 0) {\n shiftX = deltaX / (length / 2);\n shiftY = 0;\n }\n else {\n shiftX = 0;\n shiftY = deltaY / ((length - 1) / 2);\n }\n }\n else {\n if (idx % 2 !== 0) {\n shiftX = 0;\n shiftY = deltaY / (length / 2);\n }\n else {\n shiftX = deltaX / ((length - 1) / 2);\n shiftY = 0;\n }\n }\n points[idx] = new Point(points[idx - 1].x + shiftX, points[idx - 1].y + shiftY);\n }\n // need to fix the wrong 1.5 factor of the last intermediate point\n idx--;\n if ((cascadeStartHorizontal && (idx % 2 !== 0)) || (!cascadeStartHorizontal && (idx % 2 === 0))) {\n points[length - 2] = new Point(points[length - 1].x, points[length - 2].y);\n } else {\n points[length - 2] = new Point(points[length - 2].x, points[length - 1].y);\n }\n\n return [points[1], points[2]];\n },\n\n _startHorizontal: function(start, end, sourceSide) {\n var horizontal;\n if (sourceSide !== null && (sourceSide === RIGHT || sourceSide === LEFT)) {\n horizontal = true;\n } else {\n horizontal = Math.abs(start.x - end.x) > Math.abs(start.y - end.y);\n }\n\n return horizontal;\n }\n });\n\n // Adorners =========================================\n\n var AdornerBase = Class.extend({\n init: function(diagram, options) {\n var that = this;\n that.diagram = diagram;\n that.options = deepExtend({}, that.options, options);\n that.visual = new Group();\n that.diagram._adorners.push(that);\n },\n refresh: function() {\n\n }\n });\n\n var ConnectionEditAdorner = AdornerBase.extend({\n init: function(connection, options) {\n var that = this, diagram;\n that.connection = connection;\n diagram = that.connection.diagram;\n that._ts = diagram.toolService;\n AdornerBase.fn.init.call(that, diagram, options);\n var sp = that.connection.sourcePoint();\n var tp = that.connection.targetPoint();\n that.spVisual = new Circle(deepExtend(that.options.handles, { center: sp }));\n that.epVisual = new Circle(deepExtend(that.options.handles, { center: tp }));\n that.visual.append(that.spVisual);\n that.visual.append(that.epVisual);\n },\n\n options: {\n handles: {}\n },\n\n _getCursor: function() {\n return Cursors.move;\n },\n\n start: function(p) {\n this.handle = this._hitTest(p);\n this.startPoint = p;\n this._initialSource = this.connection.source();\n this._initialTarget = this.connection.target();\n switch (this.handle) {\n case -1:\n if (this.connection.targetConnector) {\n this._ts._connectionManipulation(this.connection, this.connection.targetConnector.shape);\n }\n break;\n case 1:\n if (this.connection.sourceConnector) {\n this._ts._connectionManipulation(this.connection, this.connection.sourceConnector.shape);\n }\n break;\n }\n },\n\n move: function(handle, p) {\n switch (handle) {\n case -1:\n this.connection.source(p);\n break;\n case 1:\n this.connection.target(p);\n break;\n default:\n var delta = p.minus(this.startPoint);\n this.startPoint = p;\n if (!this.connection.sourceConnector) {\n this.connection.source(this.connection.sourcePoint().plus(delta));\n }\n if (!this.connection.targetConnector) {\n this.connection.target(this.connection.targetPoint().plus(delta));\n }\n break;\n }\n this.refresh();\n return true;\n },\n\n stop: function(p) {\n var ts = this.diagram.toolService, item = ts.hoveredItem, target;\n if (ts._hoveredConnector) {\n target = ts._hoveredConnector._c;\n } else if (item && item instanceof diagram.Shape) {\n target = item.getConnector(AUTO) || item.getConnector(p);\n } else {\n target = p;\n }\n\n if (this.handle === -1) {\n this.connection.source(target);\n } else if (this.handle === 1) {\n this.connection.target(target);\n }\n\n this.handle = undefined$1;\n this._ts._connectionManipulation();\n return new ConnectionEditUndoUnit(this.connection, this._initialSource, this._initialTarget);\n },\n\n _hitTest: function(point) {\n var sourcePoint = this.connection.sourcePoint();\n var targetPoint = this.connection.targetPoint();\n var radiusX = this.options.handles.width / 2 + HIT_TEST_DISTANCE;\n var radiusY = this.options.handles.height / 2 + HIT_TEST_DISTANCE;\n var sourcePointDistance = sourcePoint.distanceTo(point);\n var targetPointDistance = targetPoint.distanceTo(point);\n var sourceHandle = new Rect(sourcePoint.x, sourcePoint.y).inflate(radiusX, radiusY).contains(point);\n var targetHandle = new Rect(targetPoint.x, targetPoint.y).inflate(radiusX, radiusY).contains(point);\n var handle = 0;\n\n if (sourceHandle && (!targetHandle || sourcePointDistance < targetPointDistance)) {\n handle = -1;\n } else if (targetHandle && (!sourceHandle || targetPointDistance < sourcePointDistance)) {\n handle = 1;\n }\n\n return handle;\n },\n\n refresh: function() {\n this.spVisual.redraw({ center: this.diagram.modelToLayer(this.connection.sourcePoint()) });\n this.epVisual.redraw({ center: this.diagram.modelToLayer(this.connection.targetPoint()) });\n }\n });\n\n var ConnectorsAdorner = AdornerBase.extend({\n init: function(diagram, options) {\n var that = this;\n AdornerBase.fn.init.call(that, diagram, options);\n that._refreshHandler = function(e) {\n if (e.item == that.shape) {\n that.refresh();\n }\n };\n },\n\n show: function(shape) {\n var that = this, len, i, ctr;\n that._visible = true;\n that.shape = shape;\n that.diagram.bind(ITEMBOUNDSCHANGE, that._refreshHandler);\n len = shape.connectors.length;\n that.connectors = [];\n that._clearVisual();\n for (i = 0; i < len; i++) {\n ctr = new ConnectorVisual(shape.connectors[i]);\n that.connectors.push(ctr);\n that.visual.append(ctr.visual);\n }\n that.visual.visible(true);\n that.refresh();\n },\n\n _clearVisual: function() {\n var that = this;\n if (that.diagram._cachedTouchTarget) {\n that._keepCachedTouchTarget();\n } else {\n that.visual.clear();\n }\n },\n\n _keepCachedTouchTarget: function() {\n var that = this,\n visualChildren = that.visual.children;\n var childrenCount = visualChildren.length;\n var index = inArray(that.diagram._cachedTouchTarget, visualChildren);\n for (var i = childrenCount - 1; i >= 0; i--) {\n if (i == index) {\n continue;\n }\n that.visual.remove(visualChildren[i]);\n }\n },\n\n destroy: function() {\n var that = this;\n that.diagram.unbind(ITEMBOUNDSCHANGE, that._refreshHandler);\n that.shape = undefined$1;\n that._visible = undefined$1;\n that.visual.visible(false);\n },\n\n _hitTest: function(p) {\n var ctr, i;\n for (i = 0; i < this.connectors.length; i++) {\n ctr = this.connectors[i];\n if (ctr._hitTest(p)) {\n ctr._hover(true);\n this.diagram.toolService._hoveredConnector = ctr;\n break;\n }\n }\n },\n\n refresh: function() {\n if (this.shape) {\n var bounds = this.shape.bounds();\n bounds = this.diagram.modelToLayer(bounds);\n this.visual.position(bounds.topLeft());\n $.each(this.connectors, function() {\n this.refresh();\n });\n }\n }\n });\n\n function hitToOppositeSide(hit, bounds) {\n var result;\n\n if (hit.x == -1 && hit.y == -1) {\n result = bounds.bottomRight();\n } else if (hit.x == 1 && hit.y == 1) {\n result = bounds.topLeft();\n } else if (hit.x == -1 && hit.y == 1) {\n result = bounds.topRight();\n } else if (hit.x == 1 && hit.y == -1) {\n result = bounds.bottomLeft();\n } else if (hit.x === 0 && hit.y == -1) {\n result = bounds.bottom();\n } else if (hit.x === 0 && hit.y == 1) {\n result = bounds.top();\n } else if (hit.x == 1 && hit.y === 0) {\n result = bounds.left();\n } else if (hit.x == -1 && hit.y === 0) {\n result = bounds.right();\n }\n\n return result;\n }\n\n var ResizingAdorner = AdornerBase.extend({\n init: function(diagram, options) {\n var that = this;\n AdornerBase.fn.init.call(that, diagram, options);\n that._manipulating = false;\n that.map = [];\n that.shapes = [];\n\n that._initSelection();\n that._createHandles();\n that.redraw();\n that.diagram.bind(\"select\", function(e) {\n that._initialize(e.selected);\n });\n\n that._refreshHandler = function() {\n if (!that._internalChange) {\n that.refreshBounds();\n that.refresh();\n }\n };\n\n that._rotatedHandler = function() {\n if (that.shapes.length == 1) {\n that._angle = that.shapes[0].rotate().angle;\n }\n that._refreshHandler();\n };\n\n that.diagram.bind(ITEMBOUNDSCHANGE, that._refreshHandler).bind(ITEMROTATE, that._rotatedHandler);\n that.refreshBounds();\n that.refresh();\n },\n\n options: {\n handles: {\n fill: {\n color: \"#fff\"\n },\n stroke: {\n color: \"#282828\"\n },\n height: 7,\n width: 7,\n hover: {\n fill: {\n color: \"#282828\"\n },\n stroke: {\n color: \"#282828\"\n }\n }\n },\n selectable: {\n stroke: {\n color: \"#778899\",\n width: 1,\n dashType: \"dash\"\n },\n fill: {\n color: TRANSPARENT\n }\n },\n offset: 10\n },\n\n _initSelection: function() {\n var that = this;\n var diagram = that.diagram;\n var selectable = diagram.options.selectable;\n var options = deepExtend({}, that.options.selectable, selectable);\n that.rect = new Rectangle(options);\n that.visual.append(that.rect);\n },\n\n _resizable: function() {\n return this.options.editable && this.options.editable.resize !== false;\n },\n\n _handleOptions: function() {\n return (this.options.editable.resize || {}).handles || this.options.handles;\n },\n\n _createHandles: function() {\n var handles, item, y, x;\n\n if (this._resizable()) {\n handles = this._handleOptions();\n for (x = -1; x <= 1; x++) {\n for (y = -1; y <= 1; y++) {\n if ((x !== 0) || (y !== 0)) { // (0, 0) element, (-1, -1) top-left, (+1, +1) bottom-right\n item = new Rectangle(handles);\n item.drawingElement._hover = this._hover.bind(this);\n this.map.push({ x: x, y: y, visual: item });\n this.visual.append(item);\n }\n }\n }\n }\n },\n\n bounds: function(value) {\n if (value) {\n this._innerBounds = value.clone();\n this._bounds = this.diagram.modelToLayer(value).inflate(this.options.offset, this.options.offset);\n } else {\n return this._bounds;\n }\n },\n\n _hitTest: function(p) {\n var tp = this.diagram.modelToLayer(p),\n i, hit, handleBounds, handlesCount = this.map.length, handle;\n\n if (this._angle) {\n tp = tp.clone().rotate(this._bounds.center(), this._angle);\n }\n\n if (this._resizable()) {\n for (i = 0; i < handlesCount; i++) {\n handle = this.map[i];\n hit = new Point(handle.x, handle.y);\n handleBounds = this._getHandleBounds(hit); //local coordinates\n handleBounds.offset(this._bounds.x, this._bounds.y);\n if (handleBounds.contains(tp)) {\n return hit;\n }\n }\n }\n\n if (this._bounds.contains(tp)) {\n return new Point(0, 0);\n }\n },\n\n _getHandleBounds: function(p) {\n if (this._resizable()) {\n var handles = this._handleOptions(),\n w = handles.width,\n h = handles.height,\n r = new Rect(0, 0, w, h);\n\n if (p.x < 0) {\n r.x = - w / 2;\n } else if (p.x === 0) {\n r.x = Math.floor(this._bounds.width / 2) - w / 2;\n } else if (p.x > 0) {\n r.x = this._bounds.width + 1.0 - w / 2;\n } if (p.y < 0) {\n r.y = - h / 2;\n } else if (p.y === 0) {\n r.y = Math.floor(this._bounds.height / 2) - h / 2;\n } else if (p.y > 0) {\n r.y = this._bounds.height + 1.0 - h / 2;\n }\n\n return r;\n }\n },\n\n _getCursor: function(point) {\n var hit = this._hitTest(point);\n if (hit && (hit.x >= -1) && (hit.x <= 1) && (hit.y >= -1) && (hit.y <= 1) && this._resizable()) {\n var angle = this._angle;\n if (angle) {\n angle = 360 - angle;\n hit.rotate(new Point(0, 0), angle);\n hit = new Point(Math.round(hit.x), Math.round(hit.y));\n }\n\n if (hit.x == -1 && hit.y == -1) {\n return \"nw-resize\";\n }\n if (hit.x == 1 && hit.y == 1) {\n return \"se-resize\";\n }\n if (hit.x == -1 && hit.y == 1) {\n return \"sw-resize\";\n }\n if (hit.x == 1 && hit.y == -1) {\n return \"ne-resize\";\n }\n if (hit.x === 0 && hit.y == -1) {\n return \"n-resize\";\n }\n if (hit.x === 0 && hit.y == 1) {\n return \"s-resize\";\n }\n if (hit.x == 1 && hit.y === 0) {\n return \"e-resize\";\n }\n if (hit.x == -1 && hit.y === 0) {\n return \"w-resize\";\n }\n }\n return this._manipulating ? Cursors.move : Cursors.select;\n },\n\n _initialize: function() {\n var that = this, i, item,\n items = that.diagram.select();\n\n that.shapes = [];\n for (i = 0; i < items.length; i++) {\n item = items[i];\n if (item instanceof diagram.Shape) {\n that.shapes.push(item);\n item._rotationOffset = new Point();\n }\n }\n\n that._angle = that.shapes.length == 1 ? that.shapes[0].rotate().angle : 0;\n that._startAngle = that._angle;\n that._rotates();\n that._positions();\n that.refreshBounds();\n that.refresh();\n that.redraw();\n },\n\n _rotates: function() {\n var that = this, i, shape;\n that.initialRotates = [];\n for (i = 0; i < that.shapes.length; i++) {\n shape = that.shapes[i];\n that.initialRotates.push(shape.rotate().angle);\n }\n },\n\n _positions: function() {\n var that = this, i, shape;\n that.initialStates = [];\n for (i = 0; i < that.shapes.length; i++) {\n shape = that.shapes[i];\n that.initialStates.push(shape.bounds());\n }\n },\n\n _hover: function(value, element) {\n if (this._resizable()) {\n var handleOptions = this._handleOptions(),\n hover = handleOptions.hover,\n stroke = handleOptions.stroke,\n fill = handleOptions.fill;\n\n if (value && Utils.isDefined(hover.stroke)) {\n stroke = deepExtend({}, stroke, hover.stroke);\n }\n\n if (value && Utils.isDefined(hover.fill)) {\n fill = hover.fill;\n }\n element.stroke(stroke.color, stroke.width, stroke.opacity);\n element.fill(fill.color, fill.opacity);\n }\n },\n\n start: function(p) {\n this._sp = p;\n this._cp = p;\n this._lp = p;\n this._manipulating = true;\n this._internalChange = true;\n this.shapeStates = [];\n for (var i = 0; i < this.shapes.length; i++) {\n var shape = this.shapes[i];\n this.shapeStates.push(shape.bounds());\n }\n },\n\n redraw: function() {\n var i, handle,\n visibleHandles = this._resizable();\n\n for (i = 0; i < this.map.length; i++) {\n handle = this.map[i];\n handle.visual.visible(visibleHandles);\n }\n },\n\n angle: function(value) {\n if (defined(value)) {\n this._angle = value;\n }\n\n return this._angle;\n },\n\n rotate: function() {\n var center = this._innerBounds.center();\n var currentAngle = this.angle();\n this._internalChange = true;\n for (var i = 0; i < this.shapes.length; i++) {\n var shape = this.shapes[i];\n currentAngle = (currentAngle + this.initialRotates[i] - this._startAngle) % 360;\n shape.rotate(currentAngle, center);\n }\n this.refresh();\n },\n\n move: function(handle, p) {\n var delta, dragging,\n dtl = new Point(),\n dbr = new Point(),\n bounds, center, shape,\n i, angle, newBounds,\n changed = 0, staticPoint,\n scaleX, scaleY;\n\n if (handle.y === -2 && handle.x === -1) {\n center = this._innerBounds.center();\n this._angle = this._truncateAngle(Utils.findAngle(center, p));\n for (i = 0; i < this.shapes.length; i++) {\n shape = this.shapes[i];\n angle = (this._angle + this.initialRotates[i] - this._startAngle) % 360;\n shape.rotate(angle, center);\n if (shape.hasOwnProperty(\"layout\")) {\n shape.layout(shape);\n }\n this._rotating = true;\n }\n this.refresh();\n } else {\n if (this.shouldSnap()) {\n var thr = this._truncateDistance(p.minus(this._lp));\n // threshold\n if (thr.x === 0 && thr.y === 0) {\n this._cp = p;\n return;\n }\n delta = thr;\n this._lp = new Point(this._lp.x + thr.x, this._lp.y + thr.y);\n } else {\n delta = p.minus(this._cp);\n }\n\n if (this.isDragHandle(handle)) {\n dbr = dtl = delta; // dragging\n dragging = true;\n } else {\n if (this._angle) { // adjust the delta so that resizers resize in the correct direction after rotation.\n delta.rotate(new Point(0, 0), this._angle);\n }\n if (handle.x == -1) {\n dtl.x = delta.x;\n } else if (handle.x == 1) {\n dbr.x = delta.x;\n }\n if (handle.y == -1) {\n dtl.y = delta.y;\n } else if (handle.y == 1) {\n dbr.y = delta.y;\n }\n }\n\n if (!dragging) {\n staticPoint = hitToOppositeSide(handle, this._innerBounds);\n scaleX = (this._innerBounds.width + delta.x * handle.x) / this._innerBounds.width;\n scaleY = (this._innerBounds.height + delta.y * handle.y) / this._innerBounds.height;\n }\n\n for (i = 0; i < this.shapes.length; i++) {\n shape = this.shapes[i];\n bounds = shape.bounds();\n if (dragging) {\n if (!canDrag(shape)) {\n continue;\n }\n newBounds = this._displaceBounds(bounds, dtl, dbr, dragging);\n } else {\n newBounds = bounds.clone();\n newBounds.scale(scaleX, scaleY, staticPoint, this._innerBounds.center(), shape.rotate().angle);\n var newCenter = newBounds.center(); // fixes the new rotation center.\n newCenter.rotate(bounds.center(), -this._angle);\n newBounds = new Rect(newCenter.x - newBounds.width / 2, newCenter.y - newBounds.height / 2, newBounds.width, newBounds.height);\n }\n if (newBounds.width >= shape.options.minWidth && newBounds.height >= shape.options.minHeight) { // if we up-size very small shape\n var oldBounds = bounds;\n shape.bounds(newBounds);\n if (shape.hasOwnProperty(\"layout\")) {\n shape.layout(shape, oldBounds, newBounds);\n }\n if (oldBounds.width !== newBounds.width || oldBounds.height !== newBounds.height) {\n shape.rotate(shape.rotate().angle); // forces the rotation to update it's rotation center\n }\n changed += 1;\n }\n }\n\n if (changed) {\n if (changed == i) {\n newBounds = this._displaceBounds(this._innerBounds, dtl, dbr, dragging);\n this.bounds(newBounds);\n } else {\n this.refreshBounds();\n }\n this.refresh();\n }\n\n this._positions();\n }\n\n this._cp = p;\n },\n\n isDragHandle: function(handle) {\n return handle.x === 0 && handle.y === 0;\n },\n\n cancel: function() {\n var shapes = this.shapes;\n var states = this.shapeStates;\n for (var idx = 0; idx < shapes.length; idx++) {\n shapes[idx].bounds(states[idx]);\n }\n this.refreshBounds();\n this.refresh();\n this._manipulating = undefined$1;\n this._internalChange = undefined$1;\n this._rotating = undefined$1;\n },\n\n _truncatePositionToGuides: function(bounds) {\n if (this.diagram.ruler) {\n return this.diagram.ruler.truncatePositionToGuides(bounds);\n }\n return bounds;\n },\n\n _truncateSizeToGuides: function(bounds) {\n if (this.diagram.ruler) {\n return this.diagram.ruler.truncateSizeToGuides(bounds);\n }\n return bounds;\n },\n\n _truncateAngle: function(a) {\n var snap = this.snapOptions();\n var snapAngle = Math.max(snap.angle || DEFAULT_SNAP_ANGLE, MIN_SNAP_ANGLE);\n return snap ? Math.floor((a % 360) / snapAngle) * snapAngle : (a % 360);\n },\n\n _truncateDistance: function(d) {\n if (d instanceof diagram.Point) {\n return new diagram.Point(this._truncateDistance(d.x), this._truncateDistance(d.y));\n } else {\n var snap = this.snapOptions() || {};\n var snapSize = Math.max(snap.size || DEFAULT_SNAP_SIZE, MIN_SNAP_SIZE);\n return snap ? Math.floor(d / snapSize) * snapSize : d;\n }\n },\n\n snapOptions: function() {\n var editable = this.diagram.options.editable;\n var snap = ((editable || {}).drag || {}).snap || {};\n return snap;\n },\n\n shouldSnap: function() {\n var editable = this.diagram.options.editable;\n var drag = (editable || {}).drag;\n var snap = (drag || {}).snap;\n return editable !== false && drag !== false && snap !== false;\n },\n\n _displaceBounds: function(bounds, dtl, dbr, dragging) {\n var tl = bounds.topLeft().plus(dtl),\n br = bounds.bottomRight().plus(dbr),\n newBounds = Rect.fromPoints(tl, br),\n newCenter;\n if (!dragging) {\n newCenter = newBounds.center();\n newCenter.rotate(bounds.center(), -this._angle);\n newBounds = new Rect(newCenter.x - newBounds.width / 2, newCenter.y - newBounds.height / 2, newBounds.width, newBounds.height);\n }\n return newBounds;\n },\n\n stop: function() {\n var unit, i, shape;\n if (this._cp != this._sp) {\n if (this._rotating) {\n unit = new RotateUnit(this, this.shapes, this.initialRotates);\n this._rotating = false;\n } else if (this._diffStates()) {\n if (this.diagram.ruler) {\n for (i = 0; i < this.shapes.length; i++) {\n shape = this.shapes[i];\n var bounds = shape.bounds();\n bounds = this._truncateSizeToGuides(this._truncatePositionToGuides(bounds));\n shape.bounds(bounds);\n this.refreshBounds();\n this.refresh();\n }\n }\n for (i = 0; i < this.shapes.length; i++) {\n shape = this.shapes[i];\n shape.updateModel();\n }\n unit = new TransformUnit(this.shapes, this.shapeStates, this);\n this.diagram._syncShapeChanges();\n }\n }\n\n this._manipulating = undefined$1;\n this._internalChange = undefined$1;\n this._rotating = undefined$1;\n return unit;\n },\n\n _diffStates: function() {\n var shapes = this.shapes;\n var states = this.shapeStates;\n for (var idx = 0; idx < shapes.length; idx++) {\n if (!shapes[idx].bounds().equals(states[idx])) {\n return true;\n }\n }\n return false;\n },\n\n refreshBounds: function() {\n var bounds = this.shapes.length == 1 ?\n this.shapes[0].bounds().clone() :\n this.diagram.boundingBox(this.shapes, true);\n\n this.bounds(bounds);\n },\n\n refresh: function() {\n var that = this, b, bounds;\n if (this.shapes.length > 0) {\n bounds = this.bounds();\n this.visual.visible(true);\n this.visual.position(bounds.topLeft());\n $.each(this.map, function() {\n b = that._getHandleBounds(new Point(this.x, this.y));\n this.visual.position(b.topLeft());\n });\n this.visual.position(bounds.topLeft());\n\n var center = new Point(bounds.width / 2, bounds.height / 2);\n this.visual.rotate(this._angle, center);\n this.rect.redraw({ width: bounds.width, height: bounds.height });\n if (this.rotationThumb) {\n var thumb = this.options.editable.rotate.thumb;\n this._rotationThumbBounds = new Rect(bounds.center().x, bounds.y + thumb.y, 0, 0).inflate(thumb.width);\n this.rotationThumb.redraw({ x: bounds.width / 2 - thumb.width / 2 });\n }\n } else {\n this.visual.visible(false);\n }\n }\n });\n\n var Selector = Class.extend({\n init: function(diagram) {\n var selectable = diagram.options.selectable;\n this.options = deepExtend({}, this.options, selectable);\n\n this.visual = new Rectangle(this.options);\n this.diagram = diagram;\n },\n options: {\n stroke: {\n color: \"#778899\",\n width: 1,\n dashType: \"dash\"\n },\n fill: {\n color: TRANSPARENT\n }\n },\n start: function(p) {\n this._sp = this._ep = p;\n this.refresh();\n this.diagram._adorn(this, true);\n },\n end: function() {\n this._sp = this._ep = undefined$1;\n this.diagram._adorn(this, false);\n },\n bounds: function(value) {\n if (value) {\n this._bounds = value;\n }\n return this._bounds;\n },\n move: function(p) {\n this._ep = p;\n this.refresh();\n },\n refresh: function() {\n if (this._sp) {\n var visualBounds = Rect.fromPoints(this.diagram.modelToLayer(this._sp), this.diagram.modelToLayer(this._ep));\n this.bounds(Rect.fromPoints(this._sp, this._ep));\n this.visual.position(visualBounds.topLeft());\n this.visual.redraw({ height: visualBounds.height + 1, width: visualBounds.width + 1 });\n }\n }\n });\n\n var ConnectorVisual = Class.extend({\n init: function(connector) {\n this.options = deepExtend({}, connector.options);\n this._c = connector;\n this.visual = new Circle(this.options);\n this.refresh();\n },\n _hover: function(value) {\n var options = this.options,\n hover = options.hover,\n stroke = options.stroke,\n fill = options.fill;\n\n if (value && Utils.isDefined(hover.stroke)) {\n stroke = deepExtend({}, stroke, hover.stroke);\n }\n\n if (value && Utils.isDefined(hover.fill)) {\n fill = hover.fill;\n }\n\n this.visual.redraw({\n stroke: stroke,\n fill: fill\n });\n },\n refresh: function() {\n var p = this._c.shape.diagram.modelToView(this._c.position()),\n relative = p.minus(this._c.shape.bounds(\"transformed\").topLeft()),\n value = new Rect(p.x, p.y, 0, 0);\n value.inflate(this.options.width / 2, this.options.height / 2);\n this._visualBounds = value;\n this.visual.redraw({ center: new Point(relative.x, relative.y) });\n },\n _hitTest: function(p) {\n var tp = this._c.shape.diagram.modelToView(p);\n return this._visualBounds.contains(tp);\n }\n });\n\n function canDrag(element) {\n var editable = element.options.editable;\n return editable && editable.drag !== false;\n }\n\n function hitTestShapeConnectors(shape, point) {\n var connector, position, rect;\n for (var idx = 0; idx < shape.connectors.length; idx++) {\n connector = shape.connectors[idx];\n position = connector.position();\n rect = new Rect(position.x, position.y);\n rect.inflate(HIT_TEST_DISTANCE, HIT_TEST_DISTANCE);\n if (rect.contains(point)) {\n return connector;\n }\n }\n }\n\n function noMeta(meta) {\n return meta.ctrlKey === false && meta.altKey === false && meta.shiftKey === false;\n }\n\n deepExtend(diagram, {\n CompositeUnit: CompositeUnit,\n TransformUnit: TransformUnit,\n PanUndoUnit: PanUndoUnit,\n AddShapeUnit: AddShapeUnit,\n AddConnectionUnit: AddConnectionUnit,\n DeleteShapeUnit: DeleteShapeUnit,\n DeleteConnectionUnit: DeleteConnectionUnit,\n ConnectionEditAdorner: ConnectionEditAdorner,\n ConnectionTool: ConnectionTool,\n ConnectorVisual: ConnectorVisual,\n UndoRedoService: UndoRedoService,\n ResizingAdorner: ResizingAdorner,\n Selector: Selector,\n ToolService: ToolService,\n ConnectorsAdorner: ConnectorsAdorner,\n LayoutUndoUnit: LayoutUndoUnit,\n ConnectionEditUnit: ConnectionEditUnit,\n ToFrontUnit: ToFrontUnit,\n ToBackUnit: ToBackUnit,\n ConnectionRouterBase: ConnectionRouterBase,\n PolylineRouter: PolylineRouter,\n CascadingRouter: CascadingRouter,\n SelectionTool: SelectionTool,\n ScrollerTool: ScrollerTool,\n PointerTool: PointerTool,\n ConnectionEditTool: ConnectionEditTool,\n RotateUnit: RotateUnit\n });\n })(window.kendo.jQuery);\n\n (function($, undefined$1) {\n var kendo = window.kendo,\n diagram = kendo.dataviz.diagram,\n Graph = diagram.Graph,\n Node = diagram.Node,\n Link = diagram.Link,\n deepExtend = kendo.deepExtend,\n Size = diagram.Size,\n Rect = diagram.Rect,\n Dictionary = diagram.Dictionary,\n Set = diagram.Set,\n HyperTree = diagram.Graph,\n Utils = diagram.Utils,\n Point = diagram.Point,\n EPSILON = 1e-06,\n DEG_TO_RAD = Math.PI / 180,\n contains = Utils.contains,\n grep = $.grep;\n\n /**\n * Base class for layout algorithms.\n * @type {*}\n */\n var LayoutBase = kendo.Class.extend({\n defaultOptions: {\n type: \"Tree\",\n subtype: \"Down\",\n roots: null,\n animate: false,\n //-------------------------------------------------------------------\n /**\n * Force-directed option: whether the motion of the nodes should be limited by the boundaries of the diagram surface.\n */\n limitToView: false,\n /**\n * Force-directed option: the amount of friction applied to the motion of the nodes.\n */\n friction: 0.9,\n /**\n * Force-directed option: the optimal distance between nodes (minimum energy).\n */\n nodeDistance: 50,\n /**\n * Force-directed option: the number of time things are being calculated.\n */\n iterations: 300,\n //-------------------------------------------------------------------\n /**\n * Tree option: the separation in one direction (depends on the subtype what direction this is).\n */\n horizontalSeparation: 90,\n /**\n * Tree option: the separation in the complementary direction (depends on the subtype what direction this is).\n */\n verticalSeparation: 50,\n\n //-------------------------------------------------------------------\n /**\n * Tip-over tree option: children-to-parent vertical distance.\n */\n underneathVerticalTopOffset: 15,\n /**\n * Tip-over tree option: children-to-parent horizontal distance.\n */\n underneathHorizontalOffset: 15,\n /**\n * Tip-over tree option: leaf-to-next-branch vertical distance.\n */\n underneathVerticalSeparation: 15,\n //-------------------------------------------------------------------\n /**\n * Settings object to organize the different components of the diagram in a grid layout structure\n */\n grid: {\n /**\n * The width of the grid in which components are arranged. Beyond this width a component will be on the next row.\n */\n width: 1500,\n /**\n * The left offset of the grid.\n */\n offsetX: 50,\n /**\n * The top offset of the grid.\n */\n offsetY: 50,\n /**\n * The horizontal padding within a cell of the grid where a single component resides.\n */\n componentSpacingX: 20,\n /**\n * The vertical padding within a cell of the grid where a single component resides.\n */\n componentSpacingY: 20\n },\n\n //-------------------------------------------------------------------\n /**\n * Layered option: the separation height/width between the layers.\n */\n layerSeparation: 50,\n /**\n * Layered option: how many rounds of shifting and fine-tuning.\n */\n layeredIterations: 2,\n /**\n * Tree-radial option: the angle at which the layout starts.\n */\n startRadialAngle: 0,\n /**\n * Tree-radial option: the angle at which the layout starts.\n */\n endRadialAngle: 360,\n /**\n * Tree-radial option: the separation between levels.\n */\n radialSeparation: 150,\n /**\n * Tree-radial option: the separation between the root and the first level.\n */\n radialFirstLevelSeparation: 200,\n /**\n * Tree-radial option: whether a virtual roots bing the components in one radial layout.\n */\n keepComponentsInOneRadialLayout: false,\n //-------------------------------------------------------------------\n\n // TODO: ensure to change this to false when containers are around\n ignoreContainers: true,\n layoutContainerChildren: false,\n ignoreInvisible: true,\n animateTransitions: false\n },\n init: function() {\n },\n\n /**\n * Organizes the components in a grid.\n * Returns the final set of nodes (not the Graph).\n * @param components\n */\n gridLayoutComponents: function(components) {\n if (!components) {\n throw \"No components supplied.\";\n }\n\n // calculate and cache the bounds of the components\n Utils.forEach(components, function(c) {\n c.calcBounds();\n });\n\n // order by decreasing width\n components.sort(function(a, b) {\n return b.bounds.width - a.bounds.width;\n });\n\n var maxWidth = this.options.grid.width,\n offsetX = this.options.grid.componentSpacingX,\n offsetY = this.options.grid.componentSpacingY,\n height = 0,\n startX = this.options.grid.offsetX,\n startY = this.options.grid.offsetY,\n x = startX,\n y = startY,\n i,\n resultLinkSet = [],\n resultNodeSet = [];\n\n while (components.length > 0) {\n if (x >= maxWidth) {\n // start a new row\n x = startX;\n y += height + offsetY;\n // reset the row height\n height = 0;\n }\n var component = components.pop();\n this.moveToOffset(component, new Point(x, y));\n for (i = 0; i < component.nodes.length; i++) {\n resultNodeSet.push(component.nodes[i]); // to be returned in the end\n }\n for (i = 0; i < component.links.length; i++) {\n resultLinkSet.push(component.links[i]);\n }\n var boundingRect = component.bounds;\n var currentHeight = boundingRect.height;\n if (currentHeight <= 0 || isNaN(currentHeight)) {\n currentHeight = 0;\n }\n var currentWidth = boundingRect.width;\n if (currentWidth <= 0 || isNaN(currentWidth)) {\n currentWidth = 0;\n }\n\n if (currentHeight >= height) {\n height = currentHeight;\n }\n x += currentWidth + offsetX;\n }\n\n return {\n nodes: resultNodeSet,\n links: resultLinkSet\n };\n },\n\n moveToOffset: function(component, p) {\n var i, j,\n bounds = component.bounds,\n deltax = p.x - bounds.x,\n deltay = p.y - bounds.y;\n\n for (i = 0; i < component.nodes.length; i++) {\n var node = component.nodes[i];\n var nodeBounds = node.bounds();\n if (nodeBounds.width === 0 && nodeBounds.height === 0 && nodeBounds.x === 0 && nodeBounds.y === 0) {\n nodeBounds = new Rect(0, 0, 0, 0);\n }\n nodeBounds.x += deltax;\n nodeBounds.y += deltay;\n node.bounds(nodeBounds);\n }\n for (i = 0; i < component.links.length; i++) {\n var link = component.links[i];\n if (link.points) {\n var newpoints = [];\n var points = link.points;\n for (j = 0; j < points.length; j++) {\n var pt = points[j];\n pt.x += deltax;\n pt.y += deltay;\n newpoints.push(pt);\n }\n link.points = newpoints;\n }\n }\n this.currentHorizontalOffset += bounds.width + this.options.grid.offsetX;\n return new Point(deltax, deltay);\n },\n\n transferOptions: function(options) {\n\n // Size options lead to stackoverflow and need special handling\n\n this.options = kendo.deepExtend({}, this.defaultOptions);\n if (Utils.isUndefined(options)) {\n return;\n }\n\n this.options = kendo.deepExtend(this.options, options || {});\n }\n });\n\n /**\n * The data bucket a hypertree holds in its nodes. *\n * @type {*}\n */\n /* var ContainerGraph = kendo.Class.extend({\n init: function (diagram) {\n this.diagram = diagram;\n this.graph = new Graph(diagram);\n this.container = null;\n this.containerNode = null;\n }\n\n });*/\n\n /**\n * 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 * 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 * to investigate how the effective graph structure looks like and how the layout has to be performed.\n * @type {*}\n */\n var DiagramToHyperTreeAdapter = kendo.Class.extend({\n init: function(diagram) {\n\n /**\n * The mapping to/from the original nodes.\n * @type {Dictionary}\n */\n this.nodeMap = new Dictionary();\n\n /**\n * Gets the mapping of a shape to a container in case the shape sits in a collapsed container.\n * @type {Dictionary}\n */\n this.shapeMap = new Dictionary();\n\n /**\n * The nodes being mapped.\n * @type {Dictionary}\n */\n this.nodes = [];\n\n /**\n * The connections being mapped.\n * @type {Dictionary}\n */\n this.edges = [];\n\n // the mapping from an edge to all the connections it represents, this can be both because of multiple connections between\n // two shapes or because a container holds multiple connections to another shape or container.\n this.edgeMap = new Dictionary();\n\n /**\n * The resulting set of Nodes when the analysis has finished.\n * @type {Array}\n */\n this.finalNodes = [];\n\n /**\n * The resulting set of Links when the analysis has finished.\n * @type {Array}\n */\n this.finalLinks = [];\n\n /**\n * The items being omitted because of multigraph edges.\n * @type {Array}\n */\n this.ignoredConnections = [];\n\n /**\n * The items being omitted because of containers, visibility and other factors.\n * @type {Array}\n */\n this.ignoredShapes = [];\n\n /**\n * The map from a node to the partition/hypernode in which it sits. This hyperMap is null if 'options.layoutContainerChildren' is false.\n * @type {Dictionary}\n */\n this.hyperMap = new Dictionary();\n\n /**\n * The hypertree contains the hierarchy defined by the containers.\n * It's in essence a Graph of Graphs with a tree structure defined by the hierarchy of containers.\n * @type {HyperTree}\n */\n this.hyperTree = new Graph();\n\n /**\n * The resulting graph after conversion. Note that this does not supply the information contained in the\n * ignored connection and shape collections.\n * @type {null}\n */\n this.finalGraph = null;\n\n this.diagram = diagram;\n },\n\n /**\n * The hyperTree is used when the 'options.layoutContainerChildren' is true. It contains the hierarchy of containers whereby each node is a ContainerGraph.\n * 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 * - 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 * since there is no node mapped for the container.\n * - 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 * - 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 * 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 * @param options\n */\n convert: function(options) {\n\n if (Utils.isUndefined(this.diagram)) {\n throw \"No diagram to convert.\";\n }\n\n this.options = kendo.deepExtend({\n ignoreInvisible: true,\n ignoreContainers: true,\n layoutContainerChildren: false\n },\n options || {}\n );\n\n this.clear();\n // create the nodes which participate effectively in the graph analysis\n this._renormalizeShapes();\n\n // recreate the incoming and outgoing collections of each and every node\n this._renormalizeConnections();\n\n // export the resulting graph\n this.finalNodes = new Dictionary(this.nodes);\n this.finalLinks = new Dictionary(this.edges);\n\n this.finalGraph = new Graph();\n this.finalNodes.forEach(function(n) {\n this.finalGraph.addNode(n);\n }, this);\n this.finalLinks.forEach(function(l) {\n this.finalGraph.addExistingLink(l);\n }, this);\n return this.finalGraph;\n },\n\n /**\n * Maps the specified connection to an edge of the graph deduced from the given diagram.\n * @param connection\n * @returns {*}\n */\n mapConnection: function(connection) {\n return this.edgeMap.get(connection.id);\n },\n\n /**\n * Maps the specified shape to a node of the graph deduced from the given diagram.\n * @param shape\n * @returns {*}\n */\n mapShape: function(shape) {\n return this.nodeMap.get(shape.id);\n },\n\n /**\n * Gets the edge, if any, between the given nodes.\n * @param a\n * @param b\n */\n getEdge: function(a, b) {\n return Utils.first(a.links, function(link) {\n return link.getComplement(a) === b;\n });\n },\n\n /**\n * Clears all the collections used by the conversion process.\n */\n clear: function() {\n this.finalGraph = null;\n this.hyperTree = (!this.options.ignoreContainers && this.options.layoutContainerChildren) ? new HyperTree() : null;\n this.hyperMap = (!this.options.ignoreContainers && this.options.layoutContainerChildren) ? new Dictionary() : null;\n this.nodeMap = new Dictionary();\n this.shapeMap = new Dictionary();\n this.nodes = [];\n this.edges = [];\n this.edgeMap = new Dictionary();\n this.ignoredConnections = [];\n this.ignoredShapes = [];\n this.finalNodes = [];\n this.finalLinks = [];\n },\n\n /**\n * The path from a given ContainerGraph to the root (container).\n * @param containerGraph\n * @returns {Array}\n */\n listToRoot: function(containerGraph) {\n var list = [];\n var s = containerGraph.container;\n if (!s) {\n return list;\n }\n list.push(s);\n while (s.parentContainer) {\n s = s.parentContainer;\n list.push(s);\n }\n list.reverse();\n return list;\n },\n\n firstNonIgnorableContainer: function(shape) {\n\n if (shape.isContainer && !this._isIgnorableItem(shape)) {\n return shape;\n }\n return !shape.parentContainer ? null : this.firstNonIgnorableContainer(shape.parentContainer);\n },\n isContainerConnection: function(a, b) {\n if (a.isContainer && this.isDescendantOf(a, b)) {\n return true;\n }\n return b.isContainer && this.isDescendantOf(b, a);\n },\n\n /**\n * Returns true if the given shape is a direct child or a nested container child of the given container.\n * If the given container and shape are the same this will return false since a shape cannot be its own child.\n * @param scope\n * @param a\n * @returns {boolean}\n */\n isDescendantOf: function(scope, a) {\n if (!scope.isContainer) {\n throw \"Expecting a container.\";\n }\n if (scope === a) {\n return false;\n }\n if (contains(scope.children, a)) {\n return true;\n }\n var containers = [];\n for (var i = 0, len = scope.children.length; i < len; i++) {\n var c = scope.children[i];\n if (c.isContainer && this.isDescendantOf(c, a)) {\n containers.push(c);\n }\n }\n\n return containers.length > 0;\n },\n isIgnorableItem: function(shape) {\n if (this.options.ignoreInvisible) {\n if (shape.isCollapsed && this._isVisible(shape)) {\n return false;\n }\n if (!shape.isCollapsed && this._isVisible(shape)) {\n return false;\n }\n return true;\n }\n else {\n return shape.isCollapsed && !this._isTop(shape);\n }\n },\n\n /**\n * Determines whether the shape is or needs to be mapped to another shape. This occurs essentially when the shape sits in\n * a collapsed container hierarchy and an external connection needs a node endpoint. This node then corresponds to the mapped shape and is\n * necessarily a container in the parent hierarchy of the shape.\n * @param shape\n */\n isShapeMapped: function(shape) {\n return shape.isCollapsed && !this._isVisible(shape) && !this._isTop(shape);\n },\n\n leastCommonAncestor: function(a, b) {\n if (!a) {\n throw \"Parameter should not be null.\";\n }\n if (!b) {\n throw \"Parameter should not be null.\";\n }\n\n if (!this.hyperTree) {\n throw \"No hypertree available.\";\n }\n var al = this.listToRoot(a);\n var bl = this.listToRoot(b);\n var found = null;\n if (Utils.isEmpty(al) || Utils.isEmpty(bl)) {\n return this.hyperTree.root.data;\n }\n var xa = al[0];\n var xb = bl[0];\n var i = 0;\n while (xa === xb) {\n found = al[i];\n i++;\n if (i >= al.length || i >= bl.length) {\n break;\n }\n xa = al[i];\n xb = bl[i];\n }\n if (!found) {\n return this.hyperTree.root.data;\n }\n else {\n return grep(this.hyperTree.nodes, function(n) {\n return n.data.container === found;\n });\n }\n },\n /**\n * Determines whether the specified item is a top-level shape or container.\n * @param item\n * @returns {boolean}\n * @private\n */\n _isTop: function(item) {\n return !item.parentContainer;\n },\n\n /**\n * Determines iteratively (by walking up the container stack) whether the specified shape is visible.\n * This does NOT tell whether the item is not visible due to an explicit Visibility change or due to a collapse state.\n * @param shape\n * @returns {*}\n * @private\n */\n _isVisible: function(shape) {\n\n if (!shape.visible()) {\n return false;\n }\n return !shape.parentContainer ? shape.visible() : this._isVisible(shape.parentContainer);\n },\n\n _isCollapsed: function(shape) {\n\n if (shape.isContainer && shape.isCollapsed) {\n return true;\n }\n return shape.parentContainer && this._isCollapsed(shape.parentContainer);\n },\n\n /**\n * First part of the graph creation; analyzing the shapes and containers and deciding whether they should be mapped to a Node.\n * @private\n */\n _renormalizeShapes: function() {\n // add the nodes, the adjacency structure will be reconstructed later on\n if (this.options.ignoreContainers) {\n for (var i = 0, len = this.diagram.shapes.length; i < len; i++) {\n var shape = this.diagram.shapes[i];\n\n // if not visible (and ignoring the invisible ones) or a container we skip\n if ((this.options.ignoreInvisible && !this._isVisible(shape)) || shape.isContainer) {\n this.ignoredShapes.push(shape);\n continue;\n }\n var node = new Node(shape.id, shape);\n node.isVirtual = false;\n\n // the mapping will always contain singletons and the hyperTree will be null\n this.nodeMap.add(shape.id, node);\n this.nodes.push(node);\n }\n }\n else {\n throw \"Containers are not supported yet, but stay tuned.\";\n }\n },\n\n /**\n * Second part of the graph creation; analyzing the connections and deciding whether they should be mapped to an edge.\n * @private\n */\n _renormalizeConnections: function() {\n if (this.diagram.connections.length === 0) {\n return;\n }\n for (var i = 0, len = this.diagram.connections.length; i < len; i++) {\n var conn = this.diagram.connections[i];\n\n if (this.isIgnorableItem(conn)) {\n this.ignoredConnections.push(conn);\n continue;\n }\n\n var source = !conn.sourceConnector ? null : conn.sourceConnector.shape;\n var sink = !conn.targetConnector ? null : conn.targetConnector.shape;\n\n // no layout for floating connections\n if (!source || !sink) {\n this.ignoredConnections.push(conn);\n continue;\n }\n\n if (contains(this.ignoredShapes, source) && !this.shapeMap.containsKey(source)) {\n this.ignoredConnections.push(conn);\n continue;\n }\n if (contains(this.ignoredShapes, sink) && !this.shapeMap.containsKey(sink)) {\n this.ignoredConnections.push(conn);\n continue;\n }\n\n // if the endpoint sits in a collapsed container we need the container rather than the shape itself\n if (this.shapeMap.containsKey(source)) {\n source = this.shapeMap[source];\n }\n if (this.shapeMap.containsKey(sink)) {\n sink = this.shapeMap[sink];\n }\n\n var sourceNode = this.mapShape(source);\n var sinkNode = this.mapShape(sink);\n if ((sourceNode === sinkNode) || this.areConnectedAlready(sourceNode, sinkNode)) {\n this.ignoredConnections.push(conn);\n continue;\n }\n\n if (sourceNode === null || sinkNode === null) {\n throw \"A shape was not mapped to a node.\";\n }\n if (this.options.ignoreContainers) {\n // much like a floating connection here since at least one end is attached to a container\n if (sourceNode.isVirtual || sinkNode.isVirtual) {\n this.ignoredConnections.push(conn);\n continue;\n }\n var newEdge = new Link(sourceNode, sinkNode, conn.id, conn);\n\n this.edgeMap.add(conn.id, newEdge);\n this.edges.push(newEdge);\n }\n else {\n throw \"Containers are not supported yet, but stay tuned.\";\n }\n }\n },\n\n areConnectedAlready: function(n, m) {\n return Utils.any(this.edges, function(l) {\n return l.source === n && l.target === m || l.source === m && l.target === n;\n });\n }\n\n /**\n * Depth-first traversal of the given container.\n * @param container\n * @param action\n * @param includeStart\n * @private\n */\n /* _visitContainer: function (container, action, includeStart) {\n\n *//*if (container == null) throw new ArgumentNullException(\"container\");\n if (action == null) throw new ArgumentNullException(\"action\");\n if (includeStart) action(container);\n if (container.children.isEmpty()) return;\n foreach(\n var item\n in\n container.children.OfType < IShape > ()\n )\n {\n var childContainer = item\n as\n IContainerShape;\n if (childContainer != null) this.VisitContainer(childContainer, action);\n else action(item);\n }*//*\n }*/\n\n\n });\n\n /**\n * The classic spring-embedder (aka force-directed, Fruchterman-Rheingold, barycentric) algorithm.\n * http://en.wikipedia.org/wiki/Force-directed_graph_drawing\n * - Chapter 12 of Tamassia et al. \"Handbook of graph drawing and visualization\".\n * - Kobourov on preprint arXiv; http://arxiv.org/pdf/1201.3011.pdf\n * - Fruchterman and Rheingold in SOFTWARE-PRACTICE AND EXPERIENCE, VOL. 21(1 1), 1129-1164 (NOVEMBER 1991)\n * @type {*}\n */\n var SpringLayout = LayoutBase.extend({\n init: function(diagram) {\n var that = this;\n LayoutBase.fn.init.call(that);\n if (Utils.isUndefined(diagram)) {\n throw \"Diagram is not specified.\";\n }\n this.diagram = diagram;\n },\n\n layout: function(options) {\n\n this.transferOptions(options);\n\n var adapter = new DiagramToHyperTreeAdapter(this.diagram);\n var graph = adapter.convert(options);\n if (graph.isEmpty()) {\n return;\n }\n // split into connected components\n var components = graph.getConnectedComponents();\n if (Utils.isEmpty(components)) {\n return;\n }\n for (var i = 0; i < components.length; i++) {\n var component = components[i];\n this.layoutGraph(component, options);\n }\n var finalNodeSet = this.gridLayoutComponents(components);\n return new diagram.LayoutState(this.diagram, finalNodeSet);\n },\n\n layoutGraph: function(graph, options) {\n\n if (Utils.isDefined(options)) {\n this.transferOptions(options);\n }\n this.graph = graph;\n\n var initialTemperature = this.options.nodeDistance * 9;\n this.temperature = initialTemperature;\n\n var guessBounds = this._expectedBounds();\n this.width = guessBounds.width;\n this.height = guessBounds.height;\n\n for (var step = 0; step < this.options.iterations; step++) {\n this.refineStage = step >= this.options.iterations * 5 / 6;\n this.tick();\n // exponential cooldown\n this.temperature = this.refineStage ?\n initialTemperature / 30 :\n initialTemperature * (1 - step / (2 * this.options.iterations ));\n }\n },\n\n /**\n * Single iteration of the simulation.\n */\n tick: function() {\n var i;\n // collect the repulsive forces on each node\n for (i = 0; i < this.graph.nodes.length; i++) {\n this._repulsion(this.graph.nodes[i]);\n }\n\n // collect the attractive forces on each node\n for (i = 0; i < this.graph.links.length; i++) {\n this._attraction(this.graph.links[i]);\n }\n // update the positions\n for (i = 0; i < this.graph.nodes.length; i++) {\n var node = this.graph.nodes[i];\n var offset = Math.sqrt(node.dx * node.dx + node.dy * node.dy);\n if (offset === 0) {\n return;\n }\n node.x += Math.min(offset, this.temperature) * node.dx / offset;\n node.y += Math.min(offset, this.temperature) * node.dy / offset;\n if (this.options.limitToView) {\n node.x = Math.min(this.width, Math.max(node.width / 2, node.x));\n node.y = Math.min(this.height, Math.max(node.height / 2, node.y));\n }\n }\n },\n\n /**\n * Shakes the node away from its current position to escape the deadlock.\n * @param node A Node.\n * @private\n */\n _shake: function(node) {\n // just a simple polar neighborhood\n var rho = Math.random() * this.options.nodeDistance / 4;\n var alpha = Math.random() * 2 * Math.PI;\n node.x += rho * Math.cos(alpha);\n node.y -= rho * Math.sin(alpha);\n },\n\n /**\n * The typical Coulomb-Newton force law F=k/r^2\n * @remark This only works in dimensions less than three.\n * @param d\n * @param n A Node.\n * @param m Another Node.\n * @returns {number}\n * @private\n */\n _InverseSquareForce: function(d, n, m) {\n var force;\n if (!this.refineStage) {\n force = Math.pow(d, 2) / Math.pow(this.options.nodeDistance, 2);\n }\n else {\n var deltax = n.x - m.x;\n var deltay = n.y - m.y;\n\n var wn = n.width / 2;\n var hn = n.height / 2;\n var wm = m.width / 2;\n var hm = m.height / 2;\n\n 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 }\n return force * 4 / 3;\n },\n\n /**\n * The typical Hooke force law F=kr^2\n * @param d\n * @param n\n * @param m\n * @returns {number}\n * @private\n */\n _SquareForce: function(d, n, m) {\n return 1 / this._InverseSquareForce(d, n, m);\n },\n\n _repulsion: function(n) {\n n.dx = 0;\n n.dy = 0;\n Utils.forEach(this.graph.nodes, function(m) {\n if (m === n) {\n return;\n }\n while (n.x === m.x && n.y === m.y) {\n this._shake(m);\n }\n var vx = n.x - m.x;\n var vy = n.y - m.y;\n var distance = Math.sqrt(vx * vx + vy * vy);\n var r = this._SquareForce(distance, n, m) * 2;\n n.dx += (vx / distance) * r;\n n.dy += (vy / distance) * r;\n }, this);\n },\n _attraction: function(link) {\n var t = link.target;\n var s = link.source;\n if (s === t) {\n // loops induce endless shakes\n return;\n }\n while (s.x === t.x && s.y === t.y) {\n this._shake(t);\n }\n\n var vx = s.x - t.x;\n var vy = s.y - t.y;\n var distance = Math.sqrt(vx * vx + vy * vy);\n\n var a = this._InverseSquareForce(distance, s, t) * 5;\n var dx = (vx / distance) * a;\n var dy = (vy / distance) * a;\n t.dx += dx;\n t.dy += dy;\n s.dx -= dx;\n s.dy -= dy;\n },\n\n /**\n * Calculates the expected bounds after layout.\n * @returns {*}\n * @private\n */\n _expectedBounds: function() {\n\n var size, N = this.graph.nodes.length, /*golden ration optimal?*/ ratio = 1.5, multiplier = 4;\n if (N === 0) {\n return size;\n }\n size = Utils.fold(this.graph.nodes, function(s, node) {\n var area = node.width * node.height;\n if (area > 0) {\n s += Math.sqrt(area);\n return s;\n }\n return 0;\n }, 0, this);\n var av = size / N;\n var squareSize = av * Math.ceil(Math.sqrt(N));\n var width = squareSize * Math.sqrt(ratio);\n var height = squareSize / Math.sqrt(ratio);\n return { width: width * multiplier, height: height * multiplier };\n }\n\n });\n\n var TreeLayoutProcessor = kendo.Class.extend({\n\n init: function(options) {\n this.center = null;\n this.options = options;\n },\n layout: function(treeGraph, root) {\n this.graph = treeGraph;\n if (!this.graph.nodes || this.graph.nodes.length === 0) {\n return;\n }\n\n if (!contains(this.graph.nodes, root)) {\n throw \"The given root is not in the graph.\";\n }\n\n this.center = root;\n this.graph.cacheRelationships();\n /* var nonull = this.graph.nodes.where(function (n) {\n return n.associatedShape != null;\n });*/\n\n // transfer the rects\n /*nonull.forEach(function (n) {\n n.Location = n.associatedShape.Position;\n n.NodeSize = n.associatedShape.ActualBounds.ToSize();\n }\n\n );*/\n\n // caching the children\n /* nonull.forEach(function (n) {\n n.children = n.getChildren();\n });*/\n\n this.layoutSwitch();\n\n // apply the layout to the actual visuals\n // nonull.ForEach(n => n.associatedShape.Position = n.Location);\n },\n\n layoutLeft: function(left) {\n this.setChildrenDirection(this.center, \"Left\", false);\n this.setChildrenLayout(this.center, \"Default\", false);\n var h = 0, w = 0, y, i, node;\n for (i = 0; i < left.length; i++) {\n node = left[i];\n node.TreeDirection = \"Left\";\n var s = this.measure(node, Size.Empty);\n w = Math.max(w, s.Width);\n h += s.height + this.options.verticalSeparation;\n }\n\n h -= this.options.verticalSeparation;\n var x = this.center.x - this.options.horizontalSeparation;\n y = this.center.y + ((this.center.height - h) / 2);\n for (i = 0; i < left.length; i++) {\n node = left[i];\n var p = new Point(x - node.Size.width, y);\n\n this.arrange(node, p);\n y += node.Size.height + this.options.verticalSeparation;\n }\n },\n\n layoutRight: function(right) {\n this.setChildrenDirection(this.center, \"Right\", false);\n this.setChildrenLayout(this.center, \"Default\", false);\n var h = 0, w = 0, y, i, node;\n for (i = 0; i < right.length; i++) {\n node = right[i];\n node.TreeDirection = \"Right\";\n var s = this.measure(node, Size.Empty);\n w = Math.max(w, s.Width);\n h += s.height + this.options.verticalSeparation;\n }\n\n h -= this.options.verticalSeparation;\n var x = this.center.x + this.options.horizontalSeparation + this.center.width;\n y = this.center.y + ((this.center.height - h) / 2);\n for (i = 0; i < right.length; i++) {\n node = right[i];\n var p = new Point(x, y);\n this.arrange(node, p);\n y += node.Size.height + this.options.verticalSeparation;\n }\n },\n\n layoutUp: function(up) {\n this.setChildrenDirection(this.center, \"Up\", false);\n this.setChildrenLayout(this.center, \"Default\", false);\n var w = 0, y, node, i;\n for (i = 0; i < up.length; i++) {\n node = up[i];\n node.TreeDirection = \"Up\";\n var s = this.measure(node, Size.Empty);\n w += s.width + this.options.horizontalSeparation;\n }\n\n w -= this.options.horizontalSeparation;\n var x = this.center.x + (this.center.width / 2) - (w / 2);\n\n // y = this.center.y -verticalSeparation -this.center.height/2 - h;\n for (i = 0; i < up.length; i++) {\n node = up[i];\n y = this.center.y - this.options.verticalSeparation - node.Size.height;\n var p = new Point(x, y);\n this.arrange(node, p);\n x += node.Size.width + this.options.horizontalSeparation;\n }\n },\n\n layoutDown: function(down) {\n var node, i;\n this.setChildrenDirection(this.center, \"Down\", false);\n this.setChildrenLayout(this.center, \"Default\", false);\n var w = 0, y;\n for (i = 0; i < down.length; i++) {\n node = down[i];\n node.treeDirection = \"Down\";\n var s = this.measure(node, Size.Empty);\n w += s.width + this.options.horizontalSeparation;\n }\n\n w -= this.options.horizontalSeparation;\n var x = this.center.x + (this.center.width / 2) - (w / 2);\n y = this.center.y + this.options.verticalSeparation + this.center.height;\n for (i = 0; i < down.length; i++) {\n node = down[i];\n var p = new Point(x, y);\n this.arrange(node, p);\n x += node.Size.width + this.options.horizontalSeparation;\n }\n },\n\n layoutRadialTree: function() {\n // var rmax = children.Aggregate(0D, (current, node) => Math.max(node.SectorAngle, current));\n this.setChildrenDirection(this.center, \"Radial\", false);\n this.setChildrenLayout(this.center, \"Default\", false);\n this.previousRoot = null;\n var startAngle = this.options.startRadialAngle * DEG_TO_RAD;\n var endAngle = this.options.endRadialAngle * DEG_TO_RAD;\n if (endAngle <= startAngle) {\n throw \"Final angle should not be less than the start angle.\";\n }\n\n this.maxDepth = 0;\n this.origin = new Point(this.center.x, this.center.y);\n this.calculateAngularWidth(this.center, 0);\n\n // perform the layout\n if (this.maxDepth > 0) {\n this.radialLayout(this.center, this.options.radialFirstLevelSeparation, startAngle, endAngle);\n }\n\n // update properties of the root node\n this.center.Angle = endAngle - startAngle;\n },\n\n tipOverTree: function(down, startFromLevel) {\n if (Utils.isUndefined(startFromLevel)) {\n startFromLevel = 0;\n }\n\n this.setChildrenDirection(this.center, \"Down\", false);\n this.setChildrenLayout(this.center, \"Default\", false);\n this.setChildrenLayout(this.center, \"Underneath\", false, startFromLevel);\n var w = 0, y, node, i;\n for (i = 0; i < down.length; i++) {\n node = down[i];\n\n // if (node.IsSpecial) continue;\n node.TreeDirection = \"Down\";\n var s = this.measure(node, Size.Empty);\n w += s.width + this.options.horizontalSeparation;\n }\n\n w -= this.options.horizontalSeparation;\n\n // 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 w -= down[down.length - 1].width;\n w += down[down.length - 1].associatedShape.bounds().width;\n\n var x = this.center.x + (this.center.width / 2) - (w / 2);\n y = this.center.y + this.options.verticalSeparation + this.center.height;\n for (i = 0; i < down.length; i++) {\n node = down[i];\n // if (node.IsSpecial) continue;\n var p = new Point(x, y);\n this.arrange(node, p);\n x += node.Size.width + this.options.horizontalSeparation;\n }\n\n /*//let's place the special node, assuming there is only one\n if (down.Count(n => n.IsSpecial) > 0)\n {\n var special = (from n in down where n.IsSpecial select n).First();\n if (special.Children.Count > 0)\n throw new DiagramException(\"The 'special' element should not have children.\");\n special.Data.Location = new Point(Center.Data.Location.X + Center.AssociatedShape.BoundingRectangle.Width + this.options.HorizontalSeparation, Center.Data.Location.Y);\n }*/\n },\n calculateAngularWidth: function(n, d) {\n if (d > this.maxDepth) {\n this.maxDepth = d;\n }\n\n var aw = 0, w = 1000, h = 1000, diameter = d === 0 ? 0 : Math.sqrt((w * w) + (h * h)) / d;\n\n if (n.children.length > 0) {\n // eventually with n.IsExpanded\n for (var i = 0, len = n.children.length; i < len; i++) {\n var child = n.children[i];\n aw += this.calculateAngularWidth(child, d + 1);\n }\n aw = Math.max(diameter, aw);\n }\n else {\n aw = diameter;\n }\n\n n.sectorAngle = aw;\n return aw;\n },\n sortChildren: function(n) {\n var basevalue = 0, i;\n\n // update basevalue angle for node ordering\n if (n.parents.length > 1) {\n throw \"Node is not part of a tree.\";\n }\n var p = n.parents[0];\n if (p) {\n var pl = new Point(p.x, p.y);\n var nl = new Point(n.x, n.y);\n basevalue = this.normalizeAngle(Math.atan2(pl.y - nl.y, pl.x - nl.x));\n }\n\n var count = n.children.length;\n if (count === 0) {\n return null;\n }\n\n var angle = [];\n var idx = [];\n\n for (i = 0; i < count; ++i) {\n var c = n.children[i];\n var l = new Point(c.x, c.y);\n idx[i] = i;\n angle[i] = this.normalizeAngle(-basevalue + Math.atan2(l.y - l.y, l.x - l.x));\n }\n\n Utils.bisort(angle, idx);\n var col = []; // list of nodes\n var children = n.children;\n for (i = 0; i < count; ++i) {\n col.push(children[idx[i]]);\n }\n\n return col;\n },\n\n normalizeAngle: function(angle) {\n while (angle > Math.PI * 2) {\n angle -= 2 * Math.PI;\n }\n while (angle < 0) {\n angle += Math.PI * 2;\n }\n return angle;\n },\n radialLayout: function(node, radius, startAngle, endAngle) {\n var deltaTheta = endAngle - startAngle;\n var deltaThetaHalf = deltaTheta / 2.0;\n var parentSector = node.sectorAngle;\n var fraction = 0;\n var sorted = this.sortChildren(node);\n for (var i = 0, len = sorted.length; i < len; i++) {\n var childNode = sorted[i];\n var cp = childNode;\n var childAngleFraction = cp.sectorAngle / parentSector;\n if (childNode.children.length > 0) {\n this.radialLayout(childNode,\n radius + this.options.radialSeparation,\n startAngle + (fraction * deltaTheta),\n startAngle + ((fraction + childAngleFraction) * deltaTheta));\n }\n\n this.setPolarLocation(childNode, radius, startAngle + (fraction * deltaTheta) + (childAngleFraction * deltaThetaHalf));\n cp.angle = childAngleFraction * deltaTheta;\n fraction += childAngleFraction;\n }\n },\n setPolarLocation: function(node, radius, angle) {\n node.x = this.origin.x + (radius * Math.cos(angle));\n node.y = this.origin.y + (radius * Math.sin(angle));\n node.BoundingRectangle = new Rect(node.x, node.y, node.width, node.height);\n },\n\n /**\n * Sets the children direction recursively.\n * @param node\n * @param direction\n * @param includeStart\n */\n setChildrenDirection: function(node, direction, includeStart) {\n var rootDirection = node.treeDirection;\n this.graph.depthFirstTraversal(node, function(n) {\n n.treeDirection = direction;\n });\n if (!includeStart) {\n node.treeDirection = rootDirection;\n }\n },\n\n /**\n * Sets the children layout recursively.\n * @param node\n * @param layout\n * @param includeStart\n * @param startFromLevel\n */\n setChildrenLayout: function(node, layout, includeStart, startFromLevel) {\n if (Utils.isUndefined(startFromLevel)) {\n startFromLevel = 0;\n }\n var rootLayout = node.childrenLayout;\n if (startFromLevel > 0) {\n // assign levels to the Node.Level property\n this.graph.assignLevels(node);\n\n // assign the layout on the condition that the level is at least the 'startFromLevel'\n this.graph.depthFirstTraversal(\n node, function(s) {\n if (s.level >= startFromLevel + 1) {\n s.childrenLayout = layout;\n }\n }\n );\n }\n else {\n this.graph.depthFirstTraversal(node, function(s) {\n s.childrenLayout = layout;\n });\n\n // if the start should not be affected we put the state back\n if (!includeStart) {\n node.childrenLayout = rootLayout;\n }\n }\n },\n\n /**\n * Returns the actual size of the node. The given size is the allowed space wherein the node can lay out itself.\n * @param node\n * @param givenSize\n * @returns {Size}\n */\n measure: function(node, givenSize) {\n var w = 0, h = 0, s;\n var result = new Size(0, 0);\n if (!node) {\n throw \"\";\n }\n var b = node.associatedShape.bounds();\n var shapeWidth = b.width;\n var shapeHeight = b.height;\n if (node.parents.length !== 1) {\n throw \"Node not in a spanning tree.\";\n }\n\n var parent = node.parents[0];\n if (node.treeDirection === \"Undefined\") {\n node.treeDirection = parent.treeDirection;\n }\n\n if (Utils.isEmpty(node.children)) {\n result = new Size(\n Math.abs(shapeWidth) < EPSILON ? 50 : shapeWidth,\n Math.abs(shapeHeight) < EPSILON ? 25 : shapeHeight);\n }\n else if (node.children.length === 1) {\n switch (node.treeDirection) {\n case \"Radial\":\n s = this.measure(node.children[0], givenSize); // child size\n w = shapeWidth + (this.options.radialSeparation * Math.cos(node.AngleToParent)) + s.width;\n h = shapeHeight + Math.abs(this.options.radialSeparation * Math.sin(node.AngleToParent)) + s.height;\n break;\n case \"Left\":\n case \"Right\":\n switch (node.childrenLayout) {\n\n case \"TopAlignedWithParent\":\n break;\n\n case \"BottomAlignedWithParent\":\n break;\n\n case \"Underneath\":\n s = this.measure(node.children[0], givenSize);\n w = shapeWidth + s.width + this.options.underneathHorizontalOffset;\n h = shapeHeight + this.options.underneathVerticalTopOffset + s.height;\n break;\n\n case \"Default\":\n s = this.measure(node.children[0], givenSize);\n w = shapeWidth + this.options.horizontalSeparation + s.width;\n h = Math.max(shapeHeight, s.height);\n break;\n\n default:\n throw \"Unhandled TreeDirection in the Radial layout measuring.\";\n }\n break;\n case \"Up\":\n case \"Down\":\n switch (node.childrenLayout) {\n\n case \"TopAlignedWithParent\":\n case \"BottomAlignedWithParent\":\n break;\n\n case \"Underneath\":\n s = this.measure(node.children[0], givenSize);\n w = Math.max(shapeWidth, s.width + this.options.underneathHorizontalOffset);\n h = shapeHeight + this.options.underneathVerticalTopOffset + s.height;\n break;\n\n case \"Default\":\n s = this.measure(node.children[0], givenSize);\n h = shapeHeight + this.options.verticalSeparation + s.height;\n w = Math.max(shapeWidth, s.width);\n break;\n\n default:\n throw \"Unhandled TreeDirection in the Down layout measuring.\";\n }\n break;\n default:\n throw \"Unhandled TreeDirection in the layout measuring.\";\n }\n\n result = new Size(w, h);\n }\n else {\n var i, childNode;\n switch (node.treeDirection) {\n case \"Left\":\n case \"Right\":\n switch (node.childrenLayout) {\n\n case \"TopAlignedWithParent\":\n case \"BottomAlignedWithParent\":\n break;\n\n case \"Underneath\":\n w = shapeWidth;\n h = shapeHeight + this.options.underneathVerticalTopOffset;\n for (i = 0; i < node.children.length; i++) {\n childNode = node.children[i];\n s = this.measure(childNode, givenSize);\n w = Math.max(w, s.width + this.options.underneathHorizontalOffset);\n h += s.height + this.options.underneathVerticalSeparation;\n }\n\n h -= this.options.underneathVerticalSeparation;\n break;\n\n case \"Default\":\n w = shapeWidth;\n h = 0;\n for (i = 0; i < node.children.length; i++) {\n childNode = node.children[i];\n s = this.measure(childNode, givenSize);\n w = Math.max(w, shapeWidth + this.options.horizontalSeparation + s.width);\n h += s.height + this.options.verticalSeparation;\n }\n h -= this.options.verticalSeparation;\n break;\n\n default:\n throw \"Unhandled TreeDirection in the Right layout measuring.\";\n }\n\n break;\n case \"Up\":\n case \"Down\":\n\n switch (node.childrenLayout) {\n\n case \"TopAlignedWithParent\":\n case \"BottomAlignedWithParent\":\n break;\n\n case \"Underneath\":\n w = shapeWidth;\n h = shapeHeight + this.options.underneathVerticalTopOffset;\n for (i = 0; i < node.children.length; i++) {\n childNode = node.children[i];\n s = this.measure(childNode, givenSize);\n w = Math.max(w, s.width + this.options.underneathHorizontalOffset);\n h += s.height + this.options.underneathVerticalSeparation;\n }\n\n h -= this.options.underneathVerticalSeparation;\n break;\n\n case \"Default\":\n w = 0;\n h = 0;\n for (i = 0; i < node.children.length; i++) {\n childNode = node.children[i];\n s = this.measure(childNode, givenSize);\n w += s.width + this.options.horizontalSeparation;\n h = Math.max(h, s.height + this.options.verticalSeparation + shapeHeight);\n }\n\n w -= this.options.horizontalSeparation;\n break;\n\n default:\n throw \"Unhandled TreeDirection in the Down layout measuring.\";\n }\n\n break;\n default:\n throw \"Unhandled TreeDirection in the layout measuring.\";\n }\n\n result = new Size(w, h);\n }\n\n node.SectorAngle = Math.sqrt((w * w / 4) + (h * h / 4));\n node.Size = result;\n return result;\n },\n arrange: function(n, p) {\n var i, pp, child, node, childrenwidth, b = n.associatedShape.bounds();\n var shapeWidth = b.width;\n var shapeHeight = b.height;\n if (Utils.isEmpty(n.children)) {\n n.x = p.x;\n n.y = p.y;\n n.BoundingRectangle = new Rect(p.x, p.y, shapeWidth, shapeHeight);\n }\n else {\n var x, y;\n var selfLocation;\n switch (n.treeDirection) {\n case \"Left\":\n switch (n.childrenLayout) {\n case \"TopAlignedWithParent\":\n case \"BottomAlignedWithParent\":\n break;\n\n case \"Underneath\":\n selfLocation = p;\n n.x = selfLocation.x;\n n.y = selfLocation.y;\n n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n y = p.y + shapeHeight + this.options.underneathVerticalTopOffset;\n for (i = 0; i < node.children.length; i++) {\n node = node.children[i];\n x = selfLocation.x - node.associatedShape.width - this.options.underneathHorizontalOffset;\n pp = new Point(x, y);\n this.arrange(node, pp);\n y += node.Size.height + this.options.underneathVerticalSeparation;\n }\n break;\n\n case \"Default\":\n selfLocation = new Point(p.x + n.Size.width - shapeWidth, p.y + ((n.Size.height - shapeHeight) / 2));\n n.x = selfLocation.x;\n n.y = selfLocation.y;\n n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n x = selfLocation.x - this.options.horizontalSeparation; // alignment of children\n y = p.y;\n for (i = 0; i < n.children.length; i++) {\n node = n.children[i];\n pp = new Point(x - node.Size.width, y);\n this.arrange(node, pp);\n y += node.Size.height + this.options.verticalSeparation;\n }\n break;\n\n default:\n throw \"Unsupported TreeDirection\";\n }\n\n break;\n case \"Right\":\n switch (n.childrenLayout) {\n case \"TopAlignedWithParent\":\n case \"BottomAlignedWithParent\":\n break;\n\n case \"Underneath\":\n selfLocation = p;\n n.x = selfLocation.x;\n n.y = selfLocation.y;\n n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n x = p.x + shapeWidth + this.options.underneathHorizontalOffset;\n\n // alignment of children left-underneath the parent\n y = p.y + shapeHeight + this.options.underneathVerticalTopOffset;\n for (i = 0; i < n.children.length; i++) {\n node = n.children[i];\n pp = new Point(x, y);\n this.arrange(node, pp);\n y += node.Size.height + this.options.underneathVerticalSeparation;\n }\n\n break;\n\n case \"Default\":\n selfLocation = new Point(p.x, p.y + ((n.Size.height - shapeHeight) / 2));\n n.x = selfLocation.x;\n n.y = selfLocation.y;\n n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n x = p.x + shapeWidth + this.options.horizontalSeparation; // alignment of children\n y = p.y;\n for (i = 0; i < n.children.length; i++) {\n node = n.children[i];\n pp = new Point(x, y);\n this.arrange(node, pp);\n y += node.Size.height + this.options.verticalSeparation;\n }\n break;\n\n default:\n throw \"Unsupported TreeDirection\";\n }\n\n break;\n case \"Up\":\n selfLocation = new Point(p.x + ((n.Size.width - shapeWidth) / 2), p.y + n.Size.height - shapeHeight);\n n.x = selfLocation.x;\n n.y = selfLocation.y;\n n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n if (Math.abs(selfLocation.x - p.x) < EPSILON) {\n childrenwidth = 0;\n // means there is an aberration due to the oversized Element with respect to the children\n for (i = 0; i < n.children.length; i++) {\n child = n.children[i];\n childrenwidth += child.Size.width + this.options.horizontalSeparation;\n }\n childrenwidth -= this.options.horizontalSeparation;\n x = p.x + ((shapeWidth - childrenwidth) / 2);\n }\n else {\n x = p.x;\n }\n\n for (i = 0; i < n.children.length; i++) {\n node = n.children[i];\n y = selfLocation.y - this.options.verticalSeparation - node.Size.height;\n pp = new Point(x, y);\n this.arrange(node, pp);\n x += node.Size.width + this.options.horizontalSeparation;\n }\n break;\n\n case \"Down\":\n\n switch (n.childrenLayout) {\n case \"TopAlignedWithParent\":\n case \"BottomAlignedWithParent\":\n break;\n case \"Underneath\":\n selfLocation = p;\n n.x = selfLocation.x;\n n.y = selfLocation.y;\n n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n x = p.x + this.options.underneathHorizontalOffset; // alignment of children left-underneath the parent\n y = p.y + shapeHeight + this.options.underneathVerticalTopOffset;\n for (i = 0; i < n.children.length; i++) {\n node = n.children[i];\n pp = new Point(x, y);\n this.arrange(node, pp);\n y += node.Size.height + this.options.underneathVerticalSeparation;\n }\n break;\n\n case \"Default\":\n selfLocation = new Point(p.x + ((n.Size.width - shapeWidth) / 2), p.y);\n n.x = selfLocation.x;\n n.y = selfLocation.y;\n n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n if (Math.abs(selfLocation.x - p.x) < EPSILON) {\n childrenwidth = 0;\n // means there is an aberration due to the oversized Element with respect to the children\n for (i = 0; i < n.children.length; i++) {\n child = n.children[i];\n childrenwidth += child.Size.width + this.options.horizontalSeparation;\n }\n\n childrenwidth -= this.options.horizontalSeparation;\n x = p.x + ((shapeWidth - childrenwidth) / 2);\n }\n else {\n x = p.x;\n }\n\n for (i = 0; i < n.children.length; i++) {\n node = n.children[i];\n y = selfLocation.y + this.options.verticalSeparation + shapeHeight;\n pp = new Point(x, y);\n this.arrange(node, pp);\n x += node.Size.width + this.options.horizontalSeparation;\n }\n break;\n\n default:\n throw \"Unsupported TreeDirection\";\n }\n break;\n\n case \"None\":\n break;\n\n default:\n throw \"Unsupported TreeDirection\";\n }\n }\n },\n layoutSwitch: function() {\n if (!this.center) {\n return;\n }\n\n if (Utils.isEmpty(this.center.children)) {\n return;\n }\n\n var type = this.options.subtype;\n if (Utils.isUndefined(type)) {\n type = \"Down\";\n }\n var single, male, female, leftcount;\n var children = this.center.children;\n switch (type.toLowerCase()) {\n case \"radial\":\n case \"radialtree\":\n this.layoutRadialTree();\n break;\n\n case \"mindmaphorizontal\":\n case \"mindmap\":\n single = this.center.children;\n\n if (this.center.children.length === 1) {\n this.layoutRight(single);\n }\n else {\n // odd number will give one more at the right\n leftcount = children.length / 2;\n male = grep(this.center.children, function(n) {\n return Utils.indexOf(children, n) < leftcount;\n });\n female = grep(this.center.children, function(n) {\n return Utils.indexOf(children, n) >= leftcount;\n });\n\n this.layoutLeft(male);\n this.layoutRight(female);\n }\n break;\n\n case \"mindmapvertical\":\n single = this.center.children;\n\n if (this.center.children.length === 1) {\n this.layoutDown(single);\n }\n else {\n // odd number will give one more at the right\n leftcount = children.length / 2;\n male = grep(this.center.children, function(n) {\n return Utils.indexOf(children, n) < leftcount;\n });\n female = grep(this.center.children, function(n) {\n return Utils.indexOf(children, n) >= leftcount;\n });\n this.layoutUp(male);\n this.layoutDown(female);\n }\n break;\n\n case \"right\":\n this.layoutRight(this.center.children);\n break;\n\n case \"left\":\n this.layoutLeft(this.center.children);\n break;\n\n case \"up\":\n case \"bottom\":\n this.layoutUp(this.center.children);\n break;\n\n case \"down\":\n case \"top\":\n this.layoutDown(this.center.children);\n break;\n\n case \"tipover\":\n case \"tipovertree\":\n if (this.options.tipOverTreeStartLevel < 0) {\n throw \"The tip-over level should be a positive integer.\";\n }\n this.tipOverTree(this.center.children, this.options.tipOverTreeStartLevel);\n break;\n\n case \"undefined\":\n case \"none\":\n break;\n }\n }\n });\n\n /**\n * The various tree layout algorithms.\n * @type {*}\n */\n var TreeLayout = LayoutBase.extend({\n init: function(diagram) {\n var that = this;\n LayoutBase.fn.init.call(that);\n if (Utils.isUndefined(diagram)) {\n throw \"No diagram specified.\";\n }\n this.diagram = diagram;\n },\n\n /**\n * Arranges the diagram in a tree-layout with the specified options and tree subtype.\n */\n layout: function(options) {\n\n this.transferOptions(options);\n\n // transform the diagram into a Graph\n var adapter = new DiagramToHyperTreeAdapter(this.diagram);\n\n /**\n * The Graph reduction from the given diagram.\n * @type {*}\n */\n this.graph = adapter.convert();\n\n var finalNodeSet = this.layoutComponents();\n\n // note that the graph contains the original data and\n // the components are another instance of nodes referring to the same set of shapes\n return new diagram.LayoutState(this.diagram, finalNodeSet);\n },\n\n layoutComponents: function() {\n if (this.graph.isEmpty()) {\n return;\n }\n\n // split into connected components\n var components = this.graph.getConnectedComponents();\n if (Utils.isEmpty(components)) {\n return;\n }\n\n var layout = new TreeLayoutProcessor(this.options);\n var trees = [];\n // find a spanning tree for each component\n for (var i = 0; i < components.length; i++) {\n var component = components[i];\n\n var treeGraph = this.getTree(component);\n if (!treeGraph) {\n throw \"Failed to find a spanning tree for the component.\";\n }\n var root = treeGraph.root;\n var tree = treeGraph.tree;\n layout.layout(tree, root);\n\n trees.push(tree);\n }\n\n return this.gridLayoutComponents(trees);\n\n },\n\n /**\n * Gets a spanning tree (and root) for the given graph.\n * Ensure that the given graph is connected!\n * @param graph\n * @returns {*} A literal object consisting of the found root and the spanning tree.\n */\n getTree: function(graph) {\n var root = null;\n if (this.options.roots && this.options.roots.length > 0) {\n for (var i = 0, len = graph.nodes.length; i < len; i++) {\n var node = graph.nodes[i];\n for (var j = 0; j < this.options.roots.length; j++) {\n var givenRootShape = this.options.roots[j];\n if (givenRootShape === node.associatedShape) {\n root = node;\n break;\n }\n }\n }\n }\n if (!root) {\n // finds the most probable root on the basis of the longest path in the component\n root = graph.root();\n // should not happen really\n if (!root) {\n throw \"Unable to find a root for the tree.\";\n }\n }\n return this.getTreeForRoot(graph, root);\n },\n\n getTreeForRoot: function(graph, root) {\n\n var tree = graph.getSpanningTree(root);\n if (Utils.isUndefined(tree) || tree.isEmpty()) {\n return null;\n }\n return {\n tree: tree,\n root: tree.root\n };\n }\n\n });\n\n /**\n * The Sugiyama aka layered layout algorithm.\n * @type {*}\n */\n var LayeredLayout = LayoutBase.extend({\n init: function(diagram) {\n var that = this;\n LayoutBase.fn.init.call(that);\n if (Utils.isUndefined(diagram)) {\n throw \"Diagram is not specified.\";\n }\n this.diagram = diagram;\n },\n\n layout: function(options) {\n\n this.transferOptions(options);\n\n var adapter = new DiagramToHyperTreeAdapter(this.diagram);\n var graph = adapter.convert(options);\n if (graph.isEmpty()) {\n return;\n }\n // split into connected components\n var components = graph.getConnectedComponents();\n if (Utils.isEmpty(components)) {\n return;\n }\n for (var i = 0; i < components.length; i++) {\n var component = components[i];\n this.layoutGraph(component, options);\n }\n var finalNodeSet = this.gridLayoutComponents(components);\n return new diagram.LayoutState(this.diagram, finalNodeSet);\n\n },\n\n /**\n * Initializes the runtime data properties of the layout.\n * @private\n */\n _initRuntimeProperties: function() {\n for (var k = 0; k < this.graph.nodes.length; k++) {\n var node = this.graph.nodes[k];\n node.layer = -1;\n node.downstreamLinkCount = 0;\n node.upstreamLinkCount = 0;\n\n node.isVirtual = false;\n\n node.uBaryCenter = 0.0;\n node.dBaryCenter = 0.0;\n\n node.upstreamPriority = 0;\n node.downstreamPriority = 0;\n\n node.gridPosition = 0;\n }\n },\n _prepare: function(graph) {\n var current = [], i, l, link;\n\n // defines a mapping of a node to the layer index\n var layerMap = new Dictionary();\n var layerCount = 0;\n var targetLayer, next, target;\n\n Utils.forEach(graph.nodes, function(node) {\n if (node.incoming.length === 0) {\n layerMap.set(node, 0);\n current.push(node);\n }\n });\n\n while (current.length > 0) {\n next = current.shift();\n for (i = 0; i < next.outgoing.length; i++) {\n link = next.outgoing[i];\n target = link.target;\n\n if (layerMap.containsKey(target)) {\n targetLayer = Math.max(layerMap.get(next) + 1, layerMap.get(target));\n } else {\n targetLayer = layerMap.get(next) + 1;\n }\n layerMap.set(target, targetLayer);\n if (targetLayer > layerCount) {\n layerCount = targetLayer;\n }\n\n if (!contains(current, target)) {\n current.push(target);\n }\n }\n }\n\n var sortedNodes = layerMap.keys();\n\n sortedNodes.sort(function(o1, o2) {\n var o1layer = layerMap.get(o1);\n var o2layer = layerMap.get(o2);\n return Utils.sign(o2layer - o1layer);\n });\n\n for (var n = 0; n < sortedNodes.length; ++n) {\n var node = sortedNodes[n];\n var minLayer = Number.MAX_VALUE;\n\n if (node.outgoing.length === 0) {\n continue;\n }\n\n for (l = 0; l < node.outgoing.length; ++l) {\n link = node.outgoing[l];\n minLayer = Math.min(minLayer, layerMap.get(link.target));\n }\n\n if (minLayer > 1) {\n layerMap.set(node, minLayer - 1);\n }\n }\n\n this.layers = [];\n var layer;\n for (i = 0; i < layerCount + 1; i++) {\n layer = [];\n layer.linksTo = {};\n this.layers.push(layer);\n }\n\n layerMap.forEach(function(node, layer) {\n node.layer = layer;\n this.layers[layer].push(node);\n }, this);\n\n // set initial grid positions\n for (l = 0; l < this.layers.length; l++) {\n layer = this.layers[l];\n for (i = 0; i < layer.length; i++) {\n layer[i].gridPosition = i;\n }\n }\n },\n /**\n * Performs the layout of a single component.\n */\n layoutGraph: function(graph, options) {\n if (Utils.isUndefined(graph)) {\n throw \"No graph given or graph analysis of the diagram failed.\";\n }\n if (Utils.isDefined(options)) {\n this.transferOptions(options);\n }\n this.graph = graph;\n\n // sets unique indices on the nodes\n graph.setItemIndices();\n\n // ensures no cycles present for this layout\n var reversedEdges = graph.makeAcyclic();\n\n // define the runtime props being used by the layout algorithm\n this._initRuntimeProperties();\n\n this._prepare(graph, options);\n\n this._dummify();\n\n this._optimizeCrossings();\n\n this._swapPairs();\n\n this.arrangeNodes();\n\n this._moveThingsAround();\n\n this._dedummify();\n\n // re-reverse the links which were switched earlier\n Utils.forEach(reversedEdges, function(e) {\n if (e.points) {\n e.points.reverse();\n }\n });\n },\n\n setMinDist: function(m, n, minDist) {\n var l = m.layer;\n var i = m.layerIndex;\n this.minDistances[l][i] = minDist;\n },\n\n getMinDist: function(m, n) {\n var dist = 0,\n i1 = m.layerIndex,\n i2 = n.layerIndex,\n l = m.layer,\n min = Math.min(i1, i2),\n max = Math.max(i1, i2);\n // use Sum()?\n for (var k = min; k < max; ++k) {\n dist += this.minDistances[l][k];\n }\n return dist;\n },\n\n placeLeftToRight: function(leftClasses) {\n var leftPos = new Dictionary(), n, node;\n for (var c = 0; c < this.layers.length; ++c) {\n var classNodes = leftClasses[c];\n if (!classNodes) {\n continue;\n }\n\n for (n = 0; n < classNodes.length; n++) {\n node = classNodes[n];\n if (!leftPos.containsKey(node)) {\n this.placeLeft(node, leftPos, c);\n }\n }\n\n // adjust class\n var d = Number.POSITIVE_INFINITY;\n for (n = 0; n < classNodes.length; n++) {\n node = classNodes[n];\n var rightSibling = this.rightSibling(node);\n if (rightSibling && this.nodeLeftClass.get(rightSibling) !== c) {\n d = Math.min(d, leftPos.get(rightSibling) - leftPos.get(node) - this.getMinDist(node, rightSibling));\n }\n }\n if (d === Number.POSITIVE_INFINITY) {\n var D = [];\n for (n = 0; n < classNodes.length; n++) {\n node = classNodes[n];\n var neighbors = [];\n Utils.addRange(neighbors, this.upNodes.get(node));\n Utils.addRange(neighbors, this.downNodes.get(node));\n\n for (var e = 0; e < neighbors.length; e++) {\n var neighbor = neighbors[e];\n if (this.nodeLeftClass.get(neighbor) < c) {\n D.push(leftPos.get(neighbor) - leftPos.get(node));\n }\n }\n }\n D.sort();\n if (D.length === 0) {\n d = 0;\n }\n else if (D.length % 2 === 1) {\n d = D[this.intDiv(D.length, 2)];\n }\n else {\n d = (D[this.intDiv(D.length, 2) - 1] + D[this.intDiv(D.length, 2)]) / 2;\n }\n }\n for (n = 0; n < classNodes.length; n++) {\n node = classNodes[n];\n leftPos.set(node, leftPos.get(node) + d);\n }\n }\n return leftPos;\n },\n\n placeRightToLeft: function(rightClasses) {\n var rightPos = new Dictionary(), n, node;\n for (var c = 0; c < this.layers.length; ++c) {\n var classNodes = rightClasses[c];\n if (!classNodes) {\n continue;\n }\n\n for (n = 0; n < classNodes.length; n++) {\n node = classNodes[n];\n if (!rightPos.containsKey(node)) {\n this.placeRight(node, rightPos, c);\n }\n }\n\n // adjust class\n var d = Number.NEGATIVE_INFINITY;\n for (n = 0; n < classNodes.length; n++) {\n node = classNodes[n];\n var leftSibling = this.leftSibling(node);\n if (leftSibling && this.nodeRightClass.get(leftSibling) !== c) {\n d = Math.max(d, rightPos.get(leftSibling) - rightPos.get(node) + this.getMinDist(leftSibling, node));\n }\n }\n if (d === Number.NEGATIVE_INFINITY) {\n var D = [];\n for (n = 0; n < classNodes.length; n++) {\n node = classNodes[n];\n var neighbors = [];\n Utils.addRange(neighbors, this.upNodes.get(node));\n Utils.addRange(neighbors, this.downNodes.get(node));\n\n for (var e = 0; e < neighbors.length; e++) {\n var neighbor = neighbors[e];\n if (this.nodeRightClass.get(neighbor) < c) {\n D.push(rightPos.get(node) - rightPos.get(neighbor));\n }\n }\n }\n D.sort();\n if (D.length === 0) {\n d = 0;\n }\n else if (D.length % 2 === 1) {\n d = D[this.intDiv(D.length, 2)];\n }\n else {\n d = (D[this.intDiv(D.length, 2) - 1] + D[this.intDiv(D.length, 2)]) / 2;\n }\n }\n for (n = 0; n < classNodes.length; n++) {\n node = classNodes[n];\n rightPos.set(node, rightPos.get(node) + d);\n }\n }\n return rightPos;\n },\n\n _getLeftWing: function() {\n var leftWing = { value: null };\n var result = this.computeClasses(leftWing, 1);\n this.nodeLeftClass = leftWing.value;\n return result;\n },\n\n _getRightWing: function() {\n var rightWing = { value: null };\n var result = this.computeClasses(rightWing, -1);\n this.nodeRightClass = rightWing.value;\n return result;\n },\n\n computeClasses: function(wingPair, d) {\n var currentWing = 0,\n wing = wingPair.value = new Dictionary();\n\n for (var l = 0; l < this.layers.length; ++l) {\n currentWing = l;\n\n var layer = this.layers[l];\n for (var n = d === 1 ? 0 : layer.length - 1; n >= 0 && n < layer.length; n += d) {\n var node = layer[n];\n if (!wing.containsKey(node)) {\n wing.set(node, currentWing);\n if (node.isVirtual) {\n var ndsinl = this._nodesInLink(node);\n for (var kk = 0; kk < ndsinl.length; kk++) {\n var vnode = ndsinl[kk];\n wing.set(vnode, currentWing);\n }\n }\n }\n else {\n currentWing = wing.get(node);\n }\n }\n }\n\n var wings = [];\n for (var i = 0; i < this.layers.length; i++) {\n wings.push(null);\n }\n wing.forEach(function(node, classIndex) {\n if (wings[classIndex] === null) {\n wings[classIndex] = [];\n }\n wings[classIndex].push(node);\n });\n\n return wings;\n },\n _isVerticalLayout: function() {\n return this.options.subtype.toLowerCase() === \"up\" || this.options.subtype.toLowerCase() === \"down\" || this.options.subtype.toLowerCase() === \"vertical\";\n },\n\n _isHorizontalLayout: function() {\n return this.options.subtype.toLowerCase() === \"right\" || this.options.subtype.toLowerCase() === \"left\" || this.options.subtype.toLowerCase() === \"horizontal\";\n },\n _isIncreasingLayout: function() {\n // meaning that the visiting of the layers goes in the natural order of increasing layer index\n return this.options.subtype.toLowerCase() === \"right\" || this.options.subtype.toLowerCase() === \"down\";\n },\n _moveThingsAround: function() {\n var i, l, node, layer, n, w;\n // sort the layers by their grid position\n for (l = 0; l < this.layers.length; ++l) {\n layer = this.layers[l];\n layer.sort(this._gridPositionComparer);\n }\n\n this.minDistances = [];\n for (l = 0; l < this.layers.length; ++l) {\n layer = this.layers[l];\n this.minDistances[l] = [];\n for (n = 0; n < layer.length; ++n) {\n node = layer[n];\n node.layerIndex = n;\n this.minDistances[l][n] = this.options.nodeDistance;\n if (n < layer.length - 1) {\n if (this._isVerticalLayout()) {\n this.minDistances[l][n] += (node.width + layer[n + 1].width) / 2;\n }\n else {\n this.minDistances[l][n] += (node.height + layer[n + 1].height) / 2;\n }\n }\n }\n }\n\n this.downNodes = new Dictionary();\n this.upNodes = new Dictionary();\n Utils.forEach(this.graph.nodes, function(node) {\n this.downNodes.set(node, []);\n this.upNodes.set(node, []);\n }, this);\n Utils.forEach(this.graph.links, function(link) {\n var origin = link.source;\n var dest = link.target;\n var down = null, up = null;\n if (origin.layer > dest.layer) {\n down = link.source;\n up = link.target;\n }\n else {\n up = link.source;\n down = link.target;\n }\n this.downNodes.get(up).push(down);\n this.upNodes.get(down).push(up);\n }, this);\n this.downNodes.forEachValue(function(list) {\n list.sort(this._gridPositionComparer);\n }, this);\n this.upNodes.forEachValue(function(list) {\n list.sort(this._gridPositionComparer);\n }, this);\n\n for (l = 0; l < this.layers.length - 1; ++l) {\n layer = this.layers[l];\n for (w = 0; w < layer.length - 1; w++) {\n var currentNode = layer[w];\n if (!currentNode.isVirtual) {\n continue;\n }\n\n var currDown = this.downNodes.get(currentNode)[0];\n if (!currDown.isVirtual) {\n continue;\n }\n\n for (n = w + 1; n < layer.length; ++n) {\n node = layer[n];\n if (!node.isVirtual) {\n continue;\n }\n\n var downNode = this.downNodes.get(node)[0];\n if (!downNode.isVirtual) {\n continue;\n }\n\n if (currDown.gridPosition > downNode.gridPosition) {\n var pos = currDown.gridPosition;\n currDown.gridPosition = downNode.gridPosition;\n downNode.gridPosition = pos;\n var i1 = currDown.layerIndex;\n var i2 = downNode.layerIndex;\n this.layers[l + 1][i1] = downNode;\n this.layers[l + 1][i2] = currDown;\n currDown.layerIndex = i2;\n downNode.layerIndex = i1;\n }\n }\n }\n }\n\n\n var leftClasses = this._getLeftWing();\n var rightClasses = this._getRightWing();\n\n\n var leftPos = this.placeLeftToRight(leftClasses);\n var rightPos = this.placeRightToLeft(rightClasses);\n var x = new Dictionary();\n Utils.forEach(this.graph.nodes, function(node) {\n x.set(node, (leftPos.get(node) + rightPos.get(node)) / 2);\n });\n\n\n var order = new Dictionary();\n var placed = new Dictionary();\n for (l = 0; l < this.layers.length; ++l) {\n layer = this.layers[l];\n var sequenceStart = -1, sequenceEnd = -1;\n for (n = 0; n < layer.length; ++n) {\n node = layer[n];\n order.set(node, 0);\n placed.set(node, false);\n if (node.isVirtual) {\n if (sequenceStart === -1) {\n sequenceStart = n;\n }\n else if (sequenceStart === n - 1) {\n sequenceStart = n;\n }\n else {\n sequenceEnd = n;\n order.set(layer[sequenceStart], 0);\n if (x.get(node) - x.get(layer[sequenceStart]) === this.getMinDist(layer[sequenceStart], node)) {\n placed.set(layer[sequenceStart], true);\n }\n else {\n placed.set(layer[sequenceStart], false);\n }\n sequenceStart = n;\n }\n }\n }\n }\n var directions = [1, -1];\n Utils.forEach(directions, function(d) {\n var start = d === 1 ? 0 : this.layers.length - 1;\n for (var l = start; l >= 0 && l < this.layers.length; l += d) {\n var layer = this.layers[l];\n var virtualStartIndex = this._firstVirtualNode(layer);\n var virtualStart = null;\n var sequence = null;\n if (virtualStartIndex !== -1) {\n virtualStart = layer[virtualStartIndex];\n sequence = [];\n for (i = 0; i < virtualStartIndex; i++) {\n sequence.push(layer[i]);\n }\n }\n else {\n virtualStart = null;\n sequence = layer;\n }\n if (sequence.length > 0) {\n this._sequencer(x, null, virtualStart, d, sequence);\n for (i = 0; i < sequence.length - 1; ++i) {\n this.setMinDist(sequence[i], sequence[i + 1], x.get(sequence[i + 1]) - x.get(sequence[i]));\n }\n if (virtualStart) {\n this.setMinDist(sequence[sequence.length - 1], virtualStart, x.get(virtualStart) - x.get(sequence[sequence.length - 1]));\n }\n }\n\n while (virtualStart) {\n var virtualEnd = this.nextVirtualNode(layer, virtualStart);\n if (!virtualEnd) {\n virtualStartIndex = virtualStart.layerIndex;\n sequence = [];\n for (i = virtualStartIndex + 1; i < layer.length; i++) {\n sequence.push(layer[i]);\n }\n if (sequence.length > 0) {\n this._sequencer(x, virtualStart, null, d, sequence);\n for (i = 0; i < sequence.length - 1; ++i) {\n this.setMinDist(sequence[i], sequence[i + 1], x.get(sequence[i + 1]) - x.get(sequence[i]));\n }\n this.setMinDist(virtualStart, sequence[0], x.get(sequence[0]) - x.get(virtualStart));\n }\n }\n else if (order.get(virtualStart) === d) {\n virtualStartIndex = virtualStart.layerIndex;\n var virtualEndIndex = virtualEnd.layerIndex;\n sequence = [];\n for (i = virtualStartIndex + 1; i < virtualEndIndex; i++) {\n sequence.push(layer[i]);\n }\n if (sequence.length > 0) {\n this._sequencer(x, virtualStart, virtualEnd, d, sequence);\n }\n placed.set(virtualStart, true);\n }\n virtualStart = virtualEnd;\n }\n this.adjustDirections(l, d, order, placed);\n }\n }, this);\n\n\n var fromLayerIndex = this._isIncreasingLayout() ? 0 : this.layers.length - 1;\n var reachedFinalLayerIndex = function(k, ctx) {\n if (ctx._isIncreasingLayout()) {\n return k < ctx.layers.length;\n }\n else {\n return k >= 0;\n }\n };\n var layerIncrement = this._isIncreasingLayout() ? +1 : -1, offset = 0;\n\n /**\n * Calcs the max height of the given layer.\n */\n function maximumHeight(layer, ctx) {\n var height = Number.MIN_VALUE;\n for (var n = 0; n < layer.length; ++n) {\n var node = layer[n];\n if (ctx._isVerticalLayout()) {\n height = Math.max(height, node.height);\n }\n else {\n height = Math.max(height, node.width);\n }\n }\n return height;\n }\n\n for (i = fromLayerIndex; reachedFinalLayerIndex(i, this); i += layerIncrement) {\n layer = this.layers[i];\n var height = maximumHeight(layer, this);\n\n for (n = 0; n < layer.length; ++n) {\n node = layer[n];\n if (this._isVerticalLayout()) {\n node.x = x.get(node);\n node.y = offset + height / 2;\n }\n else {\n node.x = offset + height / 2;\n node.y = x.get(node);\n }\n }\n\n offset += this.options.layerSeparation + height;\n }\n },\n\n adjustDirections: function(l, d, order, placed) {\n if (l + d < 0 || l + d >= this.layers.length) {\n return;\n }\n\n var prevBridge = null, prevBridgeTarget = null;\n var layer = this.layers[l + d];\n for (var n = 0; n < layer.length; ++n) {\n var nextBridge = layer[n];\n if (nextBridge.isVirtual) {\n var nextBridgeTarget = this.getNeighborOnLayer(nextBridge, l);\n if (nextBridgeTarget.isVirtual) {\n if (prevBridge) {\n var p = placed.get(prevBridgeTarget);\n var clayer = this.layers[l];\n var i1 = prevBridgeTarget.layerIndex;\n var i2 = nextBridgeTarget.layerIndex;\n for (var i = i1 + 1; i < i2; ++i) {\n if (clayer[i].isVirtual) {\n p = p && placed.get(clayer[i]);\n }\n }\n if (p) {\n order.set(prevBridge, d);\n var j1 = prevBridge.layerIndex;\n var j2 = nextBridge.layerIndex;\n for (var j = j1 + 1; j < j2; ++j) {\n if (layer[j].isVirtual) {\n order.set(layer[j], d);\n }\n }\n }\n }\n prevBridge = nextBridge;\n prevBridgeTarget = nextBridgeTarget;\n }\n }\n }\n },\n\n getNeighborOnLayer: function(node, l) {\n var neighbor = this.upNodes.get(node)[0];\n if (neighbor.layer === l) {\n return neighbor;\n }\n neighbor = this.downNodes.get(node)[0];\n if (neighbor.layer === l) {\n return neighbor;\n }\n return null;\n },\n\n _sequencer: function(x, virtualStart, virtualEnd, dir, sequence) {\n if (sequence.length === 1) {\n this._sequenceSingle(x, virtualStart, virtualEnd, dir, sequence[0]);\n }\n\n if (sequence.length > 1) {\n var r = sequence.length, t = this.intDiv(r, 2);\n this._sequencer(x, virtualStart, virtualEnd, dir, sequence.slice(0, t));\n this._sequencer(x, virtualStart, virtualEnd, dir, sequence.slice(t));\n this.combineSequences(x, virtualStart, virtualEnd, dir, sequence);\n }\n },\n\n _sequenceSingle: function(x, virtualStart, virtualEnd, dir, node) {\n var neighbors = dir === -1 ? this.downNodes.get(node) : this.upNodes.get(node);\n\n var n = neighbors.length;\n if (n !== 0) {\n if (n % 2 === 1) {\n x.set(node, x.get(neighbors[this.intDiv(n, 2)]));\n }\n else {\n x.set(node, (x.get(neighbors[this.intDiv(n, 2) - 1]) + x.get(neighbors[this.intDiv(n, 2)])) / 2);\n }\n\n if (virtualStart) {\n x.set(node, Math.max(x.get(node), x.get(virtualStart) + this.getMinDist(virtualStart, node)));\n }\n if (virtualEnd) {\n x.set(node, Math.min(x.get(node), x.get(virtualEnd) - this.getMinDist(node, virtualEnd)));\n }\n }\n },\n\n combineSequences: function(x, virtualStart, virtualEnd, dir, sequence) {\n var r = sequence.length, t = this.intDiv(r, 2);\n\n // collect left changes\n var leftHeap = [], i, c, n, neighbors, neighbor, pair;\n for (i = 0; i < t; ++i) {\n c = 0;\n neighbors = dir === -1 ? this.downNodes.get(sequence[i]) : this.upNodes.get(sequence[i]);\n for (n = 0; n < neighbors.length; ++n) {\n neighbor = neighbors[n];\n if (x.get(neighbor) >= x.get(sequence[i])) {\n c++;\n }\n else {\n c--;\n leftHeap.push({ k: x.get(neighbor) + this.getMinDist(sequence[i], sequence[t - 1]), v: 2 });\n }\n }\n leftHeap.push({ k: x.get(sequence[i]) + this.getMinDist(sequence[i], sequence[t - 1]), v: c });\n }\n if (virtualStart) {\n leftHeap.push({ k: x.get(virtualStart) + this.getMinDist(virtualStart, sequence[t - 1]), v: Number.MAX_VALUE });\n }\n leftHeap.sort(this._positionDescendingComparer);\n\n // collect right changes\n var rightHeap = [];\n for (i = t; i < r; ++i) {\n c = 0;\n neighbors = dir === -1 ? this.downNodes.get(sequence[i]) : this.upNodes.get(sequence[i]);\n for (n = 0; n < neighbors.length; ++n) {\n neighbor = neighbors[n];\n if (x.get(neighbor) <= x.get(sequence[i])) {\n c++;\n }\n else {\n c--;\n rightHeap.push({ k: x.get(neighbor) - this.getMinDist(sequence[i], sequence[t]), v: 2 });\n }\n }\n rightHeap.push({ k: x.get(sequence[i]) - this.getMinDist(sequence[i], sequence[t]), v: c });\n }\n if (virtualEnd) {\n rightHeap.push({ k: x.get(virtualEnd) - this.getMinDist(virtualEnd, sequence[t]), v: Number.MAX_VALUE });\n }\n rightHeap.sort(this._positionAscendingComparer);\n\n var leftRes = 0, rightRes = 0;\n var m = this.getMinDist(sequence[t - 1], sequence[t]);\n while (x.get(sequence[t]) - x.get(sequence[t - 1]) < m) {\n if (leftRes < rightRes) {\n if (leftHeap.length === 0) {\n x.set(sequence[t - 1], x.get(sequence[t]) - m);\n break;\n }\n else {\n pair = leftHeap.shift();\n leftRes = leftRes + pair.v;\n x.set(sequence[t - 1], pair.k);\n x.set(sequence[t - 1], Math.max(x.get(sequence[t - 1]), x.get(sequence[t]) - m));\n }\n }\n else {\n if (rightHeap.length === 0) {\n x.set(sequence[t], x.get(sequence[t - 1]) + m);\n break;\n }\n else {\n pair = rightHeap.shift();\n rightRes = rightRes + pair.v;\n x.set(sequence[t], pair.k);\n x.set(sequence[t], Math.min(x.get(sequence[t]), x.get(sequence[t - 1]) + m));\n }\n }\n }\n for (i = t - 2; i >= 0; i--) {\n x.set(sequence[i], Math.min(x.get(sequence[i]), x.get(sequence[t - 1]) - this.getMinDist(sequence[i], sequence[t - 1])));\n }\n for (i = t + 1; i < r; i++) {\n x.set(sequence[i], Math.max(x.get(sequence[i]), x.get(sequence[t]) + this.getMinDist(sequence[i], sequence[t])));\n }\n },\n\n placeLeft: function(node, leftPos, leftClass) {\n var pos = Number.NEGATIVE_INFINITY;\n Utils.forEach(this._getComposite(node), function(v) {\n var leftSibling = this.leftSibling(v);\n if (leftSibling && this.nodeLeftClass.get(leftSibling) === this.nodeLeftClass.get(v)) {\n if (!leftPos.containsKey(leftSibling)) {\n this.placeLeft(leftSibling, leftPos, leftClass);\n }\n pos = Math.max(pos, leftPos.get(leftSibling) + this.getMinDist(leftSibling, v));\n }\n }, this);\n if (pos === Number.NEGATIVE_INFINITY) {\n pos = 0;\n }\n Utils.forEach(this._getComposite(node), function(v) {\n leftPos.set(v, pos);\n });\n },\n\n placeRight: function(node, rightPos, rightClass) {\n var pos = Number.POSITIVE_INFINITY;\n Utils.forEach(this._getComposite(node), function(v) {\n var rightSibling = this.rightSibling(v);\n if (rightSibling && this.nodeRightClass.get(rightSibling) === this.nodeRightClass.get(v)) {\n if (!rightPos.containsKey(rightSibling)) {\n this.placeRight(rightSibling, rightPos, rightClass);\n }\n pos = Math.min(pos, rightPos.get(rightSibling) - this.getMinDist(v, rightSibling));\n }\n }, this);\n if (pos === Number.POSITIVE_INFINITY) {\n pos = 0;\n }\n Utils.forEach(this._getComposite(node), function(v) {\n rightPos.set(v, pos);\n });\n },\n\n leftSibling: function(node) {\n var layer = this.layers[node.layer],\n layerIndex = node.layerIndex;\n return layerIndex === 0 ? null : layer[layerIndex - 1];\n },\n\n rightSibling: function(node) {\n var layer = this.layers[node.layer];\n var layerIndex = node.layerIndex;\n return layerIndex === layer.length - 1 ? null : layer[layerIndex + 1];\n\n },\n\n _getComposite: function(node) {\n return node.isVirtual ? this._nodesInLink(node) : [node];\n },\n\n arrangeNodes: function() {\n var i, l, ni, layer, node;\n // Initialize node's base priority\n for (l = 0; l < this.layers.length; l++) {\n layer = this.layers[l];\n\n for (ni = 0; ni < layer.length; ni++) {\n node = layer[ni];\n node.upstreamPriority = node.upstreamLinkCount;\n node.downstreamPriority = node.downstreamLinkCount;\n }\n }\n\n // Layout is invoked after MinimizeCrossings\n // so we may assume node's barycenters are initially correct\n\n var maxLayoutIterations = 2;\n for (var it = 0; it < maxLayoutIterations; it++) {\n for (i = this.layers.length - 1; i >= 1; i--) {\n this.layoutLayer(false, i);\n }\n\n for (i = 0; i < this.layers.length - 1; i++) {\n this.layoutLayer(true, i);\n }\n }\n\n // Offset the whole structure so that there are no gridPositions < 0\n var gridPos = Number.MAX_VALUE;\n for (l = 0; l < this.layers.length; l++) {\n layer = this.layers[l];\n\n for (ni = 0; ni < layer.length; ni++) {\n node = layer[ni];\n gridPos = Math.min(gridPos, node.gridPosition);\n }\n }\n\n if (gridPos < 0) {\n for (l = 0; l < this.layers.length; l++) {\n layer = this.layers[l];\n\n for (ni = 0; ni < layer.length; ni++) {\n node = layer[ni];\n node.gridPosition = node.gridPosition - gridPos;\n }\n }\n }\n },\n\n /// \n /// Layout of a single layer.\n /// \n /// The layer to organize.\n /// If set to true we move down in the layer stack.\n /// \n layoutLayer: function(down, layer) {\n var iconsidered;\n var considered;\n\n if (down) {\n considered = this.layers[iconsidered = layer + 1];\n }\n else {\n considered = this.layers[iconsidered = layer - 1];\n }\n\n // list containing the nodes in the considered layer sorted by priority\n var sorted = [];\n for (var n = 0; n < considered.length; n++) {\n sorted.push(considered[n]);\n }\n sorted.sort(function(n1, n2) {\n var n1Priority = (n1.upstreamPriority + n1.downstreamPriority) / 2;\n var n2Priority = (n2.upstreamPriority + n2.downstreamPriority) / 2;\n\n if (Math.abs(n1Priority - n2Priority) < 0.0001) {\n return 0;\n }\n if (n1Priority < n2Priority) {\n return 1;\n }\n return -1;\n });\n\n // each node strives for its barycenter; high priority nodes start first\n Utils.forEach(sorted, function(node) {\n var nodeGridPos = node.gridPosition;\n var nodeBaryCenter = this.calcBaryCenter(node);\n var nodePriority = (node.upstreamPriority + node.downstreamPriority) / 2;\n\n if (Math.abs(nodeGridPos - nodeBaryCenter) < 0.0001) {\n // This node is exactly at its barycenter -> perfect\n return;\n }\n\n if (Math.abs(nodeGridPos - nodeBaryCenter) < 0.25 + 0.0001) {\n // This node is close enough to the barycenter -> should work\n return;\n }\n\n if (nodeGridPos < nodeBaryCenter) {\n // Try to move the node to the right in an\n // attempt to reach its barycenter\n while (nodeGridPos < nodeBaryCenter) {\n if (!this.moveRight(node, considered, nodePriority)) {\n break;\n }\n\n nodeGridPos = node.gridPosition;\n }\n }\n else {\n // Try to move the node to the left in an\n // attempt to reach its barycenter\n while (nodeGridPos > nodeBaryCenter) {\n if (!this.moveLeft(node, considered, nodePriority)) {\n break;\n }\n\n nodeGridPos = node.gridPosition;\n }\n }\n }, this);\n\n // after the layer has been rearranged we need to recalculate the barycenters\n // of the nodes in the surrounding layers\n if (iconsidered > 0) {\n this.calcDownData(iconsidered - 1);\n }\n if (iconsidered < this.layers.length - 1) {\n this.calcUpData(iconsidered + 1);\n }\n },\n\n /// \n /// Moves the node to the right and returns true if this was possible.\n /// \n /// The node.\n /// The layer.\n /// Returns true if the shift was possible, otherwise false.\n moveRight: function(node, layer, priority) {\n var index = Utils.indexOf(layer, node);\n if (index === layer.length - 1) {\n // this is the last node in the layer, so we can move to the right without troubles\n node.gridPosition = node.gridPosition + 0.5;\n return true;\n }\n\n var rightNode = layer[index + 1];\n var rightNodePriority = (rightNode.upstreamPriority + rightNode.downstreamPriority) / 2;\n\n // check if there is space between the right and the current node\n if (rightNode.gridPosition > node.gridPosition + 1) {\n node.gridPosition = node.gridPosition + 0.5;\n return true;\n }\n\n // we have reached a node with higher priority; no movement is allowed\n if (rightNodePriority > priority ||\n Math.abs(rightNodePriority - priority) < 0.0001) {\n return false;\n }\n\n // the right node has lower priority - try to move it\n if (this.moveRight(rightNode, layer, priority)) {\n node.gridPosition = node.gridPosition + 0.5;\n return true;\n }\n\n return false;\n },\n\n /// \n /// Moves the node to the left and returns true if this was possible.\n /// \n /// The node.\n /// The layer.\n /// Returns true if the shift was possible, otherwise false.\n moveLeft: function(node, layer, priority) {\n var index = Utils.indexOf(layer, node);\n if (index === 0) {\n // this is the last node in the layer, so we can move to the left without troubles\n node.gridPosition = node.gridPosition - 0.5;\n return true;\n }\n\n var leftNode = layer[index - 1];\n var leftNodePriority = (leftNode.upstreamPriority + leftNode.downstreamPriority) / 2;\n\n // check if there is space between the left and the current node\n if (leftNode.gridPosition < node.gridPosition - 1) {\n node.gridPosition = node.gridPosition - 0.5;\n return true;\n }\n\n // we have reached a node with higher priority; no movement is allowed\n if (leftNodePriority > priority ||\n Math.abs(leftNodePriority - priority) < 0.0001) {\n return false;\n }\n\n // The left node has lower priority - try to move it\n if (this.moveLeft(leftNode, layer, priority)) {\n node.gridPosition = node.gridPosition - 0.5;\n return true;\n }\n\n return false;\n },\n\n mapVirtualNode: function(node, link) {\n this.nodeToLinkMap.set(node, link);\n if (!this.linkToNodeMap.containsKey(link)) {\n this.linkToNodeMap.set(link, []);\n }\n this.linkToNodeMap.get(link).push(node);\n },\n\n _nodesInLink: function(node) {\n return this.linkToNodeMap.get(this.nodeToLinkMap.get(node));\n },\n\n /// \n /// Inserts dummy nodes to break long links.\n /// \n _dummify: function() {\n this.linkToNodeMap = new Dictionary();\n this.nodeToLinkMap = new Dictionary();\n\n var layer, pos, newNode, node, r, newLink, i, l, links = this.graph.links.slice(0);\n var layers = this.layers;\n\n var addLinkBetweenLayers = function(upLayer, downLayer, link) {\n layers[upLayer].linksTo[downLayer] = layers[upLayer].linksTo[downLayer] || [];\n layers[upLayer].linksTo[downLayer].push(link);\n };\n\n for (l = 0; l < links.length; l++) {\n var link = links[l];\n var o = link.source;\n var d = link.target;\n\n var oLayer = o.layer;\n var dLayer = d.layer;\n var oPos = o.gridPosition;\n var dPos = d.gridPosition;\n\n var step = (dPos - oPos) / Math.abs(dLayer - oLayer);\n\n var p = o;\n if (oLayer - dLayer > 1) {\n for (i = oLayer - 1; i > dLayer; i--) {\n newNode = new Node();\n newNode.x = o.x;\n newNode.y = o.y;\n newNode.width = o.width / 100;\n newNode.height = o.height / 100;\n\n layer = layers[i];\n pos = (i - dLayer) * step + oPos;\n if (pos > layer.length) {\n pos = layer.length;\n }\n\n // check if origin and dest are both last\n if (oPos >= layers[oLayer].length - 1 &&\n dPos >= layers[dLayer].length - 1) {\n pos = layer.length;\n }\n\n // check if origin and destination are both first\n else if (oPos === 0 && dPos === 0) {\n pos = 0;\n }\n\n newNode.layer = i;\n newNode.uBaryCenter = 0.0;\n newNode.dBaryCenter = 0.0;\n newNode.upstreamLinkCount = 0;\n newNode.downstreamLinkCount = 0;\n newNode.gridPosition = pos;\n newNode.isVirtual = true;\n\n Utils.insert(layer, newNode, pos);\n\n // translate rightwards nodes' positions\n for (r = pos + 1; r < layer.length; r++) {\n node = layer[r];\n node.gridPosition = node.gridPosition + 1;\n }\n\n newLink = new Link(p, newNode);\n newLink.depthOfDumminess = 0;\n\n addLinkBetweenLayers(i - 1, i, newLink);\n\n p = newNode;\n\n // add the new node and the new link to the graph\n this.graph._addNode(newNode);\n this.graph.addLink(newLink);\n\n newNode.index = this.graph.nodes.length - 1;\n this.mapVirtualNode(newNode, link);\n }\n\n // set the origin of the real arrow to the last dummy\n addLinkBetweenLayers(dLayer - 1, dLayer, newLink);\n link.changeSource(p);\n link.depthOfDumminess = oLayer - dLayer - 1;\n } else if (oLayer - dLayer < -1) {\n for (i = oLayer + 1; i < dLayer; i++) {\n newNode = new Node();\n newNode.x = o.x;\n newNode.y = o.y;\n newNode.width = o.width / 100;\n newNode.height = o.height / 100;\n\n layer = layers[i];\n pos = (i - oLayer) * step + oPos;\n if (pos > layer.length) {\n pos = layer.length;\n }\n\n // check if origin and dest are both last\n if (oPos >= layers[oLayer].length - 1 &&\n dPos >= layers[dLayer].length - 1) {\n pos = layer.length;\n }\n\n // check if origin and destination are both first\n else if (oPos === 0 && dPos === 0) {\n pos = 0;\n }\n\n newNode.layer = i;\n newNode.uBaryCenter = 0.0;\n newNode.dBaryCenter = 0.0;\n newNode.upstreamLinkCount = 0;\n newNode.downstreamLinkCount = 0;\n newNode.gridPosition = pos;\n newNode.isVirtual = true;\n\n pos &= pos; // truncates to int\n Utils.insert(layer, newNode, pos);\n\n // translate rightwards nodes' positions\n for (r = pos + 1; r < layer.length; r++) {\n node = layer[r];\n node.gridPosition = node.gridPosition + 1;\n }\n\n newLink = new Link(p, newNode);\n newLink.depthOfDumminess = 0;\n addLinkBetweenLayers(i - 1, i, newLink);\n\n p = newNode;\n\n // add the new node and the new link to the graph\n this.graph._addNode(newNode);\n this.graph.addLink(newLink);\n\n newNode.index = this.graph.nodes.length - 1;\n this.mapVirtualNode(newNode, link);\n }\n addLinkBetweenLayers(dLayer - 1, dLayer, link);\n\n // Set the origin of the real arrow to the last dummy\n link.changeSource(p);\n link.depthOfDumminess = dLayer - oLayer - 1;\n } else {\n addLinkBetweenLayers(oLayer, dLayer, link);\n }\n }\n },\n\n /// \n /// Removes the dummy nodes inserted earlier to break long links.\n /// \n /// The virtual nodes are effectively turned into intermediate connection points.\n _dedummify: function() {\n var dedum = true;\n while (dedum) {\n dedum = false;\n\n for (var l = 0; l < this.graph.links.length; l++) {\n var link = this.graph.links[l];\n if (!link.depthOfDumminess) {\n continue;\n }\n\n var points = [];\n\n // add points in reverse order\n points.unshift({ x: link.target.x, y: link.target.y });\n points.unshift({ x: link.source.x, y: link.source.y });\n\n // _dedummify the link\n var temp = link;\n var depthOfDumminess = link.depthOfDumminess;\n for (var d = 0; d < depthOfDumminess; d++) {\n var node = temp.source;\n var prevLink = node.incoming[0];\n\n points.unshift({ x: prevLink.source.x, y: prevLink.source.y });\n\n temp = prevLink;\n }\n\n // restore the original link origin\n link.changeSource(temp.source);\n\n // reset dummification flag\n link.depthOfDumminess = 0;\n\n // note that we only need the intermediate points, floating links have been dropped in the analysis\n if (points.length > 2) {\n // first and last are the endpoints\n points.splice(0, 1);\n points.splice(points.length - 1);\n link.points = points;\n }\n else {\n link.points = [];\n }\n\n // we are not going to delete the dummy elements;\n // they won't be needed anymore anyway.\n\n dedum = true;\n break;\n }\n }\n },\n\n /// \n /// Optimizes/reduces the crossings between the layers by turning the crossing problem into a (combinatorial) number ordering problem.\n /// \n _optimizeCrossings: function() {\n var moves = -1, i;\n var maxIterations = 3;\n var iter = 0;\n\n while (moves !== 0) {\n if (iter++ > maxIterations) {\n break;\n }\n\n moves = 0;\n\n for (i = this.layers.length - 1; i >= 1; i--) {\n moves += this.optimizeLayerCrossings(false, i);\n }\n\n for (i = 0; i < this.layers.length - 1; i++) {\n moves += this.optimizeLayerCrossings(true, i);\n }\n }\n },\n\n calcUpData: function(layer) {\n if (layer === 0) {\n return;\n }\n\n var considered = this.layers[layer], i, l, link;\n var upLayer = new Set();\n var temp = this.layers[layer - 1];\n for (i = 0; i < temp.length; i++) {\n upLayer.add(temp[i]);\n }\n\n for (i = 0; i < considered.length; i++) {\n var node = considered[i];\n\n // calculate barycenter\n var sum = 0;\n var total = 0;\n\n for (l = 0; l < node.incoming.length; l++) {\n link = node.incoming[l];\n if (upLayer.contains(link.source)) {\n total++;\n sum += link.source.gridPosition;\n }\n }\n\n for (l = 0; l < node.outgoing.length; l++) {\n link = node.outgoing[l];\n if (upLayer.contains(link.target)) {\n total++;\n sum += link.target.gridPosition;\n }\n }\n\n if (total > 0) {\n node.uBaryCenter = sum / total;\n node.upstreamLinkCount = total;\n }\n else {\n node.uBaryCenter = i;\n node.upstreamLinkCount = 0;\n }\n }\n },\n\n calcDownData: function(layer) {\n if (layer === this.layers.length - 1) {\n return;\n }\n\n var considered = this.layers[layer], i , l, link;\n var downLayer = new Set();\n var temp = this.layers[layer + 1];\n for (i = 0; i < temp.length; i++) {\n downLayer.add(temp[i]);\n }\n\n for (i = 0; i < considered.length; i++) {\n var node = considered[i];\n\n // calculate barycenter\n var sum = 0;\n var total = 0;\n\n for (l = 0; l < node.incoming.length; l++) {\n link = node.incoming[l];\n if (downLayer.contains(link.source)) {\n total++;\n sum += link.source.gridPosition;\n }\n }\n\n for (l = 0; l < node.outgoing.length; l++) {\n link = node.outgoing[l];\n if (downLayer.contains(link.target)) {\n total++;\n sum += link.target.gridPosition;\n }\n }\n\n if (total > 0) {\n node.dBaryCenter = sum / total;\n node.downstreamLinkCount = total;\n }\n else {\n node.dBaryCenter = i;\n node.downstreamLinkCount = 0;\n }\n }\n },\n\n /// \n /// Optimizes the crossings.\n /// \n /// The big trick here is the usage of weights or values attached to connected nodes which turn a problem of crossing links\n /// to an a problem of ordering numbers.\n /// The layer index.\n /// If set to true we move down in the layer stack.\n /// The number of nodes having moved, i.e. the number of crossings reduced.\n optimizeLayerCrossings: function(down, layer) {\n var iconsidered;\n var considered;\n\n if (down) {\n considered = this.layers[iconsidered = layer + 1];\n }\n else {\n considered = this.layers[iconsidered = layer - 1];\n }\n\n // remember what it was\n var presorted = considered.slice(0);\n\n // calculate barycenters for all nodes in the considered layer\n if (down) {\n this.calcUpData(iconsidered);\n }\n else {\n this.calcDownData(iconsidered);\n }\n\n var that = this;\n // sort nodes within this layer according to the barycenters\n considered.sort(function(n1, n2) {\n var n1BaryCenter = that.calcBaryCenter(n1),\n n2BaryCenter = that.calcBaryCenter(n2);\n if (Math.abs(n1BaryCenter - n2BaryCenter) < 0.0001) {\n // in case of coinciding barycenters compare by the count of in/out links\n if (n1.degree() === n2.degree()) {\n return that.compareByIndex(n1, n2);\n }\n else if (n1.degree() < n2.degree()) {\n return 1;\n }\n return -1;\n }\n var compareValue = (n2BaryCenter - n1BaryCenter) * 1000;\n if (compareValue > 0) {\n return -1;\n }\n else if (compareValue < 0) {\n return 1;\n }\n return that.compareByIndex(n1, n2);\n });\n\n // count relocations\n var i, moves = 0;\n for (i = 0; i < considered.length; i++) {\n if (considered[i] !== presorted[i]) {\n moves++;\n }\n }\n\n if (moves > 0) {\n // now that the boxes have been arranged, update their grid positions\n var inode = 0;\n for (i = 0; i < considered.length; i++) {\n var node = considered[i];\n node.gridPosition = inode++;\n }\n }\n\n return moves;\n },\n\n /// \n /// Swaps a pair of nodes in a layer.\n /// \n /// Index of the layer.\n /// The Nth node in the layer.\n _swapPairs: function() {\n var maxIterations = this.options.layeredIterations;\n var iter = 0;\n\n while (true) {\n if (iter++ > maxIterations) {\n break;\n }\n\n var downwards = (iter % 4 <= 1);\n var secondPass = (iter % 4 === 1);\n\n for (var l = (downwards ? 0 : this.layers.length - 1);\n downwards ? l <= this.layers.length - 1 : l >= 0; l += (downwards ? 1 : -1)) {\n var layer = this.layers[l];\n var hasSwapped = false;\n\n // there is no need to recalculate crossings if they were calculated\n // on the previous step and nothing has changed\n var calcCrossings = true;\n var memCrossings = 0;\n\n for (var n = 0; n < layer.length - 1; n++) {\n // count crossings\n var up = 0;\n var down = 0;\n var crossBefore = 0;\n\n if (calcCrossings) {\n if (l !== 0) {\n up = this.countLinksCrossingBetweenTwoLayers(l - 1, l);\n }\n if (l !== this.layers.length - 1) {\n down = this.countLinksCrossingBetweenTwoLayers(l, l + 1);\n }\n if (downwards) {\n up *= 2;\n }\n else {\n down *= 2;\n }\n\n crossBefore = up + down;\n }\n else {\n crossBefore = memCrossings;\n }\n\n if (crossBefore === 0) {\n continue;\n }\n\n // Swap nodes\n var node1 = layer[n];\n var node2 = layer[n + 1];\n\n var node1GridPos = node1.gridPosition;\n var node2GridPos = node2.gridPosition;\n layer[n] = node2;\n layer[n + 1] = node1;\n node1.gridPosition = node2GridPos;\n node2.gridPosition = node1GridPos;\n\n // count crossings again and if worse than before, restore swapping\n up = 0;\n if (l !== 0) {\n up = this.countLinksCrossingBetweenTwoLayers(l - 1, l);\n }\n down = 0;\n if (l !== this.layers.length - 1) {\n down = this.countLinksCrossingBetweenTwoLayers(l, l + 1);\n }\n if (downwards) {\n up *= 2;\n }\n else {\n down *= 2;\n }\n var crossAfter = up + down;\n\n var revert = false;\n if (secondPass) {\n revert = crossAfter >= crossBefore;\n }\n else {\n revert = crossAfter > crossBefore;\n }\n\n if (revert) {\n node1 = layer[n];\n node2 = layer[n + 1];\n\n node1GridPos = node1.gridPosition;\n node2GridPos = node2.gridPosition;\n layer[n] = node2;\n layer[n + 1] = node1;\n node1.gridPosition = node2GridPos;\n node2.gridPosition = node1GridPos;\n\n // nothing has changed, remember the crossings so that\n // they are not calculated again on the next step\n memCrossings = crossBefore;\n calcCrossings = false;\n }\n else {\n hasSwapped = true;\n calcCrossings = true;\n }\n }\n\n if (hasSwapped) {\n if (l !== this.layers.length - 1) {\n this.calcUpData(l + 1);\n }\n if (l !== 0) {\n this.calcDownData(l - 1);\n }\n }\n }\n }\n },\n\n /// \n /// Counts the number of links crossing between two layers.\n /// \n /// The layer index.\n /// Another layer index.\n /// \n countLinksCrossingBetweenTwoLayers: function(ulayer, dlayer) {\n var links = this.layers[ulayer].linksTo[dlayer];\n var link1, link2, n11, n12, n21, n22, l1, l2;\n var crossings = 0;\n var length = links.length;\n\n for (l1 = 0; l1 < length; l1++) {\n link1 = links[l1];\n for (l2 = l1 + 1; l2 < length; l2++) {\n\n link2 = links[l2];\n\n if (link1.target.layer === dlayer) {\n n11 = link1.source;\n n12 = link1.target;\n }\n else {\n n11 = link1.target;\n n12 = link1.source;\n }\n\n if (link2.target.layer === dlayer) {\n n21 = link2.source;\n n22 = link2.target;\n }\n else {\n n21 = link2.target;\n n22 = link2.source;\n }\n\n var n11gp = n11.gridPosition;\n var n12gp = n12.gridPosition;\n var n21gp = n21.gridPosition;\n var n22gp = n22.gridPosition;\n\n if ((n11gp - n21gp) * (n12gp - n22gp) < 0) {\n crossings++;\n }\n }\n }\n\n return crossings;\n },\n\n calcBaryCenter: function(node) {\n var upstreamLinkCount = node.upstreamLinkCount;\n var downstreamLinkCount = node.downstreamLinkCount;\n var uBaryCenter = node.uBaryCenter;\n var dBaryCenter = node.dBaryCenter;\n\n if (upstreamLinkCount > 0 && downstreamLinkCount > 0) {\n return (uBaryCenter + dBaryCenter) / 2;\n }\n if (upstreamLinkCount > 0) {\n return uBaryCenter;\n }\n if (downstreamLinkCount > 0) {\n return dBaryCenter;\n }\n\n return 0;\n },\n\n _gridPositionComparer: function(x, y) {\n if (x.gridPosition < y.gridPosition) {\n return -1;\n }\n if (x.gridPosition > y.gridPosition) {\n return 1;\n }\n return 0;\n },\n\n _positionAscendingComparer: function(x, y) {\n return x.k < y.k ? -1 : x.k > y.k ? 1 : 0;\n },\n\n _positionDescendingComparer: function(x, y) {\n return x.k < y.k ? 1 : x.k > y.k ? -1 : 0;\n },\n\n _firstVirtualNode: function(layer) {\n for (var c = 0; c < layer.length; c++) {\n if (layer[c].isVirtual) {\n return c;\n }\n }\n return -1;\n },\n\n compareByIndex: function(o1, o2) {\n var i1 = o1.index;\n var i2 = o2.index;\n\n if (i1 < i2) {\n return 1;\n }\n\n if (i1 > i2) {\n return -1;\n }\n\n return 0;\n },\n\n intDiv: function(numerator, denominator) {\n return (numerator - numerator % denominator) / denominator;\n },\n\n nextVirtualNode: function(layer, node) {\n var nodeIndex = node.layerIndex;\n for (var i = nodeIndex + 1; i < layer.length; ++i) {\n if (layer[i].isVirtual) {\n return layer[i];\n }\n }\n return null;\n }\n\n });\n\n /**\n * Captures the state of a diagram; node positions, link points and so on.\n * @type {*}\n */\n var LayoutState = kendo.Class.extend({\n init: function(diagram, graphOrNodes) {\n if (Utils.isUndefined(diagram)) {\n throw \"No diagram given\";\n }\n this.diagram = diagram;\n this.nodeMap = new Dictionary();\n this.linkMap = new Dictionary();\n this.capture(graphOrNodes ? graphOrNodes : diagram);\n },\n\n /**\n * Will capture either\n * - the state of the shapes and the intermediate points of the connections in the diagram\n * - the bounds of the nodes contained in the Graph together with the intermediate points of the links in the Graph\n * - the bounds of the nodes in the Array\n * - the links points and node bounds in the literal object\n * @param diagramOrGraphOrNodes\n */\n capture: function(diagramOrGraphOrNodes) {\n var node,\n nodes,\n shape,\n i,\n conn,\n link,\n links;\n\n if (diagramOrGraphOrNodes instanceof diagram.Graph) {\n\n for (i = 0; i < diagramOrGraphOrNodes.nodes.length; i++) {\n node = diagramOrGraphOrNodes.nodes[i];\n shape = node.associatedShape;\n //shape.bounds(new Rect(node.x, node.y, node.width, node.height));\n this.nodeMap.set(shape.visual.id, new Rect(node.x, node.y, node.width, node.height));\n }\n for (i = 0; i < diagramOrGraphOrNodes.links.length; i++) {\n link = diagramOrGraphOrNodes.links[i];\n conn = link.associatedConnection;\n this.linkMap.set(conn.visual.id, link.points());\n }\n }\n else if (diagramOrGraphOrNodes instanceof Array) {\n nodes = diagramOrGraphOrNodes;\n for (i = 0; i < nodes.length; i++) {\n node = nodes[i];\n shape = node.associatedShape;\n if (shape) {\n this.nodeMap.set(shape.visual.id, new Rect(node.x, node.y, node.width, node.height));\n }\n }\n }\n else if (diagramOrGraphOrNodes.hasOwnProperty(\"links\") && diagramOrGraphOrNodes.hasOwnProperty(\"nodes\")) {\n nodes = diagramOrGraphOrNodes.nodes;\n links = diagramOrGraphOrNodes.links;\n for (i = 0; i < nodes.length; i++) {\n node = nodes[i];\n shape = node.associatedShape;\n if (shape) {\n this.nodeMap.set(shape.visual.id, new Rect(node.x, node.y, node.width, node.height));\n }\n }\n for (i = 0; i < links.length; i++) {\n link = links[i];\n conn = link.associatedConnection;\n if (conn) {\n this.linkMap.set(conn.visual.id, link.points);\n }\n }\n }\n else { // capture the diagram\n var shapes = this.diagram.shapes;\n var connections = this.diagram.connections;\n for (i = 0; i < shapes.length; i++) {\n shape = shapes[i];\n this.nodeMap.set(shape.visual.id, shape.bounds());\n }\n for (i = 0; i < connections.length; i++) {\n conn = connections[i];\n this.linkMap.set(conn.visual.id, conn.points());\n }\n }\n }\n });\n\n deepExtend(diagram, {\n init: function(element) {\n kendo.init(element, diagram.ui);\n },\n SpringLayout: SpringLayout,\n TreeLayout: TreeLayout,\n GraphAdapter: DiagramToHyperTreeAdapter,\n LayeredLayout: LayeredLayout,\n LayoutBase: LayoutBase,\n LayoutState: LayoutState\n });\n })(window.kendo.jQuery);\n\n (function($, undefined$1) {\n // Imports ================================================================\n var dataviz = kendo.dataviz,\n draw = kendo.drawing,\n geom = kendo.geometry,\n diagram = dataviz.diagram,\n Widget = kendo.ui.Widget,\n Class = kendo.Class,\n deepExtend = kendo.deepExtend,\n outerWidth = kendo._outerWidth,\n outerHeight = kendo._outerHeight,\n extend = $.extend,\n HierarchicalDataSource = kendo.data.HierarchicalDataSource,\n Canvas = diagram.Canvas,\n Group = diagram.Group,\n Rectangle = diagram.Rectangle,\n Circle = diagram.Circle,\n CompositeTransform = diagram.CompositeTransform,\n Rect = diagram.Rect,\n Path = diagram.Path,\n DeleteShapeUnit = diagram.DeleteShapeUnit,\n DeleteConnectionUnit = diagram.DeleteConnectionUnit,\n TextBlock = diagram.TextBlock,\n Image = diagram.Image,\n Point = diagram.Point,\n Intersect = diagram.Intersect,\n ConnectionEditAdorner = diagram.ConnectionEditAdorner,\n UndoRedoService = diagram.UndoRedoService,\n ToolService = diagram.ToolService,\n Selector = diagram.Selector,\n ResizingAdorner = diagram.ResizingAdorner,\n ConnectorsAdorner = diagram.ConnectorsAdorner,\n Cursors = diagram.Cursors,\n Utils = diagram.Utils,\n Observable = kendo.Observable,\n ToBackUnit = diagram.ToBackUnit,\n ToFrontUnit = diagram.ToFrontUnit,\n PolylineRouter = diagram.PolylineRouter,\n CascadingRouter = diagram.CascadingRouter,\n isUndefined = Utils.isUndefined,\n isDefined = Utils.isDefined,\n defined = draw.util.defined,\n isArray = Array.isArray,\n isFunction = kendo.isFunction,\n isString = Utils.isString,\n isPlainObject = $.isPlainObject,\n\n math = Math;\n\n // Constants ==============================================================\n var NS = \".kendoDiagram\",\n CASCADING = \"cascading\",\n ITEMBOUNDSCHANGE = \"itemBoundsChange\",\n CHANGE = \"change\",\n CLICK = \"click\",\n DRAG = \"drag\",\n DRAG_END = \"dragEnd\",\n DRAG_START = \"dragStart\",\n MOUSE_ENTER = \"mouseEnter\",\n MOUSE_LEAVE = \"mouseLeave\",\n ERROR = \"error\",\n AUTO = \"Auto\",\n TOP = \"Top\",\n RIGHT = \"Right\",\n LEFT = \"Left\",\n BOTTOM = \"Bottom\",\n MAXINT = 9007199254740992,\n SELECT = \"select\",\n ITEMROTATE = \"itemRotate\",\n PAN = \"pan\",\n ZOOM_START = \"zoomStart\",\n ZOOM_END = \"zoomEnd\",\n NONE = \"none\",\n DEFAULT_CANVAS_WIDTH = 600,\n DEFAULT_CANVAS_HEIGHT = 600,\n DEFAULT_SHAPE_TYPE = \"rectangle\",\n DEFAULT_SHAPE_WIDTH = 100,\n DEFAULT_SHAPE_HEIGHT = 100,\n DEFAULT_SHAPE_MINWIDTH = 20,\n DEFAULT_SHAPE_MINHEIGHT = 20,\n DEFAULT_SHAPE_POSITION = 0,\n DEFAULT_CONNECTION_BACKGROUND = \"Yellow\",\n MAX_VALUE = Number.MAX_VALUE,\n MIN_VALUE = -Number.MAX_VALUE,\n ABSOLUTE = \"absolute\",\n TRANSFORMED = \"transformed\",\n ROTATED = \"rotated\",\n TRANSPARENT = \"transparent\",\n WIDTH = \"width\",\n HEIGHT = \"height\",\n X = \"x\",\n Y = \"y\",\n MOUSEWHEEL_NS = \"DOMMouseScroll\" + NS + \" mousewheel\" + NS,\n MOBILE_ZOOM_RATE = 0.05,\n MOBILE_PAN_DISTANCE = 5,\n BUTTON_TEMPLATE = '' +\n '' +\n '#=text#' +\n '',\n CONNECTION_CONTENT_OFFSET = 5;\n\n diagram.DefaultConnectors = [{\n name: TOP\n }, {\n name: BOTTOM\n }, {\n name: LEFT\n }, {\n name: RIGHT\n }, {\n name: AUTO,\n position: function(shape) {\n return shape.getPosition(\"center\");\n }\n }];\n\n var defaultButtons = {\n cancel: {\n text: \"Cancel\",\n imageClass: \"k-i-cancel\",\n className: \"k-diagram-cancel\",\n iconClass: \"k-icon\"\n },\n update: {\n text: \"Update\",\n imageClass: \"k-i-checkmark\",\n className: \"k-diagram-update\",\n iconClass: \"k-icon\"\n }\n };\n\n diagram.shapeDefaults = function(extra) {\n var defaults = {\n type: DEFAULT_SHAPE_TYPE,\n path: \"\",\n autoSize: true,\n visual: null,\n x: DEFAULT_SHAPE_POSITION,\n y: DEFAULT_SHAPE_POSITION,\n minWidth: DEFAULT_SHAPE_MINWIDTH,\n minHeight: DEFAULT_SHAPE_MINHEIGHT,\n width: DEFAULT_SHAPE_WIDTH,\n height: DEFAULT_SHAPE_HEIGHT,\n hover: {},\n editable: {\n connect: true,\n tools: []\n },\n connectors: diagram.DefaultConnectors,\n rotation: {\n angle: 0\n }\n };\n\n Utils.simpleExtend(defaults, extra);\n\n return defaults;\n };\n\n function mwDelta(e) {\n var origEvent = e.originalEvent,\n delta = 0;\n\n if (origEvent.wheelDelta) {\n delta = -origEvent.wheelDelta / 40;\n delta = delta > 0 ? math.ceil(delta) : math.floor(delta);\n } else if (origEvent.detail) {\n delta = origEvent.detail;\n }\n\n return delta;\n }\n\n function isAutoConnector(connector) {\n return connector.options.name.toLowerCase() === AUTO.toLowerCase();\n }\n\n function closestConnector(point, connectors) {\n var minimumDistance = MAXINT, resCtr, connector;\n for (var i = 0; i < connectors.length; i++) {\n connector = connectors[i];\n if (!isAutoConnector(connector)) {\n var dist = point.distanceTo(connector.position());\n if (dist < minimumDistance) {\n minimumDistance = dist;\n resCtr = connector;\n }\n }\n }\n return resCtr;\n }\n\n function indicesOfItems(group, visuals) {\n var i, indices = [], visual;\n var children = group.drawingContainer().children;\n var length = children.length;\n for (i = 0; i < visuals.length; i++) {\n visual = visuals[i];\n for (var j = 0; j < length; j++) {\n if (children[j] == visual.drawingContainer()) {\n indices.push(j);\n break;\n }\n }\n }\n return indices;\n }\n\n var DiagramElement = Observable.extend({\n init: function(options) {\n var that = this;\n that.dataItem = (options || {}).dataItem;\n Observable.fn.init.call(that);\n that.options = deepExtend({ id: diagram.randomId() }, that.options, options);\n that.isSelected = false;\n that.visual = new Group({\n id: that.options.id,\n autoSize: that.options.autoSize\n });\n that.id = that.options.id;\n that._template();\n },\n\n options: {\n hover: {},\n cursor: Cursors.grip,\n content: {\n align: \"center middle\"\n },\n selectable: true,\n serializable: true,\n enable: true\n },\n\n _getCursor: function(point) {\n if (this.adorner) {\n return this.adorner._getCursor(point);\n }\n return this.options.cursor;\n },\n\n visible: function(value) {\n if (isUndefined(value)) {\n return this.visual.visible();\n } else {\n this.visual.visible(value);\n }\n },\n\n bounds: function() {\n },\n\n refresh: function() {\n this.visual.redraw();\n },\n\n position: function(point) {\n this.options.x = point.x;\n this.options.y = point.y;\n this.visual.position(point);\n },\n\n toString: function() {\n return this.options.id;\n },\n\n serialize: function() {\n // the options json object describes the shape perfectly. So this object can serve as shape serialization.\n var json = deepExtend({}, { options: this.options });\n if (this.dataItem) {\n json.dataItem = this.dataItem.toString();\n }\n return json;\n },\n\n _content: function(content) {\n if (content !== undefined$1) {\n var options = this.options;\n\n if (diagram.Utils.isString(content)) {\n options.content.text = content;\n } else {\n deepExtend(options.content, content);\n }\n\n var contentOptions = options.content;\n var contentVisual = this._contentVisual;\n\n if (!contentVisual) {\n this._createContentVisual(contentOptions);\n } else {\n this._updateContentVisual(contentOptions);\n }\n }\n\n return this.options.content.text;\n },\n\n _createContentVisual: function(options) {\n if (options.text) {\n this._contentVisual = new TextBlock(options);\n this._contentVisual._includeInBBox = false;\n this.visual.append(this._contentVisual);\n }\n },\n\n _updateContentVisual: function(options) {\n this._contentVisual.redraw(options);\n },\n\n _hitTest: function(point) {\n var bounds = this.bounds();\n return this.visible() && bounds.contains(point) && this.options.enable;\n },\n\n _template: function() {\n var that = this;\n if (that.options.content.template) {\n var data = that.dataItem || {},\n elementTemplate = kendo.template(that.options.content.template, {\n paramName: \"dataItem\"\n });\n\n that.options.content.text = elementTemplate(data);\n }\n },\n\n _canSelect: function() {\n return this.options.selectable !== false;\n },\n\n toJSON: function() {\n return {\n id: this.options.id\n };\n }\n });\n\n var Connector = Class.extend({\n init: function(shape, options) {\n this.options = deepExtend({}, this.options, options);\n this.connections = [];\n this.shape = shape;\n },\n options: {\n width: 7,\n height: 7,\n fill: {\n color: DEFAULT_CONNECTION_BACKGROUND\n },\n hover: {}\n },\n position: function() {\n if (this.options.position) {\n return this.options.position(this.shape);\n } else {\n return this.shape.getPosition(this.options.name);\n }\n },\n toJSON: function() {\n return {\n shapeId: this.shape.toString(),\n connector: this.options.name\n };\n }\n });\n\n Connector.parse = function(diagram, str) {\n var tempStr = str.split(\":\"),\n id = tempStr[0],\n name = tempStr[1] || AUTO;\n\n for (var i = 0; i < diagram.shapes.length; i++) {\n var shape = diagram.shapes[i];\n if (shape.options.id == id) {\n return shape.getConnector(name.trim());\n }\n }\n };\n\n var Shape = DiagramElement.extend({\n init: function(options, diagram) {\n var that = this;\n DiagramElement.fn.init.call(that, options);\n this.diagram = diagram;\n this.updateOptionsFromModel();\n options = that.options;\n that.connectors = [];\n that.type = options.type;\n that.createShapeVisual();\n that.updateBounds();\n that.content(that.content());\n\n that._createConnectors();\n },\n\n options: diagram.shapeDefaults(),\n\n _setOptionsFromModel: function(model) {\n var modelOptions = filterShapeDataItem(model || this.dataItem);\n this.options = deepExtend({}, this.options, modelOptions);\n\n this.redrawVisual();\n },\n\n updateOptionsFromModel: function(model, field) {\n if (this.diagram && this.diagram._isEditable) {\n var modelOptions = filterShapeDataItem(model || this.dataItem);\n\n if (model && field) {\n if (!dataviz.inArray(field, [\"x\", \"y\", \"width\", \"height\"])) {\n if (this.options.visual) {\n this._redrawVisual();\n } else if (modelOptions.type) {\n this.options = deepExtend({}, this.options, modelOptions);\n this._redrawVisual();\n }\n\n if (this.options.content) {\n this._template();\n this.content(this.options.content);\n }\n } else {\n var bounds = this.bounds();\n bounds[field] = model[field];\n this.bounds(bounds);\n }\n } else {\n this.options = deepExtend({}, this.options, modelOptions);\n }\n }\n },\n\n _redrawVisual: function() {\n this.visual.clear();\n this._contentVisual = null;\n this.options.dataItem = this.dataItem;\n this.createShapeVisual();\n this.updateBounds();\n },\n\n redrawVisual: function() {\n this._redrawVisual();\n if (this.options.content) {\n this._template();\n this.content(this.options.content);\n }\n },\n\n updateModel: function(syncChanges) {\n var diagram = this.diagram;\n if (diagram && diagram._isEditable) {\n var bounds = this._bounds;\n var model = this.dataItem;\n\n if (model) {\n diagram._suspendModelRefresh();\n if (defined(model.x) && bounds.x !== model.x) {\n model.set(\"x\", bounds.x);\n }\n\n if (defined(model.y) && bounds.y !== model.y) {\n model.set(\"y\", bounds.y);\n }\n\n if (defined(model.width) && bounds.width !== model.width) {\n model.set(\"width\", bounds.width);\n }\n\n if (defined(model.height) && bounds.height !== model.height) {\n model.set(\"height\", bounds.height);\n }\n\n this.dataItem = model;\n diagram._resumeModelRefresh();\n\n if (syncChanges) {\n diagram._syncShapeChanges();\n }\n }\n }\n },\n\n updateBounds: function() {\n var bounds = this.visual._measure(true);\n var options = this.options;\n this.bounds(new Rect(options.x, options.y, bounds.width, bounds.height));\n this._rotate();\n this._alignContent();\n },\n\n content: function(content) {\n var result = this._content(content);\n\n this._alignContent();\n\n return result;\n },\n\n _alignContent: function() {\n var contentOptions = this.options.content || {};\n var contentVisual = this._contentVisual;\n if (contentVisual && contentOptions.align) {\n var containerRect = this.visual._measure();\n var aligner = new diagram.RectAlign(containerRect);\n var contentBounds = contentVisual.drawingElement.bbox(null);\n\n var contentRect = new Rect(0, 0, contentBounds.width(), contentBounds.height());\n var alignedBounds = aligner.align(contentRect, contentOptions.align);\n\n contentVisual.position(alignedBounds.topLeft());\n }\n },\n\n _createConnectors: function() {\n var options = this.options,\n length = options.connectors.length,\n connectorDefaults = options.connectorDefaults,\n connector, i;\n\n for (i = 0; i < length; i++) {\n connector = new Connector(\n this, deepExtend({},\n connectorDefaults,\n options.connectors[i]\n )\n );\n this.connectors.push(connector);\n }\n },\n\n bounds: function(value) {\n var bounds;\n\n if (value) {\n if (isString(value)) {\n switch (value) {\n case TRANSFORMED :\n bounds = this._transformedBounds();\n break;\n case ABSOLUTE :\n bounds = this._transformedBounds();\n var pan = this.diagram._pan;\n bounds.x += pan.x;\n bounds.y += pan.y;\n break;\n case ROTATED :\n bounds = this._rotatedBounds();\n break;\n default:\n bounds = this._bounds;\n }\n } else {\n this._setBounds(value);\n this._triggerBoundsChange();\n if (!(this.diagram && this.diagram._layouting)) {\n this.refreshConnections();\n }\n }\n } else {\n bounds = this._bounds;\n }\n\n return bounds;\n },\n\n _setBounds: function(rect) {\n var options = this.options;\n var topLeft = rect.topLeft();\n var x = options.x = topLeft.x;\n var y = options.y = topLeft.y;\n var width = options.width = math.max(rect.width, options.minWidth);\n var height = options.height = math.max(rect.height, options.minHeight);\n\n this._bounds = new Rect(x, y, width, height);\n\n this.visual.redraw({\n x: x,\n y: y,\n width: width,\n height: height\n });\n },\n\n position: function(point) {\n if (point) {\n this.bounds(new Rect(point.x, point.y, this._bounds.width, this._bounds.height));\n } else {\n return this._bounds.topLeft();\n }\n },\n /**\n * Returns a clone of this shape.\n * @returns {Shape}\n */\n clone: function() {\n var json = this.serialize();\n\n json.options.id = diagram.randomId();\n\n if (this.diagram && this.diagram._isEditable && defined(this.dataItem)) {\n json.options.dataItem = cloneDataItem(this.dataItem);\n }\n\n return new Shape(json.options);\n },\n\n select: function(value) {\n var diagram = this.diagram, selected, deselected;\n if (isUndefined(value)) {\n value = true;\n }\n\n if (this._canSelect()) {\n if (this.isSelected != value) {\n selected = [];\n deselected = [];\n this.isSelected = value;\n if (this.isSelected) {\n diagram._selectedItems.push(this);\n selected.push(this);\n } else {\n Utils.remove(diagram._selectedItems, this);\n deselected.push(this);\n }\n\n if (!diagram._internalSelection) {\n diagram._selectionChanged(selected, deselected);\n }\n\n return true;\n }\n }\n },\n\n rotate: function(angle, center, undoable) { // we assume the center is always the center of the shape.\n var rotate = this.visual.rotate();\n if (angle !== undefined$1) {\n if (undoable !== false && this.diagram && this.diagram.undoRedoService && angle !== rotate.angle) {\n this.diagram.undoRedoService.add(\n new diagram.RotateUnit(this.diagram._resizingAdorner, [this], [rotate.angle]), false);\n }\n\n var b = this.bounds(),\n sc = new Point(b.width / 2, b.height / 2),\n deltaAngle,\n newPosition;\n\n if (center) {\n deltaAngle = angle - rotate.angle;\n newPosition = b.center().rotate(center, 360 - deltaAngle).minus(sc);\n this._rotationOffset = this._rotationOffset.plus(newPosition.minus(b.topLeft()));\n this.position(newPosition);\n }\n\n this.visual.rotate(angle, sc);\n this.options.rotation.angle = angle;\n\n if (this.diagram && this.diagram._connectorsAdorner) {\n this.diagram._connectorsAdorner.refresh();\n }\n\n this.refreshConnections();\n\n if (this.diagram) {\n this.diagram.trigger(ITEMROTATE, { item: this });\n }\n }\n\n return rotate;\n },\n\n connections: function(type) { // in, out, undefined = both\n var result = [], i, j, con, cons, ctr;\n\n for (i = 0; i < this.connectors.length; i++) {\n ctr = this.connectors[i];\n cons = ctr.connections;\n for (j = 0, cons; j < cons.length; j++) {\n con = cons[j];\n if (type == \"out\") {\n var source = con.source();\n if (source.shape && source.shape == this) {\n result.push(con);\n }\n } else if (type == \"in\") {\n var target = con.target();\n if (target.shape && target.shape == this) {\n result.push(con);\n }\n } else {\n result.push(con);\n }\n }\n }\n\n return result;\n },\n\n refreshConnections: function() {\n $.each(this.connections(), function() {\n this.refresh();\n });\n },\n /**\n * Gets a connector of this shape either by the connector's supposed name or\n * via a Point in which case the closest connector will be returned.\n * @param nameOrPoint The name of a Connector or a Point.\n * @returns {Connector}\n */\n getConnector: function(nameOrPoint) {\n var i, ctr;\n if (isString(nameOrPoint)) {\n nameOrPoint = nameOrPoint.toLocaleLowerCase();\n for (i = 0; i < this.connectors.length; i++) {\n ctr = this.connectors[i];\n if (ctr.options.name.toLocaleLowerCase() == nameOrPoint) {\n return ctr;\n }\n }\n } else if (nameOrPoint instanceof Point) {\n return closestConnector(nameOrPoint, this.connectors);\n } else {\n return this.connectors.length ? this.connectors[0] : null;\n }\n },\n\n getPosition: function(side) {\n var b = this.bounds(),\n fnName = side.charAt(0).toLowerCase() + side.slice(1);\n\n if (isFunction(b[fnName])) {\n return this._transformPoint(b[fnName]());\n }\n\n return b.center();\n },\n\n redraw: function(options) {\n if (options) {\n var shapeOptions = this.options;\n var boundsChange;\n\n this.shapeVisual.redraw(this._visualOptions(options));\n\n if (this._diffNumericOptions(options, [WIDTH, HEIGHT, X, Y])) {\n this.bounds(new Rect(shapeOptions.x, shapeOptions.y, shapeOptions.width, shapeOptions.height));\n boundsChange = true;\n }\n\n if (options.connectors) {\n shapeOptions.connectors = options.connectors;\n this._updateConnectors();\n }\n\n shapeOptions = deepExtend(shapeOptions, options);\n\n if (options.rotation || boundsChange) {\n this._rotate();\n }\n\n if (shapeOptions.content) {\n this.content(shapeOptions.content);\n }\n }\n },\n\n _updateConnectors: function() {\n var connections = this.connections();\n this.connectors = [];\n this._createConnectors();\n var connection;\n var source;\n var target;\n\n for (var idx = 0; idx < connections.length; idx++) {\n connection = connections[idx];\n source = connection.source();\n target = connection.target();\n if (source.shape && source.shape === this) {\n connection.source(this.getConnector(source.options.name) || null);\n } else if (target.shape && target.shape === this) {\n connection.target(this.getConnector(target.options.name) || null);\n }\n connection.updateModel();\n }\n },\n\n _diffNumericOptions: diagram.diffNumericOptions,\n\n _visualOptions: function(options) {\n return {\n data: options.path,\n source: options.source,\n hover: options.hover,\n fill: options.fill,\n stroke: options.stroke\n };\n },\n\n _triggerBoundsChange: function() {\n if (this.diagram) {\n this.diagram.trigger(ITEMBOUNDSCHANGE, { item: this, bounds: this._bounds.clone() }); // the trigger modifies the arguments internally.\n }\n },\n\n _transformPoint: function(point) {\n var rotate = this.rotate(),\n bounds = this.bounds(),\n tl = bounds.topLeft();\n\n if (rotate.angle) {\n point.rotate(rotate.center().plus(tl), 360 - rotate.angle);\n }\n\n return point;\n },\n\n _transformedBounds: function() {\n var bounds = this.bounds(),\n tl = bounds.topLeft(),\n br = bounds.bottomRight();\n\n return Rect.fromPoints(this.diagram.modelToView(tl), this.diagram.modelToView(br));\n },\n\n _rotatedBounds: function() {\n var bounds = this.bounds().rotatedBounds(this.rotate().angle),\n tl = bounds.topLeft(),\n br = bounds.bottomRight();\n\n return Rect.fromPoints(tl, br);\n },\n\n _rotate: function() {\n var rotation = this.options.rotation;\n\n if (rotation && rotation.angle) {\n this.rotate(rotation.angle);\n }\n\n this._rotationOffset = new Point();\n },\n\n _hover: function(value) {\n var options = this.options,\n hover = options.hover,\n stroke = options.stroke,\n fill = options.fill;\n\n if (value && isDefined(hover.stroke)) {\n stroke = deepExtend({}, stroke, hover.stroke);\n }\n\n if (value && isDefined(hover.fill)) {\n fill = hover.fill;\n }\n\n this.shapeVisual.redraw({\n stroke: stroke,\n fill: fill\n });\n\n if (options.editable && options.editable.connect) {\n this.diagram._showConnectors(this, value);\n }\n },\n\n _hitTest: function(value) {\n if (this.visible()) {\n var bounds = this.bounds(), rotatedPoint,\n angle = this.rotate().angle;\n\n if (value.isEmpty && !value.isEmpty()) { // rect selection\n return Intersect.rects(value, bounds, angle ? angle : 0);\n } else { // point\n rotatedPoint = value.clone().rotate(bounds.center(), angle); // cloning is important because rotate modifies the point inline.\n if (bounds.contains(rotatedPoint)) {\n return this;\n }\n }\n }\n },\n\n toJSON: function() {\n return {\n shapeId: this.options.id\n };\n },\n\n createShapeVisual: function() {\n var options = this.options;\n var visualOptions = this._visualOptions(options);\n var visualTemplate = options.visual;\n var type = (options.type + \"\").toLocaleLowerCase();\n var shapeVisual;\n\n visualOptions.width = options.width;\n visualOptions.height = options.height;\n\n if (isFunction(visualTemplate)) { // custom template\n shapeVisual = visualTemplate.call(this, options);\n } else if (visualOptions.data) {\n shapeVisual = new Path(visualOptions);\n translateToOrigin(shapeVisual);\n } else if (type == \"rectangle\") {\n shapeVisual = new Rectangle(visualOptions);\n } else if (type == \"circle\") {\n shapeVisual = new Circle(visualOptions);\n } else if (type == \"text\") {\n shapeVisual = new TextBlock(visualOptions);\n } else if (type == \"image\") {\n shapeVisual = new Image(visualOptions);\n } else {\n shapeVisual = new Path(visualOptions);\n }\n\n this.shapeVisual = shapeVisual;\n this.visual.append(this.shapeVisual);\n }\n });\n\n /**\n * The visual link between two Shapes through the intermediate of Connectors.\n */\n var Connection = DiagramElement.extend({\n init: function(from, to, options) {\n var that = this;\n DiagramElement.fn.init.call(that, options);\n this.updateOptionsFromModel();\n this._initRouter();\n that.path = new diagram.Polyline(that.options);\n that.path.fill(TRANSPARENT);\n that.visual.append(that.path);\n that._sourcePoint = that._targetPoint = new Point();\n that._setSource(from);\n that._setTarget(to);\n that.content(that.options.content);\n that.definers = [];\n if (defined(options) && options.points) {\n that.points(options.points);\n }\n },\n\n options: {\n hover: {\n stroke: {}\n },\n startCap: NONE,\n endCap: NONE,\n points: [],\n selectable: true,\n fromConnector: AUTO,\n toConnector: AUTO\n },\n\n _setOptionsFromModel: function(model) {\n this.updateOptionsFromModel(model || this.dataItem);\n },\n\n updateOptionsFromModel: function(model) {\n if (this.diagram && this.diagram._isEditable) {\n var dataMap = this.diagram._dataMap;\n var options = filterConnectionDataItem(model || this.dataItem);\n\n if (model) {\n if (defined(options.from)) {\n var from = dataMap[options.from];\n if (from && defined(options.fromConnector)) {\n from = from.getConnector(options.fromConnector);\n }\n this.source(from);\n } else if (defined(options.fromX) && defined(options.fromY)) {\n this.source(new Point(options.fromX, options.fromY));\n }\n\n if (defined(options.to)) {\n var to = dataMap[options.to];\n if (to && defined(options.toConnector)) {\n to = to.getConnector(options.toConnector);\n }\n this.target(to);\n } else if (defined(options.toX) && defined(options.toY)) {\n this.target(new Point(options.toX, options.toY));\n }\n\n if (defined(options.type) && this.type() !== options.type) {\n this.points([]);\n this.type(options.type);\n }\n\n this.dataItem = model;\n\n this._template();\n this.redraw(this.options);\n } else {\n this.options = deepExtend({}, options, this.options);\n }\n }\n },\n\n updateModel: function(syncChanges) {\n if (this.diagram && this.diagram._isEditable) {\n if (this.diagram.connectionsDataSource) {\n var model = this.diagram.connectionsDataSource.getByUid(this.dataItem.uid);\n\n if (model) {\n this.diagram._suspendModelRefresh();\n if (defined(this.options.fromX) && this.options.fromX !== null) {\n clearField(\"from\", model);\n clearField(\"fromConnector\", model);\n model.set(\"fromX\", this.options.fromX);\n model.set(\"fromY\", this.options.fromY);\n } else {\n model.set(\"from\", this.options.from);\n if (defined(model.fromConnector)) {\n model.set(\"fromConnector\", this.sourceConnector ? this.sourceConnector.options.name : null);\n }\n clearField(\"fromX\", model);\n clearField(\"fromY\", model);\n }\n\n if (defined(this.options.toX) && this.options.toX !== null) {\n clearField(\"to\", model);\n clearField(\"toConnector\", model);\n model.set(\"toX\", this.options.toX);\n model.set(\"toY\", this.options.toY);\n } else {\n model.set(\"to\", this.options.to);\n if (defined(model.toConnector)) {\n model.set(\"toConnector\", this.targetConnector ? this.targetConnector.options.name : null);\n }\n clearField(\"toX\", model);\n clearField(\"toY\", model);\n }\n\n if (defined(this.options.type) && defined(model.type)) {\n model.set(\"type\", this.options.type);\n }\n\n this.dataItem = model;\n this.diagram._resumeModelRefresh();\n\n if (syncChanges) {\n this.diagram._syncConnectionChanges();\n }\n }\n }\n }\n },\n\n /**\n * Gets the Point where the source of the connection resides.\n * If the endpoint in Auto-connector the location of the resolved connector will be returned.\n * If the endpoint is floating the location of the endpoint is returned.\n */\n sourcePoint: function() {\n return this._resolvedSourceConnector ? this._resolvedSourceConnector.position() : this._sourcePoint;\n },\n\n _setSource: function(source) {\n var shapeSource = source instanceof Shape;\n var defaultConnector = this.options.fromConnector || AUTO;\n var dataItem;\n if (shapeSource && !source.getConnector(defaultConnector)) {\n return;\n }\n\n if (source !== undefined$1) {\n this.from = source;\n }\n\n this._removeFromSourceConnector();\n\n if (source === null) { // detach\n if (this.sourceConnector) {\n this._sourcePoint = (this._resolvedSourceConnector || this.sourceConnector).position();\n this._clearSourceConnector();\n this._setFromOptions(null, this._sourcePoint);\n }\n } else if (source instanceof Connector) {\n dataItem = source.shape.dataItem;\n if (dataItem) {\n this._setFromOptions(dataItem.id);\n }\n this.sourceConnector = source;\n this.sourceConnector.connections.push(this);\n } else if (source instanceof Point) {\n this._setFromOptions(null, source);\n this._sourcePoint = source;\n if (this.sourceConnector) {\n this._clearSourceConnector();\n }\n\n } else if (shapeSource) {\n dataItem = source.dataItem;\n if (dataItem) {\n this._setFromOptions(dataItem.id);\n }\n\n this.sourceConnector = source.getConnector(defaultConnector);\n this.sourceConnector.connections.push(this);\n }\n },\n\n source: function(source, undoable) {\n if (isDefined(source)) {\n if (undoable && this.diagram) {\n this.diagram.undoRedoService.addCompositeItem(new diagram.ConnectionEditUnit(this, source));\n }\n this._setSource(source);\n this.refresh();\n }\n return this.sourceConnector ? this.sourceConnector : this._sourcePoint;\n },\n\n _setFromOptions: function(from, fromPoint) {\n this.options.from = from;\n if (fromPoint) {\n this.options.fromX = fromPoint.x;\n this.options.fromY = fromPoint.y;\n } else {\n this.options.fromX = null;\n this.options.fromY = null;\n }\n },\n\n /**\n * Gets or sets the PathDefiner of the sourcePoint.\n * The left part of this definer is always null since it defines the source tangent.\n * @param value\n * @returns {*}\n */\n sourceDefiner: function(value) {\n if (value) {\n if (value instanceof diagram.PathDefiner) {\n value.left = null;\n this._sourceDefiner = value;\n this.source(value.point); // refresh implicit here\n } else {\n throw \"The sourceDefiner needs to be a PathDefiner.\";\n }\n } else {\n if (!this._sourceDefiner) {\n this._sourceDefiner = new diagram.PathDefiner(this.sourcePoint(), null, null);\n }\n return this._sourceDefiner;\n }\n },\n\n /**\n * Gets the Point where the target of the connection resides.\n */\n targetPoint: function() {\n return this._resolvedTargetConnector ? this._resolvedTargetConnector.position() : this._targetPoint;\n },\n\n _setTarget: function(target) {\n var shapeTarget = target instanceof Shape;\n var defaultConnector = this.options.toConnector || AUTO;\n var dataItem;\n\n if (shapeTarget && !target.getConnector(defaultConnector)) {\n return;\n }\n\n if (target !== undefined$1) {\n this.to = target;\n }\n\n this._removeFromTargetConnector();\n\n if (target === null) { // detach\n if (this.targetConnector) {\n this._targetPoint = (this._resolvedTargetConnector || this.targetConnector).position();\n this._clearTargetConnector();\n this._setToOptions(null, this._targetPoint);\n }\n } else if (target instanceof Connector) {\n dataItem = target.shape.dataItem;\n if (dataItem) {\n this._setToOptions(dataItem.id);\n }\n this.targetConnector = target;\n this.targetConnector.connections.push(this);\n } else if (target instanceof Point) {\n this._setToOptions(null, target);\n this._targetPoint = target;\n if (this.targetConnector) {\n this._clearTargetConnector();\n }\n } else if (shapeTarget) {\n dataItem = target.dataItem;\n if (dataItem) {\n this._setToOptions(dataItem.id);\n }\n this.targetConnector = target.getConnector(defaultConnector);\n this.targetConnector.connections.push(this);\n }\n },\n\n target: function(target, undoable) {\n if (isDefined(target)) {\n if (undoable && this.diagram) {\n this.diagram.undoRedoService.addCompositeItem(new diagram.ConnectionEditUnit(this, undefined$1, target));\n }\n this._setTarget(target);\n\n this.refresh();\n }\n return this.targetConnector ? this.targetConnector : this._targetPoint;\n },\n\n _setToOptions: function(to, toPoint) {\n this.options.to = to;\n if (toPoint) {\n this.options.toX = toPoint.x;\n this.options.toY = toPoint.y;\n } else {\n this.options.toX = null;\n this.options.toY = null;\n }\n },\n\n /**\n * Gets or sets the PathDefiner of the targetPoint.\n * The right part of this definer is always null since it defines the target tangent.\n * @param value\n * @returns {*}\n */\n targetDefiner: function(value) {\n if (value) {\n if (value instanceof diagram.PathDefiner) {\n value.right = null;\n this._targetDefiner = value;\n this.target(value.point); // refresh implicit here\n } else {\n throw \"The sourceDefiner needs to be a PathDefiner.\";\n }\n } else {\n if (!this._targetDefiner) {\n this._targetDefiner = new diagram.PathDefiner(this.targetPoint(), null, null);\n }\n return this._targetDefiner;\n }\n },\n\n _updateConnectors: function() {\n this._updateConnector(this.source(), \"source\");\n this._updateConnector(this.target(), \"target\");\n },\n\n _updateConnector: function(instance, name) {\n var that = this;\n var diagram = that.diagram;\n if (instance instanceof Connector && !diagram.getShapeById(instance.shape.id)) {\n var dataItem = instance.shape.dataItem;\n var connectorName = instance.options.name;\n var setNewTarget = function() {\n var shape = diagram._dataMap[dataItem.id];\n instance = shape.getConnector(connectorName);\n that[name](instance, false);\n that.updateModel();\n };\n if (diagram._dataMap[dataItem.id]) {\n setNewTarget();\n } else {\n var inactiveItem = diagram._inactiveShapeItems.getByUid(dataItem.uid);\n if (inactiveItem) {\n diagram._deferredConnectionUpdates.push(inactiveItem.onActivate(setNewTarget));\n }\n }\n } else {\n that[name](instance, false);\n }\n },\n\n content: function(content) {\n var result = this._content(content);\n if (defined(content)) {\n this._alignContent();\n }\n return result;\n },\n\n _createContentVisual: function(options) {\n var visual;\n if (isFunction(options.visual)) {\n visual = options.visual.call(this, options);\n } else if (options.text) {\n visual = new TextBlock(options);\n }\n\n if (visual) {\n this._contentVisual = visual;\n visual._includeInBBox = false;\n this.visual.append(visual);\n }\n\n return visual;\n },\n\n _updateContentVisual: function(options) {\n if (isFunction(options.visual)) {\n this.visual.remove(this._contentVisual);\n this._createContentVisual(options);\n } else {\n this._contentVisual.redraw(options);\n }\n },\n\n _alignContent: function() {\n if (this._contentVisual) {\n var offset = CONNECTION_CONTENT_OFFSET;\n var points = this.allPoints();\n var endIdx = math.floor(points.length / 2);\n var startIdx = endIdx - 1;\n\n while (startIdx > 0 && points[startIdx].equals(points[endIdx])) {\n startIdx--;\n endIdx++;\n }\n\n var endPoint = points[endIdx];\n var startPoint = points[startIdx];\n\n var boundingBox = this._contentVisual._measure();\n var width = boundingBox.width;\n var height = boundingBox.height;\n var alignToPath = points.length % 2 === 0;\n var distance = startPoint.distanceTo(endPoint);\n\n if (alignToPath && points.length > 2 && distance > 0 &&\n ((startPoint.y === endPoint.y && distance < width) || (startPoint.x === endPoint.x && distance < height))) {\n alignToPath = false;\n offset = 0;\n }\n\n var point;\n\n if (alignToPath) {\n var angle = draw.util.deg(math.atan2(endPoint.y - startPoint.y, endPoint.x - startPoint.x));\n point = new Point((endPoint.x - startPoint.x) / 2 + startPoint.x, (endPoint.y - startPoint.y) / 2 + startPoint.y);\n\n if (math.abs(angle) === 90) {\n point.x += offset;\n point.y -= height / 2;\n } else if (angle % 180 === 0) {\n point.x -= width / 2;\n point.y -= height + offset;\n } else if (angle < -90 || (0 < angle && angle < 90)) {\n point.y -= height;\n } else if (angle < 0 || angle > 90) {\n point.x -= width;\n point.y -= height;\n }\n } else {\n var midIdx = math.floor(points.length / 2);\n point = points[midIdx].clone();\n startPoint = points[midIdx - 1];\n endPoint = points[midIdx + 1];\n\n var offsetX = startPoint.x <= point.x && endPoint.x <= point.x ? offset : -boundingBox.width - offset;\n var offsetY = startPoint.y <= point.y && endPoint.y <= point.y ? offset : -boundingBox.height - offset;\n\n point.x += offsetX;\n point.y += offsetY;\n }\n\n this._contentVisual.position(point);\n }\n },\n\n /**\n * Selects or unselects this connections.\n * @param value True to select, false to unselect.\n */\n select: function(value) {\n var diagram = this.diagram, selected, deselected;\n if (this._canSelect()) {\n if (this.isSelected !== value) {\n this.isSelected = value;\n selected = [];\n deselected = [];\n if (this.isSelected) {\n this.adorner = new ConnectionEditAdorner(this, this.options.selection);\n diagram._adorn(this.adorner, true);\n diagram._selectedItems.push(this);\n selected.push(this);\n } else {\n if (this.adorner) {\n diagram._adorn(this.adorner, false);\n Utils.remove(diagram._selectedItems, this);\n this.adorner = undefined$1;\n deselected.push(this);\n }\n }\n\n if (this.adorner) {\n this.adorner.refresh();\n }\n\n if (!diagram._internalSelection) {\n diagram._selectionChanged(selected, deselected);\n }\n return true;\n }\n }\n },\n /**\n * Gets or sets the bounds of this connection.\n * @param value A Rect object.\n * @remark This is automatically set in the refresh().\n * @returns {Rect}\n */\n bounds: function(value) {\n if (value && !isString(value)) {\n this._bounds = value;\n } else {\n return this._bounds;\n }\n },\n /**\n * Gets or sets the connection type (see ConnectionType enumeration).\n * @param value A ConnectionType value.\n * @returns {ConnectionType}\n */\n type: function(value) {\n var options = this.options;\n if (value) {\n if (value !== options.type) {\n options.type = value;\n this._initRouter();\n this.refresh();\n }\n } else {\n return options.type;\n }\n },\n\n _initRouter: function() {\n var type = (this.options.type || \"\").toLowerCase();\n if (type == CASCADING) {\n this._router = new CascadingRouter(this);\n } else {\n this._router = new PolylineRouter(this);\n }\n },\n /**\n * Gets or sets the collection of *intermediate* points.\n * The 'allPoints()' property will return all the points.\n * The 'definers' property returns the definers of the intermediate points.\n * The 'sourceDefiner' and 'targetDefiner' return the definers of the endpoints.\n * @param value\n */\n points: function(value) {\n if (value) {\n this.definers = [];\n for (var i = 0; i < value.length; i++) {\n var definition = value[i];\n if (definition instanceof diagram.Point) {\n this.definers.push(new diagram.PathDefiner(definition));\n } else if (definition.hasOwnProperty(\"x\") && definition.hasOwnProperty(\"y\")) { // e.g. Clipboard does not preserve the Point definition and tunred into an Object\n this.definers.push(new diagram.PathDefiner(new Point(definition.x, definition.y)));\n } else {\n throw \"A Connection point needs to be a Point or an object with x and y properties.\";\n }\n }\n\n } else {\n var pts = [];\n if (isDefined(this.definers)) {\n for (var k = 0; k < this.definers.length; k++) {\n pts.push(this.definers[k].point);\n }\n }\n return pts;\n }\n },\n /**\n * Gets all the points of this connection. This is the combination of the sourcePoint, the points and the targetPoint.\n * @returns {Array}\n */\n allPoints: function() {\n var pts = [this.sourcePoint()];\n if (this.definers) {\n for (var k = 0; k < this.definers.length; k++) {\n pts.push(this.definers[k].point);\n }\n }\n pts.push(this.targetPoint());\n return pts;\n },\n\n refresh: function() {\n this._resolveConnectors();\n this._refreshPath();\n this._alignContent();\n\n if (this.adorner) {\n this.adorner.refresh();\n }\n },\n\n _resolveConnectors: function() {\n var connection = this,\n sourcePoint, targetPoint,\n sourceConnectors, targetConnectors,\n source = connection.source(),\n target = connection.target();\n\n if (source instanceof Point) {\n sourcePoint = source;\n } else if (source instanceof Connector) {\n if (isAutoConnector(source)) {\n sourceConnectors = source.shape.connectors;\n } else {\n sourceConnectors = [source];\n }\n }\n\n if (target instanceof Point) {\n targetPoint = target;\n } else if (target instanceof Connector) {\n if (isAutoConnector(target)) {\n targetConnectors = target.shape.connectors;\n } else {\n targetConnectors = [target];\n }\n }\n\n if (sourcePoint) {\n if (targetConnectors) {\n connection._resolvedTargetConnector = closestConnector(sourcePoint, targetConnectors);\n }\n } else if (sourceConnectors) {\n if (targetPoint) {\n connection._resolvedSourceConnector = closestConnector(targetPoint, sourceConnectors);\n } else if (targetConnectors) {\n this._resolveAutoConnectors(sourceConnectors, targetConnectors);\n }\n }\n },\n\n _resolveAutoConnectors: function(sourceConnectors, targetConnectors) {\n var minNonConflict = MAXINT;\n var minDist = MAXINT;\n var minNonConflictSource, minNonConflictTarget;\n var sourcePoint, targetPoint;\n var minSource, minTarget;\n var sourceConnector, targetConnector;\n var sourceIdx, targetIdx;\n var dist;\n\n for (sourceIdx = 0; sourceIdx < sourceConnectors.length; sourceIdx++) {\n sourceConnector = sourceConnectors[sourceIdx];\n if (!isAutoConnector(sourceConnector)) {\n sourcePoint = sourceConnector.position();\n\n for (targetIdx = 0; targetIdx < targetConnectors.length; targetIdx++) {\n targetConnector = targetConnectors[targetIdx];\n if (!isAutoConnector(targetConnector)) {\n targetPoint = targetConnector.position();\n dist = math.round(sourcePoint.distanceTo(targetPoint));\n\n if (dist < minNonConflict && this.diagram && this._testRoutePoints(sourcePoint, targetPoint, sourceConnector, targetConnector)) {\n minNonConflict = dist;\n minNonConflictSource = sourceConnector;\n minNonConflictTarget = targetConnector;\n }\n\n if (dist < minDist) {\n minSource = sourceConnector;\n minTarget = targetConnector;\n minDist = dist;\n }\n }\n }\n }\n }\n\n if (minNonConflictSource) {\n minSource = minNonConflictSource;\n minTarget = minNonConflictTarget;\n }\n\n this._resolvedSourceConnector = minSource;\n this._resolvedTargetConnector = minTarget;\n },\n\n _testRoutePoints: function(sourcePoint, targetPoint, sourceConnector, targetConnector) {\n var router = this._router;\n var passRoute = true;\n if (router instanceof CascadingRouter) {\n var points = router.routePoints(sourcePoint, targetPoint, sourceConnector, targetConnector),\n start, end,\n rect, exclude;\n\n exclude = this._getRouteExclude(sourcePoint, targetPoint, sourceConnector.shape, targetConnector.shape);\n points.unshift(sourcePoint);\n points.push(targetPoint);\n\n\n for (var idx = 1; idx < points.length; idx++) {\n start = points[idx - 1];\n end = points[idx];\n rect = new Rect(math.min(start.x, end.x), math.min(start.y, end.y),\n math.abs(start.x - end.x), math.abs(start.y - end.y));\n if (rect.width > 0) {\n rect.x++;\n rect.width -= 2;\n }\n if (rect.height > 0) {\n rect.y++;\n rect.height -= 2;\n }\n\n if (!rect.isEmpty() && this.diagram._shapesQuadTree.hitTestRect(rect, exclude)) {\n passRoute = false;\n break;\n }\n }\n }\n return passRoute;\n },\n\n _getRouteExclude: function(sourcePoint, targetPoint, sourceShape, targetShape) {\n var exclude = [];\n if (this._isPointInsideShape(sourcePoint, sourceShape)) {\n exclude.push(sourceShape);\n }\n if (this._isPointInsideShape(targetPoint, targetShape)) {\n exclude.push(targetShape);\n }\n return exclude;\n },\n\n _isPointInsideShape: function(point, shape) {\n var bounds = shape.bounds(), rotatedPoint,\n angle = shape.rotate().angle,\n pointX, pointY,\n boundsX = bounds.x,\n boundsY = bounds.y;\n\n rotatedPoint = point.clone().rotate(bounds.center(), angle);\n pointX = rotatedPoint.x;\n pointY = rotatedPoint.y;\n return pointX > boundsX && pointX < (boundsX + bounds.width) && pointY > boundsY && pointY < (boundsY + bounds.height);\n },\n\n redraw: function(options) {\n if (options) {\n this.options = deepExtend({}, this.options, options);\n\n var points = this.options.points;\n\n if (defined(points) && points.length > 0) {\n this.points(points);\n this._refreshPath();\n }\n\n if ((options && options.content) || options.text) {\n this.content(options.content);\n }\n\n this.path.redraw({\n fill: options.fill,\n stroke: options.stroke,\n startCap: options.startCap,\n endCap: options.endCap\n });\n }\n },\n /**\n * Returns a clone of this connection.\n * @returns {Connection}\n */\n clone: function() {\n var json = this.serialize();\n\n if (this.diagram && this.diagram._isEditable && defined(this.dataItem)) {\n json.options.dataItem = cloneDataItem(this.dataItem);\n }\n\n return new Connection(this.from, this.to, json.options);\n },\n /**\n * Returns a serialized connection in json format. Consist of the options and the dataItem.\n * @returns {Connection}\n */\n serialize: function() {\n var from = this.from.toJSON ? this.from.toJSON : this.from.toString(),\n to = this.to.toJSON ? this.to.toJSON : this.to.toString();\n\n var json = deepExtend({}, {\n options: this.options,\n from: from,\n to: to\n });\n\n if (defined(this.dataItem)) {\n json.dataItem = this.dataItem.toString();\n }\n\n json.options.points = this.points();\n return json;\n },\n\n /**\n * Returns whether the given Point or Rect hits this connection.\n * @param value\n * @returns {Connection}\n * @private\n */\n _hitTest: function(value) {\n if (this.visible()) {\n var p = new Point(value.x, value.y), from = this.sourcePoint(), to = this.targetPoint();\n if (value.isEmpty && !value.isEmpty() && value.contains(from) && value.contains(to)) {\n return this;\n }\n if (this._router.hitTest(p)) {\n return this;\n }\n }\n },\n\n _hover: function(value) {\n var color = (this.options.stroke || {}).color;\n\n if (value && isDefined(this.options.hover.stroke.color)) {\n color = this.options.hover.stroke.color;\n }\n\n this.path.redraw({\n stroke: {\n color: color\n }\n });\n },\n\n _refreshPath: function() {\n if (!defined(this.path)) {\n return;\n }\n this._drawPath();\n this.bounds(this._router.getBounds());\n },\n\n _drawPath: function() {\n if (this._router) {\n this._router.route(); // sets the intermediate points\n }\n var source = this.sourcePoint();\n var target = this.targetPoint();\n var points = this.points();\n\n this.path.redraw({\n points: [source].concat(points, [target])\n });\n },\n\n _clearSourceConnector: function() {\n this.sourceConnector = undefined$1;\n this._resolvedSourceConnector = undefined$1;\n },\n\n _clearTargetConnector: function() {\n this.targetConnector = undefined$1;\n this._resolvedTargetConnector = undefined$1;\n },\n\n _removeFromSourceConnector: function() {\n if (this.sourceConnector) {\n Utils.remove(this.sourceConnector.connections, this);\n }\n },\n\n _removeFromTargetConnector: function() {\n if (this.targetConnector) {\n Utils.remove(this.targetConnector.connections, this);\n }\n },\n\n toJSON: function() {\n var connection = this;\n var from, to, point;\n if (connection.from && connection.from.toJSON) {\n from = connection.from.toJSON();\n } else {\n point = connection._sourcePoint;\n from = {\n x: point.x,\n y: point.y\n };\n }\n\n if (connection.to && connection.to.toJSON) {\n to = connection.to.toJSON();\n } else {\n point = connection._targetPoint;\n to = {\n x: point.x,\n y: point.y\n };\n }\n\n return {\n from: from,\n to: to\n };\n }\n });\n\n var Diagram = Widget.extend({\n init: function(element, userOptions) {\n var that = this;\n\n kendo.destroy(element);\n Widget.fn.init.call(that, element, userOptions);\n\n that._initTheme();\n\n that._initElements();\n that._extendLayoutOptions(that.options);\n that._initDefaults(userOptions);\n that._interactionDefaults();\n\n that._initCanvas();\n\n that.mainLayer = new Group({\n id: \"main-layer\"\n });\n that.canvas.append(that.mainLayer);\n\n that._shapesQuadTree = new ShapesQuadTree(that);\n\n that._pan = new Point();\n that._adorners = [];\n that.adornerLayer = new Group({\n id: \"adorner-layer\"\n });\n that.canvas.append(that.adornerLayer);\n\n that._createHandlers();\n\n that._initialize();\n\n that._resizingAdorner = new ResizingAdorner(that, { editable: that.options.editable });\n that._connectorsAdorner = new ConnectorsAdorner(that);\n\n that._adorn(that._resizingAdorner, true);\n that._adorn(that._connectorsAdorner, true);\n\n that.selector = new Selector(that);\n // TODO: We may consider using real Clipboard API once is supported by the standard.\n that._clipboard = [];\n\n that.pauseMouseHandlers = false;\n\n that._fetchFreshData();\n\n that._createGlobalToolBar();\n\n that._createOptionElements();\n\n that.zoom(that.options.zoom);\n\n that.canvas.draw();\n },\n\n options: {\n name: \"Diagram\",\n theme: \"default\",\n layout: \"\",\n zoomRate: 0.1,\n zoom: 1,\n zoomMin: 0,\n zoomMax: 2,\n dataSource: {},\n draggable: true,\n template: \"\",\n autoBind: true,\n editable: {\n rotate: {},\n resize: {},\n text: true,\n tools: [],\n drag: {\n snap: {\n size: 10,\n angle: 10\n }\n },\n remove: true\n },\n pannable: {},\n selectable: {\n key: \"none\"\n },\n tooltip: { enabled: true, format: \"{0}\" },\n copy: {\n enabled: true,\n offsetX: 20,\n offsetY: 20\n },\n shapeDefaults: diagram.shapeDefaults({ undoable: true }),\n connectionDefaults: {\n editable: {\n tools: []\n },\n type: CASCADING\n },\n shapes: [],\n connections: []\n },\n\n events: [\n ZOOM_END,\n ZOOM_START,\n PAN, SELECT,\n ITEMROTATE,\n ITEMBOUNDSCHANGE,\n CHANGE,\n CLICK,\n MOUSE_ENTER,\n MOUSE_LEAVE,\n \"toolBarClick\",\n \"save\",\n \"cancel\",\n \"edit\",\n \"remove\",\n \"add\",\n \"dataBound\",\n DRAG_START,\n DRAG,\n DRAG_END\n ],\n\n items: function() {\n return $();\n },\n\n _createGlobalToolBar: function() {\n var editable = this.options.editable;\n if (editable) {\n var tools = editable.tools;\n if (this._isEditable && tools !== false && (!tools || tools.length === 0)) {\n tools = [\"createShape\", \"undo\", \"redo\", \"rotateClockwise\", \"rotateAnticlockwise\"];\n }\n\n if (tools && tools.length) {\n this.toolBar = new DiagramToolBar(this, {\n tools: tools || {},\n click: this._toolBarClick.bind(this),\n modal: false\n });\n\n this.toolBar.element.css({\n textAlign: \"left\"\n });\n\n this.element.prepend(this.toolBar.element);\n this._resize();\n }\n }\n },\n\n createShape: function() {\n if ((this.editor && this.editor.end()) || !this.editor) {\n var dataSource = this.dataSource;\n var view = dataSource.view() || [];\n var index = view.length;\n var model = createModel(dataSource, {});\n var shape = this._createShape(model, {});\n\n if (!this.trigger(\"add\", { shape: shape })) {\n dataSource.insert(index, model);\n var inactiveItem = this._inactiveShapeItems.getByUid(model.uid);\n inactiveItem.element = shape;\n this.edit(shape);\n }\n }\n },\n\n _createShape: function(dataItem, options) {\n options = deepExtend({}, this.options.shapeDefaults, options);\n options.dataItem = dataItem;\n var shape = new Shape(options, this);\n return shape;\n },\n\n createConnection: function() {\n if (((this.editor && this.editor.end()) || !this.editor)) {\n var connectionsDataSource = this.connectionsDataSource;\n var view = connectionsDataSource.view() || [];\n var index = view.length;\n var model = createModel(connectionsDataSource, {});\n var connection = this._createConnection(model);\n if (!this.trigger(\"add\", { connection: connection })) {\n this._connectionsDataMap[model.uid] = connection;\n connectionsDataSource.insert(index, model);\n this.addConnection(connection, false);\n this.edit(connection);\n }\n }\n },\n\n _createConnection: function(dataItem, source, target) {\n var options = deepExtend({}, this.options.connectionDefaults);\n options.dataItem = dataItem;\n\n var connection = new Connection(source || new Point(), target || new Point(), options);\n\n return connection;\n },\n\n editModel: function(dataItem, editorType) {\n this.cancelEdit();\n var editors, template;\n var editable = this.options.editable;\n\n if (editorType == \"shape\") {\n editors = editable.shapeEditors;\n template = editable.shapeTemplate;\n } else if (editorType == \"connection\") {\n var connectionSelectorHandler = connectionSelector.bind(this);\n editors = deepExtend({}, { from: connectionSelectorHandler, to: connectionSelectorHandler }, editable.connectionEditors);\n template = editable.connectionTemplate;\n } else {\n return;\n }\n\n this.editor = new PopupEditor(this.element, {\n update: this._update.bind(this),\n cancel: this._cancel.bind(this),\n model: dataItem,\n type: editorType,\n target: this,\n editors: editors,\n template: template\n });\n\n this.trigger(\"edit\", this._editArgs());\n },\n\n edit: function(item) {\n if (item.dataItem) {\n var editorType = item instanceof Shape ? \"shape\" : \"connection\";\n this.editModel(item.dataItem, editorType);\n }\n },\n\n cancelEdit: function() {\n if (this.editor) {\n this._getEditDataSource().cancelChanges(this.editor.model);\n\n this._destroyEditor();\n }\n },\n\n saveEdit: function() {\n if (this.editor && this.editor.end() &&\n !this.trigger(\"save\", this._editArgs())) {\n this._getEditDataSource().sync();\n }\n },\n\n _update: function() {\n if (this.editor && this.editor.end() &&\n !this.trigger(\"save\", this._editArgs())) {\n this._getEditDataSource().sync();\n this._destroyEditor();\n }\n },\n\n _cancel: function() {\n if (this.editor && !this.trigger(\"cancel\", this._editArgs())) {\n var model = this.editor.model;\n this._getEditDataSource().cancelChanges(model);\n var element = this._connectionsDataMap[model.uid] || this._dataMap[model.id];\n if (element) {\n element._setOptionsFromModel(model);\n }\n this._destroyEditor();\n }\n },\n\n _getEditDataSource: function() {\n return this.editor.options.type === \"shape\" ? this.dataSource : this.connectionsDataSource;\n },\n\n _editArgs: function() {\n var result = { container: this.editor.wrapper };\n result[this.editor.options.type] = this.editor.model;\n return result;\n },\n\n _destroyEditor: function() {\n if (this.editor) {\n this.editor.close();\n this.editor = null;\n }\n },\n\n _initElements: function() {\n this.wrapper = this.element.empty()\n .css(\"position\", \"relative\")\n .attr(\"tabindex\", 0)\n .addClass(\"k-widget k-diagram\");\n\n this.scrollable = $(\"
\").appendTo(this.element);\n },\n\n _initDefaults: function(userOptions) {\n var options = this.options;\n var editable = options.editable;\n var shapeDefaults = options.shapeDefaults;\n var connectionDefaults = options.connectionDefaults;\n var userShapeDefaults = (userOptions || {}).shapeDefaults;\n if (editable === false) {\n shapeDefaults.editable = false;\n connectionDefaults.editable = false;\n } else {\n copyDefaultOptions(editable, shapeDefaults.editable, [\"drag\", \"remove\", \"connect\"]);\n copyDefaultOptions(editable, connectionDefaults.editable, [\"drag\", \"remove\"]);\n }\n\n if (userShapeDefaults && userShapeDefaults.connectors) {\n options.shapeDefaults.connectors = userShapeDefaults.connectors;\n }\n },\n\n _interactionDefaults: function() {\n var options = this.options;\n var selectable = options.selectable;\n var pannable = options.pannable;\n var mobile = kendo.support.mobileOS;\n\n if (selectable && !defined(selectable.multiple)) {\n options.selectable = deepExtend({\n multiple: mobile ? false : true\n }, options.selectable);\n }\n\n if (pannable && !defined(pannable.key)) {\n options.pannable = deepExtend({\n key: mobile ? \"none\" : \"ctrl\"\n }, options.pannable);\n }\n },\n\n _initCanvas: function() {\n var canvasContainer = $(\"
\").appendTo(this.scrollable)[0];\n var viewPort = this.viewport();\n this.canvas = new Canvas(canvasContainer, {\n width: viewPort.width || DEFAULT_CANVAS_WIDTH,\n height: viewPort.height || DEFAULT_CANVAS_HEIGHT\n });\n },\n\n _createHandlers: function() {\n var that = this;\n var element = that.element;\n\n element.on(MOUSEWHEEL_NS, that._wheel.bind(that))\n .on(\"keydown\" + NS, that._keydown.bind(that));\n\n that._userEvents = new kendo.UserEvents(this.scrollable, {\n multiTouch: true,\n fastTap: true,\n tap: that._tap.bind(that),\n start: that._dragStart.bind(that),\n move: that._drag.bind(that),\n end: that._dragEnd.bind(that),\n gesturestart: that._gestureStart.bind(that),\n gesturechange: that._gestureChange.bind(that),\n gestureend: that._gestureEnd.bind(that),\n doubleTap: that._doubleTap.bind(that),\n supportDoubleTap: true\n });\n\n that.toolService = new ToolService(that);\n\n this.scrollable\n .on(\"mouseover\" + NS, that._mouseover.bind(that))\n .on(\"mouseout\" + NS, that._mouseout.bind(that))\n .on(\"mousemove\" + NS, that._mouseMove.bind(that))\n .on(\"mousedown\" + NS, that._mouseDown.bind(that))\n .on(\"mouseup\" + NS, that._mouseUp.bind(that));\n\n this._syncHandler = that._syncChanges.bind(that);\n\n that._resizeHandler = that.resize.bind(that, false);\n kendo.onResize(that._resizeHandler);\n\n this.bind(ZOOM_START, that._destroyToolBar.bind(that));\n this.bind(PAN, that._destroyToolBar.bind(that));\n },\n\n _dragStart: function(e) {\n this._pauseMouseHandlers = true;\n var point = this._eventPositions(e, true);\n\n var event = e.event;\n if (this.toolService.start(point, this._meta(event))) {\n this._destroyToolBar();\n event.preventDefault();\n }\n },\n\n _drag: function(e) {\n var p = this._eventPositions(e);\n var event = e.event;\n if (this.toolService.move(p, this._meta(event))) {\n event.preventDefault();\n }\n },\n\n _dragEnd: function(e) {\n this._pauseMouseHandlers = false;\n var p = this._eventPositions(e);\n var event = e.event;\n if (this.toolService.end(p, this._meta(event))) {\n this._createToolBar();\n event.preventDefault();\n }\n },\n\n _mouseMove: function(e) {\n if (!this._pauseMouseHandlers) {\n var p = this._eventPositions(e);\n this.toolService._updateHoveredItem(p);\n this.toolService._updateCursor(p);\n }\n },\n\n _mouseDown: function() {\n this._pauseMouseHandlers = true;\n },\n\n _mouseUp: function() {\n this._pauseMouseHandlers = false;\n },\n\n _tap: function(e) {\n var toolService = this.toolService;\n var selectable = this.options.selectable;\n var point = this._eventPositions(e);\n var focused = this.focus();\n\n toolService._updateHoveredItem(point);\n\n if (toolService.hoveredItem) {\n var item = toolService.hoveredItem;\n\n this.trigger(\"click\", {\n item: item,\n point: point,\n meta: this._meta(e.event)\n });\n\n if (selectable && item.options.selectable !== false) {\n var multiple = selectable.multiple !== false;\n var ctrlPressed = kendo.support.mobileOS || this._meta(e.event).ctrlKey;\n\n if (item.isSelected) {\n if (ctrlPressed) {\n this._destroyToolBar();\n item.select(false);\n } else {\n this._createToolBar(focused);\n }\n } else {\n this._destroyToolBar();\n this.select(item, {\n addToSelection: multiple && ctrlPressed\n });\n this._createToolBar(focused);\n }\n }\n } else if (selectable) {\n this._destroyToolBar();\n this.deselect();\n }\n },\n\n _keydown: function(e) {\n if (this.toolService.keyDown(e.keyCode, this._meta(e))) {\n e.preventDefault();\n }\n },\n\n _wheel: function(e) {\n var delta = mwDelta(e),\n p = this._eventPositions(e),\n meta = deepExtend(this._meta(e), { delta: delta });\n\n if (this.toolService.wheel(p, meta)) {\n e.preventDefault();\n }\n },\n\n _meta: function(e) {\n return { ctrlKey: e.ctrlKey, metaKey: e.metaKey, altKey: e.altKey, shiftKey: e.shiftKey, type: e.type };\n },\n\n _eventPositions: function(e, start) {\n var point;\n if (e.touch) {\n var field = start ? \"startLocation\" : \"location\";\n point = new Point(e.x[field], e.y[field]);\n } else {\n var event = e.originalEvent;\n point = new Point(event.pageX, event.pageY);\n }\n\n return this.documentToModel(point);\n },\n\n _gestureStart: function(e) {\n this._destroyToolBar();\n this.scroller.disable();\n var initialCenter = this.documentToModel(new Point(e.center.x, e.center.y));\n var eventArgs = {\n point: initialCenter,\n zoom: this.zoom()\n };\n\n if (this.trigger(ZOOM_START, eventArgs)) {\n return;\n }\n\n this._gesture = e;\n this._initialCenter = initialCenter;\n },\n\n _gestureChange: function(e) {\n var previousGesture = this._gesture;\n var initialCenter = this._initialCenter;\n var center = this.documentToView(new Point(e.center.x, e.center.y));\n var scaleDelta = e.distance / previousGesture.distance;\n var zoom = this._zoom;\n var updateZoom = false;\n\n if (math.abs(scaleDelta - 1) >= MOBILE_ZOOM_RATE) {\n this._zoom = zoom = this._getValidZoom(zoom * scaleDelta);\n this.options.zoom = zoom;\n this._gesture = e;\n updateZoom = true;\n }\n\n var zoomedPoint = initialCenter.times(zoom);\n var pan = center.minus(zoomedPoint);\n if (updateZoom || this._pan.distanceTo(pan) >= MOBILE_PAN_DISTANCE) {\n this._panTransform(pan);\n this._updateAdorners();\n }\n\n e.preventDefault();\n },\n\n _doubleTap: function(e) {\n var diagram = this;\n var pointPosition = this._eventPositions(e);\n var options = diagram.options;\n var zoomRate = options.zoomRate;\n var zoom = diagram.zoom() + zoomRate;\n var meta = this._meta(e);\n var zoomOptions = { point: pointPosition, meta: meta, zoom: zoom };\n\n\n if (diagram.trigger(ZOOM_START, zoomOptions)) {\n return;\n }\n\n zoom = kendo.dataviz.round(Math.max(options.zoomMin, Math.min(options.zoomMax, zoom)), 2);\n zoomOptions.zoom = zoom;\n\n diagram.zoom(zoom, zoomOptions);\n diagram.trigger(ZOOM_END, zoomOptions);\n },\n\n _gestureEnd: function() {\n if (this.options.pannable !== false) {\n this.scroller.enable();\n }\n this.trigger(ZOOM_END, {\n point: this._initialCenter,\n zoom: this.zoom()\n });\n },\n\n _resize: function() {\n var viewport = this.viewport();\n if (this.canvas) {\n this.canvas.size(viewport);\n }\n\n if (this.scrollable && this.toolBar) {\n this.scrollable.height(viewport.height);\n }\n },\n\n _mouseover: function(e) {\n var node = e.target._kendoNode;\n if (node && node.srcElement._hover) {\n node.srcElement._hover(true, node.srcElement);\n }\n },\n\n _mouseout: function(e) {\n var node = e.target._kendoNode;\n if (node && node.srcElement._hover) {\n node.srcElement._hover(false, node.srcElement);\n }\n },\n\n _initTheme: function() {\n var that = this;\n var themeName = ((that.options || {}).theme || \"\").toLowerCase();\n var themes = dataviz.ui.themes || {};\n var themeOptions;\n\n if (dataviz.SASS_THEMES.indexOf(themeName) != -1) {\n themeOptions = dataviz.autoTheme().diagram;\n }\n else {\n themeOptions = (themes[themeName] || {}).diagram;\n }\n\n that.options = deepExtend({}, themeOptions, that.options);\n if (that.options.editable === true) {\n deepExtend(that.options, {\n editable: (themeOptions || {}).editable\n });\n }\n },\n\n _createOptionElements: function() {\n var options = this.options;\n var shapesLength = options.shapes.length;\n\n if (shapesLength) {\n this._createShapes();\n }\n\n if (options.connections.length) {\n this._createConnections();\n }\n\n if (shapesLength && options.layout) {\n this.layout(options.layout);\n }\n },\n\n _createShapes: function() {\n var that = this,\n options = that.options,\n shapes = options.shapes,\n shape, i;\n\n for (i = 0; i < shapes.length; i++) {\n shape = shapes[i];\n that.addShape(shape);\n }\n },\n\n _createConnections: function() {\n var diagram = this,\n options = diagram.options,\n defaults = options.connectionDefaults,\n connections = options.connections,\n conn, source, target, i;\n\n for (i = 0; i < connections.length; i++) {\n conn = connections[i];\n source = diagram._findConnectionTarget(conn.from);\n target = diagram._findConnectionTarget(conn.to);\n\n diagram.connect(source, target, deepExtend({}, defaults, conn));\n }\n },\n\n _findConnectionTarget: function(options) {\n options = options || {};\n var diagram = this;\n var shapeId = isString(options) ? options : options.shapeId || options.id;\n var target;\n if (shapeId) {\n target = diagram.getShapeById(shapeId);\n if (options.connector) {\n target = target.getConnector(options.connector);\n }\n } else {\n target = new Point(options.x || 0, options.y || 0);\n }\n\n return target;\n },\n\n destroy: function() {\n var that = this;\n Widget.fn.destroy.call(that);\n\n if (this._userEvents) {\n this._userEvents.destroy();\n }\n\n kendo.unbindResize(that._resizeHandler);\n\n that.clear();\n that.element.off(NS);\n that.scroller.wrapper.off(NS);\n that.canvas.destroy(true);\n that.canvas = undefined$1;\n\n that._destroyEditor();\n that.destroyScroller();\n that._destroyGlobalToolBar();\n that._destroyToolBar();\n },\n\n destroyScroller: function() {\n var scroller = this.scroller;\n\n if (!scroller) {\n return;\n }\n\n scroller.destroy();\n scroller.element.remove();\n this.scroller = null;\n },\n\n save: function() {\n var json = {\n shapes: [],\n connections: []\n };\n var i, connection, shape;\n\n for (i = 0; i < this.shapes.length; i++) {\n shape = this.shapes[i];\n if (shape.options.serializable) {\n json.shapes.push(shape.options);\n }\n }\n\n for (i = 0; i < this.connections.length; i++) {\n connection = this.connections[i];\n\n json.connections.push(deepExtend({}, connection.options, connection.toJSON()));\n }\n\n return json;\n },\n\n focus: function() {\n if (!this.element.is(kendo._activeElement())) {\n var element = this.element,\n scrollContainer = element[0],\n containers = [],\n offsets = [],\n documentElement = document.documentElement,\n i;\n\n do {\n scrollContainer = scrollContainer.parentNode;\n\n if (scrollContainer.scrollHeight > scrollContainer.clientHeight) {\n containers.push(scrollContainer);\n offsets.push(scrollContainer.scrollTop);\n }\n } while (scrollContainer != documentElement);\n\n element.trigger(\"focus\");\n\n for (i = 0; i < containers.length; i++) {\n containers[i].scrollTop = offsets[i];\n }\n return true;\n }\n },\n\n load: function(options) {\n this.clear();\n\n this.setOptions(options);\n this._createShapes();\n this._createConnections();\n },\n\n setOptions: function(options) {\n deepExtend(this.options, options);\n },\n\n clear: function() {\n var that = this;\n\n that.select(false);\n that.mainLayer.clear();\n that._shapesQuadTree.clear();\n that._initialize();\n },\n /**\n * Connects two items.\n * @param source Shape, Connector, Point.\n * @param target Shape, Connector, Point.\n * @param options Connection options that will be passed to the newly created connection.\n * @returns The newly created connection.\n */\n connect: function(source, target, options) {\n var connection;\n if (this.connectionsDataSource && this._isEditable) {\n var dataItem = this.connectionsDataSource.add({});\n connection = this._connectionsDataMap[dataItem.uid];\n connection.source(source);\n connection.target(target);\n connection.redraw(options);\n connection.updateModel();\n } else {\n connection = new Connection(source, target,\n deepExtend({ }, this.options.connectionDefaults, options));\n\n this.addConnection(connection);\n }\n\n return connection;\n },\n /**\n * Determines whether the the two items are connected.\n * @param source Shape, Connector, Point.\n * @param target Shape, Connector, Point.\n * @returns true if the two items are connected.\n */\n connected: function(source, target) {\n for (var i = 0; i < this.connections.length; i++) {\n var c = this.connections[i];\n if (c.from == source && c.to == target) {\n return true;\n }\n }\n\n return false;\n },\n /**\n * Adds connection to the diagram.\n * @param connection Connection.\n * @param undoable Boolean.\n * @returns The newly created connection.\n */\n addConnection: function(connection, undoable) {\n if (undoable !== false) {\n this.undoRedoService.add(\n new diagram.AddConnectionUnit(connection, this), false);\n }\n\n connection.diagram = this;\n connection._setOptionsFromModel();\n connection.refresh();\n this.mainLayer.append(connection.visual);\n this.connections.push(connection);\n\n this.trigger(CHANGE, {\n added: [connection],\n removed: []\n });\n\n return connection;\n },\n\n _addConnection: function(connection, undoable) {\n var connectionsDataSource = this.connectionsDataSource;\n var dataItem;\n if (connectionsDataSource && this._isEditable) {\n dataItem = createModel(connectionsDataSource, cloneDataItem(connection.dataItem));\n connection.dataItem = dataItem;\n connection.updateModel();\n\n if (!this.trigger(\"add\", { connection: connection })) {\n this._connectionsDataMap[dataItem.uid] = connection;\n\n connectionsDataSource.add(dataItem);\n this.addConnection(connection, undoable);\n connection._updateConnectors();\n\n return connection;\n }\n } else if (!this.trigger(\"add\", { connection: connection })) {\n this.addConnection(connection, undoable);\n connection._updateConnectors();\n return connection;\n }\n },\n\n /**\n * Adds shape to the diagram.\n * @param item Shape, Point. If point is passed it will be created new Shape and positioned at that point.\n * @param options. The options to be passed to the newly created Shape.\n * @returns The newly created shape.\n */\n addShape: function(item, undoable) {\n var shape,\n shapeDefaults = this.options.shapeDefaults;\n\n if (item instanceof Shape) {\n shape = item;\n this._parseBounds(shape.bounds());\n } else if (!(item instanceof kendo.Class)) {\n shapeDefaults = deepExtend({}, shapeDefaults, item || {});\n shape = new Shape(shapeDefaults, this);\n this._parseBounds(shape.bounds());\n } else {\n return;\n }\n\n if (undoable !== false) {\n this.undoRedoService.add(new diagram.AddShapeUnit(shape, this), false);\n }\n\n this.shapes.push(shape);\n if (shape.diagram !== this) {\n this._shapesQuadTree.insert(shape);\n shape.diagram = this;\n }\n this.mainLayer.append(shape.visual);\n\n this.trigger(CHANGE, {\n added: [shape],\n removed: []\n });\n\n return shape;\n },\n\n _addShape: function(shape, undoable) {\n var that = this;\n var dataSource = that.dataSource;\n var dataItem;\n if (dataSource && this._isEditable) {\n dataItem = createModel(dataSource, cloneDataItem(shape.dataItem));\n shape.dataItem = dataItem;\n shape.updateModel();\n\n if (!this.trigger(\"add\", { shape: shape })) {\n this.dataSource.add(dataItem);\n var inactiveItem = this._inactiveShapeItems.getByUid(dataItem.uid);\n inactiveItem.element = shape;\n inactiveItem.undoable = undoable;\n return shape;\n }\n } else if (!this.trigger(\"add\", { shape: shape })) {\n return this.addShape(shape, undoable);\n }\n },\n\n _parseBounds: function(bounds) {\n bounds.x = typeof(bounds.x) == \"string\" ? parseFloat(bounds.x) : bounds.x;\n bounds.y = typeof(bounds.y) == \"string\" ? parseFloat(bounds.y) : bounds.y;\n },\n /**\n * Removes items (or single item) from the diagram.\n * @param items DiagramElement, Array of Items.\n * @param undoable.\n */\n\n remove: function(items, undoable) {\n items = isArray(items) ? items.slice(0) : [items];\n var elements = splitDiagramElements(items);\n var shapes = elements.shapes;\n var connections = elements.connections;\n var i;\n\n if (!defined(undoable)) {\n undoable = true;\n }\n\n if (undoable) {\n this.undoRedoService.begin();\n }\n\n this._suspendModelRefresh();\n for (i = shapes.length - 1; i >= 0; i--) {\n this._removeItem(shapes[i], undoable, connections);\n }\n\n for (i = connections.length - 1; i >= 0; i--) {\n this._removeItem(connections[i], undoable);\n }\n\n this._resumeModelRefresh();\n\n if (undoable) {\n this.undoRedoService.commit(false);\n }\n\n this.trigger(CHANGE, {\n added: [],\n removed: items\n });\n },\n\n _removeShapeDataItem: function(item) {\n if (this._isEditable) {\n this.dataSource.remove(item.dataItem);\n delete this._dataMap[item.dataItem.id];\n }\n },\n\n _removeConnectionDataItem: function(item) {\n if (this._isEditable) {\n this.connectionsDataSource.remove(item.dataItem);\n delete this._connectionsDataMap[item.dataItem.uid];\n }\n },\n\n _triggerRemove: function(items) {\n var toRemove = [];\n var item, args, editable;\n\n for (var idx = 0; idx < items.length; idx++) {\n item = items[idx];\n editable = item.options.editable;\n if (item instanceof Shape) {\n args = { shape: item };\n } else {\n args = { connection: item };\n }\n if (editable && editable.remove !== false && !this.trigger(\"remove\", args)) {\n toRemove.push(item);\n }\n }\n return toRemove;\n },\n\n /**\n * Executes the next undoable action on top of the undo stack if any.\n */\n undo: function() {\n this.undoRedoService.undo();\n },\n /**\n * Executes the previous undoable action on top of the redo stack if any.\n */\n redo: function() {\n this.undoRedoService.redo();\n },\n /**\n * Selects items on the basis of the given input or returns the current selection if none.\n * @param itemsOrRect DiagramElement, Array of elements, \"All\", false or Rect. A value 'false' will deselect everything.\n * @param options\n * @returns {Array}\n */\n select: function(item, options) {\n if (isDefined(item)) {\n options = deepExtend({ addToSelection: false }, options);\n\n var addToSelection = options.addToSelection,\n items = [],\n selected = [],\n i, element;\n\n if (!addToSelection) {\n this.deselect();\n }\n\n this._internalSelection = true;\n\n if (item instanceof Array) {\n items = item;\n } else if (item instanceof DiagramElement) {\n items = [ item ];\n }\n\n for (i = 0; i < items.length; i++) {\n element = items[i];\n if (element.select(true)) {\n selected.push(element);\n }\n }\n\n this._selectionChanged(selected, []);\n\n this._internalSelection = false;\n } else {\n return this._selectedItems;\n }\n },\n\n selectAll: function() {\n this.select(this.shapes.concat(this.connections));\n },\n\n selectArea: function(rect) {\n var i, items, item;\n this._internalSelection = true;\n var selected = [];\n if (rect instanceof Rect) {\n items = this.shapes.concat(this.connections);\n for (i = 0; i < items.length; i++) {\n item = items[i];\n if ((!rect || item._hitTest(rect)) && item.options.enable) {\n if (item.select(true)) {\n selected.push(item);\n }\n }\n }\n }\n\n this._selectionChanged(selected, []);\n this._internalSelection = false;\n },\n\n deselect: function(item) {\n this._internalSelection = true;\n var deselected = [],\n items = [],\n element, i;\n\n if (item instanceof Array) {\n items = item;\n } else if (item instanceof DiagramElement) {\n items.push(item);\n } else if (!isDefined(item)) {\n items = this._selectedItems.slice(0);\n }\n\n for (i = 0; i < items.length; i++) {\n element = items[i];\n if (element.select(false)) {\n deselected.push(element);\n }\n }\n\n this._selectionChanged([], deselected);\n this._internalSelection = false;\n },\n /**\n * Brings to front the passed items.\n * @param items DiagramElement, Array of Items.\n * @param undoable. By default the action is undoable.\n */\n toFront: function(items, undoable) {\n if (!items) {\n items = this._selectedItems.slice();\n }\n\n var result = this._getDiagramItems(items), indices;\n if (!defined(undoable) || undoable) {\n indices = indicesOfItems(this.mainLayer, result.visuals);\n var unit = new ToFrontUnit(this, items, indices);\n this.undoRedoService.add(unit);\n } else {\n this.mainLayer.toFront(result.visuals);\n this._fixOrdering(result, true);\n }\n },\n /**\n * Sends to back the passed items.\n * @param items DiagramElement, Array of Items.\n * @param undoable. By default the action is undoable.\n */\n toBack: function(items, undoable) {\n if (!items) {\n items = this._selectedItems.slice();\n }\n\n var result = this._getDiagramItems(items), indices;\n if (!defined(undoable) || undoable) {\n indices = indicesOfItems(this.mainLayer, result.visuals);\n var unit = new ToBackUnit(this, items, indices);\n this.undoRedoService.add(unit);\n } else {\n this.mainLayer.toBack(result.visuals);\n this._fixOrdering(result, false);\n }\n },\n /**\n * Bring into view the passed item(s) or rectangle.\n * @param items DiagramElement, Array of Items, Rect.\n * @param options. align - controls the position of the calculated rectangle relative to the viewport.\n * \"Center middle\" will position the items in the center. animate - controls if the pan should be animated.\n */\n bringIntoView: function(item, options) { // jQuery|Item|Array|Rect\n var viewport = this.viewport();\n var aligner = new diagram.RectAlign(viewport);\n var current, rect, original, newPan;\n\n if (viewport.width === 0 || viewport.height === 0) {\n return;\n }\n\n options = deepExtend({ animate: false, align: \"center middle\" }, options);\n if (options.align == \"none\") {\n options.align = \"center middle\";\n }\n\n if (item instanceof DiagramElement) {\n rect = item.bounds(TRANSFORMED);\n } else if (isArray(item)) {\n rect = this.boundingBox(item);\n } else if (item instanceof Rect) {\n rect = item.clone();\n }\n\n original = rect.clone();\n\n rect.zoom(this._zoom);\n\n if (rect.width > viewport.width || rect.height > viewport.height) {\n this._zoom = this._getValidZoom(math.min(viewport.width / original.width, viewport.height / original.height));\n rect = original.clone().zoom(this._zoom);\n }\n\n this._zoomMainLayer();\n\n current = rect.clone();\n aligner.align(rect, options.align);\n\n newPan = rect.topLeft().minus(current.topLeft());\n this.pan(newPan.times(-1), options.animate);\n },\n\n alignShapes: function(direction) {\n if (isUndefined(direction)) {\n direction = \"Left\";\n }\n var items = this.select(),\n val,\n item,\n i;\n\n if (items.length === 0) {\n return;\n }\n\n switch (direction.toLowerCase()) {\n case \"left\":\n case \"top\":\n val = MAX_VALUE;\n break;\n case \"right\":\n case \"bottom\":\n val = MIN_VALUE;\n break;\n }\n\n for (i = 0; i < items.length; i++) {\n item = items[i];\n if (item instanceof Shape) {\n switch (direction.toLowerCase()) {\n case \"left\":\n val = math.min(val, item.options.x);\n break;\n case \"top\":\n val = math.min(val, item.options.y);\n break;\n case \"right\":\n val = math.max(val, item.options.x);\n break;\n case \"bottom\":\n val = math.max(val, item.options.y);\n break;\n }\n }\n }\n var undoStates = [];\n var shapes = [];\n for (i = 0; i < items.length; i++) {\n item = items[i];\n if (item instanceof Shape) {\n shapes.push(item);\n undoStates.push(item.bounds());\n switch (direction.toLowerCase()) {\n case \"left\":\n case \"right\":\n item.position(new Point(val, item.options.y));\n break;\n case \"top\":\n case \"bottom\":\n item.position(new Point(item.options.x, val));\n break;\n }\n }\n }\n var unit = new diagram.TransformUnit(shapes, undoStates);\n this.undoRedoService.add(unit, false);\n },\n\n zoom: function(zoom, options) {\n if (zoom) {\n var staticPoint = options ? options.point : new diagram.Point(0, 0);\n // var meta = options ? options.meta : 0;\n zoom = this._zoom = this._getValidZoom(zoom);\n\n if (!isUndefined(staticPoint)) {//Viewpoint vector is constant\n staticPoint = new diagram.Point(math.round(staticPoint.x), math.round(staticPoint.y));\n var zoomedPoint = staticPoint.times(zoom);\n var viewportVector = this.modelToView(staticPoint);\n var raw = viewportVector.minus(zoomedPoint);//pan + zoomed point = viewpoint vector\n this._storePan(new diagram.Point(math.round(raw.x), math.round(raw.y)));\n }\n\n if (options) {\n options.zoom = zoom;\n }\n\n this._panTransform();\n\n this.canvas.surface.hideTooltip();\n\n this._updateAdorners();\n }\n\n return this._zoom;\n },\n\n _getPan: function(pan) {\n var canvas = this.canvas;\n if (!canvas.translate) {\n pan = pan.plus(this._pan);\n }\n return pan;\n },\n\n pan: function(pan, animate) {\n if (pan instanceof Point) {\n var that = this;\n var scroller = that.scroller;\n pan = that._getPan(pan);\n pan = pan.times(-1);\n\n if (animate) {\n scroller.animatedScrollTo(pan.x, pan.y, function() {\n that._updateAdorners();\n });\n } else {\n scroller.scrollTo(pan.x, pan.y);\n that._updateAdorners();\n }\n } else {\n return this._pan.times(-1);\n }\n },\n\n viewport: function() {\n var element = this.element;\n var width = element.width();\n var height = element.height();\n\n if (this.toolBar) {\n height -= outerHeight(this.toolBar.element);\n }\n\n return new Rect(0, 0, width, height);\n },\n copy: function() {\n if (this.options.copy.enabled) {\n this._clipboard = [];\n this._copyOffset = 1;\n for (var i = 0; i < this._selectedItems.length; i++) {\n var item = this._selectedItems[i];\n this._clipboard.push(item);\n }\n }\n },\n cut: function() {\n if (this.options.copy.enabled) {\n this._clipboard = [];\n this._copyOffset = 0;\n for (var i = 0; i < this._selectedItems.length; i++) {\n var item = this._selectedItems[i];\n this._clipboard.push(item);\n }\n this.remove(this._clipboard, true);\n }\n },\n\n paste: function() {\n if (this._clipboard.length > 0) {\n var item, copied, i;\n var mapping = {};\n var elements = splitDiagramElements(this._clipboard);\n var connections = elements.connections;\n var shapes = elements.shapes;\n var offset = {\n x: this._copyOffset * this.options.copy.offsetX,\n y: this._copyOffset * this.options.copy.offsetY\n };\n this.deselect();\n // first the shapes\n for (i = 0; i < shapes.length; i++) {\n item = shapes[i];\n copied = item.clone();\n mapping[item.id] = copied;\n copied.position(new Point(item.options.x + offset.x, item.options.y + offset.y));\n copied.diagram = this;\n copied = this._addShape(copied);\n if (copied) {\n copied.select();\n }\n }\n // then the connections\n for (i = 0; i < connections.length; i++) {\n item = connections[i];\n copied = this._addConnection(item.clone());\n if (copied) {\n this._updateCopiedConnection(copied, item, \"source\", mapping, offset);\n this._updateCopiedConnection(copied, item, \"target\", mapping, offset);\n\n copied.select(true);\n copied.updateModel();\n }\n }\n\n this._syncChanges();\n\n this._copyOffset += 1;\n }\n },\n\n _updateCopiedConnection: function(connection, sourceConnection, connectorName, mapping, offset) {\n var onActivate, inactiveItem, targetShape;\n var target = sourceConnection[connectorName]();\n var diagram = this;\n if (target instanceof Connector && mapping[target.shape.id]) {\n targetShape = mapping[target.shape.id];\n if (diagram.getShapeById(targetShape.id)) {\n connection[connectorName](targetShape.getConnector(target.options.name));\n } else {\n inactiveItem = diagram._inactiveShapeItems.getByUid(targetShape.dataItem.uid);\n if (inactiveItem) {\n onActivate = function(item) {\n targetShape = diagram._dataMap[item.id];\n connection[connectorName](targetShape.getConnector(target.options.name));\n connection.updateModel();\n };\n diagram._deferredConnectionUpdates.push(inactiveItem.onActivate(onActivate));\n }\n }\n } else {\n connection[connectorName](new Point(sourceConnection[connectorName + \"Point\"]().x + offset.x, sourceConnection[connectorName + \"Point\"]().y + offset.y));\n }\n },\n /**\n * Gets the bounding rectangle of the given items.\n * @param items DiagramElement, Array of elements.\n * @param origin Boolean. Pass 'true' if you need to get the bounding box of the shapes without their rotation offset.\n * @returns {Rect}\n */\n boundingBox: function(items, origin) {\n var rect = Rect.empty(), temp,\n di = isDefined(items) ? this._getDiagramItems(items) : { shapes: this.shapes };\n if (di.shapes.length > 0) {\n var item = di.shapes[0];\n rect = item.bounds(ROTATED);\n for (var i = 1; i < di.shapes.length; i++) {\n item = di.shapes[i];\n temp = item.bounds(ROTATED);\n if (origin === true) {\n temp.x -= item._rotationOffset.x;\n temp.y -= item._rotationOffset.y;\n }\n rect = rect.union(temp);\n }\n }\n return rect;\n },\n\n _containerOffset: function() {\n var containerOffset = this.element.offset();\n if (this.toolBar) {\n containerOffset.top += outerHeight(this.toolBar.element);\n }\n return containerOffset;\n },\n\n documentToView: function(point) {\n var containerOffset = this._containerOffset();\n\n return new Point(point.x - containerOffset.left, point.y - containerOffset.top);\n },\n viewToDocument: function(point) {\n var containerOffset = this._containerOffset();\n\n return new Point(point.x + containerOffset.left, point.y + containerOffset.top);\n },\n viewToModel: function(point) {\n return this._transformWithMatrix(point, this._matrixInvert);\n },\n modelToView: function(point) {\n return this._transformWithMatrix(point, this._matrix);\n },\n modelToLayer: function(point) {\n return this._transformWithMatrix(point, this._layerMatrix);\n },\n layerToModel: function(point) {\n return this._transformWithMatrix(point, this._layerMatrixInvert);\n },\n documentToModel: function(point) {\n var viewPoint = this.documentToView(point);\n if (!this.canvas.translate) {\n viewPoint.x = viewPoint.x + this.scroller.scrollLeft;\n viewPoint.y = viewPoint.y + this.scroller.scrollTop;\n }\n return this.viewToModel(viewPoint);\n },\n modelToDocument: function(point) {\n return this.viewToDocument(this.modelToView(point));\n },\n _transformWithMatrix: function(point, matrix) {\n var result = point;\n if (point instanceof Point) {\n if (matrix) {\n result = matrix.apply(point);\n }\n }\n else {\n var tl = this._transformWithMatrix(point.topLeft(), matrix),\n br = this._transformWithMatrix(point.bottomRight(), matrix);\n result = Rect.fromPoints(tl, br);\n }\n return result;\n },\n\n setDataSource: function(dataSource) {\n this.options.dataSource = dataSource;\n this._dataSource();\n if (this.options.autoBind) {\n this.dataSource.fetch();\n }\n },\n\n setConnectionsDataSource: function(dataSource) {\n this.options.connectionsDataSource = dataSource;\n this._connectionDataSource();\n if (this.options.autoBind) {\n this.connectionsDataSource.fetch();\n }\n },\n\n /**\n * Performs a diagram layout of the given type.\n * @param layoutType The layout algorithm to be applied (TreeLayout, LayeredLayout, SpringLayout).\n * @param options Layout-specific options.\n */\n layout: function(options) {\n this._layouting = true;\n // TODO: raise layout event?\n var type;\n if (isUndefined(options)) {\n options = this.options.layout;\n }\n if (isUndefined(options) || isUndefined(options.type)) {\n type = \"Tree\";\n }\n else {\n type = options.type;\n }\n var l;\n switch (type.toLowerCase()) {\n case \"tree\":\n l = new diagram.TreeLayout(this);\n break;\n\n case \"layered\":\n l = new diagram.LayeredLayout(this);\n break;\n\n case \"forcedirected\":\n case \"force\":\n case \"spring\":\n case \"springembedder\":\n l = new diagram.SpringLayout(this);\n break;\n default:\n throw \"Layout algorithm '\" + type + \"' is not supported.\";\n }\n var initialState = new diagram.LayoutState(this);\n var finalState = l.layout(options);\n if (finalState) {\n var unit = new diagram.LayoutUndoUnit(initialState, finalState, options ? options.animate : null);\n this.undoRedoService.add(unit);\n }\n this._layouting = false;\n this._redrawConnections();\n },\n /**\n * Gets a shape on the basis of its identifier.\n * @param id (string) the identifier of a shape.\n * @returns {Shape}\n */\n getShapeById: function(id) {\n var found;\n found = Utils.first(this.shapes, function(s) {\n return s.visual.id === id;\n });\n if (found) {\n return found;\n }\n found = Utils.first(this.connections, function(c) {\n return c.visual.id === id;\n });\n return found;\n },\n\n getShapeByModelId: function(id) {\n var shape;\n if (this._isEditable) {\n shape = this._dataMap[id];\n } else {\n shape = Utils.first(this.shapes, function(shape) {\n return (shape.dataItem || {}).id === id;\n });\n }\n return shape;\n },\n\n getShapeByModelUid: function(uid) {\n var shape;\n if (this._isEditable) {\n shape = Utils.first(this.shapes, function(shape) {\n return (shape.dataItem || {}).uid === uid;\n });\n } else {\n shape = this._dataMap[uid];\n }\n return shape;\n },\n\n getConnectionByModelId: function(id) {\n var connection;\n if (this.connectionsDataSource) {\n connection = Utils.first(this.connections, function(connection) {\n return (connection.dataItem || {}).id === id;\n });\n }\n return connection;\n },\n\n getConnectionByModelUid: function(uid) {\n var connection;\n if (this.connectionsDataSource) {\n connection = this._connectionsDataMap[uid];\n }\n return connection;\n },\n\n _extendLayoutOptions: function(options) {\n if (options.layout) {\n options.layout = deepExtend({}, diagram.LayoutBase.fn.defaultOptions || {}, options.layout);\n }\n },\n\n _selectionChanged: function(selected, deselected) {\n if (selected.length || deselected.length) {\n this.trigger(SELECT, { selected: selected, deselected: deselected });\n }\n },\n _getValidZoom: function(zoom) {\n return math.min(math.max(zoom, this.options.zoomMin), this.options.zoomMax);\n },\n _panTransform: function(pos) {\n var diagram = this,\n pan = pos || diagram._pan;\n\n if (diagram.canvas.translate) {\n diagram.scroller.scrollTo(pan.x, pan.y);\n diagram._zoomMainLayer();\n } else {\n diagram._storePan(pan);\n diagram._transformMainLayer();\n }\n },\n\n _finishPan: function() {\n this.trigger(PAN, { total: this._pan, delta: Number.NaN });\n },\n _storePan: function(pan) {\n this._pan = pan;\n this._storeViewMatrix();\n },\n _zoomMainLayer: function() {\n var zoom = this._zoom;\n\n var transform = new CompositeTransform(0, 0, zoom, zoom);\n transform.render(this.mainLayer);\n this._storeLayerMatrix(transform);\n this._storeViewMatrix();\n },\n _transformMainLayer: function() {\n var pan = this._pan,\n zoom = this._zoom;\n\n var transform = new CompositeTransform(pan.x, pan.y, zoom, zoom);\n transform.render(this.mainLayer);\n this._storeLayerMatrix(transform);\n this._storeViewMatrix();\n },\n _storeLayerMatrix: function(canvasTransform) {\n this._layerMatrix = canvasTransform.toMatrix();\n this._layerMatrixInvert = canvasTransform.invert().toMatrix();\n },\n _storeViewMatrix: function() {\n var pan = this._pan,\n zoom = this._zoom;\n\n var transform = new CompositeTransform(pan.x, pan.y, zoom, zoom);\n this._matrix = transform.toMatrix();\n this._matrixInvert = transform.invert().toMatrix();\n },\n _toIndex: function(items, indices) {\n var result = this._getDiagramItems(items);\n this.mainLayer.toIndex(result.visuals, indices);\n this._fixOrdering(result, false);\n },\n _fixOrdering: function(result, toFront) {\n var shapePos = toFront ? this.shapes.length - 1 : 0,\n conPos = toFront ? this.connections.length - 1 : 0,\n i, item;\n for (i = 0; i < result.shapes.length; i++) {\n item = result.shapes[i];\n Utils.remove(this.shapes, item);\n Utils.insert(this.shapes, item, shapePos);\n }\n for (i = 0; i < result.cons.length; i++) {\n item = result.cons[i];\n Utils.remove(this.connections, item);\n Utils.insert(this.connections, item, conPos);\n }\n },\n _getDiagramItems: function(items) {\n var i, result = {}, args = items;\n result.visuals = [];\n result.shapes = [];\n result.cons = [];\n\n if (!items) {\n args = this._selectedItems.slice();\n } else if (!isArray(items)) {\n args = [items];\n }\n\n for (i = 0; i < args.length; i++) {\n var item = args[i];\n if (item instanceof Shape) {\n result.shapes.push(item);\n result.visuals.push(item.visual);\n } else if (item instanceof Connection) {\n result.cons.push(item);\n result.visuals.push(item.visual);\n }\n }\n\n return result;\n },\n\n _removeItem: function(item, undoable, removedConnections) {\n item.select(false);\n if (item instanceof Shape) {\n this._removeShapeDataItem(item);\n this._removeShape(item, undoable, removedConnections);\n } else if (item instanceof Connection) {\n this._removeConnectionDataItem(item);\n this._removeConnection(item, undoable);\n }\n\n this.mainLayer.remove(item.visual);\n },\n\n _removeShape: function(shape, undoable, removedConnections) {\n var i, connection, connector,\n sources = [], targets = [];\n this.toolService._removeHover();\n\n if (undoable) {\n this.undoRedoService.addCompositeItem(new DeleteShapeUnit(shape));\n }\n Utils.remove(this.shapes, shape);\n this._shapesQuadTree.remove(shape);\n\n for (i = 0; i < shape.connectors.length; i++) {\n connector = shape.connectors[i];\n for (var j = 0; j < connector.connections.length; j++) {\n connection = connector.connections[j];\n if (!removedConnections || !dataviz.inArray(connection, removedConnections)) {\n if (connection.sourceConnector == connector) {\n sources.push(connection);\n } else if (connection.targetConnector == connector) {\n targets.push(connection);\n }\n }\n }\n }\n\n for (i = 0; i < sources.length; i++) {\n sources[i].source(null, undoable);\n sources[i].updateModel();\n }\n for (i = 0; i < targets.length; i++) {\n targets[i].target(null, undoable);\n targets[i].updateModel();\n }\n },\n\n _removeConnection: function(connection, undoable) {\n if (connection.sourceConnector) {\n Utils.remove(connection.sourceConnector.connections, connection);\n }\n if (connection.targetConnector) {\n Utils.remove(connection.targetConnector.connections, connection);\n }\n if (undoable) {\n this.undoRedoService.addCompositeItem(new DeleteConnectionUnit(connection));\n }\n\n Utils.remove(this.connections, connection);\n },\n\n _removeDataItems: function(items, recursive) {\n var item, children, shape, idx;\n items = isArray(items) ? items : [items];\n\n while (items.length) {\n item = items.shift();\n shape = this._dataMap[item.uid];\n if (shape) {\n this._removeShapeConnections(shape);\n this._removeItem(shape, false);\n delete this._dataMap[item.uid];\n if (recursive && item.hasChildren && item.loaded()) {\n children = item.children.data();\n for (idx = 0; idx < children.length; idx++) {\n items.push(children[idx]);\n }\n }\n }\n }\n },\n\n _removeShapeConnections: function(shape) {\n var connections = shape.connections();\n var idx;\n\n if (connections) {\n for (idx = 0; idx < connections.length; idx++) {\n this._removeItem(connections[idx], false);\n }\n }\n },\n\n _addDataItem: function(dataItem, undoable) {\n if (!defined(dataItem)) {\n return;\n }\n\n var shape = this._dataMap[dataItem.id];\n if (shape) {\n return shape;\n }\n\n var options = deepExtend({}, this.options.shapeDefaults);\n options.dataItem = dataItem;\n shape = new Shape(options, this);\n this.addShape(shape, undoable !== false);\n this._dataMap[dataItem.id] = shape;\n return shape;\n },\n\n _addDataItemByUid: function(dataItem) {\n if (!defined(dataItem)) {\n return;\n }\n\n var shape = this._dataMap[dataItem.uid];\n if (shape) {\n return shape;\n }\n\n var options = deepExtend({}, this.options.shapeDefaults);\n options.dataItem = dataItem;\n shape = new Shape(options, this);\n this.addShape(shape);\n this._dataMap[dataItem.uid] = shape;\n return shape;\n },\n\n _addDataItems: function(items, parent) {\n var item, idx, shape, parentShape, connection;\n for (idx = 0; idx < items.length; idx++) {\n item = items[idx];\n shape = this._addDataItemByUid(item);\n parentShape = this._addDataItemByUid(parent);\n if (parentShape && !this.connected(parentShape, shape)) { // check if connected to not duplicate connections.\n connection = this.connect(parentShape, shape);\n }\n }\n },\n\n _refreshSource: function(e) {\n var that = this,\n node = e.node,\n action = e.action,\n items = e.items,\n options = that.options,\n idx,\n dataBound;\n\n if (e.field) {\n for (idx = 0; idx < items.length; idx++) {\n if (this._dataMap[items[idx].uid]) {\n this._dataMap[items[idx].uid].redrawVisual();\n }\n }\n return;\n }\n\n if (action == \"remove\") {\n this._removeDataItems(e.items, true);\n } else {\n\n if ((!action || action === \"itemloaded\") && !this._bindingRoots) {\n this._bindingRoots = true;\n dataBound = true;\n }\n\n if (!action && !node) {\n that.clear();\n }\n\n this._addDataItems(items, node);\n\n for (idx = 0; idx < items.length; idx++) {\n items[idx].load();\n }\n }\n\n if (options.layout && (dataBound || action == \"remove\" || action == \"add\")) {\n that.layout(options.layout);\n }\n\n if (dataBound) {\n this.trigger(\"dataBound\");\n this._bindingRoots = false;\n }\n },\n\n _addItem: function(item) {\n if (item instanceof Shape) {\n this.addShape(item);\n } else if (item instanceof Connection) {\n this.addConnection(item);\n }\n },\n\n _createToolBar: function(preventClosing) {\n var diagram = this.toolService.diagram;\n\n if (!this.singleToolBar && diagram.select().length === 1) {\n var element = diagram.select()[0];\n if (element && element.options.editable !== false) {\n var editable = element.options.editable;\n var tools = editable.tools;\n if (this._isEditable && tools.length === 0) {\n if (element instanceof Shape) {\n tools = [\"edit\", \"rotateClockwise\", \"rotateAnticlockwise\"];\n } else if (element instanceof Connection) {\n tools = [\"edit\"];\n }\n\n if (editable && editable.remove !== false) {\n tools.push(\"delete\");\n }\n }\n\n if (tools && tools.length) {\n var padding = 20;\n var point;\n this.singleToolBar = new DiagramToolBar(diagram, {\n tools: tools,\n click: this._toolBarClick.bind(this),\n modal: true,\n popupZIndex: parseInt(diagram.element.closest(\".k-window\").css(\"zIndex\"), 10) + 10\n });\n var popupWidth = outerWidth(this.singleToolBar._popup.element);\n var popupHeight = outerHeight(this.singleToolBar._popup.element);\n if (element instanceof Shape) {\n var shapeBounds = this.modelToView(element.bounds(ROTATED));\n point = new Point(shapeBounds.x, shapeBounds.y).minus(new Point(\n (popupWidth - shapeBounds.width) / 2,\n popupHeight + padding));\n } else if (element instanceof Connection) {\n var connectionBounds = this.modelToView(element.bounds());\n\n point = new Point(connectionBounds.x, connectionBounds.y)\n .minus(new Point(\n (popupWidth - connectionBounds.width - 20) / 2,\n popupHeight + padding\n ));\n }\n\n if (point) {\n if (!this.canvas.translate) {\n point = point.minus(new Point(this.scroller.scrollLeft, this.scroller.scrollTop));\n }\n point = this.viewToDocument(point);\n point = new Point(math.max(point.x, 0), math.max(point.y, 0));\n this.singleToolBar.showAt(point);\n if (preventClosing) {\n this.singleToolBar._popup.one(\"close\", preventDefault);\n }\n } else {\n this._destroyToolBar();\n }\n }\n }\n }\n },\n\n _toolBarClick: function(e) {\n this.trigger(\"toolBarClick\", e);\n this._destroyToolBar();\n },\n\n _normalizePointZoom: function(point) {\n return point.times(1 / this.zoom());\n },\n\n _initialize: function() {\n this.shapes = [];\n this._selectedItems = [];\n this.connections = [];\n this._dataMap = {};\n this._connectionsDataMap = {};\n this._inactiveShapeItems = new InactiveItemsCollection();\n this._deferredConnectionUpdates = [];\n this.undoRedoService = new UndoRedoService({\n undone: this._syncHandler,\n redone: this._syncHandler\n });\n this.id = diagram.randomId();\n },\n\n _fetchFreshData: function() {\n var that = this;\n that._dataSource();\n\n if (that._isEditable) {\n that._connectionDataSource();\n }\n\n if (that.options.autoBind) {\n if (that._isEditable) {\n this._loadingShapes = true;\n this._loadingConnections = true;\n that.dataSource.fetch();\n that.connectionsDataSource.fetch();\n } else {\n that.dataSource.fetch();\n }\n }\n },\n\n _dataSource: function() {\n if (defined(this.options.connectionsDataSource)) {\n this._isEditable = true;\n var dsOptions = this.options.dataSource || {};\n var ds = isArray(dsOptions) ? { data: dsOptions } : dsOptions;\n\n if (this.dataSource && this._shapesRefreshHandler) {\n this.dataSource\n .unbind(\"change\", this._shapesRefreshHandler)\n .unbind(\"requestStart\", this._shapesRequestStartHandler)\n .unbind(\"error\", this._shapesErrorHandler);\n } else {\n this._shapesRefreshHandler = this._refreshShapes.bind(this);\n this._shapesRequestStartHandler = this._shapesRequestStart.bind(this);\n this._shapesErrorHandler = this._error.bind(this);\n }\n\n this.dataSource = kendo.data.DataSource.create(ds)\n .bind(\"change\", this._shapesRefreshHandler)\n .bind(\"requestStart\", this._shapesRequestStartHandler)\n .bind(\"error\", this._shapesErrorHandler);\n } else {\n this._treeDataSource();\n this._isEditable = false;\n }\n },\n\n _connectionDataSource: function() {\n var dsOptions = this.options.connectionsDataSource;\n if (dsOptions) {\n var ds = isArray(dsOptions) ? { data: dsOptions } : dsOptions;\n\n if (this.connectionsDataSource && this._connectionsRefreshHandler) {\n this.connectionsDataSource\n .unbind(\"change\", this._connectionsRefreshHandler)\n .unbind(\"requestStart\", this._connectionsRequestStartHandler)\n .unbind(\"error\", this._connectionsErrorHandler);\n } else {\n this._connectionsRefreshHandler = this._refreshConnections.bind(this);\n this._connectionsRequestStartHandler = this._connectionsRequestStart.bind(this);\n this._connectionsErrorHandler = this._connectionsError.bind(this);\n }\n\n this.connectionsDataSource = kendo.data.DataSource.create(ds)\n .bind(\"change\", this._connectionsRefreshHandler)\n .bind(\"requestStart\", this._connectionsRequestStartHandler)\n .bind(\"error\", this._connectionsErrorHandler);\n }\n },\n\n _shapesRequestStart: function(e) {\n if (e.type == \"read\") {\n this._loadingShapes = true;\n }\n },\n\n _connectionsRequestStart: function(e) {\n if (e.type == \"read\") {\n this._loadingConnections = true;\n }\n },\n\n _error: function() {\n this._loadingShapes = false;\n },\n\n _connectionsError: function() {\n this._loadingConnections = false;\n },\n\n _refreshShapes: function(e) {\n if (e.action === \"remove\") {\n if (this._shouldRefresh()) {\n this._removeShapes(e.items);\n }\n } else if (e.action === \"itemchange\") {\n if (this._shouldRefresh()) {\n this._updateShapes(e.items, e.field);\n }\n } else if (e.action === \"add\") {\n this._inactiveShapeItems.add(e.items);\n } else if (e.action === \"sync\") {\n this._syncShapes(e.items);\n } else {\n this.refresh();\n }\n },\n\n _shouldRefresh: function() {\n return !this._suspended;\n },\n\n _suspendModelRefresh: function() {\n this._suspended = (this._suspended || 0) + 1;\n },\n\n _resumeModelRefresh: function() {\n this._suspended = math.max((this._suspended || 0) - 1, 0);\n },\n\n refresh: function() {\n this._loadingShapes = false;\n if (!this._loadingConnections) {\n this._rebindShapesAndConnections();\n }\n },\n\n _rebindShapesAndConnections: function() {\n this.clear();\n this._addShapes(this.dataSource.view());\n if (this.connectionsDataSource) {\n this._addConnections(this.connectionsDataSource.view(), false);\n }\n\n if (this.options.layout) {\n this.layout(this.options.layout);\n } else {\n this._redrawConnections();\n }\n this.trigger(\"dataBound\");\n },\n\n refreshConnections: function() {\n this._loadingConnections = false;\n if (!this._loadingShapes) {\n this._rebindShapesAndConnections();\n }\n },\n\n _redrawConnections: function() {\n var connections = this.connections;\n for (var idx = 0; idx < connections.length; idx++) {\n connections[idx].refresh();\n }\n },\n\n _removeShapes: function(items) {\n var dataMap = this._dataMap;\n var item, i;\n for (i = 0; i < items.length; i++) {\n item = items[i];\n if (dataMap[item.id]) {\n this.remove(dataMap[item.id], false);\n dataMap[item.id] = null;\n }\n }\n },\n\n _syncShapes: function() {\n var diagram = this;\n var inactiveItems = diagram._inactiveShapeItems;\n inactiveItems.forEach(function(inactiveItem) {\n var dataItem = inactiveItem.dataItem;\n var shape = inactiveItem.element;\n if (!dataItem.isNew()) {\n if (shape) {\n shape._setOptionsFromModel();\n diagram.addShape(shape, inactiveItem.undoable);\n diagram._dataMap[dataItem.id] = shape;\n } else {\n diagram._addDataItem(dataItem);\n }\n inactiveItem.activate();\n inactiveItems.remove(dataItem);\n }\n });\n },\n\n _updateShapes: function(items, field) {\n for (var i = 0; i < items.length; i++) {\n var dataItem = items[i];\n\n var shape = this._dataMap[dataItem.id];\n if (shape) {\n shape.updateOptionsFromModel(dataItem, field);\n }\n }\n },\n\n _addShapes: function(dataItems) {\n for (var i = 0; i < dataItems.length; i++) {\n this._addDataItem(dataItems[i], false);\n }\n },\n\n _refreshConnections: function(e) {\n if (e.action === \"remove\") {\n if (this._shouldRefresh()) {\n this._removeConnections(e.items);\n }\n } else if (e.action === \"add\") {\n this._addConnections(e.items);\n } else if (e.action === \"sync\") {\n //TO DO: include logic to update the connections with different values returned from the server.\n } else if (e.action === \"itemchange\") {\n if (this._shouldRefresh()) {\n this._updateConnections(e.items);\n }\n } else {\n this.refreshConnections();\n }\n },\n\n _removeConnections: function(items) {\n for (var i = 0; i < items.length; i++) {\n this.remove(this._connectionsDataMap[items[i].uid], false);\n this._connectionsDataMap[items[i].uid] = null;\n }\n },\n\n _updateConnections: function(items) {\n for (var i = 0; i < items.length; i++) {\n var dataItem = items[i];\n\n var connection = this._connectionsDataMap[dataItem.uid];\n connection.updateOptionsFromModel(dataItem);\n }\n },\n\n _addConnections: function(connections, undoable) {\n var length = connections.length;\n\n for (var i = 0; i < length; i++) {\n var dataItem = connections[i];\n this._addConnectionDataItem(dataItem, undoable);\n }\n },\n\n _addConnectionDataItem: function(dataItem, undoable) {\n if (!this._connectionsDataMap[dataItem.uid]) {\n var from = this._validateConnector(dataItem.from);\n if (!defined(from) || from === null) {\n from = new Point(dataItem.fromX, dataItem.fromY);\n }\n\n var to = this._validateConnector(dataItem.to);\n if (!defined(to) || to === null) {\n to = new Point(dataItem.toX, dataItem.toY);\n }\n\n if (defined(from) && defined(to)) {\n var options = deepExtend({}, this.options.connectionDefaults);\n options.dataItem = dataItem;\n var connection = new Connection(from, to, options);\n\n this._connectionsDataMap[dataItem.uid] = connection;\n this.addConnection(connection, undoable);\n }\n }\n },\n\n _validateConnector: function(value) {\n var connector;\n\n if (defined(value) && value !== null) {\n connector = this._dataMap[value];\n }\n\n return connector;\n },\n\n _treeDataSource: function() {\n var that = this,\n options = that.options,\n dataSource = options.dataSource;\n\n dataSource = isArray(dataSource) ? { data: dataSource } : dataSource;\n\n if (dataSource instanceof kendo.data.DataSource && !(dataSource instanceof kendo.data.HierarchicalDataSource)) {\n throw new Error(\"Incorrect DataSource type. If a single dataSource instance is set to the diagram then it should be a HierarchicalDataSource. You should set only the options instead of an instance or a HierarchicalDataSource instance or supply connectionsDataSource as well.\");\n }\n\n if (!dataSource.fields) {\n dataSource.fields = [\n { field: \"text\" },\n { field: \"url\" },\n { field: \"spriteCssClass\" },\n { field: \"imageUrl\" }\n ];\n }\n if (that.dataSource && that._refreshHandler) {\n that._unbindDataSource();\n }\n\n that._refreshHandler = that._refreshSource.bind(that);\n that._errorHandler = that._error.bind(that);\n\n that.dataSource = HierarchicalDataSource.create(dataSource)\n .bind(CHANGE, that._refreshHandler)\n .bind(ERROR, that._errorHandler);\n },\n\n _unbindDataSource: function() {\n var that = this;\n\n that.dataSource.unbind(CHANGE, that._refreshHandler).unbind(ERROR, that._errorHandler);\n },\n\n _adorn: function(adorner, isActive) {\n if (isActive !== undefined$1 && adorner) {\n if (isActive) {\n this._adorners.push(adorner);\n this.adornerLayer.append(adorner.visual);\n }\n else {\n Utils.remove(this._adorners, adorner);\n this.adornerLayer.remove(adorner.visual);\n }\n }\n },\n\n _showConnectors: function(shape, value) {\n if (value) {\n this._connectorsAdorner.show(shape);\n } else {\n this._connectorsAdorner.destroy();\n }\n },\n\n _updateAdorners: function() {\n var adorners = this._adorners;\n\n for (var i = 0; i < adorners.length; i++) {\n var adorner = adorners[i];\n\n if (adorner.refreshBounds) {\n adorner.refreshBounds();\n }\n adorner.refresh();\n }\n },\n\n _refresh: function() {\n for (var i = 0; i < this.connections.length; i++) {\n this.connections[i].refresh();\n }\n },\n\n _destroyToolBar: function() {\n if (this.singleToolBar) {\n this.singleToolBar.hide();\n this.singleToolBar.destroy();\n this.singleToolBar = null;\n }\n },\n\n _destroyGlobalToolBar: function() {\n if (this.toolBar) {\n this.toolBar.hide();\n this.toolBar.destroy();\n this.toolBar = null;\n }\n },\n\n exportDOMVisual: function() {\n var viewBox = this.canvas._viewBox;\n var scrollOffset = geom.transform()\n .translate(-viewBox.x, -viewBox.y);\n\n var viewRect = new geom.Rect([0, 0], [viewBox.width, viewBox.height]);\n var clipPath = draw.Path.fromRect(viewRect);\n var wrap = new draw.Group({ transform: scrollOffset });\n var clipWrap = new draw.Group({ clip: clipPath });\n var root = this.canvas.drawingElement.children[0];\n\n clipWrap.append(wrap);\n\n // Don't reparent the root\n wrap.children.push(root);\n\n return clipWrap;\n },\n\n exportVisual: function() {\n var scale = geom.transform().scale(1 / this._zoom);\n var wrap = new draw.Group({\n transform: scale\n });\n\n var root = this.mainLayer.drawingElement;\n wrap.children.push(root);\n\n return wrap;\n },\n\n _syncChanges: function() {\n this._syncShapeChanges();\n this._syncConnectionChanges();\n },\n\n _syncShapeChanges: function() {\n if (this.dataSource && this._isEditable) {\n this.dataSource.sync();\n }\n },\n\n _syncConnectionChanges: function() {\n var that = this;\n if (that.connectionsDataSource && that._isEditable) {\n $.when.apply($, that._deferredConnectionUpdates).then(function() {\n that.connectionsDataSource.sync();\n });\n that.deferredConnectionUpdates = [];\n }\n }\n });\n\n dataviz.ExportMixin.extend(Diagram.fn, true);\n\n if (kendo.PDFMixin) {\n kendo.PDFMixin.extend(Diagram.fn);\n }\n\n function filterShapeDataItem(dataItem) {\n var result = {};\n\n dataItem = dataItem || {};\n\n if (defined(dataItem.text) && dataItem.text !== null) {\n result.text = dataItem.text;\n }\n\n if (defined(dataItem.x) && dataItem.x !== null) {\n result.x = dataItem.x;\n }\n\n if (defined(dataItem.y) && dataItem.y !== null) {\n result.y = dataItem.y;\n }\n\n if (defined(dataItem.width) && dataItem.width !== null) {\n result.width = dataItem.width;\n }\n\n if (defined(dataItem.height) && dataItem.height !== null) {\n result.height = dataItem.height;\n }\n\n if (defined(dataItem.type) && dataItem.type !== null) {\n result.type = dataItem.type;\n }\n\n return result;\n }\n\n function filterConnectionDataItem(dataItem) {\n var result = {};\n\n dataItem = dataItem || {};\n\n if (defined(dataItem.text) && dataItem.text !== null) {\n result.content = dataItem.text;\n }\n\n if (defined(dataItem.type) && dataItem.type !== null) {\n result.type = dataItem.type;\n }\n\n if (defined(dataItem.from) && dataItem.from !== null) {\n result.from = dataItem.from;\n }\n\n if (defined(dataItem.fromConnector) && dataItem.fromConnector !== null) {\n result.fromConnector = dataItem.fromConnector;\n }\n\n if (defined(dataItem.fromX) && dataItem.fromX !== null) {\n result.fromX = dataItem.fromX;\n }\n\n if (defined(dataItem.fromY) && dataItem.fromY !== null) {\n result.fromY = dataItem.fromY;\n }\n\n if (defined(dataItem.to) && dataItem.to !== null) {\n result.to = dataItem.to;\n }\n\n if (defined(dataItem.toConnector) && dataItem.toConnector !== null) {\n result.toConnector = dataItem.toConnector;\n }\n\n if (defined(dataItem.toX) && dataItem.toX !== null) {\n result.toX = dataItem.toX;\n }\n\n if (defined(dataItem.toY) && dataItem.toY !== null) {\n result.toY = dataItem.toY;\n }\n\n return result;\n }\n\n\n var DiagramToolBar = kendo.Observable.extend({\n init: function(diagram, options) {\n kendo.Observable.fn.init.call(this);\n this.diagram = diagram;\n this.options = deepExtend({}, this.options, options);\n this._tools = [];\n this.createToolBar();\n this.createTools();\n this.appendTools();\n\n if (this.options.modal) {\n this.createPopup();\n }\n\n this.bind(this.events, options);\n },\n\n events: [\"click\"],\n\n createPopup: function() {\n this.container = $(\"
\").append(this.element);\n this._popup = this.container.kendoPopup({}).getKendoPopup();\n },\n\n appendTools: function() {\n for (var i = 0; i < this._tools.length; i++) {\n var tool = this._tools[i];\n if (tool.buttons && tool.buttons.length || !defined(tool.buttons)) {\n this._toolBar.add(tool);\n }\n }\n },\n\n createToolBar: function() {\n this.element = $(\"
\");\n this._toolBar = this.element\n .kendoToolBar({\n click: this.click.bind(this),\n resizable: false\n }).getKendoToolBar();\n\n this.element.css(\"border\", \"none\");\n },\n\n createTools: function() {\n for (var i = 0; i < this.options.tools.length; i++) {\n this.createTool(this.options.tools[i]);\n }\n },\n\n createTool: function(tool) {\n if (!isPlainObject(tool)) {\n tool = {\n name: tool\n };\n }\n var toolName = tool.name + \"Tool\";\n if (this[toolName]) {\n this[toolName](tool);\n } else {\n this._tools.push(deepExtend({}, tool, {\n attributes: this._setAttributes({ action: tool.name })\n }));\n }\n },\n\n showAt: function(point) {\n var popupZIndex = parseInt(this.options.popupZIndex, 10);\n\n if (this._popup) {\n this._popup.open(point.x, point.y);\n\n if (popupZIndex) {\n this._popup.wrapper.css(\"zIndex\", popupZIndex);\n }\n }\n },\n\n hide: function() {\n if (this._popup) {\n this._popup.close();\n }\n },\n\n newGroup: function() {\n return {\n type: \"buttonGroup\",\n buttons: []\n };\n },\n\n editTool: function() {\n this._tools.push({\n icon: \"edit\",\n showText: \"overflow\",\n type: \"button\",\n text: \"Edit\",\n attributes: this._setAttributes({ action: \"edit\" })\n });\n },\n\n deleteTool: function() {\n this._tools.push({\n icon: \"close\",\n showText: \"overflow\",\n type: \"button\",\n text: \"Delete\",\n attributes: this._setAttributes({ action: \"delete\" })\n });\n },\n\n rotateAnticlockwiseTool: function(options) {\n this._appendGroup(\"rotate\");\n this._rotateGroup.buttons.push({\n icon: \"rotate-left\",\n showText: \"overflow\",\n text: \"RotateAnticlockwise\",\n group: \"rotate\",\n attributes: this._setAttributes({ action: \"rotateAnticlockwise\", step: options.step })\n });\n },\n\n rotateClockwiseTool: function(options) {\n this._appendGroup(\"rotate\");\n this._rotateGroup.buttons.push({\n icon: \"rotate-right\",\n attributes: this._setAttributes({ action: \"rotateClockwise\", step: options.step }),\n showText: \"overflow\",\n text: \"RotateClockwise\",\n group: \"rotate\"\n });\n },\n\n createShapeTool: function() {\n this._appendGroup(\"create\");\n this._createGroup.buttons.push({\n icon: \"shape\",\n showText: \"overflow\",\n text: \"CreateShape\",\n group: \"create\",\n attributes: this._setAttributes({ action: \"createShape\" })\n });\n },\n\n createConnectionTool: function() {\n this._appendGroup(\"create\");\n this._createGroup.buttons.push({\n icon: \"connector\",\n showText: \"overflow\",\n text: \"CreateConnection\",\n group: \"create\",\n attributes: this._setAttributes({ action: \"createConnection\" })\n });\n },\n\n undoTool: function() {\n this._appendGroup(\"history\");\n this._historyGroup.buttons.push({\n icon: \"undo\",\n showText: \"overflow\",\n text: \"Undo\",\n group: \"history\",\n attributes: this._setAttributes({ action: \"undo\" })\n });\n },\n\n redoTool: function() {\n this._appendGroup(\"history\");\n this._historyGroup.buttons.push({\n icon: \"redo\",\n showText: \"overflow\",\n text: \"Redo\",\n group: \"history\",\n attributes: this._setAttributes({ action: \"redo\" })\n });\n },\n\n _appendGroup: function(name) {\n var prop = \"_\" + name + \"Group\";\n if (!this[prop]) {\n this[prop] = this.newGroup();\n this._tools.push(this[prop]);\n }\n },\n\n _setAttributes: function(attributes) {\n var attr = {};\n\n if (attributes.action) {\n attr[kendo.attr(\"action\")] = attributes.action;\n }\n\n if (attributes.step) {\n attr[kendo.attr(\"step\")] = attributes.step;\n }\n\n return attr;\n },\n\n _getAttributes: function(element) {\n var attr = {};\n\n var action = element.attr(kendo.attr(\"action\"));\n if (action) {\n attr.action = action;\n }\n\n var step = element.attr(kendo.attr(\"step\"));\n if (step) {\n attr.step = step;\n }\n\n return attr;\n },\n\n click: function(e) {\n var attributes = this._getAttributes($(e.target));\n var action = attributes.action;\n\n if (action && this[action]) {\n this[action](attributes);\n }\n\n this.trigger(\"click\", this.eventData(action, e.target));\n },\n\n eventData: function(action, target) {\n var elements = this.selectedElements(),\n length = elements.length,\n shapes = [], connections = [], element;\n\n for (var idx = 0; idx < length; idx++) {\n element = elements[idx];\n if (element instanceof Shape) {\n shapes.push(element);\n } else {\n connections.push(element);\n }\n }\n\n return {\n shapes: shapes,\n connections: connections,\n action: action,\n target: target\n };\n },\n\n \"delete\": function() {\n var diagram = this.diagram;\n var toRemove = diagram._triggerRemove(this.selectedElements());\n if (toRemove.length) {\n this.diagram.remove(toRemove, true);\n this.diagram._syncChanges();\n }\n },\n\n edit: function() {\n var selectedElemens = this.selectedElements();\n if (selectedElemens.length === 1) {\n this.diagram.edit(selectedElemens[0]);\n }\n },\n\n rotateClockwise: function(options) {\n var angle = parseFloat(options.step || 90);\n this._rotate(angle);\n },\n\n rotateAnticlockwise: function(options) {\n var angle = parseFloat(options.step || 90);\n this._rotate(-angle);\n },\n\n _rotate: function(angle) {\n var adorner = this.diagram._resizingAdorner;\n adorner.angle(adorner.angle() + angle);\n adorner.rotate();\n },\n\n selectedElements: function() {\n return this.diagram.select();\n },\n\n createShape: function() {\n this.diagram.createShape();\n },\n\n createConnection: function() {\n this.diagram.createConnection();\n },\n\n undo: function() {\n this.diagram.undo();\n },\n\n redo: function() {\n this.diagram.redo();\n },\n\n destroy: function() {\n this.diagram = null;\n this.element = null;\n this.options = null;\n\n if (this._toolBar) {\n this._toolBar.destroy();\n }\n\n if (this._popup) {\n this._popup.destroy();\n }\n }\n });\n\n var Editor = kendo.Observable.extend({\n init: function(element, options) {\n kendo.Observable.fn.init.call(this);\n\n this.options = extend(true, {}, this.options, options);\n this.element = element;\n this.model = this.options.model;\n this.fields = this._getFields();\n this._initContainer();\n this.createEditable();\n },\n\n options: {\n editors: {}\n },\n\n _initContainer: function() {\n this.wrapper = this.element;\n },\n\n createEditable: function() {\n var options = this.options;\n\n this.editable = new kendo.ui.Editable(this.wrapper, {\n fields: this.fields,\n target: options.target,\n clearContainer: false,\n model: this.model\n });\n },\n\n _isEditable: function(field) {\n return this.model.editable && this.model.editable(field);\n },\n\n _getFields: function() {\n var fields = [];\n var modelFields = this.model.fields;\n\n for (var field in modelFields) {\n var result = {};\n if (this._isEditable(field)) {\n var editor = this.options.editors[field];\n if (editor) {\n result.editor = editor;\n }\n result.field = field;\n fields.push(result);\n }\n }\n\n return fields;\n },\n\n end: function() {\n return this.editable.end();\n },\n\n destroy: function() {\n this.editable.destroy();\n this.editable.element.find(\"[\" + kendo.attr(\"container-for\") + \"]\").empty();\n this.model = this.wrapper = this.element = this.columns = this.editable = null;\n }\n });\n\n var PopupEditor = Editor.extend({\n init: function(element, options) {\n Editor.fn.init.call(this, element, options);\n this.bind(this.events, this.options);\n\n this.open();\n },\n\n events: [ \"update\", \"cancel\" ],\n\n options: {\n window: {\n modal: true,\n resizable: false,\n draggable: true,\n title: \"Edit\",\n visible: false\n }\n },\n\n _initContainer: function() {\n var that = this;\n this.wrapper = $('
')\n .attr(kendo.attr(\"uid\"), this.model.uid);\n\n var formContent = \"\";\n\n if (this.options.template) {\n formContent += this._renderTemplate();\n this.fields = [];\n } else {\n formContent += this._renderFields();\n }\n\n formContent += this._renderButtons();\n\n this.wrapper.append(\n $('
').append(formContent));\n\n this.window = new kendo.ui.Window(this.wrapper.appendTo(this.element), this.options.window);\n this.window.bind(\"close\", function(e) {\n //The bellow line is required due to: draggable window in IE, change event will be triggered while the window is closing\n if (e.userTriggered) {\n e.sender.element.trigger(\"focus\");\n that._cancelClick(e);\n }\n });\n\n this._attachButtonEvents();\n },\n\n _renderTemplate: function() {\n var template = this.options.template;\n\n if (typeof template === \"string\") {\n template = kendo.unescape(template);\n }\n\n template = kendo.template(template)(this.model);\n\n return template;\n },\n\n _renderFields: function() {\n var form = \"\";\n for (var i = 0; i < this.fields.length; i++) {\n var field = this.fields[i];\n\n form += '
';\n\n if (this._isEditable(field.field)) {\n form += '
';\n }\n }\n\n return form;\n },\n\n _renderButtons: function() {\n var form = '
';\n form += this._createButton(\"update\");\n form += this._createButton(\"cancel\");\n form += '
';\n return form;\n },\n\n _createButton: function(name) {\n return kendo.template(BUTTON_TEMPLATE)(defaultButtons[name]);\n },\n\n _attachButtonEvents: function() {\n this._cancelClickHandler = this._cancelClick.bind(this);\n this.window.element.on(CLICK + NS, \"a.k-diagram-cancel\", this._cancelClickHandler);\n\n this._updateClickHandler = this._updateClick.bind(this);\n this.window.element.on(CLICK + NS, \"a.k-diagram-update\", this._updateClickHandler);\n },\n\n _updateClick: function(e) {\n e.preventDefault();\n this.trigger(\"update\");\n },\n\n _cancelClick: function(e) {\n e.preventDefault();\n this.trigger(\"cancel\");\n },\n\n open: function() {\n this.window.center().open();\n },\n\n close: function() {\n this.window.bind(\"deactivate\", this.destroy.bind(this)).close();\n },\n\n destroy: function() {\n this.window.close().destroy();\n this.window.element.off(CLICK + NS, \"a.k-diagram-cancel\", this._cancelClickHandler);\n this.window.element.off(CLICK + NS, \"a.k-diagram-update\", this._updateClickHandler);\n this._cancelClickHandler = null;\n this._editUpdateClickHandler = null;\n this.window = null;\n Editor.fn.destroy.call(this);\n }\n });\n\n function connectionSelector(container, options) {\n var model = this.dataSource.reader.model;\n if (model) {\n var textField = model.fn.fields.text ? \"text\" : model.idField;\n $(\"\")\n .appendTo(container).kendoDropDownList({\n dataValueField: model.idField,\n dataTextField: textField,\n dataSource: this.dataSource.data().toJSON(),\n optionLabel: \" \",\n valuePrimitive: true\n });\n }\n }\n\n function InactiveItem(dataItem) {\n this.dataItem = dataItem;\n this.callbacks = [];\n }\n\n InactiveItem.fn = InactiveItem.prototype = {\n onActivate: function(callback) {\n var deffered = $.Deferred();\n this.callbacks.push({\n callback: callback,\n deferred: deffered\n });\n return deffered;\n },\n\n activate: function() {\n var callbacks = this.callbacks;\n var item;\n for (var idx = 0; idx < callbacks.length; idx++) {\n item = this.callbacks[idx];\n item.callback(this.dataItem);\n item.deferred.resolve();\n }\n this.callbacks = [];\n }\n };\n\n function InactiveItemsCollection() {\n this.items = {};\n }\n\n InactiveItemsCollection.fn = InactiveItemsCollection.prototype = {\n add: function(items) {\n for (var idx = 0; idx < items.length; idx++) {\n this.items[items[idx].uid] = new InactiveItem(items[idx]);\n }\n },\n\n forEach: function(callback) {\n for (var uid in this.items) {\n callback(this.items[uid]);\n }\n },\n\n getByUid: function(uid) {\n return this.items[uid];\n },\n\n remove: function(item) {\n delete this.items[item.uid];\n }\n };\n\n var QuadRoot = Class.extend({\n init: function() {\n this.shapes = [];\n },\n\n _add: function(shape, bounds) {\n this.shapes.push({\n bounds: bounds,\n shape: shape\n });\n shape._quadNode = this;\n },\n\n insert: function(shape, bounds) {\n this._add(shape, bounds);\n },\n\n remove: function(shape) {\n var shapes = this.shapes;\n var length = shapes.length;\n\n for (var idx = 0; idx < length; idx++) {\n if (shapes[idx].shape === shape) {\n shapes.splice(idx, 1);\n break;\n }\n }\n },\n\n hitTestRect: function(rect, exclude) {\n var shapes = this.shapes;\n var length = shapes.length;\n\n for (var i = 0; i < length; i++) {\n if (this._testRect(shapes[i].shape, rect) && !dataviz.inArray(shapes[i].shape, exclude)) {\n return true;\n }\n }\n },\n\n _testRect: function(shape, rect) {\n var angle = shape.rotate().angle;\n var bounds = shape.bounds();\n var hit;\n if (!angle) {\n hit = bounds.overlaps(rect);\n } else {\n hit = Intersect.rects(rect, bounds, -angle);\n }\n return hit;\n }\n });\n\n var QuadNode = QuadRoot.extend({\n init: function(rect) {\n QuadRoot.fn.init.call(this);\n this.children = [];\n this.rect = rect;\n },\n\n inBounds: function(rect) {\n var nodeRect = this.rect;\n var nodeBottomRight = nodeRect.bottomRight();\n var bottomRight = rect.bottomRight();\n var inBounds = nodeRect.x <= rect.x && nodeRect.y <= rect.y && bottomRight.x <= nodeBottomRight.x &&\n bottomRight.y <= nodeBottomRight.y;\n return inBounds;\n },\n\n overlapsBounds: function(rect) {\n return this.rect.overlaps(rect);\n },\n\n insert: function(shape, bounds) {\n var inserted = false;\n var children = this.children;\n var length = children.length;\n if (this.inBounds(bounds)) {\n if (!length && this.shapes.length < 4) {\n this._add(shape, bounds);\n } else {\n if (!length) {\n this._initChildren();\n }\n\n for (var idx = 0; idx < children.length; idx++) {\n if (children[idx].insert(shape, bounds)) {\n inserted = true;\n break;\n }\n }\n\n if (!inserted) {\n this._add(shape, bounds);\n }\n }\n inserted = true;\n }\n\n return inserted;\n },\n\n _initChildren: function() {\n var rect = this.rect,\n children = this.children,\n shapes = this.shapes,\n center = rect.center(),\n halfWidth = rect.width / 2,\n halfHeight = rect.height / 2,\n childIdx, shapeIdx;\n\n children.push(\n new QuadNode(new Rect(rect.x, rect.y, halfWidth, halfHeight)),\n new QuadNode(new Rect(center.x, rect.y, halfWidth, halfHeight)),\n new QuadNode(new Rect(rect.x, center.y, halfWidth, halfHeight)),\n new QuadNode(new Rect(center.x, center.y, halfWidth, halfHeight))\n );\n for (shapeIdx = shapes.length - 1; shapeIdx >= 0; shapeIdx--) {\n for (childIdx = 0; childIdx < children.length; childIdx++) {\n if (children[childIdx].insert(shapes[shapeIdx].shape, shapes[shapeIdx].bounds)) {\n shapes.splice(shapeIdx, 1);\n break;\n }\n }\n }\n },\n\n hitTestRect: function(rect, exclude) {\n var idx;\n var children = this.children;\n var length = children.length;\n var hit = false;\n\n if (this.overlapsBounds(rect)) {\n if (QuadRoot.fn.hitTestRect.call(this, rect, exclude)) {\n hit = true;\n } else {\n for (idx = 0; idx < length; idx++) {\n if (children[idx].hitTestRect(rect, exclude)) {\n hit = true;\n break;\n }\n }\n }\n }\n\n return hit;\n }\n });\n\n var ShapesQuadTree = Class.extend({\n ROOT_SIZE: 1000,\n\n init: function(diagram) {\n var boundsChangeHandler = this._boundsChange.bind(this);\n diagram.bind(ITEMBOUNDSCHANGE, boundsChangeHandler);\n diagram.bind(ITEMROTATE, boundsChangeHandler);\n this.initRoots();\n },\n\n initRoots: function() {\n this.rootMap = {};\n this.root = new QuadRoot();\n },\n\n clear: function() {\n this.initRoots();\n },\n\n _boundsChange: function(e) {\n if (e.item._quadNode) {\n e.item._quadNode.remove(e.item);\n }\n this.insert(e.item);\n },\n\n insert: function(shape) {\n var bounds = shape.bounds(ROTATED);\n var rootSize = this.ROOT_SIZE;\n var sectors = this.getSectors(bounds);\n var x = sectors[0][0];\n var y = sectors[1][0];\n\n if (this.inRoot(sectors)) {\n this.root.insert(shape, bounds);\n } else {\n if (!this.rootMap[x]) {\n this.rootMap[x] = {};\n }\n\n if (!this.rootMap[x][y]) {\n this.rootMap[x][y] = new QuadNode(\n new Rect(x * rootSize, y * rootSize, rootSize, rootSize)\n );\n }\n\n this.rootMap[x][y].insert(shape, bounds);\n }\n },\n\n remove: function(shape) {\n if (shape._quadNode) {\n shape._quadNode.remove(shape);\n }\n },\n\n inRoot: function(sectors) {\n return sectors[0].length > 1 || sectors[1].length > 1;\n },\n\n getSectors: function(rect) {\n var rootSize = this.ROOT_SIZE;\n var bottomRight = rect.bottomRight();\n var bottomX = math.floor(bottomRight.x / rootSize);\n var bottomY = math.floor(bottomRight.y / rootSize);\n var sectors = [[],[]];\n for (var x = math.floor(rect.x / rootSize); x <= bottomX; x++) {\n sectors[0].push(x);\n }\n for (var y = math.floor(rect.y / rootSize); y <= bottomY; y++) {\n sectors[1].push(y);\n }\n return sectors;\n },\n\n hitTestRect: function(rect, exclude) {\n var sectors = this.getSectors(rect);\n var xIdx, yIdx, x, y;\n var root;\n\n if (this.root.hitTestRect(rect, exclude)) {\n return true;\n }\n\n for (xIdx = 0; xIdx < sectors[0].length; xIdx++) {\n x = sectors[0][xIdx];\n for (yIdx = 0; yIdx < sectors[1].length; yIdx++) {\n y = sectors[1][yIdx];\n root = (this.rootMap[x] || {})[y];\n if (root && root.hitTestRect(rect, exclude)) {\n return true;\n }\n }\n }\n\n return false;\n }\n });\n\n function cloneDataItem(dataItem) {\n var result = dataItem;\n if (dataItem instanceof kendo.data.Model) {\n result = dataItem.toJSON();\n result[dataItem.idField] = dataItem._defaultId;\n }\n return result;\n }\n\n function splitDiagramElements(elements) {\n var connections = [];\n var shapes = [];\n var element, idx;\n for (idx = 0; idx < elements.length; idx++) {\n element = elements[idx];\n if (element instanceof Shape) {\n shapes.push(element);\n } else {\n connections.push(element);\n }\n }\n return {\n shapes: shapes,\n connections: connections\n };\n }\n\n function createModel(dataSource, model) {\n if (dataSource.reader.model) {\n return new dataSource.reader.model(model);\n }\n\n return new kendo.data.ObservableObject(model);\n }\n\n function clearField(field, model) {\n if (defined(model[field])) {\n model.set(field, null);\n }\n }\n\n function copyDefaultOptions(mainOptions, elementOptions, fields) {\n var field;\n for (var idx = 0; idx < fields.length; idx++) {\n field = fields[idx];\n if (elementOptions && !defined(elementOptions[field])) {\n elementOptions[field] = mainOptions[field];\n }\n }\n }\n\n function translateToOrigin(visual) {\n var bbox = visual.drawingContainer().clippedBBox(null);\n if (bbox.origin.x !== 0 || bbox.origin.y !== 0) {\n visual.position(-bbox.origin.x, -bbox.origin.y);\n }\n }\n\n function preventDefault(e) {\n e.preventDefault();\n }\n\n dataviz.ui.plugin(Diagram);\n\n deepExtend(diagram, {\n Shape: Shape,\n Connection: Connection,\n Connector: Connector,\n DiagramToolBar: DiagramToolBar,\n QuadNode: QuadNode,\n QuadRoot: QuadRoot,\n ShapesQuadTree: ShapesQuadTree,\n PopupEditor: PopupEditor\n });\n })(window.kendo.jQuery);\n\n var __meta__ = {\n id: \"dataviz.diagram\",\n name: \"Diagram\",\n category: \"dataviz\",\n description: \"The Kendo DataViz Diagram \",\n depends: [ \"data\", \"userevents\", \"mobile.scroller\", \"draganddrop\", \"drawing\", \"dataviz.core\", \"dataviz.themes\", \"toolbar\" ],\n features: [{\n id: \"dataviz.diagram-pdf-export\",\n name: \"PDF export\",\n description: \"Export Diagram as PDF\",\n depends: [ \"pdf\" ]\n },{\n id: \"dataviz.diagram-editing\",\n name: \"Editing\",\n description: \"Support for model editing\",\n depends: [ \"editable\", \"window\", \"dropdownlist\" ]\n }]\n };\n\n}));\n"]}