Node=function(f,e){this.label=f;this.repulsion=e;this.dy=this.dx=this.y=this.x=0};Edge=function(f,e){this.from=f;this.to=e;this.length=40};
Graph=function(f,e,h){this.nodes=[];this.edges=[];this.foreground=f||"#CAE6E8";this.background=e||"#313F54";this.colorlines=h||"#2B2E2E";this.findNode=function(a){for(var c=0;c<this.nodes.length;c++)if(this.nodes[c].label==a)return this.nodes[c];return null};this.addNode=function(a,c){var b=this.findNode(a);if(b)return b;b=new Node(a,c||100);this.nodes.push(b);return b};this.addEdge=function(a,c,b){a=new Edge(this.addNode(a,b||100),this.addNode(c,b||100));this.edges.push(a);return a};this.render=
function(a,c,b){a=document.getElementById(a);if(a.getContext){a=a.getContext("2d");a.clearRect(0,0,c,b);a.strokeStyle=this.colorlines;a.beginPath();for(var d=0;d<this.edges.length;d++)a.moveTo(this.edges[d].from.x+c/2,0.75*this.edges[d].from.y+b/2),a.lineTo(this.edges[d].to.x+c/2,0.75*this.edges[d].to.y+b/2);a.stroke();a.font="10px Sans-Serif";for(d=0;d<this.nodes.length;d++)a.fillStyle=this.background,a.fillRect(this.nodes[d].x+c/2-50,0.75*this.nodes[d].y+b/2-8,100,16),a.fillStyle=this.foreground,
a.fillText(this.nodes[d].label,this.nodes[d].x+c/2-40,0.75*this.nodes[d].y+b/2+4)}};this.rigidity=0.25;this.damping=!1;this.maxMotion=0;this.start=function(){this.damping=!0};this.stop=function(){this.damping=!1;this.damper=1};this.reset=function(){this.damping=!0;this.damper=1};this.freeze=function(){this.damping=!0;this.damper=0.3<this.damper?0.3:0};this.damp=function(){this.damping&&0.001>=this.motionRatio&&((0.2>this.maxMotion||1<this.maxMotion&&0.9>this.damper)&&0.01<this.damper?this.damper-=
0.01:0.4>this.maxMotion&&0.003<this.damper?this.damper-=0.003:1.0E-4<this.damper&&(this.damper-=1.0E-4));if(0.001>this.maxMotion&&this.damping)this.damper=0};this.moveNodes=function(){this.lastMaxMotion=this.maxMotion;for(var a=this.maxMotionA=0;a<this.nodes.length;a++)this.layoutNode(this.nodes[a]);this.maxMotion=this.maxMotionA;this.motionRatio=0<this.maxMotion?this.lastMaxMotion/this.maxMotion-1:0;this.damp()};this.relax=function(a){if(!(0.1>this.damper&&this.damping&&this.maxMotion<this.maxMotionA))for(var c=
0;c<a;c++){for(var b=0;b<this.edges.length;b++)this.layoutEdge(this.edges[b]);for(b=0;b<this.nodes.length;b++)for(var d=b+1;d<this.nodes.length;d++)this.layoutNodePair(this.nodes[b],this.nodes[d]);this.moveNodes()}};this.layoutNode=function(a){var c=a.dx*this.damper,b=a.dy*this.damper;a.dx=c/2;a.dy=b/2;var d=Math.sqrt(c*c+b*b);a.x+=Math.max(-30,Math.min(30,c));a.y+=Math.max(-30,Math.min(30,b));this.maxMotionA=Math.max(d,this.maxMotionA)};this.layoutEdge=function(a){var c=a.to.x-a.from.x,b=a.to.y-
a.from.y,d=Math.sqrt(c*c+b*b),c=c*this.rigidity,b=b*this.rigidity,c=c/(100*a.length),b=b/(100*a.length);a.to.dx-=c*d;a.to.dy-=b*d;a.from.dx+=c*d;a.from.dy+=b*d};this.layoutNodePair=function(a,c){var b=0,d=0,g=a.x-c.x,f=a.y-c.y,e=g*g+f*f;0==e?(b=Math.random(),d=Math.random()):36E4>e&&(b=g/e,d=f/e);g=a.repulsion*c.repulsion/100;a.dx+=b*g*this.rigidity;a.dy+=d*g*this.rigidity;c.dx-=b*g*this.rigidity;c.dy-=d*g*this.rigidity}};
