| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -251,9 +251,14 @@ class PhysicsEngine { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      this.physicsUpdateHandler = (properties) => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (properties.options.physics !== undefined) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if (properties.options.physics) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            let nodes = {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            nodes[properties.id] = this.createPhysicsNode(properties.id); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            this.physicsWorker.postMessage({ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              type: 'addElements', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              data: this.createPhysicsNode(properties.id) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              data: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                nodes: nodes, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                edges: {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            this.physicsWorker.postMessage({type: 'removeElements', data: { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -480,9 +485,7 @@ class PhysicsEngine { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  createPhysicsNode(nodeId) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let node = this.body.nodes[nodeId]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (node && node.options.physics === true) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // for updating fixed later
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      this.physicsBody.physicsNodeIndices.push(nodeId); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (node) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      return { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        id: node.id.toString(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        x: node.x, | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -498,6 +501,36 @@ class PhysicsEngine { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  createPhysicsEdge(edgeId) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let edge = this.body.edges[edgeId]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (edge && edge.options.physics === true && edge.connected === true) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let physicsEdge = { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        connected: edge.connected, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        id: edge.id, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        edgeType: {}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        toId: edge.toId, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        fromId: edge.fromId, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        to: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          id: edge.to.id | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        }, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        from: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          id: edge.from.id | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        }, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        options: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          length: edge.length | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (edge.edgeType.via) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        physicsEdge.edgeType = { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          via: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            id: edge.edgeType.via.id | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      return physicsEdge; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  /** | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   * Nodes and edges can have the physics toggles on or off. A collection of indices is created here so we can skip the check all the time. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					   * | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -510,91 +543,60 @@ class PhysicsEngine { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this.physicsBody.forces = {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this.physicsBody.physicsNodeIndices = []; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    this.physicsBody.physicsEdgeIndices = []; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let physicsWorkerNodes = {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    let physicsWorkerEdges = {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (this.physicsWorker) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let physicsWorkerNodes = {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let physicsWorkerEdges = {}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      for (let nodeId in nodes) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (nodes.hasOwnProperty(nodeId)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          physicsWorkerNodes[nodeId] = this.createPhysicsNode(nodeId); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      for (let edgeId in edges) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (edges.hasOwnProperty(edgeId)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          let edge = edges[edgeId]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if (edge.options.physics === true && edge.connected === true) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            physicsWorkerEdges[edgeId] = { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              connected: edge.connected, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              id: edge.id, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              edgeType: {}, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              toId: edge.toId, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              fromId: edge.fromId, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              to: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                id: edge.to.id | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              }, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              from: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                id: edge.from.id | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              }, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              options: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                length: edge.length | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if (edge.edgeType.via) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              physicsWorkerEdges[edgeId].edgeType = { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                via: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                  id: edge.edgeType.via.id | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					              } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // get node indices for physics
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (let nodeId in nodes) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (nodes.hasOwnProperty(nodeId)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (nodes[nodeId].options.physics === true) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          this.physicsBody.physicsNodeIndices.push(nodeId); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if (this.physicsWorker) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            physicsWorkerNodes[nodeId] = this.createPhysicsNode(nodeId); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      this.physicsWorker.postMessage({ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        type: 'physicsObjects', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        data: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          nodes: physicsWorkerNodes, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          edges: physicsWorkerEdges | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // get node indices for physics
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      for (let nodeId in nodes) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (nodes.hasOwnProperty(nodeId)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if (nodes[nodeId].options.physics === true) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            this.physicsBody.physicsNodeIndices.push(nodeId); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // get edge indices for physics
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (let edgeId in edges) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (edges.hasOwnProperty(edgeId)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (edges[edgeId].options.physics === true) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          this.physicsBody.physicsEdgeIndices.push(edgeId); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if (this.physicsWorker) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            physicsWorkerEdges[edgeId] = this.createPhysicsEdge(edgeId); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // get edge indices for physics
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      for (let edgeId in edges) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (edges.hasOwnProperty(edgeId)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          if (edges[edgeId].options.physics === true) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            this.physicsBody.physicsEdgeIndices.push(edgeId); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // get the velocity and the forces vector
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (let i = 0; i < this.physicsBody.physicsNodeIndices.length; i++) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      let nodeId = this.physicsBody.physicsNodeIndices[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      this.physicsBody.forces[nodeId] = {x: 0, y: 0}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // get the velocity and the forces vector
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      for (let i = 0; i < this.physicsBody.physicsNodeIndices.length; i++) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        let nodeId = this.physicsBody.physicsNodeIndices[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        this.physicsBody.forces[nodeId] = {x: 0, y: 0}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // forces can be reset because they are recalculated. Velocities have to persist.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (this.physicsBody.velocities[nodeId] === undefined) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        this.physicsBody.velocities[nodeId] = {x: 0, y: 0}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // forces can be reset because they are recalculated. Velocities have to persist.
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (this.physicsBody.velocities[nodeId] === undefined) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          this.physicsBody.velocities[nodeId] = {x: 0, y: 0}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // clean deleted nodes from the velocity vector
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (let nodeId in this.physicsBody.velocities) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      if (nodes[nodeId] === undefined) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        delete this.physicsBody.velocities[nodeId]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      // clean deleted nodes from the velocity vector
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      for (let nodeId in this.physicsBody.velocities) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (nodes[nodeId] === undefined) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          delete this.physicsBody.velocities[nodeId]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (this.physicsWorker) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      this.physicsWorker.postMessage({ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        type: 'initPhysicsData', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        data: { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          nodes: physicsWorkerNodes, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					          edges: physicsWorkerEdges | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					      }); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				
					
 |