moduleLoader.beginCacheLoading(["/script/shared/utils.js?v=94","/script/shared/gzip.js?v=94","/script/entities/graph/api/index.js?v=94","/script/shared/point.js?v=94","/script/entities/edge/api/index.js?v=94","/script/entities/edge/model/BaseEdge.js?v=94","/script/entities/edge/model/EdgeModel.js?v=94","/script/entities/vertex/api/index.js?v=94","/script/entities/vertex/model/BaseVertex.js?v=94","/script/entities/vertex/model/VertexModel.js?v=94","/script/entities/graph/model/Graph.js?v=94","/script/features/draw_graph/api/index.js?v=94","/script/features/draw_graph/model/BaseBackgroundDrawer.js?v=94","/script/features/draw_graph/model/EdgeStyle.js?v=94","/script/features/draw_graph/model/BaseEdgeDrawer.js?v=94","/script/features/draw_graph/model/VertexShape.js?v=94","/script/features/draw_graph/model/VertexStyle.js?v=94","/script/features/draw_graph/model/BaseVertexDrawer.js?v=94","/script/features/draw_graph/model/GraphFullStyle.js?v=94","/script/features/algorithms/api/index.js?v=94","/script/features/algorithms/model/Algorithms.js?v=94","/script/features/algorithms/model/BaseTraversal.js?v=94","/script/features/base_handler/index.js?v=94","/script/features/default_handler/index.js?v=94","/script/features/add_vertices_handler/index.js?v=94","/script/features/connect_vertices_handler/index.js?v=94","/script/features/delete_objects_handler/index.js?v=94","/script/features/algorithm_handler/index.js?v=94","/script/features/select_auto_save_graph_or_not/index.js?v=94","/script/features/graph_preview/index.js?v=94","/script/features/serialization/api/index.js?v=94","/script/features/serialization/model/GraphMLCreator.js?v=94","/script/features/enum_vertices/EnumVertices.js?v=94","/script/pages/editor/model/texts.js?v=94","/script/pages/editor/model/UndoStack.js?v=94","/script/pages/editor/model/DiskSaveLoad.js?v=94","/script/pages/editor/model/Application.js?v=94","/script/pages/editor/ui/ya_metrika.js?v=94","/script/pages/editor/ui/editor.js?v=94","/script/pages/editor/ui/main.js?v=94",]);{function onloadEditor(){console.log("onload() call");doIncludeAsync([include("shared/canvas2svg.js"),include("features/group_rename_handler/index.js"),include("features/saved_graph_handler/index.js"),include("features/saved_graph_image_handler/index.js"),include("features/show_adjacency_matrix/index.js"),include("features/show_distance_matrix/index.js"),include("features/show_incidence_matrix/index.js"),include("features/setup_background_style/index.js"),include("features/setup_edge_style/index.js"),include("features/setup_vertex_style/index.js"),]);postLoadPage();}
let modulDir="pages/editor/";doInclude([include("shared/utils.js"),include("shared/gzip.js"),include("entities/graph/api/index.js"),include("features/draw_graph/api/index.js"),include("features/algorithms/api/index.js"),include("features/base_handler/index.js"),include("features/default_handler/index.js"),include("features/add_vertices_handler/index.js"),include("features/connect_vertices_handler/index.js"),include("features/delete_objects_handler/index.js"),include("features/algorithm_handler/index.js"),include("features/select_auto_save_graph_or_not/index.js"),include("features/serialization/api/index.js"),include("features/enum_vertices/EnumVertices.js"),include("model/texts.js",modulDir),include("model/UndoStack.js",modulDir),include("model/DiskSaveLoad.js",modulDir),include("model/Application.js",modulDir),include("ui/ya_metrika.js",modulDir),include("ui/editor.js",modulDir),include("ui/main.js",modulDir)],onloadEditor);}
function gEncodeToHTML(str)
{if(typeof str!=='string')
return str;return str.replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"').replace(/'/g,''');}
function gDecodeFromHTML(str)
{if(typeof str!=='string')
return str;return str.replace(/'/g,"'").replace(/"/g,'"').replace(/>/g,'>').replace(/</g,'<').replace(/&/g,'&');}
function FullObjectCopy(obj)
{var newObj=Object.create(Object.getPrototypeOf(obj));return Object.assign(newObj,obj);}
function FullArrayCopy(arr)
{var res=[];arr.forEach(function(element){var copyElement=FullObjectCopy(element);res.push(copyElement);});return res;}
function formatString(string,params){return string.replace(/{(\d+)}/g,(match,index)=>{return typeof params[index]!=='undefined'?params[index]:match;});}
Array.prototype.swap=function(x,y){var b=this[x];this[x]=this[y];this[y]=b;return this;};async function compress_text_into_zip_base64(str,callback,mode="gzip")
{try
{const blobToBase64=blob=>new Promise((resolve,_)=>{const reader=new FileReader();reader.onloadend=()=>resolve(reader.result.split(',')[1]);reader.readAsDataURL(blob);});const byteArray=new TextEncoder().encode(str);const cs=new CompressionStream(mode);const writer=cs.writable.getWriter();writer.write(byteArray);writer.close();return await new Response(cs.readable).blob().then(blobToBase64).then(res=>callback(res));}
catch(err)
{console.log(err);callback("");}
return"";}
async function decompress_base64_zip_into_text(str,callback,mode="gzip")
{try
{const bytes=Uint8Array.from(atob(str),c=>c.charCodeAt(0));const cs=new DecompressionStream(mode)
const writer=cs.writable.getWriter()
writer.write(bytes)
writer.close()
return await new Response(cs.readable).arrayBuffer().then(arr=>callback(new TextDecoder().decode(arr)),async _=>{throw new Error(await Promise.reject(await writer.closed))});}
catch(err)
{console.log(err);callback("");}
return"";}
{let modulDir="entities/graph/";doInclude([include("shared/point.js"),include("entities/edge/api/index.js"),include("entities/vertex/api/index.js"),include("model/Graph.js",modulDir)])}function Point(x,y){this.x=x||0;this.y=y||0;};Point.prototype.x=null;Point.prototype.y=null;Point.prototype.add=function(v){return new Point(this.x+v.x,this.y+v.y);};Point.prototype.addValue=function(v){return new Point(this.x+v,this.y+v);};Point.prototype.clone=function(){return new Point(this.x,this.y);};Point.prototype.degreesTo=function(v){var dx=this.x-v.x;var dy=this.y-v.y;var angle=Math.atan2(dy,dx);return angle*(180/Math.PI);};Point.prototype.distance=function(v){return Math.sqrt(this.distanceSqr(v));};Point.prototype.distanceSqr=function(v){var x=this.x-v.x;var y=this.y-v.y;return x*x+y*y;};Point.prototype.equals=function(toCompare){return this.x==toCompare.x&&this.y==toCompare.y;};Point.prototype.interpolate=function(v,f){return new Point((this.x+v.x)*f,(this.y+v.y)*f);};Point.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y);};Point.prototype.normalize=function(thickness){var l=this.length();this.x=this.x/l*thickness;this.y=this.y/l*thickness;return new Point(this.x,this.y);};Point.prototype.normalizeCopy=function(thickness){var l=this.length();return new Point(this.x/l*thickness,this.y/l*thickness);};Point.prototype.orbit=function(origin,arcWidth,arcHeight,degrees){var radians=degrees*(Math.PI/180);this.x=origin.x+arcWidth*Math.cos(radians);this.y=origin.y+arcHeight*Math.sin(radians);};Point.prototype.rotate=function(center,degrees){var radians=degrees*(Math.PI/180);offset=this.subtract(center);this.x=offset.x*Math.cos(radians)-offset.y*Math.sin(radians);this.y=offset.x*Math.sin(radians)+offset.y*Math.cos(radians);this.x=this.x+center.x;this.y=this.y+center.y;return this;};Point.prototype.offset=function(dx,dy){this.x+=dx;this.y+=dy;};Point.prototype.subtract=function(v){return new Point(this.x-v.x,this.y-v.y);};Point.prototype.subtractValue=function(value){return new Point(this.x-value,this.y-value);};Point.prototype.multiply=function(value){return new Point(this.x*value,this.y*value);};Point.prototype.toString=function(){return"(x="+this.x+", y="+this.y+")";};Point.prototype.normal=function(){return new Point(-this.y,this.x);};Point.prototype.min=function(point)
{return new Point(Math.min(this.x,point.x),Math.min(this.y,point.y));};Point.prototype.max=function(point)
{return new Point(Math.max(this.x,point.x),Math.max(this.y,point.y));};Point.prototype.inverse=function()
{return new Point(-this.x,-this.y);};Point.prototype.cross=function(point)
{return this.x*point.y-this.y*point.x;};Point.interpolate=function(pt1,pt2,f){return new Point(pt1.x*(1.0-f)+pt2.x*f,pt1.y*(1.0-f)+pt2.y*f);};Point.polar=function(len,angle){return new Point(len*Math.cos(angle),len*Math.sin(angle));};Point.distance=function(pt1,pt2){var x=pt1.x-pt2.x;var y=pt1.y-pt2.y;return Math.sqrt(x*x+y*y);};Point.center=function(pt1,pt2){return new Point((pt1.x+pt2.x)/2.0,(pt1.y+pt2.y)/2.0);};Point.toString=function(){return x+" "+y;}
Point.projection=function(point,line1,line2)
{var x=line2.y-line1.y;var y=line1.x-line2.x;var l=(line1.cross(line2)+line1.cross(point)+line2.cross(point))/(x*(line2.y-line1.y)+y*(line1.x-line2.x));var res=new Point(point.x+x*l,point.y+y*l);return res;}
Point.hitTest=function(pt11,pt12,pt21,pt22)
{var res=null;var n=0.0;var x1=pt11.x;var y1=pt11.y;var x2=pt12.x;var y2=pt12.y;var x3=pt21.x;var y3=pt21.y;var x4=pt22.x;var y4=pt22.y;if(y2-y1!=0.0)
{var q=(x2-x1)/(y1-y2);var sn=(x3-x4)+(y3-y4)*q;if(sn==0.0)
{return res;}
var fn=(x3-x1)+(y3-y1)*q;n=fn/sn;}
else
{if((y3-y4)==0.0)
{return res;}
n=(y3-y1)/(y3-y4);}
res=new Point(x3+(x4-x3)*n,y3+(y4-y3)*n);var epsilon=1E-5;if(!(res.x>=Math.min(x1,x2)-epsilon&&res.x>=Math.min(x3,x4)-epsilon&&res.x<=Math.max(x1,x2)+epsilon&&res.x<=Math.max(x3,x4)+epsilon&&res.y>=Math.min(y1,y2)-epsilon&&res.y>=Math.min(y3,y4)-epsilon&&res.y<=Math.max(y1,y2)+epsilon&&res.y<=Math.max(y3,y4)+epsilon))
{res=null;}
return res;}
function Rect(minPoint,maxPoint){this.minPoint=minPoint;this.maxPoint=maxPoint;};Rect.prototype.center=function()
{return Point.center(this.minPoint,this.maxPoint);};Rect.prototype.size=function()
{return this.maxPoint.subtract(this.minPoint);};Rect.prototype.left=function()
{return this.minPoint.x;};Rect.prototype.top=function()
{return this.minPoint.y;};Rect.prototype.isIn=function(v)
{return this.minPoint.x<=v.x&&this.minPoint.y<=v.y&&this.maxPoint.x>v.x&&this.maxPoint.y>v.y;};{let modulDir="entities/edge/";doInclude([include("model/BaseEdge.js",modulDir),include("model/EdgeModel.js",modulDir)])}
function BaseEdge(vertex1,vertex2,isDirect,weight,upText)
{this.vertex1=vertex1;this.vertex2=vertex2;this.arrayStyleStart="";this.arrayStyleFinish="";this.isDirect=isDirect;this.weight=0;this.text="";this.useWeight=false;this.id=0;this.model=new EdgeModel();if(upText===undefined)
this.upText="";else
this.upText=upText;if(weight!==undefined)
this.SetWeight(weight);this.ownStyles={};}
BaseEdge.prototype.copyFrom=function(other)
{this.vertex1=other.vertex1;this.vertex2=other.vertex2;this.arrayStyleStart=other.arrayStyleStart;this.arrayStyleFinish=other.arrayStyleFinish;this.isDirect=other.isDirect;this.weight=other.weight;this.text=other.text;this.useWeight=other.useWeight;this.id=other.id;this.model=new EdgeModel();this.model.copyFrom(other.model);this.upText=other.upText;this.ownStyles=FullObjectCopy(other.ownStyles);}
BaseEdge.prototype.SaveToXML=function()
{return"0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+
this.model.SaveToXML()+">";}
BaseEdge.prototype.LoadFromXML=function(xml,graph,defaultLoadEdges)
{var attr=xml.attr('vertex1');if(typeof attr==='undefined')
{attr=xml.attr('source');}
this.vertex1=graph.FindVertex(typeof attr!=='undefined'?attr:xml.attr('graph1'));var attr=xml.attr('vertex2');if(typeof attr==='undefined')
{attr=xml.attr('target');}
this.vertex2=graph.FindVertex(typeof attr!=='undefined'?attr:xml.attr('graph2'));var directedAttribute=xml.attr('directed');if(typeof directedAttribute!=='undefined')
{this.isDirect=directedAttribute=="true";}
else
{var isDirectedAttribute=xml.attr('isDirect');if(typeof isDirectedAttribute!=='undefined')
{this.isDirect=isDirectedAttribute=="true";}
else
{this.isDirect=defaultLoadEdges=="directed";}}
this.weight=parseFloat(xml.attr('weight'));if(isNaN(this.weight))
{this.weight=1;}
this.hasPair=xml.attr('hasPair')=="true";this.useWeight=xml.attr('useWeight')=="true";this.id=xml.attr('id');this.text=xml.attr("text")==null?"":gDecodeFromHTML(xml.attr("text"));this.arrayStyleStart=xml.attr("arrayStyleStart")==null?"":xml.attr("arrayStyleStart");this.arrayStyleFinish=xml.attr("arrayStyleFinish")==null?"":xml.attr("arrayStyleFinish");this.upText=xml.attr('upText');if(typeof this.upText==='undefined')
{this.upText="";}
else
{this.upText=gDecodeFromHTML(this.upText);}
var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
{if(this.ownStyles[index].ShouldLoad(field))
this.ownStyles[index][field]=parsedSave[indexField][field];}}}
this.model.LoadFromXML(xml);}
BaseEdge.prototype.GetPixelLength=function()
{if(this.vertex1==this.vertex2)
{return this.model.GetLoopSize()*2*Math.PI;}
else
{return Point.distance(this.vertex1.position,this.vertex2.position);}}
BaseEdge.prototype.GetWeight=function()
{return this.useWeight?this.weight:1;}
BaseEdge.prototype.GetText=function()
{return this.text.length>0?this.text:(this.useWeight?this.weight.toString():"");}
BaseEdge.prototype.GetUpText=function()
{return this.upText;}
BaseEdge.prototype.GetStartEdgeStyle=function()
{return this.arrayStyleStart;}
BaseEdge.prototype.GetFinishEdgeStyle=function()
{return(this.arrayStyleFinish!=""?this.arrayStyleFinish:(this.isDirect?"arrow":""));}
BaseEdge.prototype.HitTest=function(pos)
{var positions=this.GetEdgePositionsShift();return this.model.HitTest(positions[0],positions[1],pos);}
BaseEdge.prototype.GetEdgePositionsShift=function()
{return this.GetEdgePositions();}
BaseEdge.prototype.GetEdgePositions=function()
{var res=[];if(this.vertex1==this.vertex2)
{res.push(this.vertex1.position);res.push(this.vertex2.position);return res;}
var position1=this.vertex1.position;var position2=this.vertex2.position;var diameter1=this.vertex1.model.diameter+parseInt(this.vertex1.currentStyle.GetStyle({},this.vertex1).lineWidth);var diameter2=this.vertex2.model.diameter+parseInt(this.vertex2.currentStyle.GetStyle({},this.vertex2).lineWidth);var direction=position1.subtract(position2);var direction1=direction;var direction2=direction;var d1=diameter1;var d2=diameter2;if(this.model.type==EdgeModels.curve)
{var dist=position1.distance(position2);var point1=this.model.GetCurvePoint(position1,position2,10.0/dist);direction1=position1.subtract(point1);var point2=this.model.GetCurvePoint(position1,position2,1.0-10.0/dist);direction2=position2.subtract(point2);d2=diameter2;}
else
{direction2=direction2.multiply(-1);}
direction1.normalize(1.0);direction2.normalize(1.0);var vertices=[];vertices.push({vertex:this.vertex1,direction:direction1,position:position1,diameter:d1});vertices.push({vertex:this.vertex2,direction:direction2,position:position2,diameter:d2});vertices.forEach(function(data)
{var style=data.vertex.currentStyle.GetStyle({},data.vertex);var shape=style.shape;if(shape==VertexCircleShape)
{var direction=data.direction.multiply(0.5);res.push(data.position.subtract(direction.multiply(data.diameter)));}
else
{var lineFinish1=data.direction.multiply(-1).multiply(1000.0);var pointsVertex1=GetPointsForShape(shape,data.diameter,{style:style,text:data.vertex.mainText});pointsVertex1.push(pointsVertex1[0]);for(var i=0;i=(new Point(r2,r12)).length()||r2>=(new Point(r1,r12)).length())
{}
else
{var distance=((pos1.y-pos2.y)*pos0.x+(pos2.x-pos1.x)*pos0.y+(pos1.x*pos2.y-pos2.x*pos1.y))/r12;if(Math.abs(distance)<=this.width*1.5*factor)
{return true;}}
return false;}
EdgeModel.prototype.HitTestCurve=function(position1,position2,mousePos)
{var pos1=position1;var pos2=position2;var pos0=mousePos;if(pos1.equals(pos2))
{var xCenter=pos1.x-Math.cos(this.GetLoopShiftAngel())*this.GetLoopSize();var yCenter=pos1.y-Math.sin(this.GetLoopShiftAngel())*this.GetLoopSize();return Math.abs((Point.distance(new Point(xCenter,yCenter),pos0))-this.GetLoopSize())<=this.width*1.5;}
var interval_count=position1.distance(position2)/100*30;var start=position1;for(var i=0;i=0.0){normalCurve+=this.defaultCurve}
return this.sizeOfLoop*Math.abs(normalCurve)*(1/this.defaultCurve);}}
EdgeModel.prototype.GetLoopShiftAngel=function()
{if(this.type==EdgeModels.line||this.curveValue>=0.0)
{return this.loopShiftAngel;}
else
{return this.loopShiftAngel+Math.PI;}}
{let modulDir="entities/vertex/";doInclude([include("model/BaseVertex.js",modulDir),include("model/VertexModel.js",modulDir)])}
function GetTextWidth(text,font)
{const canvas=GetTextWidth.canvas||(GetTextWidth.canvas=document.createElement("canvas"));const context=canvas.getContext("2d");context.font=font;const metrics=context.measureText(text);return metrics.width;}
function BaseVertex(x,y,vertexEnumType)
{this.position=new Point(x,y);this.id=0;this.mainText="";this.upText="";this.vertexEnumType=vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=false;this.ownStyles={};};BaseVertex.prototype.position=new Point(0,0);BaseVertex.prototype.copyFrom=function(other)
{this.position=new Point(other.position.x,other.position.y);this.id=other.id;this.mainText=other.mainText;this.upText=other.upText;this.vertexEnumType=other.vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=other.hasUndefinedPosition;this.ownStyles=FullObjectCopy(other.ownStyles);}
BaseVertex.prototype.SaveToXML=function()
{return"0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+"size=\""+this.model.diameter+"\" "+">";}
BaseVertex.prototype.LoadFromXML=function(xml)
{var xmlX=xml.attr('positionX');var xmlY=xml.attr('positionY');this.hasUndefinedPosition=(typeof xmlX==='undefined')||(typeof xmlY==='undefined');this.position=new Point(parseFloat(xmlX),parseFloat(xmlY));this.id=xml.attr('id');this.mainText=xml.attr('mainText');this.upText=xml.attr('upText');if(typeof this.mainText==='undefined')
this.mainText=this.id;else
this.mainText=gDecodeFromHTML(this.mainText);if(typeof this.upText==='undefined')
this.upText="";else
this.upText=gDecodeFromHTML(this.upText);var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
{if(this.ownStyles[index].ShouldLoad(field))
this.ownStyles[index][field]=parsedSave[indexField][field];}}}
var size=xml.attr('size');if(typeof size!=='undefined')
this.model.diameter=parseInt(size);}
BaseVertex.prototype.SetId=function(id)
{this.id=id;if(this.vertexEnumType!=null)
this.mainText=this.vertexEnumType.GetVertexText(id);}
BaseVertex.prototype.IsUndefinedPosition=function()
{return this.hasUndefinedPosition;}
BaseVertex.prototype.HitTest=function(pos)
{var style=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this):null;var shape=style!=null?style.shape:VertexCircleShape;var width=style!=null?style.lineWidth:0;if(shape==VertexCircleShape)
{return this.position.distance(pos)-1)
{this.edges.splice(index,1);}
this.isMultiGraph=this.checkMutiGraph();this.hasNegativeWeight=this.checkNegativeWeight();}
Graph.prototype.DeleteVertex=function(vertexObject)
{var index=this.vertices.indexOf(vertexObject);if(index>-1)
{for(var i=0;i-1)
{for(var i=0;imaxWeight)
{res=edge;maxWeight=edge.weight;}}}
return res;}
Graph.prototype.FindEdgeMinIgnoreDirection=function(id1,id2)
{var res=null;var minWeight=this.infinity;for(var i=0;i.+$/g,/^.+<.+$/g,/^.+-\(\d+\.?\d+\)-.+$/g,/^.+-\(\d+\.?\d+\)\>.+$/g,/^.+<\(\d+\.?\d+\)\-.+$/g];let res=true;for(let i=0;i0||cols[j][vertexIndex]>0)&&j!=vertexIndex)
{relatedVertex.push(this.vertices[j]);}}
var diameter=(new VertexModel()).diameter;if(relatedVertex.length>1)
{for(var j=0;jmaxDistance)
{var force=(otherVertex.position.subtract(currentVertex.object.position)).normalize(edgeGravityKof*(distance-maxDistance));currentVertex.net_force=currentVertex.net_force.add(force);}}}
var distanceToCenter=centerPoint.distance(currentVertex.object.position);var force=centerPoint.subtract(currentVertex.object.position).normalize(distanceToCenter*kCenterForce);currentVertex.net_force=currentVertex.net_force.add(force);currentVertex.velocity=currentVertex.velocity.add(currentVertex.net_force);}
bChanged=false;for(i=0;ivelocityMax)
{velocity=velocity.normalize(velocityMax);}
v.object.position=v.object.position.add(velocity);if(velocity.length()>=1)
{bChanged=true;}}
k++;}
var bbox=this.getGraphBBox();if(bbox.size().length()>viewportSize.length()*1000)
{for(i=0;i=this.vertices.length)
{var newPos=this.GetRandomPositionOfVertex(matrix,j,viewportSize);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
if(cols[i][j]!=0)
{var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[i],this.vertices[j],cols[i][j]!=cols[j][i],cols[i][j],true);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
for(var i=rows.length;i(.+)$/g,/^(.+)<(.+)$/g,/^(.+)-\((-?\d+|-?\d+\.?\d+)\)-(.+)$/g,/^(.+)-\((-?\d+|-?\d+\.?\d+)\)\>(.+)$/g,/^(.+)<\((-?\d+|-?\d+\.?\d+)\)\-(.+)$/g,];let bWeightGraph=false;var newVertices=[];for(var i=0;i=0;--j){if(!line.match(regExp[j])){continue;}
let groupes=Array.from(line.matchAll(regExp[j]));let groupe=groupes[0];let vetext1Title=groupe[1];let vertex1=this.FindVertexByTitle(vetext1Title);if(vertex1==null){let newPosition=this.GetRandomPosition(viewportSize);vertex1=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex1.mainText=vetext1Title;newVertices.push(vertex1);}
let vetext2Title=groupe[j<=2?2:3];let vertex2=this.FindVertexByTitle(vetext2Title);if(vertex2==null){let newPosition=this.GetRandomPosition(viewportSize);vertex2=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex2.mainText=vetext2Title;newVertices.push(vertex2);}
let isDirect=j==1||j==2||j==4||j==5;let weight=1;if(j>2){weight=groupe[2];bWeightGraph=true;}
let isRevertEdge=j==2||j==5;let nEdgeIndex=this.AddNewEdgeSafe(isRevertEdge?vertex2:vertex1,isRevertEdge?vertex1:vertex2,isDirect,weight,false);this.FixEdgeCurve(nEdgeIndex);break;}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.TestIncidenceMatrix=function(matrix,rowsObj,colsObj,separator)
{if(separator===undefined)
{separator=",";}
var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j=this.vertices.length)
{var newPos=new Point(0,0);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
if(cols[j][i]!=0)
{edgeValue.push(cols[j][i]);edgeIndex.push(j);}}
if(edgeIndex.length==1)
{edgeValue.push(edgeValue[0]);edgeIndex.push(edgeIndex[0]);}
if(edgeIndex.length==2)
{if(edgeValue[0]!=edgeValue[1])
{if(edgeValue[1]>0)
{edgeValue=edgeValue.swap(0,1);edgeIndex=edgeIndex.swap(0,1);}}
var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[edgeIndex[0]],this.vertices[edgeIndex[1]],edgeValue[0]!=edgeValue[1],Math.abs(edgeValue[1]),false);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}
if(!bWeightGraph)
{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
for(var i=cols.length;i0)
{res.push(line.substr(0,i));}
if(i==0)
{i=1;}
line=line.substr(i,line.length-i);i=-1;}}
if(line.length>0)
{res.push(line);}}
else
{for(i=0;i";var header="";var xmlBody="";for(var i=0;i0)
{additionalField=""}
return mainHeader+header+xmlBody+""+additionalField+"";}
Graph.prototype.LoadFromXML=function(xmlText,additionalData)
{xmlDoc=$.parseXML(xmlText);var $xml=$(xmlDoc);$graphs=$xml.find("graph");var loadedGraphId=0;var loadedEdgeId=0;var defaultLoadEdges="";$graphs.each(function(){loadedGraphId=parseInt($(this).attr('uidGraph'));loadedEdgeId=parseInt($(this).attr('uidEdge'));defaultLoadEdges=$(this).attr('edgedefault');});if(isNaN(loadedEdgeId))
{loadedEdgeId=this.edgesOffset;}else if(loadedEdgeId0;}
Graph.prototype.clampPositions=function(viewportSize)
{var diameter=(new VertexModel()).diameter;for(i=0;i=2)
{var curve=this.GetAvailableCurveValue(neighborEdges,edgeObject);if(edgeObject.model.default)
{edgeObject.model.type=EdgeModels.curve;edgeObject.model.curveValue=curve;}}}
Graph.prototype.GetAvailableCurveValue=function(neighborEdges,originalEdge)
{var values=[];for(var i=0;i0.0)
{context.globalAlpha=style.commonOpacity;context.fillStyle=style.commonColor;context.fillRect(-rect.minPoint.x,-rect.minPoint.y,rect.size().x+1,rect.size().y+1);this.DrawImage(style,width,height,position,scale);}
context.globalAlpha=oldOpacity;}
BaseBackgroundDrawer.prototype.DrawImage=function(style,width,height,position,scale)
{if(style.image==null){return;}
var context=this.context;context.clearRect(0,0,style.image.width,style.image.height);context.drawImage(style.image,0,0)}
const lineDashTypes=[[],[4,4],[12,12],[16,4,4,4],];const WeightTextCenter=0,WeightTextUp=1;const DefaultFontEdge="px sans-serif",DefaultMainTextFontSizeEdge=16,TopTextFontSizeDeltaEdge=-4;function BaseEdgeStyle()
{this.baseStyles=[];}
BaseEdgeStyle.prototype.GetStyle=function(baseStyle,object)
{this.baseStyles.forEach(function(element){var styleObject=globalApplication.GetStyle("edge",element,object);baseStyle=styleObject.GetStyle(baseStyle,object);});if(this.hasOwnProperty('weightText'))
baseStyle.weightText=this.weightText;if(this.hasOwnProperty('strokeStyle'))
baseStyle.strokeStyle=this.strokeStyle;if(this.hasOwnProperty('fillStyle'))
baseStyle.fillStyle=this.fillStyle;if(this.hasOwnProperty('textPadding'))
baseStyle.textPadding=this.textPadding;if(this.hasOwnProperty('textStrokeWidth'))
baseStyle.textStrokeWidth=this.textStrokeWidth;if(this.hasOwnProperty('lineDash'))
baseStyle.lineDash=this.lineDash;if(this.hasOwnProperty('additionalTextColor'))
baseStyle.additionalTextColor=this.additionalTextColor;if(this.hasOwnProperty('weightPosition'))
baseStyle.weightPosition=this.weightPosition;if(this.hasOwnProperty('mainTextFontSize'))
baseStyle.mainTextFontSize=this.mainTextFontSize;return this.FixNewFields(baseStyle);}
BaseEdgeStyle.prototype.FixNewFields=function(style)
{if(!style.hasOwnProperty('lineDash'))
style.lineDash=0;if(!style.hasOwnProperty('weightPosition'))
style.weightPosition=WeightTextCenter;if(!style.hasOwnProperty('mainTextFontSize'))
style.mainTextFontSize=DefaultMainTextFontSizeEdge;return style;}
BaseEdgeStyle.prototype.Clear=function()
{delete this.weightText;delete this.strokeStyle;delete this.fillStyle;delete this.textPadding;delete this.textStrokeWidth;delete this.lineDash;delete this.additionalTextColor;delete this.weightPosition;delete this.mainTextFontSize;}
BaseEdgeStyle.prototype.ShouldLoad=function(field)
{return field!="baseStyles";}
function CommonEdgeStyle()
{BaseEdgeStyle.apply(this,arguments);this.strokeStyle='#c7b7c7';this.weightText='#f0d543';this.fillStyle='#68aeba';this.textPadding=4;this.textStrokeWidth=2;this.lineDash=0;this.additionalTextColor='#c7b7c7';this.weightPosition=WeightTextCenter;}
CommonEdgeStyle.prototype=Object.create(BaseEdgeStyle.prototype);function CommonPrintEdgeStyle()
{BaseEdgeStyle.apply(this,arguments);this.strokeStyle='#000000';this.weightText='#000000';this.fillStyle='#FFFFFF';this.textPadding=4;this.textStrokeWidth=2;this.baseStyles.push("common");}
CommonPrintEdgeStyle.prototype=Object.create(BaseEdgeStyle.prototype);function SelectedEdgeStyle0()
{BaseEdgeStyle.apply(this,arguments);this.strokeStyle='#f0d543';this.weightText='#f0d543';this.fillStyle='#c7627a';this.baseStyles.push("common");}
SelectedEdgeStyle0.prototype=Object.create(BaseEdgeStyle.prototype);function SelectedEdgeStyle1()
{BaseEdgeStyle.apply(this,arguments);this.strokeStyle='#8FBF83';this.weightText='#8FBF83';this.fillStyle='#F9F9D5';this.baseStyles.push("selected");}
SelectedEdgeStyle1.prototype=Object.create(BaseEdgeStyle.prototype);function SelectedEdgeStyle2()
{BaseEdgeStyle.apply(this,arguments);this.strokeStyle='#8C4C86';this.weightText='#8C4C86';this.fillStyle='#253267';this.baseStyles.push("selected");}
SelectedEdgeStyle2.prototype=Object.create(BaseEdgeStyle.prototype);function SelectedEdgeStyle3()
{BaseEdgeStyle.apply(this,arguments);this.strokeStyle='#6188FF';this.weightText='#6188FF';this.fillStyle='#E97CF9';this.baseStyles.push("selected");}
SelectedEdgeStyle3.prototype=Object.create(BaseEdgeStyle.prototype);function SelectedEdgeStyle4()
{BaseEdgeStyle.apply(this,arguments);this.strokeStyle='#C6B484';this.weightText='#C6B484';this.fillStyle='#E0DEE1';this.baseStyles.push("selected");}
SelectedEdgeStyle4.prototype=Object.create(BaseEdgeStyle.prototype);function SelectedEdgePrintStyle()
{BaseEdgeStyle.apply(this,arguments);this.strokeStyle='#AAAAAA';this.weightText='#000000';this.fillStyle='#AAAAAA';this.baseStyles.push("printed");}
SelectedEdgePrintStyle.prototype=Object.create(BaseEdgeStyle.prototype);var DefaultSelectedEdgeStyles=[new SelectedEdgeStyle0(),new SelectedEdgeStyle1(),new SelectedEdgeStyle2(),new SelectedEdgeStyle3(),new SelectedEdgeStyle4()];var DefaultPrintSelectedEdgeStyles=[new SelectedEdgePrintStyle()];function BaseEdgeDrawer(context,drawObjects)
{if(drawObjects===undefined)
{drawObjects=null;}
this.context=context;this.drawObject=null;this.drawArc=null;this.startArrowDirection=null;this.finishArrowDirection=null;this.textCenterObject=null;this.getPointOnArc=null;if(drawObjects)
{if(drawObjects.hasOwnProperty("drawObject"))
this.drawObject=drawObjects.drawObject;if(drawObjects.hasOwnProperty("drawArc"))
this.drawArc=drawObjects.drawArc;if(drawObjects.hasOwnProperty("startArrowDirection"))
this.startArrowDirection=drawObjects.startArrowDirection;if(drawObjects.hasOwnProperty("finishArrowDirection"))
this.finishArrowDirection=drawObjects.finishArrowDirection;if(drawObjects.hasOwnProperty("textCenterObject"))
this.textCenterObject=drawObjects.textCenterObject;if(drawObjects.hasOwnProperty("getPointOnArc"))
this.getPointOnArc=drawObjects.getPointOnArc;}}
BaseEdgeDrawer.prototype.Draw=function(baseEdge,arcStyle)
{if(this.drawObject&&this.drawObject!=this)
{this.drawObject.Draw(baseEdge,arcStyle);return;}
this.SetupStyle(baseEdge,arcStyle);var lengthArrow=Math.max(baseEdge.model.width*4,8);var widthArrow=Math.max(baseEdge.model.width*2,4);var position1=baseEdge.vertex1.position;var position2=baseEdge.vertex2.position;var direction=position1.subtract(position2);direction.normalize(1.0);var positions=baseEdge.GetEdgePositionsShift();var hasStartStyle=!position1.equals(position2)&&baseEdge.GetStartEdgeStyle()!="";var hasFinishStyle=!position1.equals(position2)&&baseEdge.GetFinishEdgeStyle()!="";var arcPos1=positions[0];var arcPos2=positions[1];if(hasStartStyle)
{var dirArrow=this.GetStartArrowDirection(positions[0],positions[1],lengthArrow);arcPos1=arcPos1.add(dirArrow.multiply(lengthArrow/2));}
if(hasFinishStyle)
{var dirArrow=this.GetFinishArrowDirection(positions[0],positions[1],lengthArrow);arcPos2=arcPos2.add(dirArrow.multiply(-lengthArrow/2));}
this.DrawArc(arcPos1,arcPos2,arcStyle);this.context.fillStyle=this.context.strokeStyle;this.context.lineWidth=0;if(hasStartStyle)
{this.DrawArrow(positions[0],this.GetStartArrowDirection(positions[0],positions[1],lengthArrow),lengthArrow,widthArrow);}
if(hasFinishStyle)
{this.DrawArrow(positions[1],this.GetFinishArrowDirection(positions[0],positions[1],lengthArrow),lengthArrow,widthArrow);}
this.SetupStyle(baseEdge,arcStyle);if(arcStyle.weightPosition==WeightTextCenter)
{if(baseEdge.GetText().length>0)
{this.DrawWeight(positions[0],positions[1],baseEdge.GetText(),arcStyle,false);}
if(baseEdge.GetUpText().length>0)
{this.DrawUpText(positions[0],positions[1],baseEdge.GetUpText(),arcStyle,false,arcStyle.additionalTextColor,baseEdge.model.width/2+arcStyle.mainTextFontSize+4,arcStyle.mainTextFontSize);}}
else if(arcStyle.weightPosition==WeightTextUp)
{if(baseEdge.GetText().length>0)
{this.DrawUpText(positions[0],positions[1],baseEdge.GetText(),arcStyle,false,arcStyle.weightText,baseEdge.model.width/2+arcStyle.mainTextFontSize/2,arcStyle.mainTextFontSize);}
if(baseEdge.GetUpText().length>0)
{this.DrawUpText(positions[0],positions[1],baseEdge.GetUpText(),arcStyle,false,arcStyle.additionalTextColor,-baseEdge.model.width/2-(arcStyle.mainTextFontSize/2+4),arcStyle.mainTextFontSize);}}}
BaseEdgeDrawer.prototype.SetupStyle=function(baseEdge,arcStyle)
{this.context.lineWidth=baseEdge.model.width;this.context.strokeStyle=arcStyle.strokeStyle;this.context.fillStyle=arcStyle.fillStyle;this.model=baseEdge.model;this.style=arcStyle;}
BaseEdgeDrawer.prototype.DrawArc=function(position1,position2,arcStyle)
{if(this.drawArc&&this.drawArc!=this)
{this.drawArc.DrawArc(position1,position2,arcStyle);return;}
this.context.setLineDash(lineDashTypes[arcStyle.lineDash]);if(position1.equals(position2))
{this.context.beginPath();this.context.arc(position1.x-Math.cos(this.model.GetLoopShiftAngel())*this.model.GetLoopSize(),position1.y-Math.sin(this.model.GetLoopShiftAngel())*this.model.GetLoopSize(),this.model.GetLoopSize(),0,2*Math.PI);this.context.stroke();}
else
{this.context.beginPath();this.context.moveTo(position1.x,position1.y);this.context.lineTo(position2.x,position2.y);this.context.stroke();}
this.context.setLineDash([]);}
BaseEdgeDrawer.prototype.DrawWeight=function(position1,position2,text,arcStyle,hasPair)
{var centerPoint=this.GetTextCenterPoint(position1,position2,hasPair,arcStyle);this.context.font="bold "+arcStyle.mainTextFontSize+"px sans-serif";this.context.textBaseline="middle";this.context.lineWidth=arcStyle.textStrokeWidth;this.context.fillStyle=arcStyle.fillStyle;var widthText=this.context.measureText(text).width;this.context.beginPath();this.context.rect(centerPoint.x-widthText/2-arcStyle.textPadding/2,centerPoint.y-arcStyle.mainTextFontSize/1.7-arcStyle.textPadding/2,widthText+arcStyle.textPadding,arcStyle.mainTextFontSize+arcStyle.textPadding);this.context.closePath();this.context.fill();this.context.stroke();this.context.fillStyle=arcStyle.weightText;this.context.fillText(text,centerPoint.x-widthText/2,centerPoint.y);}
BaseEdgeDrawer.prototype.DrawUpText=function(position1,position2,text,arcStyle,hasPair,color,offset,fontSize)
{var centerPoint=this.GetTextCenterPoint(position1,position2,hasPair,arcStyle);this.context.font=fontSize==null?"bold "+(DefaultMainTextFontSizeEdge+TopTextFontSizeDeltaEdge)+"px sans-serif":"bold "+(fontSize+TopTextFontSizeDeltaEdge)+"px sans-serif";this.context.textBaseline="middle";var widthText=this.context.measureText(text).width;this.context.fillStyle=color;var vectorEdge=new Point(position2.x-position1.x,position2.y-position1.y);var angleRadians=Math.atan2(vectorEdge.y,vectorEdge.x);if(angleRadians>Math.PI/2||angleRadians<-Math.PI/2)
{vectorEdge=new Point(position1.x-position2.x,position1.y-position2.y);angleRadians=Math.atan2(vectorEdge.y,vectorEdge.x);}
var normalize=vectorEdge.normal().normalizeCopy(offset);this.context.save();this.context.translate(centerPoint.x-normalize.x,centerPoint.y-normalize.y);this.context.rotate(angleRadians);this.context.textAlign="center";this.context.fillText(text,0,0);this.context.restore();}
BaseEdgeDrawer.prototype.DrawArrow=function(position,direction,length,width)
{var normal=direction.normal();var pointOnLine=position.subtract(direction.multiply(length));var point1=pointOnLine.add(normal.multiply(width));var point2=pointOnLine.add(normal.multiply(-width));this.context.beginPath();this.context.moveTo(position.x,position.y);this.context.lineTo(point1.x,point1.y);this.context.lineTo(point2.x,point2.y);this.context.lineTo(position.x,position.y);this.context.closePath();this.context.fill();}
BaseEdgeDrawer.prototype.GetStartArrowDirection=function(position1,position2,lengthArrow)
{if(this.startArrowDirection&&this.startArrowDirection!=this)
{return this.startArrowDirection.GetStartArrowDirection(position1,position2,lengthArrow);}
var direction=position1.subtract(position2);direction.normalize(1.0);return direction;}
BaseEdgeDrawer.prototype.GetFinishArrowDirection=function(position1,position2,lengthArrow)
{if(this.finishArrowDirection&&this.finishArrowDirection!=this)
{return this.finishArrowDirection.GetFinishArrowDirection(position1,position2,lengthArrow);}
var direction=position2.subtract(position1);direction.normalize(1.0);return direction;}
BaseEdgeDrawer.prototype.GetTextCenterPoint=function(position1,position2,hasPair,arcStyle)
{if(this.textCenterObject&&this.textCenterObject!=this)
{return this.textCenterObject.GetTextCenterPoint(position1,position2,hasPair,arcStyle);}
var textShift=Math.min(12/position1.subtract(position2).length(),0.4);var centerPoint=Point.interpolate(position1,position2,0.5);if(position1.equals(position2))
{let sinVal=Math.sin(this.model.GetLoopShiftAngel());let cosVal=Math.cos(this.model.GetLoopShiftAngel());centerPoint.x=centerPoint.x-cosVal*this.model.GetLoopSize();centerPoint.y=centerPoint.y-(sinVal+Math.sign(sinVal)*1.0)*this.model.GetLoopSize();}
return centerPoint;}
BaseEdgeDrawer.prototype.GetPointOnArc=function(position1,position2,percent)
{if(this.getPointOnArc&&this.getPointOnArc!=this)
{return this.getPointOnArc.GetPointOnArc(position1,position2,percent);}
return Point.interpolate(position1,position2,percent);}
function ProgressArcDrawer(context,baseDrawer,progress)
{this.context=context;this.baseDrawer=baseDrawer;this.progress=progress;}
ProgressArcDrawer.prototype=Object.create(BaseEdgeDrawer.prototype);ProgressArcDrawer.prototype.Draw=function(baseEdge,arcStyle)
{this.baseDrawer.Draw(baseEdge,arcStyle);this.context.lineWidth=10;var positions=baseEdge.GetEdgePositionsShift();var progressSize=10;if(positions[0].equals(positions[1]))
{var sizeInRadian=progressSize/(2*Math.PI*this.baseDrawer.model.GetLoopSize())*6;this.context.beginPath();this.context.arc(positions[0].x-Math.cos(this.baseDrawer.model.GetLoopShiftAngel())*this.baseDrawer.model.GetLoopSize(),positions[0].y-Math.sin(this.baseDrawer.model.GetLoopShiftAngel())*this.baseDrawer.model.GetLoopSize(),this.baseDrawer.model.GetLoopSize(),this.progress*2*Math.PI,this.progress*2*Math.PI+sizeInRadian);this.context.stroke();}
else
{var startPosition=this.baseDrawer.GetPointOnArc(positions[0],positions[1],this.progress);var vectorOffset=positions[0].subtract(positions[1]).normalizeCopy(progressSize);var finishPosition=startPosition.add(vectorOffset);this.context.beginPath();this.context.moveTo(startPosition.x,startPosition.y);this.context.lineTo(finishPosition.x,finishPosition.y);this.context.stroke();}}
function CurvedArcDrawer(context,model)
{this.context=context;this.model=model;}
CurvedArcDrawer.prototype=Object.create(BaseEdgeDrawer.prototype);CurvedArcDrawer.prototype.DrawArc=function(position1,position2,arcStyle)
{this.context.setLineDash(lineDashTypes[arcStyle.lineDash]);if(position1.equals(position2))
{this.context.beginPath();this.context.arc(position1.x-Math.cos(this.model.GetLoopShiftAngel())*this.model.GetLoopSize(),position1.y-Math.sin(this.model.GetLoopShiftAngel())*this.model.GetLoopSize(),this.model.GetLoopSize(),0,2*Math.PI);this.context.closePath();this.context.stroke();}
else
{var points=this.model.GetBezierPoints(position1,position2);var firstBezierPoint=points[0];var secondBezierPoint=points[1];this.context.beginPath();this.context.moveTo(position1.x,position1.y);this.context.bezierCurveTo(firstBezierPoint.x,firstBezierPoint.y,secondBezierPoint.x,secondBezierPoint.y,position2.x,position2.y);this.context.stroke();}
this.context.setLineDash([]);}
CurvedArcDrawer.prototype.GetStartArrowDirection=function(position1,position2,lengthArrow)
{var dist=position1.distance(position2);var direction=position1.subtract(this.model.GetCurvePoint(position1,position2,lengthArrow/dist));direction.normalize(1.0);return direction;}
CurvedArcDrawer.prototype.GetFinishArrowDirection=function(position1,position2,lengthArrow)
{var dist=position1.distance(position2);var direction=position2.subtract(this.model.GetCurvePoint(position1,position2,1.0-lengthArrow/dist));direction.normalize(1.0);return direction;}
CurvedArcDrawer.prototype.GetTextCenterPoint=function(position1,position2,hasPair,arcStyle)
{var centerPoint=this.model.GetCurvePoint(position1,position2,0.5)
if(position1.equals(position2))
{let sinVal=Math.sin(this.model.GetLoopShiftAngel());let cosVal=Math.cos(this.model.GetLoopShiftAngel());centerPoint.x=centerPoint.x-cosVal*this.model.GetLoopSize();centerPoint.y=centerPoint.y-(sinVal+Math.sign(sinVal)*1.0)*this.model.GetLoopSize();}
return centerPoint;}
CurvedArcDrawer.prototype.GetPointOnArc=function(position1,position2,percent)
{return this.model.GetCurvePoint(position1,position2,percent);}
const VertexCircleShape=0,VertexSquareShape=1,VertexTriangleShape=2,VertexPentagonShape=3,VertexHomeShape=4,VertexTextboxShape=5;VertexSnowflakeShape=6;function GetSquarePoints(diameter)
{var res=[];var a=diameter;res.push(new Point(-a/2,-a/2));res.push(new Point(a/2,-a/2));res.push(new Point(a/2,a/2));res.push(new Point(-a/2,a/2));return res;}
function GetTrianglePoints(diameter)
{var res=[];var effectiveDiameter=diameter*1.5;var upOffset=effectiveDiameter/2;var downOffset=effectiveDiameter/4;var lrOffset=effectiveDiameter*3/(Math.sqrt(3)*4);res.push(new Point(0,-upOffset));res.push(new Point(lrOffset,downOffset));res.push(new Point(-lrOffset,downOffset));return res;}
function GetPentagonPoints(diameter)
{var res=[];var baseValue=diameter/2*1.2;res.push(new Point(0,-baseValue));res.push((new Point(0,-baseValue)).rotate(new Point(0,0),72));res.push((new Point(0,-baseValue)).rotate(new Point(0,0),72*2));res.push((new Point(0,-baseValue)).rotate(new Point(0,0),72*3));res.push((new Point(0,-baseValue)).rotate(new Point(0,0),72*4));res.push((new Point(0,-baseValue)).rotate(new Point(0,0),72*5));return res;}
function GetTextboxPoints(diameter,additional_data)
{var res=[];var width=diameter;var height=diameter;if(additional_data)
{var tempContext=document.createElement('canvas').getContext('2d');tempContext.font="bold "+additional_data.style.mainTextFontSize+
DefaultFont;let metrics=tempContext.measureText(additional_data.text);width=metrics.width+diameter/2;let actualHeight=metrics.actualBoundingBoxAscent*1.6;height=Math.max(height,actualHeight);}
res.push(new Point(-width/2,-height/2));res.push(new Point(width/2,-height/2));res.push(new Point(width/2,height/2));res.push(new Point(-width/2,height/2));return res;}
function GetShowflakePoints(diameter)
{var res=[];var superSmallRadius=diameter*0.8/2;var smallRadius=diameter*0.95/2;var bigRadius=diameter*1.5/2;let angel=8;res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),-angel));res.push(new Point(smallRadius,0));res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),angel));res.push(new Point(bigRadius,0).rotate(new Point(0,0),30));res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),60-angel));res.push(new Point(smallRadius,0).rotate(new Point(0,0),60));res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),60+angel));res.push(new Point(bigRadius,0).rotate(new Point(0,0),30+60));res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),60+60-angel));res.push(new Point(smallRadius,0).rotate(new Point(0,0),60+60));res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),60+60+angel));res.push(new Point(bigRadius,0).rotate(new Point(0,0),30+60+60));res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),60+60+60-angel));res.push(new Point(smallRadius,0).rotate(new Point(0,0),60+60+60));res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),60+60+60+angel));res.push(new Point(bigRadius,0).rotate(new Point(0,0),30+60+60+60));res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),60+60+60+60-angel));res.push(new Point(smallRadius,0).rotate(new Point(0,0),60+60+60+60));res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),60+60+60+60+angel));res.push(new Point(bigRadius,0).rotate(new Point(0,0),30+60+60+60+60));res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),60+60+60+60+60-angel));res.push(new Point(smallRadius,0).rotate(new Point(0,0),60+60+60+60+60));res.push(new Point(superSmallRadius,0).rotate(new Point(0,0),60+60+60+60+60+angel));res.push(new Point(bigRadius,0).rotate(new Point(0,0),30+60+60+60+60+60));return res;}
function GetPointsForShape(shape,diameter,additional_data=null)
{switch(parseInt(shape))
{case VertexSquareShape:return GetSquarePoints(diameter);break;case VertexTriangleShape:return GetTrianglePoints(diameter);break;case VertexPentagonShape:return GetPentagonPoints(diameter);break;case VertexTextboxShape:return GetTextboxPoints(diameter,additional_data);break;case VertexSnowflakeShape:return GetShowflakePoints(diameter);break;default:return null;break;}}
function GetSizeForShape(shape,diameter)
{switch(parseInt(shape))
{case VertexSquareShape:return diameter;break;case VertexTriangleShape:return diameter*1.5;break;case VertexPentagonShape:return diameter*1.2;break;case VertexTextboxShape:return diameter;break;case VertexSnowflakeShape:return diameter*1.5;break;default:return diameter;break;}}
const CommonTextCenter=0,CommonTextUp=1;const DefaultFont="px sans-serif",DefaultMainTextFontSize=16,TopTextFontSizeDelta=-4;function BaseVertexStyle()
{this.baseStyles=[];}
BaseVertexStyle.prototype.GetStyle=function(baseStyle,object)
{this.baseStyles.forEach(function(element){var styleObject=globalApplication.GetStyle("vertex",element,object);baseStyle=styleObject.GetStyle(baseStyle,object);});if(this.hasOwnProperty('lineWidth'))
baseStyle.lineWidth=this.lineWidth;if(this.hasOwnProperty('strokeStyle'))
baseStyle.strokeStyle=this.strokeStyle;if(this.hasOwnProperty('fillStyle'))
baseStyle.fillStyle=this.fillStyle;if(this.hasOwnProperty('mainTextColor'))
baseStyle.mainTextColor=this.mainTextColor;if(this.hasOwnProperty('shape'))
baseStyle.shape=this.shape;if(this.hasOwnProperty('upTextColor'))
baseStyle.upTextColor=this.upTextColor;if(this.hasOwnProperty('commonTextPosition'))
baseStyle.commonTextPosition=this.commonTextPosition;if(this.hasOwnProperty('mainTextFontSize'))
baseStyle.mainTextFontSize=this.mainTextFontSize;baseStyle.lineWidth=parseInt(baseStyle.lineWidth);return this.FixNewFields(baseStyle);}
BaseVertexStyle.prototype.FixNewFields=function(style)
{if(!style.hasOwnProperty('shape'))
style.shape=VertexCircleShape;if(!style.hasOwnProperty('commonTextPosition'))
style.commonTextPosition=CommonTextCenter;if(!style.hasOwnProperty('mainTextFontSize'))
style.mainTextFontSize=DefaultMainTextFontSize;return style;}
BaseVertexStyle.prototype.Clear=function()
{delete this.lineWidth;delete this.strokeStyle;delete this.fillStyle;delete this.mainTextColor;delete this.shape;delete this.upTextColor;delete this.commonTextPosition;delete this.lineWidth;delete this.mainTextFontSize;}
BaseVertexStyle.prototype.ShouldLoad=function(field)
{return field!="baseStyles";}
function CommonVertexStyle()
{BaseVertexStyle.apply(this,arguments);this.lineWidth=2;this.strokeStyle='#c7b7c7';this.fillStyle='#68aeba';this.mainTextColor='#f0d543';this.shape=VertexCircleShape;this.upTextColor='#68aeba';this.commonTextPosition=CommonTextCenter;this.baseStyles=[];}
CommonVertexStyle.prototype=Object.create(BaseVertexStyle.prototype);function CommonPrintVertexStyle()
{BaseVertexStyle.apply(this,arguments);this.strokeStyle='#000000';this.fillStyle='#FFFFFF';this.mainTextColor='#000000';this.baseStyles.push("common");}
CommonPrintVertexStyle.prototype=Object.create(BaseVertexStyle.prototype);function SelectedVertexStyle0()
{BaseVertexStyle.apply(this,arguments);this.strokeStyle='#f0d543';this.mainTextColor='#f0d543';this.fillStyle='#c7627a';this.baseStyles.push("common");}
SelectedVertexStyle0.prototype=Object.create(BaseVertexStyle.prototype);function SelectedVertexStyle1()
{BaseVertexStyle.apply(this,arguments);this.strokeStyle='#7a9ba0';this.mainTextColor='#c3d2d5';this.fillStyle='#534641';this.baseStyles.push("selected");}
SelectedVertexStyle1.prototype=Object.create(BaseVertexStyle.prototype);function SelectedVertexStyle2()
{BaseVertexStyle.apply(this,arguments);this.strokeStyle='#8C4C86';this.mainTextColor='#dbbdd8';this.fillStyle='#253267';this.baseStyles.push("selected");}
SelectedVertexStyle2.prototype=Object.create(BaseVertexStyle.prototype);function SelectedVertexStyle3()
{BaseVertexStyle.apply(this,arguments);this.strokeStyle='#6188FF';this.mainTextColor='#6188FF';this.fillStyle='#E97CF9';this.baseStyles.push("selected");}
SelectedVertexStyle3.prototype=Object.create(BaseVertexStyle.prototype);function SelectedVertexStyle4()
{BaseVertexStyle.apply(this,arguments);this.strokeStyle='#C6B484';this.mainTextColor='#C6B484';this.fillStyle='#E0DEE1';this.baseStyles.push("selected");}
SelectedVertexStyle4.prototype=Object.create(BaseVertexStyle.prototype);function SelectedPrintVertexStyle()
{BaseVertexStyle.apply(this,arguments);this.strokeStyle='#000000';this.mainTextColor='#000000';this.fillStyle='#AAAAAA';this.baseStyles.push("printed");}
SelectedPrintVertexStyle.prototype=Object.create(BaseVertexStyle.prototype);var DefaultSelectedGraphStyles=[new SelectedVertexStyle0(),new SelectedVertexStyle1(),new SelectedVertexStyle2(),new SelectedVertexStyle3(),new SelectedVertexStyle4()];var DefaultPrintSelectedGraphStyles=[new SelectedPrintVertexStyle()];function BaseVertexDrawer(context)
{this.context=context;}
BaseVertexDrawer.prototype.Draw=function(baseGraph,graphStyle)
{this.SetupStyle(graphStyle);this.DrawShape(baseGraph);if(this.currentStyle.lineWidth!=0)
this.context.stroke();this.context.fill();var shapeSize=GetSizeForShape(graphStyle.shape,baseGraph.model.diameter+graphStyle.lineWidth);if(graphStyle.commonTextPosition==CommonTextCenter)
{this.DrawCenterText(baseGraph.position,baseGraph.mainText,graphStyle.mainTextColor,graphStyle.fillStyle,true,true,graphStyle.mainTextFontSize);this.DrawCenterText(baseGraph.position.add(new Point(0,-shapeSize/2.0-graphStyle.mainTextFontSize/2.2)),baseGraph.upText,graphStyle.upTextColor,graphStyle.strokeStyle,false,false,graphStyle.mainTextFontSize+TopTextFontSizeDelta);}
else if(graphStyle.commonTextPosition==CommonTextUp)
{this.DrawCenterText(baseGraph.position.add(new Point(0,-shapeSize/2.0-graphStyle.mainTextFontSize/2.2)),baseGraph.mainText,graphStyle.mainTextColor,graphStyle.fillStyle,true,false,graphStyle.mainTextFontSize);this.DrawCenterText(baseGraph.position.add(new Point(0,shapeSize/2.0+graphStyle.mainTextFontSize/1.7)),baseGraph.upText,graphStyle.upTextColor,graphStyle.strokeStyle,false,false,graphStyle.mainTextFontSize+TopTextFontSizeDelta);}}
BaseVertexDrawer.prototype.SetupStyle=function(style)
{this.currentStyle=style;this.context.lineWidth=style.lineWidth;this.context.strokeStyle=style.strokeStyle;this.context.fillStyle=style.fillStyle;}
BaseVertexDrawer.prototype.DrawShape=function(baseGraph)
{this.context.beginPath();if(this.currentStyle.shape==VertexCircleShape)
{this.context.arc(baseGraph.position.x,baseGraph.position.y,baseGraph.model.diameter/2.0,0,2*Math.PI);}
else
{var points=GetPointsForShape(this.currentStyle.shape,baseGraph.model.diameter,{style:this.currentStyle,text:baseGraph.mainText});this.context.moveTo(baseGraph.position.x+points[points.length-1].x,baseGraph.position.y+points[points.length-1].y);var context=this.context;points.forEach(function(point){context.lineTo(baseGraph.position.x+point.x,baseGraph.position.y+point.y);});}
this.context.closePath();}
BaseVertexDrawer.prototype.DrawText=function(position,text,color,outlineColor,outline,font)
{this.context.fillStyle=color;this.context.font=font;this.context.lineWidth=4;this.context.strokeStyle=outlineColor;if(outline)
{this.context.save();this.context.lineJoin='round';this.context.strokeText(text,position.x,position.y);this.context.restore();}
this.context.fillText(text,position.x,position.y);}
BaseVertexDrawer.prototype.DrawCenterText=function(position,text,color,outlineColor,bold,outline,size)
{this.context.textBaseline="middle";this.context.font=(bold?"bold ":"")+size+DefaultFont;var textWidth=this.context.measureText(text).width;this.DrawText(new Point(position.x-textWidth/2,position.y),text,color,outlineColor,outline,this.context.font);}
function GraphFullStyle(redrawCallback)
{this.edgeCommonStyle=new CommonEdgeStyle();this.isEdgeCommonStyleCustom=false;this.edgeSelectedStyles=FullArrayCopy(DefaultSelectedEdgeStyles);this.isEdgeSelectedStylesCustom=false;this.vertexCommonStyle=new CommonVertexStyle();this.isVertexCommonStyleCustom=false;this.vertexSelectedVertexStyles=FullArrayCopy(DefaultSelectedGraphStyles);this.isVertexSelectedVertexStylesCustom=false;this.backgroundCommonStyle=new CommonBackgroundStyle();this.isBackgroundCommonStyleCustom=false;this.defaultVertexSize=null;this.defaultEdgeWidth=null;this.redrawCallback=redrawCallback;}
GraphFullStyle.prototype.Save=function()
{var res="";var needEnd=false;var checkValue=[];checkValue.push({field:"edgeCommonStyle",value:this.edgeCommonStyle,check:this.isEdgeCommonStyleCustom});checkValue.push({field:"edgeSelectedStyles",value:this.edgeSelectedStyles,check:this.isEdgeSelectedStylesCustom});checkValue.push({field:"vertexCommonStyle",value:this.vertexCommonStyle,check:this.isVertexCommonStyleCustom});checkValue.push({field:"vertexSelectedVertexStyles",value:this.vertexSelectedVertexStyles,check:this.isVertexSelectedVertexStylesCustom});checkValue.push({field:"backgroundCommonStyle",value:this.backgroundCommonStyle,check:this.isBackgroundCommonStyleCustom});checkValue.push({field:"defaultVertexSize",value:this.defaultVertexSize,check:this.defaultVertexSize!=null});checkValue.push({field:"defaultEdgeWidth",value:this.defaultEdgeWidth,check:this.defaultEdgeWidth!=null});checkValue.forEach(function(entry){if(!entry.check)
return;if(needEnd)
res=res+",";let valueJson="";if(typeof entry.value.saveToJson==="function"){valueJson=entry.value.saveToJson();}else{valueJson=JSON.stringify(entry.value);}
res=res+"\""+entry.field+"\""+":"+valueJson;needEnd=true;});res=res+"";return gEncodeToHTML(res);}
GraphFullStyle.prototype.Load=function(json)
{var checkValue=[];checkValue.push({field:"edgeCommonStyle",value:this.edgeCommonStyle,check:"isEdgeCommonStyleCustom",deep:false});checkValue.push({field:"edgeSelectedStyles",value:this.edgeSelectedStyles,check:"isEdgeSelectedStylesCustom",deep:true});checkValue.push({field:"vertexCommonStyle",value:this.vertexCommonStyle,check:"isVertexCommonStyleCustom",deep:false});checkValue.push({field:"vertexSelectedVertexStyles",value:this.vertexSelectedVertexStyles,check:"isVertexSelectedVertexStylesCustom",deep:true});checkValue.push({field:"defaultVertexSize",value:"defaultVertexSize",check:null,deep:false});checkValue.push({field:"defaultEdgeWidth",value:"defaultEdgeWidth",check:null,deep:false});checkValue.push({field:"backgroundCommonStyle",value:this.backgroundCommonStyle,check:"isBackgroundCommonStyleCustom",deep:false});var decoderStr=gDecodeFromHTML(json);var parsedSave=JSON.parse(decoderStr);var app=this;checkValue.forEach(function(entry){if(parsedSave.hasOwnProperty(entry.field))
{if(typeof parsedSave[entry.field]==='number')
{app[entry.value]=parseInt(parsedSave[entry.field]);}
else
{if(typeof entry.value.loadFromJson==="function"){entry.value.loadFromJson(parsedSave[entry.field],function(){setTimeout(function()
{if(app.redrawCallback!=null)
{app.redrawCallback();}},1000);});if(entry.check!=null)
app[entry.check]=true;return;}
if(!entry.deep)
entry.value.Clear();for(var k in parsedSave[entry.field])
{if(!entry.deep)
{if(entry.value.ShouldLoad(k))
{entry.value[k]=parsedSave[entry.field][k];}}
else
{if(k%1!=0)
{continue;}
if(entry.value[k]==undefined)
{continue;}
entry.value[k].Clear();for(var deepK in parsedSave[entry.field][k])
{if(kinclude("model/plugins/"+plugin,modulDir)),onFinish);}}
function getVertexToVertexArray(graph,ignoreDirection)
{res={};for(var i=0;iqueryString+="&"+param.name+"="+param.value);$.ajax({type:"POST",url:"/"+SiteDir+"cgi-bin/GraphCGI.exe?"+queryString,data:xml,dataType:"text",}).done(function(msg)
{processResult(msg);});};if(this.app.isSupportEmscripten()){console.log("Use Emscripten");var delimiter="";var processData=algorithmName+delimiter+xml+
delimiter+"report"+delimiter+"xml";otherParams.forEach((param)=>processData+=delimiter+param.name+delimiter+param.value);var res={};try{res=this.app.processEmscripten(processData);}
catch(error){userAction("emscripten_error_"+algorithmName);console.log("Error on Emscripten: "+error+"\n"+error.stack);callCGIAlgorithms();return true;}
processResult(res);}else{console.log("Use new CGI");callCGIAlgorithms();}
return true;}
BaseAlgorithmEx.prototype.GetNodesPath=function(array,start,count)
{var res=[];for(var index=start;index