graphonline/script/pages/editor/api/index.js.cache

2252 lines
215 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

moduleLoader.beginCacheLoading(["/script/shared/utils.js?v=96","/script/shared/gzip.js?v=96","/script/entities/graph/api/index.js?v=96","/script/shared/point.js?v=96","/script/entities/edge/api/index.js?v=96","/script/entities/edge/model/BaseEdge.js?v=96","/script/entities/edge/model/EdgeModel.js?v=96","/script/entities/vertex/api/index.js?v=96","/script/entities/vertex/model/BaseVertex.js?v=96","/script/entities/vertex/model/VertexModel.js?v=96","/script/entities/graph/model/Graph.js?v=96","/script/features/draw_graph/api/index.js?v=96","/script/features/draw_graph/model/BaseBackgroundDrawer.js?v=96","/script/features/draw_graph/model/EdgeStyle.js?v=96","/script/features/draw_graph/model/BaseEdgeDrawer.js?v=96","/script/features/draw_graph/model/VertexShape.js?v=96","/script/features/draw_graph/model/VertexStyle.js?v=96","/script/features/draw_graph/model/BaseVertexDrawer.js?v=96","/script/features/draw_graph/model/GraphFullStyle.js?v=96","/script/features/algorithms/api/index.js?v=96","/script/features/algorithms/model/Algorithms.js?v=96","/script/features/algorithms/model/BaseTraversal.js?v=96","/script/features/base_handler/index.js?v=96","/script/features/default_handler/index.js?v=96","/script/features/add_vertices_handler/index.js?v=96","/script/features/connect_vertices_handler/index.js?v=96","/script/features/delete_objects_handler/index.js?v=96","/script/features/algorithm_handler/index.js?v=96","/script/features/select_auto_save_graph_or_not/index.js?v=96","/script/features/graph_preview/index.js?v=96","/script/features/serialization/api/index.js?v=96","/script/features/serialization/model/GraphMLCreator.js?v=96","/script/features/enum_vertices/EnumVertices.js?v=96","/script/pages/editor/model/texts.js?v=96","/script/pages/editor/model/UndoStack.js?v=96","/script/pages/editor/model/DiskSaveLoad.js?v=96","/script/pages/editor/model/Application.js?v=96","/script/pages/editor/ui/ya_metrika.js?v=96","/script/pages/editor/ui/editor.js?v=96","/script/pages/editor/ui/main.js?v=96",]);{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,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&apos;');}
function gDecodeFromHTML(str)
{if(typeof str!=='string')
return str;return str.replace(/&apos;/g,"'").replace(/&quot;/g,'"').replace(/&gt;/g,'>').replace(/&lt;/g,'<').replace(/&amp;/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"<edge "+"source=\""+this.vertex1.id+"\" "+"target=\""+this.vertex2.id+"\" "+"directed=\""+this.isDirect+"\" "+"weight=\""+this.weight+"\" "+"useWeight=\""+this.useWeight+"\" "+"id=\""+this.id+"\" "+"text=\""+gEncodeToHTML(this.text)+"\" "+"upText=\""+gEncodeToHTML(this.upText)+"\" "+"arrayStyleStart=\""+this.arrayStyleStart+"\" "+"arrayStyleFinish=\""+this.arrayStyleFinish+"\" "+
((Object.keys(this.ownStyles).length>0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+
this.model.SaveToXML()+"></edge>";}
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<pointsVertex1.length-1;i++)
{var hitText=Point.hitTest(new Point(0,0),lineFinish1,pointsVertex1[i],pointsVertex1[i+1]);if(hitText!=null)
{res.push(data.position.add(hitText));break;}}}});return res;}
BaseEdge.prototype.SetWeight=function(weight)
{var useWeight=false;if(!isNaN(parseInt(weight,10)))
{useWeight=true;}
weight=(!isNaN(parseInt(weight,10)))?weight:1;this.weight=Number(weight);this.useWeight=useWeight;}
BaseEdge.prototype.SetUpText=function(text)
{this.upText=text;}
BaseEdge.prototype.resetOwnStyle=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{delete this.ownStyles[index];}}
BaseEdge.prototype.setOwnStyle=function(index,style)
{this.ownStyles[index]=style;}
BaseEdge.prototype.getStyleFor=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{return this.ownStyles[index];}
else
{var style=null;if(index==0)
style=globalApplication.GetStyle("edge","common");else
style=globalApplication.GetStyle("edge","selected",undefined,index-1);return style;}}
BaseEdge.prototype.hasOwnStyleFor=function(index)
{return this.ownStyles.hasOwnProperty(index);}
var EdgeModels={"line":0,"curve":1};const defaultEdgeWidth=4;function EdgeModel()
{this.width=globalApplication.GetDefaultEdgeWidth();this.type=EdgeModels.line;this.curveValue=EdgeModel.prototype.defaultCurve;this.default=true;this.sizeOfLoop=24;this.loopShiftAngel=Math.PI/6;}
EdgeModel.prototype.defaultCurve=0.1;EdgeModel.prototype.copyFrom=function(other)
{this.width=other.width;this.type=other.type;this.curveValue=other.curveValue;this.default=other.default;}
EdgeModel.prototype.SaveToXML=function()
{return"model_width=\""+this.width+"\" "+"model_type=\""+this.type+"\" "+"model_curveValue=\""+this.curveValue+"\" "+"model_default=\""+this.default+"\" ";}
EdgeModel.prototype.LoadFromXML=function(xml,graph)
{this.width=xml.attr('model_width')==null?this.width:parseFloat(xml.attr("model_width"));this.type=xml.attr('model_type')==null?this.type:xml.attr("model_type");this.curveValue=xml.attr('model_curveValue')==null?this.curveValue:parseFloat(xml.attr("model_curveValue"));this.default=xml.attr('model_default')==null?this.default:xml.attr("model_default")=="true";}
EdgeModel.prototype.GetCurvePoint=function(position1,position2,t)
{var points=this.GetBezierPoints(position1,position2);var firstBezierPoint=points[0];var secondBezierPoint=points[1];var B0_t=Math.pow(1-t,3);var B1_t=3*t*Math.pow(1-t,2);var B2_t=3*t*t*(1-t)
var B3_t=t*t*t;var ax=position1.x;var ay=position1.y;var dx=position2.x;var dy=position2.y;var bx=firstBezierPoint.x;var by=firstBezierPoint.y;var cx=secondBezierPoint.x;var cy=secondBezierPoint.y;var px_t=(B0_t*ax)+(B1_t*bx)+(B2_t*cx)+(B3_t*dx);var py_t=(B0_t*ay)+(B1_t*by)+(B2_t*cy)+(B3_t*dy);return new Point(px_t,py_t);}
EdgeModel.prototype.GetBezierPoints=function(position1,position2)
{var direction=position2.subtract(position1);var delta=direction.length();direction.normalize(1.0);var normal=direction.normal();var deltaOffsetPixels=delta*this.curveValue;var yOffset=normal.multiply(deltaOffsetPixels);var firstBezierPointShift=(direction.multiply(delta*0.2)).add(yOffset);var secondBezierPointShift=(direction.multiply(-delta*0.2)).add(yOffset);var firstBezierPoint=position1.add(firstBezierPointShift);var secondBezierPoint=position2.add(secondBezierPointShift);return[firstBezierPoint,secondBezierPoint];}
EdgeModel.prototype.HitTest=function(position1,position2,mousePos)
{if(this.type==EdgeModels.line)
return this.HitTestLine(position1,position2,mousePos,1.0,false);else if(this.type==EdgeModels.curve)
return this.HitTestCurve(position1,position2,mousePos);return false;}
EdgeModel.prototype.HitTestLine=function(position1,position2,mousePos,factor,ignoreSelfLoop)
{if(factor===undefined)
{factor=1.0;}
var pos1=position1;var pos2=position2;var pos0=mousePos;if(pos1.equals(pos2)&&!ignoreSelfLoop)
{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*factor;}
var r1=pos0.distance(pos1);var r2=pos0.distance(pos2);var r12=pos1.distance(pos2);if(r1>=(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<interval_count;i++)
{var finish=this.GetCurvePoint(position1,position2,i/interval_count);if(this.HitTestLine(start,finish,mousePos,2.0,true))
return true;start=finish;}
return false;}
EdgeModel.prototype.ChangeCurveValue=function(delta)
{if(this.type==EdgeModels.line)
{this.type=EdgeModels.curve;this.curveValue=0.0;}
this.curveValue=this.curveValue+delta;if(Math.abs(this.curveValue)<=0.01)
this.type=EdgeModels.line;this.default=false;}
EdgeModel.prototype.SetCurveValue=function(value)
{if(this.type==EdgeModels.line)
{this.type=EdgeModels.curve;this.curveValue=0.0;}
this.curveValue=value;if(Math.abs(this.curveValue)<=0.01)
this.type=EdgeModels.line;this.default=false;}
EdgeModel.prototype.GetLoopSize=function()
{if(Math.abs(this.curveValue)<=0.01)
{return this.sizeOfLoop;}
else
{let normalCurve=this.curveValue;if(this.type==EdgeModels.line){normalCurve=this.defaultCurve;}
else if(normalCurve>=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"<node "+"positionX=\""+this.position.x+"\" "+"positionY=\""+this.position.y+"\" "+"id=\""+this.id+"\" "+"mainText=\""+gEncodeToHTML(this.mainText)+"\" "+"upText=\""+gEncodeToHTML(this.upText)+"\" "+
((Object.keys(this.ownStyles).length>0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+"size=\""+this.model.diameter+"\" "+"></node>";}
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)<this.model.diameter/2.0+width;}
else
{var relativePos=(new Point(pos.x,pos.y)).subtract(this.position);var lineFinish1=relativePos.add(new Point(1000,0));var lineFinish2=relativePos.add(new Point(-1000,0));if(style==null)
{console.error("Some thing wrong with style");}
var pointsVertex1=GetPointsForShape(shape,this.model.diameter+width,style!=null?{style:style,text:this.mainText}:null);pointsVertex1.push(pointsVertex1[0]);var hitNumber1=0;var hitNumber2=0;for(var i=0;i<pointsVertex1.length-1;i++)
{var hitTest=Point.hitTest(relativePos,lineFinish1,pointsVertex1[i],pointsVertex1[i+1]);if(hitTest!=null)
{hitNumber1++;}
hitTest=Point.hitTest(relativePos,lineFinish2,pointsVertex1[i],pointsVertex1[i+1]);if(hitTest!=null)
{hitNumber2++;}}
return hitNumber1==1&&hitNumber2==1;}
return false;}
BaseVertex.prototype.resetOwnStyle=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{delete this.ownStyles[index];}}
BaseVertex.prototype.setOwnStyle=function(index,style)
{this.ownStyles[index]=FullObjectCopy(style);}
BaseVertex.prototype.getStyleFor=function(index)
{if(this.ownStyles.hasOwnProperty(index))
{return this.ownStyles[index];}
else
{var style=null;if(index==0)
style=globalApplication.GetStyle("vertex","common");else
style=globalApplication.GetStyle("vertex","selected",undefined,index-1);return style;}}
BaseVertex.prototype.hasOwnStyleFor=function(index)
{return this.ownStyles.hasOwnProperty(index);}
BaseVertex.prototype.getDefaultDiameterFactor=function(textSize)
{var textFactor=defaultVertexDiameter*8.0/(2.0*textSize);return new Point(1.0+(this.mainText.length?this.mainText.length/textFactor:0),1.5);}
BaseVertex.prototype.getBBox=function(style)
{var textSize=DefaultMainTextFontSize;if(style!==undefined&&style.mainTextFontSize!==undefined)
{textSize=style.mainTextFontSize;}
var defaultDiameter=(new VertexModel()).diameter;var vertexDiameter=this.model.diameter;var factor=this.getDefaultDiameterFactor(textSize);let textWidth=(GetTextWidth(this.mainText,textSize+"px sans-serif")+8)/1.5;let textHeight=textSize+4;let isTextAbove=style.commonTextPosition==1;return new Point(Math.max(factor.x*defaultDiameter,vertexDiameter,textWidth),Math.max(factor.y*defaultDiameter,vertexDiameter+(isTextAbove?textHeight:0),textHeight));}
const defaultVertexDiameter=30;function VertexModel()
{this.diameter=globalApplication.GetDefaultVertexSize();}
function Graph()
{this.vertices=[];this.edges=[];this.uidGraph=0;this.uidEdge=10000;this.hasDirect=false;this.isMultiGraph=false;this.hasNegativeWeight=false;};Graph.prototype.infinity=1E8;Graph.prototype.maxVertices=1000;Graph.prototype.edgesOffset=10000;Graph.prototype.AddNewVertex=function(vertex)
{if(this.vertices.length<=this.maxVertices)
{vertex.SetId(this.uidGraph);this.uidGraph=this.uidGraph+1;this.vertices.push(vertex);}
return this.vertices.length-1;}
Graph.prototype.ClearGraph=function(){this.vertices=[];this.edges=[];this.uidGraph=0;this.uidEdge=10000;this.hasDirect=false;this.isMultiGraph=false;this.hasNegativeWeight=false;}
Graph.prototype.AddNewEdgeSafe=function(graph1,graph2,isDirect,weight,replaceIfExists=true)
{return this.AddNewEdge(new BaseEdge(graph1,graph2,isDirect,weight),replaceIfExists);}
Graph.prototype.AddNewEdge=function(edge,replaceIfExists)
{edge.id=this.uidEdge;this.uidEdge=this.uidEdge+1;var edge1=this.FindEdgeAny(edge.vertex1.id,edge.vertex2.id);var edgeRevert=this.FindEdgeAny(edge.vertex2.id,edge.vertex1.id);if(!edge.isDirect)
{if(edge1!=null&&replaceIfExists)
this.DeleteEdge(edge1);if(edgeRevert!=null&&replaceIfExists)
this.DeleteEdge(edgeRevert);this.edges.push(edge);}
else
{if(edge1!=null&&replaceIfExists)
this.DeleteEdge(edge1);if(edgeRevert!=null&&!edgeRevert.isDirect&&replaceIfExists)
this.DeleteEdge(edgeRevert);this.edges.push(edge);}
this.isMultiGraph=this.checkMutiGraph();this.hasNegativeWeight=this.checkNegativeWeight();return this.edges.length-1;}
Graph.prototype.DeleteEdge=function(edgeObject)
{var index=this.edges.indexOf(edgeObject);if(index>-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<this.edges.length;i++)
{if(this.edges[i].vertex1==vertexObject||this.edges[i].vertex2==vertexObject)
{this.DeleteEdge(this.edges[i]);i--;}}
this.vertices.splice(index,1);}}
Graph.prototype.HasConnectedNodes=function(vertexObject)
{var res=false;var index=this.vertices.indexOf(vertexObject);if(index>-1)
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].vertex1==vertexObject||this.edges[i].vertex2==vertexObject)
{res=true;break;}}}
return res;}
Graph.prototype.FindVertex=function(id)
{var res=null;for(var i=0;i<this.vertices.length;i++)
{if(this.vertices[i].id==id)
{res=this.vertices[i];break;}}
return res;}
Graph.prototype.FindVertexByTitle=function(title)
{var res=null;for(var i=0;i<this.vertices.length;i++)
{if(this.vertices[i].mainText==title)
{res=this.vertices[i];break;}}
return res;}
Graph.prototype.FindEdge=function(id1,id2)
{return this.FindEdgeAny(id1,id2);}
Graph.prototype.FindEdgeById=function(edgeId)
{var res=null;for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].id==edgeId)
{res=this.edges[i];break;}}
return res;}
Graph.prototype.FindEdgeAny=function(id1,id2)
{var res=null;for(var i=0;i<this.edges.length;i++)
{if((this.edges[i].vertex1.id==id1&&this.edges[i].vertex2.id==id2)||(!this.edges[i].isDirect&&this.edges[i].vertex1.id==id2&&this.edges[i].vertex2.id==id1))
{res=this.edges[i];break;}}
return res;}
Graph.prototype.FindEdgeMin=function(id1,id2)
{var res=null;var minWeight=this.infinity;for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight<minWeight)
{res=edge;minWeight=edge.weight;}}}
return res;}
Graph.prototype.FindEdgeMax=function(id1,id2)
{var res=null;var maxWeight=-this.infinity;for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight>maxWeight)
{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<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(edge.vertex1.id==id2&&edge.vertex2.id==id1))
{if(edge.weight<minWeight)
{res=edge;minWeight=edge.weight;}}}
return res;}
Graph.prototype.FindAllEdges=function(id1,id2)
{var res=[];for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if((edge.vertex1.id==id1&&edge.vertex2.id==id2)||(!edge.isDirect&&edge.vertex1.id==id2&&edge.vertex2.id==id1))
{res.push(edge);}}
return res;}
Graph.prototype.GetAdjacencyMatrixStr=function()
{var matrix="";for(var i=0;i<this.vertices.length;i++)
{for(var j=0;j<this.vertices.length;j++)
{var edge=this.FindEdgeMin(this.vertices[i].id,this.vertices[j].id);if(edge!=null)
{matrix+=edge.weight;}
else
{matrix+="0";}
if(j!=this.vertices.length)
{matrix+=", ";}}
matrix=matrix+"\n";}
return matrix;}
Graph.prototype.GetAdjacencyMatrix=function()
{var matrix=[];for(var i=0;i<this.vertices.length;i++)
{matrix.push([]);var v1=this.vertices[i];for(var j=0;j<this.vertices.length;j++)
{var v2=this.vertices[j];var edge=this.FindEdgeMin(v1.id,v2.id);if(edge!=null)
{matrix[i][j]=edge.GetWeight();}
else
{matrix[i][j]=this.infinity;}}}
return matrix;}
Graph.prototype.TestAdjacencyMatrix=function(matrix,rowsObj,colsObj,separator)
{if(separator===undefined)
{separator=",";}
var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j<rowsObj.rows.length;++j)
{if(rowsObj.rows[j]==="")
{rowsObj.rows.splice(j--,1);}}
colsObj.cols=[];for(var i=0;i<rowsObj.rows.length;i++)
{colsObj.cols[i]=this.SplitMatrixString(rowsObj.rows[i],separator);for(j=0;j<colsObj.cols[i].length;++j)
{if(colsObj.cols[i][j]==="")
{colsObj.cols[i].splice(j--,1);}}
if(colsObj.cols[i].length!=rowsObj.rows.length)
{bGoodFormat=false;break;}}
return bGoodFormat;}
Graph.prototype.TestPair=function(pair)
{let lines=pair.split("\n");let regExp=[/^.+-.+$/g,/^.+\>.+$/g,/^.+<.+$/g,/^.+-\(\d+\.?\d+\)-.+$/g,/^.+-\(\d+\.?\d+\)\>.+$/g,/^.+<\(\d+\.?\d+\)\-.+$/g];let res=true;for(let i=0;i<lines.length;++i)
{let resLine=false;let line=lines[i];if(line==""){continue;}
for(let j=0;j<regExp.length;++j){if(line.match(regExp[j])){resLine=true;}}
res=resLine&&res;}
return res;}
Graph.prototype.IsVerticesHaveSamePosition=function(position,vertexCount)
{var res=false;for(var j=0;j<Math.min(this.vertices.length,vertexCount);j++)
{if(position.distance(this.vertices[j].position)<this.vertices[j].model.diameter*2)
{res=true;break;}}
return res;}
Graph.prototype.GetRandomPosition=function(viewportSize){return new Point(Math.random()*viewportSize.x,Math.random()*viewportSize.y);}
Graph.prototype.GetRandomPositionOfVertex=function(matrix,vertexIndex,viewportSize)
{var point=new Point(0,0);var relatedVertex=[];for(var j=0;j<matrix.length;j++)
{if(j<this.vertices.length&&(cols[vertexIndex][j]>0||cols[j][vertexIndex]>0)&&j!=vertexIndex)
{relatedVertex.push(this.vertices[j]);}}
var diameter=(new VertexModel()).diameter;if(relatedVertex.length>1)
{for(var j=0;j<relatedVertex.length;j++)
{point=point.add(relatedVertex[j].position);}
point=point.multiply(1/relatedVertex.length);point.offset(Math.random()*diameter+(Math.random()?-1:1)*2*diameter,Math.random()*diameter+(Math.random()?-1:1)*2*diameter);}
else
{point=new Point(Math.random()*viewportSize.x,Math.random()*viewportSize.y);}
if(this.IsVerticesHaveSamePosition(point,matrix.length))
{point.offset(Math.random()*diameter+ +(Math.random()?-1:1)*4*diameter,Math.random()*diameter+ +(Math.random()?-1:1)*4*diameter);}
point.x=Math.min(Math.max(point.x,diameter),viewportSize.x);point.y=Math.min(Math.max(point.y,diameter),viewportSize.y);return point;}
Graph.prototype.VerticesReposition=function(viewportSize,newVertices)
{var maxGravityDistanceSqr=Math.max(viewportSize.x,viewportSize.y)/5.0;maxGravityDistanceSqr=maxGravityDistanceSqr*maxGravityDistanceSqr;var velocityDamping=0.85;var diameter=(new VertexModel()).diameter;var maxDistance=diameter*3;var gravityDistanceSqr=10*(maxDistance*maxDistance);var edgeGravityKof=10/(maxDistance);var kCenterForce=10/(maxDistance*10);var centerPoint=viewportSize.multiply(0.5);var velocityMax=maxDistance*10;var edgesMatrix={};for(var i=0;i<this.edges.length;i++)
{edgesMatrix[this.edges[i].vertex1.id+this.edges[i].vertex2.id*1000]=1;edgesMatrix[this.edges[i].vertex2.id+this.edges[i].vertex1.id*1000]=1;}
var startAngel=Math.random()*180.0;for(i=0;i<newVertices.length;i++)
{newVertices[i].position.orbit(new Point(viewportSize.x/2,viewportSize.y/2),(viewportSize.x-diameter*2)/2,(viewportSize.y-diameter*2)/2,360*i/newVertices.length+startAngel);}
var k=0;var bChanged=true;while(k<1000&&bChanged)
{var vertexData=[];for(i=0;i<newVertices.length;i++)
{var currentVertex={};currentVertex.object=newVertices[i];currentVertex.net_force=new Point(0,0);currentVertex.velocity=new Point(0,0);vertexData.push(currentVertex);for(j=0;j<this.vertices.length;j++)
{otherVertex=this.vertices[j];if(otherVertex==currentVertex.object)continue;var rsq=currentVertex.object.position.distanceSqr(otherVertex.position);{var force=(currentVertex.object.position.subtract(otherVertex.position)).normalize(gravityDistanceSqr/rsq);currentVertex.net_force=currentVertex.net_force.add(force);}}
for(j=0;j<this.vertices.length;j++)
{otherVertex=this.vertices[j];if(edgesMatrix.hasOwnProperty(currentVertex.object.id+1000*otherVertex.id))
{var distance=currentVertex.object.position.distance(otherVertex.position);if(distance>maxDistance)
{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;i<vertexData.length;i++)
{var v=vertexData[i];var velocity=v.velocity;if(velocity.length()>velocityMax)
{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<newVertices.length;i++)
{newVertices[i].position.orbit(new Point(viewportSize.x/2,viewportSize.y/2),(viewportSize.x-diameter*2)/2,(viewportSize.y-diameter*2)/2,360*i/newVertices.length+startAngel);}}
else
{var count=10;var angle=360.0/count;var viewportAspect=viewportSize.x/viewportSize.y;var bestIndex=0;var graphSize=bbox.size();var bestAspect=graphSize.x/graphSize.y;var center=bbox.center();for(var i=1;i<count;i++)
{for(j=0;j<newVertices.length;j++)
{newVertices[j].position.rotate(center,angle);}
var newBBox=this.getGraphBBox();var newAspect=newBBox.size().x/newBBox.size().y;if(Math.abs(newAspect-viewportAspect)<Math.abs(bestAspect-viewportAspect))
{bestAspect=newAspect;bestIndex=i;}}
for(j=0;j<newVertices.length;j++)
{newVertices[j].position.rotate(center,-angle*(count-bestIndex-1));}}}
Graph.prototype.SetAdjacencyMatrix=function(matrix,viewportSize,currentEnumVerticesType,separator)
{if(separator===undefined)
{separator=",";}
var rowsObj={};var colsObj={};if(this.TestAdjacencyMatrix(matrix,rowsObj,colsObj,separator))
{rows=rowsObj.rows;cols=colsObj.cols;var clonedEdge=this.edges.slice(0);for(var i=0;i<clonedEdge.length;i++)
{this.DeleteEdge(clonedEdge[i]);}
var newVertices=[];var bWeightGraph=false;for(var i=0;i<rows.length;i++)
{for(var j=0;j<rows.length;j++)
{if(j>=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<Math.max(this.vertices.length,rows.length);i++)
{this.DeleteVertex(this.vertices[i]);i--;}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.SetPair=function(pairs,viewportSize,currentEnumVerticesType)
{if(this.TestPair(pairs))
{this.ClearGraph();let lines=pairs.split("\n");let regExp=[/^(.+)-(.+)$/g,/^(.+)\>(.+)$/g,/^(.+)<(.+)$/g,/^(.+)-\((-?\d+|-?\d+\.?\d+)\)-(.+)$/g,/^(.+)-\((-?\d+|-?\d+\.?\d+)\)\>(.+)$/g,/^(.+)<\((-?\d+|-?\d+\.?\d+)\)\-(.+)$/g,];let bWeightGraph=false;var newVertices=[];for(var i=0;i<lines.length;i++)
{let line=lines[i];if(line==""){continue;}
for(let j=regExp.length-1;j>=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<rowsObj.rows.length;++j)
{if(rowsObj.rows[j]==="")
{rowsObj.rows.splice(j--,1);}}
colsObj.cols=[];var columnCount=0;for(var i=0;i<rowsObj.rows.length;i++)
{colsObj.cols[i]=this.SplitMatrixString(rowsObj.rows[i],separator);for(j=0;j<colsObj.cols[i].length;++j)
{if(colsObj.cols[i][j]==="")
{colsObj.cols[i].splice(j--,1);}}
if(i==0)
{columnCount=colsObj.cols[i].length;}
if(colsObj.cols[i].length!=columnCount)
{bGoodFormat=false;break;}}
if(bGoodFormat)
{for(var i=0;i<colsObj.cols[0].length;i++)
{var values=[];for(j=0;j<colsObj.cols.length;++j)
{if(colsObj.cols[j][i]!=0)
{values.push(colsObj.cols[j][i]);}}
if(!(values.length<=1||(values.length==2&&(values[0]==values[1]||values[0]==-values[1]))))
{bGoodFormat=false;break;}}}
return bGoodFormat;}
Graph.prototype.SetIncidenceMatrix=function(matrix,viewportSize,currentEnumVerticesType)
{var rowsObj={};var colsObj={};if(this.TestIncidenceMatrix(matrix,rowsObj,colsObj))
{rows=rowsObj.rows;cols=colsObj.cols;var clonedEdge=this.edges.slice(0);for(var i=0;i<clonedEdge.length;i++)
{this.DeleteEdge(clonedEdge[i]);}
var newVertices=[];var bWeightGraph=false;for(var i=0;i<cols[0].length;i++)
{var edgeValue=[];var edgeIndex=[];for(var j=0;j<cols.length;j++)
{if(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;i<Math.max(this.vertices.length,cols.length);i++)
{this.DeleteVertex(this.vertices[i]);i--;}
this.VerticesReposition(viewportSize,newVertices);}}
Graph.prototype.GetIncidenceMatrix=function()
{var matrix="";for(var i=0;i<this.vertices.length;i++)
{for(var j=0;j<this.edges.length;j++)
{if(this.edges[j].vertex1==this.vertices[i])
{matrix+=this.edges[j].weight;}
else if(this.edges[j].vertex2==this.vertices[i]&&!this.edges[j].isDirect)
{matrix+=this.edges[j].weight;}
else if(this.edges[j].vertex2==this.vertices[i]&&this.edges[j].isDirect)
{matrix+=-this.edges[j].weight;}
else
{matrix+="0";}
if(j!=this.edges.length-1)
{matrix+=", ";}}
matrix=matrix+"\n";}
return matrix;}
Graph.prototype.SplitMatrixString=function(line,separator)
{if(separator===undefined)
{separator=",";}
var res=[];var i=0;var isZeroOneLine=true;for(i=0;i<line.length;i++)
{if(line.charAt(i)!='0'&&line.charAt(i)!='1')
{isZeroOneLine=false;break;}}
if(!isZeroOneLine)
{if(separator!=",")
{line=line.replace(/,/g,".");}
for(i=0;i<line.length;i++)
{if(("0123456789.-e").indexOf(line.charAt(i))<0)
{if(i>0)
{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<line.length;i++)
{res.push(line.charAt(i));}}
console.log(res);return res;}
Graph.prototype.SaveToXML=function(additionalData)
{var mainHeader="<?xml version=\"1.0\" encoding=\"UTF-8\"?><graphml>";var header="<graph id=\"Graph\" uidGraph=\""+this.uidGraph+"\""+" uidEdge=\""+this.uidEdge+"\">";var xmlBody="";for(var i=0;i<this.vertices.length;i++)
{xmlBody=xmlBody+this.vertices[i].SaveToXML();}
xmlBody=xmlBody+"";for(var i=0;i<this.edges.length;i++)
{xmlBody=xmlBody+this.edges[i].SaveToXML();}
xmlBody=xmlBody+"";additionalField="";if(additionalData.length>0)
{additionalField="<additional data=\""+additionalData+"\"/>"}
return mainHeader+header+xmlBody+"</graph>"+additionalField+"</graphml>";}
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(loadedEdgeId<this.edgesOffset)
{loadedEdgeId=this.edgesOffset;}
if(defaultLoadEdges!="directed"&&defaultLoadEdges!="undirected")
{defaultLoadEdges="undirected";}
this.uidGraph=loadedGraphId;this.uidEdge=loadedEdgeId;$nodes=$xml.find("node");var vertices=[];$nodes.each(function(){var vertex=new BaseVertex();vertex.LoadFromXML($(this));vertices.push(vertex);});this.vertices=vertices;$edges=$xml.find("edge");var edges=[];var graph=this;$edges.each(function(){var edge=new BaseEdge();edge.LoadFromXML($(this),graph,defaultLoadEdges);if(edge.id<graph.uidEdge){edge.id=graph.uidEdge;graph.uidEdge++;}
edges.push(edge);});this.edges=edges;$additional=$xml.find("additional");if($additional.length!=0&&additionalData!=null)
{additionalData["data"]=$additional.attr('data');}
this.isMultiGraph=this.checkMutiGraph();this.hasNegativeWeight=this.checkNegativeWeight();}
Graph.prototype.hasDirectEdge=function()
{var res=false;for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{res=true;break;}}
return res;}
Graph.prototype.hasUndirectEdge=function()
{var res=false;for(var i=0;i<this.edges.length;i++)
{if(!this.edges[i].isDirect)
{res=true;break;}}
return res;}
Graph.prototype.hasEdges=function()
{return this.edges.length>0;}
Graph.prototype.clampPositions=function(viewportSize)
{var diameter=(new VertexModel()).diameter;for(i=0;i<this.vertices.length;i++)
{this.vertices[i].position.x=Math.min(Math.max(this.vertices[i].position.x,diameter),viewportSize.x-diameter);this.vertices[i].position.y=Math.min(Math.max(this.vertices[i].position.y,diameter),viewportSize.y-diameter);}}
Graph.prototype.getGraphBBox=function(vertexStyle)
{var pointMin=new Point(1e5,1e5);var pointMax=new Point(-1e5,-1e5);var diameter=(new VertexModel()).diameter;for(i=0;i<this.vertices.length;i++)
{var vertex=this.vertices[i];var bbox=vertex.getBBox(vertexStyle==undefined?vertex.getStyleFor(0):vertexStyle);pointMin=pointMin.min(vertex.position.subtract(bbox));pointMax=pointMax.max(vertex.position.add(bbox));}
var max_curve_length=32;for(i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if(edge.model.type==EdgeModels.curve)
{var max_curve=edge.vertex2.position.subtract(edge.vertex1.position).length()/max_curve_length;for(j=0;j<max_curve;j++)
{var point=edge.model.GetCurvePoint(edge.vertex1.position,edge.vertex2.position,j/max_curve);var deltaVector=new Point(max_curve_length,max_curve_length);pointMin=pointMin.min(point.subtract(deltaVector));pointMax=pointMax.max(point.add(deltaVector));}}}
return new Rect(pointMin,pointMax);}
Graph.prototype.hasPair=function(edge)
{return this.FindPairFor(edge)!=null;}
Graph.prototype.FindPairFor=function(edge)
{var res=this.getNeighborEdges(edge);return res.length==1?res[0]:null;}
Graph.prototype.getNeighborEdges=function(edge)
{var res=[];for(var i=0;i<this.edges.length;i++)
{var curEdge=this.edges[i];if(curEdge==edge)
continue;if((curEdge.vertex1.id==edge.vertex1.id&&curEdge.vertex2.id==edge.vertex2.id)||(curEdge.vertex1.id==edge.vertex2.id&&curEdge.vertex2.id==edge.vertex1.id))
{res.push(curEdge);}}
return res;}
Graph.prototype.checkMutiGraph=function()
{var res=false;var start={};for(var i=0;i<this.edges.length;i++)
{var edge=this.edges[i];if(start.hasOwnProperty(edge.vertex1.id)&&start[edge.vertex1.id]==edge.vertex2.id)
{res=true;break;}
start[edge.vertex1.id]=edge.vertex2.id;if(!edge.isDirect)
{if(start.hasOwnProperty(edge.vertex2.id)&&start[edge.vertex2.id]==edge.vertex1.id)
{res=true;break;}
start[edge.vertex2.id]=edge.vertex1.id;}}
return res;}
Graph.prototype.checkNegativeWeight=function()
{var res=false;for(var i=0;i<this.edges.length&&!res;i++)
{var edge=this.edges[i];res=edge.GetWeight()<0;}
return res;}
Graph.prototype.isMulti=function()
{return this.isMultiGraph;}
Graph.prototype.hasNegative=function()
{return this.hasNegativeWeight;}
Graph.prototype.isNeedReposition=function()
{var res=false;for(var i=0;i<this.vertices.length;i++)
{res=res||this.vertices[i].IsUndefinedPosition();}
return res;}
Graph.prototype.FixEdgeCurve=function(edgeIndex)
{var edgeObject=this.edges[edgeIndex];var hasPair=this.hasPair(edgeObject);var neighborEdges=this.getNeighborEdges(edgeObject);if(hasPair)
{if(edgeObject.model.default)
edgeObject.model.type=EdgeModels.curve;var pairEdge=this.FindPairFor(edgeObject);if(pairEdge.model.default)
{pairEdge.model.type=EdgeModels.curve;if(pairEdge.vertex1==edgeObject.vertex1&&pairEdge.vertex2==edgeObject.vertex2)
pairEdge.model.curveValue=-pairEdge.model.curveValue;}}
else if(neighborEdges.length>=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;i<neighborEdges.length;i++)
{var edge=neighborEdges[i];var sameDirection=(originalEdge.vertex1.id==edge.vertex1.id);if(edge.model.type==EdgeModels.curve)
{values[(sameDirection?edge.model.curveValue:-edge.model.curveValue)]=true;}}
var changeValue=DefaultHandler.prototype.curveValue;var defaultValue=0.0;var maxSearch=10;for(var i=1;i<maxSearch;i++)
{value=i*changeValue;if(!values.hasOwnProperty(value))
return value;value=-i*changeValue;if(!values.hasOwnProperty(value))
return value;}
return defaultValue;}
Graph.prototype.reverseAllEdges=function()
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{let v1=this.edges[i].vertex1;this.edges[i].vertex1=this.edges[i].vertex2;this.edges[i].vertex2=v1;}}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.makeAllEdgesDirected=function()
{for(var i=0;i<this.edges.length;i++)
{if(!this.edges[i].isDirect)
{this.edges[i].isDirect=true;}}
this.isMultiGraph=this.checkMutiGraph();}
Graph.prototype.makeAllEdgesUndirected=function()
{for(var i=0;i<this.edges.length;i++)
{if(this.edges[i].isDirect)
{this.edges[i].isDirect=false;}}
this.isMultiGraph=this.checkMutiGraph();}
{let modulDir="features/draw_graph/";doInclude([include("model/BaseBackgroundDrawer.js",modulDir),include("model/EdgeStyle.js",modulDir),include("model/BaseEdgeDrawer.js",modulDir),include("model/VertexShape.js",modulDir),include("model/VertexStyle.js",modulDir),include("model/BaseVertexDrawer.js",modulDir),include("model/GraphFullStyle.js",modulDir)])}
function CommonBackgroundStyle()
{this.commonColor='#ffffff';this.commonOpacity=1.0;this.image=null;}
CommonBackgroundStyle.prototype.Clear=function()
{delete this.commonColor;delete this.commonOpacity;delete this.image;}
CommonBackgroundStyle.prototype.ShouldLoad=function(field)
{return true;}
CommonBackgroundStyle.prototype.saveToJson=function(field)
{return JSON.stringify({commonColor:this.commonColor,commonOpacity:this.commonOpacity,image:this.image!=null?this.image.src:null});}
CommonBackgroundStyle.prototype.loadFromJson=function(json,callbackOnLoaded)
{this.commonColor=json["commonColor"];this.commonOpacity=json["commonOpacity"];this.image=null;if(typeof json["image"]==='string'){this.image=new Image();this.image.onload=function(){callbackOnLoaded();}
this.image.src=json["image"];}}
PrintBackgroundStyle.prototype=Object.create(CommonBackgroundStyle.prototype);function PrintBackgroundStyle()
{CommonBackgroundStyle.apply(this,arguments);this.commonColor='#ffffff';this.commonOpacity=1.0;this.image=null;}
function BaseBackgroundDrawer(context)
{this.context=context;}
BaseBackgroundDrawer.prototype.Draw=function(style,width,height,position,scale)
{var context=this.context;var rect=new Rect(position,position.add(new Point(width/scale,height/scale)));context.clearRect(-rect.minPoint.x,-rect.minPoint.y,rect.size().x+1,rect.size().y+1);var oldOpacity=context.globalAlpha;if(style.commonOpacity>0.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(k<entry.value.length&&entry.value[k].ShouldLoad(deepK))
entry.value[k][deepK]=parsedSave[entry.field][k][deepK];}}}}
if(entry.check!=null)
app[entry.check]=true;}});}
{let modulDir="features/algorithms/";doInclude([include("model/Algorithms.js",modulDir),include("model/BaseTraversal.js",modulDir)])
function loadAsyncAlgorithms(onFinish){let modulDir="features/algorithms/";let pluginsList=["BFS.js","Coloring.js","ConnectedComponent.js","DFS.js","EulerianLoop.js","EulerianPath.js","FindAllPatches.js","FindLongestPath.js","FindShortPatchsFromOne.js","Floid.js","GraphReorder.js","HamiltonianLoop.js","HamiltonianPath.js","IsomorphismCheck.js","MaxClique.js","MaxFlow.js","MinimumSpanningTree.js","ModernGraphStyle.js","RadiusAndDiameter.js","ShortestPath.js","VerticesDegree.js"];doIncludeAsync(pluginsList.map((plugin)=>include("model/plugins/"+plugin,modulDir)),onFinish);}}
function getVertexToVertexArray(graph,ignoreDirection)
{res={};for(var i=0;i<graph.edges.length;i++)
{edge=graph.edges[i];if(!res.hasOwnProperty(edge.vertex1.id))
{res[edge.vertex1.id]=[];}
res[edge.vertex1.id].push(edge.vertex2);if(!edge.isDirect||ignoreDirection)
{if(!res.hasOwnProperty(edge.vertex2.id))
{res[edge.vertex2.id]=[];}
res[edge.vertex2.id].push(edge.vertex1);}}
return res;}
var g_Algorithms=[];var g_AlgorithmIds=[];function RegisterAlgorithm(factory)
{g_Algorithms.push(factory);g_AlgorithmIds.push(factory(null).getId());}
function BaseAlgorithm(graph,app)
{this.graph=graph;this.app=app;}
BaseAlgorithm.prototype.getName=function(local)
{return"unknown_name_"+local;}
BaseAlgorithm.prototype.getId=function()
{return"unknown.unknown";}
BaseAlgorithm.prototype.getMessage=function(local)
{return"unknown_message_"+local;}
BaseAlgorithm.prototype.selectVertex=function(vertex)
{return false;}
BaseAlgorithm.prototype.selectEdge=function(edge)
{return false;}
BaseAlgorithm.prototype.deselectAll=function()
{return true;}
BaseAlgorithm.prototype.result=function(resultCallback)
{return null;}
BaseAlgorithm.prototype.instance=function()
{return true;}
BaseAlgorithm.prototype.needRestoreUpText=function()
{return true;}
BaseAlgorithm.prototype.wantRestore=function()
{return false;}
BaseAlgorithm.prototype.restore=function()
{}
BaseAlgorithm.prototype.getObjectSelectedGroup=function(object)
{return 0;}
BaseAlgorithm.prototype.messageWasChanged=function(){}
BaseAlgorithm.prototype.getPriority=function()
{return 0;}
BaseAlgorithm.prototype.IsSupportMultiGraph=function()
{return false;}
BaseAlgorithm.prototype.getCategory=function()
{return 0;}
BaseAlgorithm.prototype.IsSupportNegativeWeight=function()
{return false;}
function BaseAlgorithmEx(graph,app)
{BaseAlgorithm.apply(this,arguments);}
BaseAlgorithmEx.prototype=Object.create(BaseAlgorithm.prototype);class ProcessingMessage
{constructor(algorithm_object){this.algorithm_object=algorithm_object;this.processing_index=0;this.original_message=this.algorithm_object.message;this.processing_timer=setInterval(function()
{this.processing_index=(this.processing_index+1)%3;this.algorithm_object.message=this.original_message+".".repeat(this.processing_index);this.algorithm_object.app.updateMessage();}.bind(this),500);}
stop(){this.algorithm_object.message=this.original_message;this.algorithm_object.app.updateMessage();clearInterval(this.processing_timer);}}
BaseAlgorithmEx.prototype.CalculateAlgorithm=function(algorithmName,otherParams,resultCallback,ignoreSeparateNodes=false)
{let processing_message=new ProcessingMessage(this);if(location.hostname==="localhost"||location.hostname==="127.0.0.1")
console.log(algorithmName+" "+otherParams);var graph=this.graph;var ignoreNodes={};if(ignoreSeparateNodes)
for(var i=0;i<graph.vertices.length;i++)
if(!graph.HasConnectedNodes(graph.vertices[i]))
ignoreNodes[graph.vertices[i].id]=1;var creator=new GraphMLCreator(graph.vertices,graph.edges,ignoreNodes);var pathObjects=[];var properties={};var result=[];var xml=creator.GetXMLString();console.log(xml);var processResult=function(msg){console.log(msg);$('#debug').text(msg);xmlDoc=$.parseXML(msg);var $xml=$(xmlDoc);$results=$xml.find("result");$results.each(function(){$values=$(this).find("value");$values.each(function(){var type=$(this).attr('type');var value=$(this).text();var res={};res.type=type;res.value=value;result.push(res);});});$nodes=$xml.find("node");$nodes.each(function(){var id=$(this).attr('id');$data=$(this).find("data");$data.each(function(){if("hightlightNode"==$(this).attr('key')&&$(this).text()=="1")
{pathObjects.push(graph.FindVertex(id));}
else
{if(!properties[id])
{properties[id]={};}
properties[id][$(this).attr('key')]=$(this).text();}});});$edges=$xml.find("edge");$edges.each(function(){var source=$(this).attr('source');var target=$(this).attr('target');var edge=graph.FindEdge(source,target);if(typeof $(this).attr('id')!=='undefined')
{edge=graph.FindEdgeById($(this).attr('id'));}
pathObjects.push(edge);$data=$(this).find("data");$data.each(function(){if(!properties[edge.id])
{properties[edge.id]={};}
properties[edge.id][$(this).attr('key')]=$(this).text();});});console.log(result);processing_message.stop();resultCallback(pathObjects,properties,result);};var callCGIAlgorithms=function()
{var queryString=algorithmName+"=cgiInput&report=xml";otherParams.forEach((param)=>queryString+="&"+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="<s\\emscript_split\\s>";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<start+count;index++)
{if(array[index].type==4)
{res.push(array[index].value);}}
return res;}
BaseAlgorithmEx.prototype.GetNodesEdgesPath=function(array,start,count)
{var res=[];for(var index=start;index<start+count;index++)
{if(array[index].type==4||array[index].type==5)
{res.push(array[index].value);}}
return res;}
function BaseTraversal(graph,app)
{BaseAlgorithmEx.apply(this,arguments);this.visited=[];this.edges=[];this.timer=null;}
BaseTraversal.prototype=Object.create(BaseAlgorithmEx.prototype);BaseTraversal.prototype.timerInterval=500;BaseTraversal.prototype.result=function(resultCallback)
{var result={};result["version"]=1;return result;}
BaseTraversal.prototype.selectVertex=function(vertex)
{this.visited=[];this.edges=[];if(this.timer)
clearTimeout(this.timer);this.timer=null;this.visited.push(vertex);var context=this;this.timer=setInterval(function()
{context.step();},this.timerInterval);this.message=this.getMainMessage();return true;}
BaseTraversal.prototype.getObjectSelectedGroup=function(object)
{return(this.visited.includes(object)?1:(this.edges.includes(object)?1:0));}
BaseTraversal.prototype.instance=function()
{return false;}
function BaseHandler(app)
{this.app=app;this.app.setRenderPath([]);if(this.removeStack){this.removeContextMenu();}
this.contextMenuObject=null;this.contextMenuPoint=null;}
BaseHandler.prototype.needRedraw=false;BaseHandler.prototype.objects=[];BaseHandler.prototype.message="";BaseHandler.prototype.IsNeedRedraw=function(object)
{return this.needRedraw;}
BaseHandler.prototype.RestRedraw=function(object)
{this.needRedraw=false;}
BaseHandler.prototype.SetObjects=function(objects)
{this.objects=objects;}
BaseHandler.prototype.GetSelectedGraph=function(pos)
{var res=null;for(var i=0;i<this.app.graph.vertices.length;i++)
{if(this.app.graph.vertices[i].HitTest(pos))
{res=this.app.graph.vertices[i];}}
return res;}
BaseHandler.prototype.GetSelectedArc=function(pos)
{let res=null;for(var i=0;i<this.app.graph.edges.length;i++)
{var edge=this.app.graph.edges[i];if(edge.HitTest(new Point(pos.x,pos.y)))
res=edge;}
return res;}
BaseHandler.prototype.GetSelectedObject=function(pos)
{var graphObject=this.GetSelectedGraph(pos);if(graphObject)
{return graphObject;}
var arcObject=this.GetSelectedArc(pos);if(arcObject)
{return arcObject;}
return null;}
BaseHandler.prototype.GetUpText=function(object)
{return"";}
BaseHandler.prototype.GetMessage=function()
{return this.message;}
BaseHandler.prototype.MouseMove=function(pos){}
BaseHandler.prototype.MouseDown=function(pos){}
BaseHandler.prototype.MouseUp=function(pos){}
BaseHandler.prototype.GetSelectedGroup=function(object)
{return 0;}
BaseHandler.prototype.InitControls=function()
{var vertex1Text=document.getElementById("Vertex1");if(vertex1Text)
{var handler=this;vertex1Text.onchange=function(){for(var i=0;i<handler.app.graph.vertices.length;i++)
{if(handler.app.graph.vertices[i].mainText==vertex1Text.value)
{handler.SelectFirstVertexMenu(vertex1Text,handler.app.graph.vertices[i]);userAction("selectVertex1_menu");break;}}};this.UpdateFirstVertexMenu(vertex1Text);}
var vertex2Text=document.getElementById("Vertex2");if(vertex2Text)
{var handler=this;vertex2Text.onchange=function(){for(var i=0;i<handler.app.graph.vertices.length;i++)
{if(handler.app.graph.vertices[i].mainText==vertex2Text.value)
{handler.SelectSecondVertexMenu(vertex2Text,handler.app.graph.vertices[i]);userAction("selectVertex2_menu");break;}}};this.UpdateSecondVertexMenu(vertex2Text);}}
BaseHandler.prototype.GetNodesPath=function(array,start,count)
{var res=[];for(var index=start;index<start+count;index++)
{res.push(this.app.graph.FindVertex(array[index].value));}
return res;}
BaseHandler.prototype.RestoreAll=function()
{}
BaseHandler.prototype.GetSelectVertexMenu=function(menuName)
{var res="<input list=\"vertexList"+menuName+"\" id=\""+menuName+"\" class=\"SelectVertexInput\"/>"+"<datalist id=\"vertexList"+menuName+"\">";for(var i=0;i<this.app.graph.vertices.length;i++)
{res=res+"<option value=\""+this.app.graph.vertices[i].mainText+"\"/>";}
return res+"</datalist>";}
BaseHandler.prototype.GetSelect2VertexMenu=function()
{return"<span style=\"float:right\">"+
this.GetSelectVertexMenu("Vertex1")+" &rarr; "+this.GetSelectVertexMenu("Vertex2")+"</span>";}
BaseHandler.prototype.SelectFirstVertexMenu=function(vertex1Text,vertex)
{}
BaseHandler.prototype.UpdateFirstVertexMenu=function()
{}
BaseHandler.prototype.SelectSecondVertexMenu=function(vertex2Text,vertex)
{}
BaseHandler.prototype.UpdateSecondVertexMenu=function()
{}
BaseHandler.prototype.GetSelectedVertex=function()
{return null;}
BaseHandler.prototype.addContextMenu=function()
{var $contextMenu=$("#contextMenu");var handler=this;$("#Context_Delete").click(function(){if(handler.contextMenuObject!=null){handler.app.PushToStack("DeleteObject");handler.app.DeleteObject(handler.contextMenuObject);handler.app.redrawGraph();userAction("DeleteObject_contextMenu");}});$("#Context_Rename").click(function(){if(handler.contextMenuObject!=null){var callback=function(enumType){handler.RenameVertex(enumType.GetVertexText(0),handler.contextMenuObject);userAction("RenameVertex_contextMenu");};var customEnum=new TextEnumVerticesCustom(handler.app);customEnum.ShowDialog(callback,g_rename,g_renameVertex,handler.contextMenuObject.mainText);}});$("#Context_Connect").click(function(){if(handler.contextMenuObject!=null&&handler.GetSelectedVertex()!=null){var addFunc=function(firstVertex,secondVertex,direct){handler.app.CreateNewArc(firstVertex,secondVertex,direct,document.getElementById('EdgeWeight').value,$("#RadiosReplaceEdge").prop("checked"),document.getElementById('EdgeLable').value);handler.app.redrawGraph();}
handler.ShowCreateEdgeDialog(handler.GetSelectedVertex(),handler.contextMenuObject,addFunc);}});$("#Context_Delete_Edge").click(function(){if(handler.contextMenuObject!=null){handler.app.PushToStack("DeleteObject");handler.app.DeleteObject(handler.contextMenuObject);handler.app.redrawGraph();userAction("DeleteObject_contextMenu");}});$("#Context_Edit_Edge").click(function(){if(handler.contextMenuObject!=null){handler.ShowEditEdgeDialog(handler.contextMenuObject);}});$("#Context_Add_Vertex").click(function(){handler.app.PushToStack("Add");handler.app.CreateNewGraph(handler.contextMenuPoint.x,handler.contextMenuPoint.y);handler.app.redrawGraph();});$("#Context_Back_Color").click(function(){var setupBackgroundStyle=new SetupBackgroundStyle(handler.app);setupBackgroundStyle.show();});$("body").on("contextmenu","canvas",function(e){handler.contextMenuPoint=handler.app.getMousePos(handler.app.canvas,e);handler.contextMenuObject=handler.GetSelectedObject(handler.contextMenuPoint);if(handler.contextMenuObject instanceof BaseVertex){$("#edgeContextMenu").hide();$("#backgroundContextMenu").hide();$("#vertexContextMenu").show();if(handler.GetSelectedVertex()==null){$("#Context_Connect").hide();}else{$("#Context_Connect").show();}}else if(handler.contextMenuObject instanceof BaseEdge){$("#vertexContextMenu").hide();$("#backgroundContextMenu").hide();$("#edgeContextMenu").show();}else{$("#vertexContextMenu").hide();$("#edgeContextMenu").hide();$("#backgroundContextMenu").show();}
$contextMenu.css({display:"block",left:e.offsetX,top:e.offsetY});return false;});$("body").click(function(){$contextMenu.hide();});}
BaseHandler.prototype.removeContextMenu=function()
{$("body").off("contextmenu");$("#Context_Delete").off("click");$("#Context_Rename").off("click");$("#Context_Connect").off("click");$("#Context_Delete_Edge").off("click");$("#Context_Edit_Edge").off("click");$("#Context_Add_Vertex").off("click");$("#Context_Back_Color").off("click");}
BaseHandler.prototype.RenameVertex=function(text,object)
{if(object!=null&&(object instanceof BaseVertex))
{this.app.PushToStack("RenameVertex");object.mainText=text;this.app.redrawGraph();}}
BaseHandler.prototype.ShowCreateEdgeDialog=function(firstVertex,secondVertex,addEdgeCallBack){if(!this.app.graph.isMulti())
{var hasEdge=this.app.graph.FindEdgeAny(firstVertex.id,secondVertex.id);var hasReverseEdge=this.app.graph.FindEdgeAny(secondVertex.id,firstVertex.id);if(hasEdge==null&&hasReverseEdge==null)
{$("#RadiosReplaceEdge").prop("checked",true);$("#NewEdgeAction").hide();}
else{$("#NewEdgeAction").show();}}
else
{$("#RadiosAddEdge").prop("checked",true);$("#NewEdgeAction").hide();}
var dialogButtons={};var handler=this;$("#CheckSaveDefaultEdge").prop("checked",false);$("#defaultEdgeDialogBlock").show();dialogButtons[g_orintEdge]=function(){handler.app.PushToStack("Connect");addEdgeCallBack(firstVertex,secondVertex,true);$(this).dialog("close");};dialogButtons[g_notOrintEdge]=function(){handler.app.PushToStack("Connect");addEdgeCallBack(firstVertex,secondVertex,false);$(this).dialog("close");};var edgePresets=this.app.GetEdgePresets();var presetsStr="<span onClick=\"document.getElementById('EdgeWeight').value='"+g_DefaultWeightPreset
+"'; document.getElementById('EdgeWeightSlider').value='"+g_DefaultWeightPreset
+"';\" style=\"cursor: pointer\" class=\"defaultWeigth\">"+g_DefaultWeightPreset+"</span>";for(var i=0;i<edgePresets.length;i++)
{var edgePreset=edgePresets[i];presetsStr+="<span onClick=\"document.getElementById('EdgeWeight').value='"+edgePreset
+"'; document.getElementById('EdgeWeightSlider').value="+edgePreset
+";\" style=\"cursor: pointer\" class=\"defaultWeigth\">"+edgePreset+"</span>";}
document.getElementById("EdgesPresets").innerHTML=presetsStr;document.getElementById('EdgeLable').value="";$("#addEdge").dialog({resizable:false,height:"auto",width:"auto",modal:true,title:g_addEdge,buttons:dialogButtons,dialogClass:'EdgeDialog',open:function(){$(this).off('submit').on('submit',function(){return false;});setTimeout(function(){const weightInput=document.getElementById('EdgeWeight');if(weightInput)
{weightInput.focus();weightInput.select();}},0);}});}
BaseHandler.prototype.ShowEditEdgeDialog=function(edgeObject){var dialogButtons={};var handler=this;dialogButtons[g_save]=function(){handler.app.PushToStack("ChangeEdge");edgeObject.SetWeight(document.getElementById('EdgeWeight').value);edgeObject.SetUpText(document.getElementById('EdgeLable').value);handler.needRedraw=true;handler.app.redrawGraph();userAction("ChangeWeight");$(this).dialog("close");};document.getElementById('EdgeWeight').value=edgeObject.useWeight?edgeObject.weight:g_noWeight;document.getElementById('EdgeWeightSlider').value=edgeObject.useWeight?edgeObject.weight:0;var edgePresets=handler.app.GetEdgePresets();var presetsStr="<span onClick=\"document.getElementById('EdgeWeight').value='"+g_DefaultWeightPreset+"'; document.getElementById('EdgeWeightSlider').value='"+
g_DefaultWeightPreset+"';\" style=\"cursor: pointer\" class=\"defaultWeigth\">"+g_DefaultWeightPreset+"</span>";for(var i=0;i<edgePresets.length;i++)
{var edgePreset=edgePresets[i];presetsStr+="<span onClick=\"document.getElementById('EdgeWeight').value='"+edgePreset+"'; document.getElementById('EdgeWeightSlider').value="+
edgePreset+";\" style=\"cursor: pointer\" class=\"defaultWeigth\">"+edgePreset+"</span>";}
document.getElementById("EdgesPresets").innerHTML=presetsStr;document.getElementById('EdgeLable').value=edgeObject.upText;$("#CheckSaveDefaultEdge").prop("checked",false);$("#defaultEdgeDialogBlock").hide();$("#addEdge").dialog({resizable:false,height:"auto",width:"auto",modal:true,title:g_editWeight,buttons:dialogButtons,dialogClass:'EdgeDialog',open:function(){$(handler).off('submit').on('submit',function(){return false;});}});}
doInclude([include("features/base_handler/index.js")])
function DefaultHandler(app)
{this.removeStack=true;BaseHandler.apply(this,arguments);this.message=g_textsSelectAndMove+" <span class=\"hidden-phone\">"+g_selectGroupText+"</span>"+" <span class=\"hidden-phone\">"+g_useContextMenuText+"</span>";this.selectedObjects=[];this.dragObject=null;this.selectedObject=null;this.prevPosition=null;this.groupingSelect=false;this.selectedLogRect=false;this.selectedLogCtrl=false;this.saveUndo=false;this.addContextMenu();}
DefaultHandler.prototype=Object.create(BaseHandler.prototype);DefaultHandler.prototype.pressed=false;DefaultHandler.prototype.curveValue=0.1;DefaultHandler.prototype.GetSelectedVertex=function()
{return(this.selectedObject instanceof BaseVertex)?this.selectedObject:null;}
DefaultHandler.prototype.MouseMove=function(pos)
{if(this.dragObject)
{if(!this.saveUndo)
{this.app.PushToStack("Move");this.saveUndo=true;}
this.dragObject.position.x=pos.x;this.dragObject.position.y=pos.y;this.needRedraw=true;}
else if(this.selectedObjects.length>0&&this.pressed&&!this.groupingSelect)
{if(!this.saveUndo)
{this.app.PushToStack("Move");this.saveUndo=true;}
var offset=(new Point(pos.x,pos.y)).subtract(this.prevPosition);for(var i=0;i<this.selectedObjects.length;i++)
{var object=this.selectedObjects[i];if(object instanceof BaseVertex)
{object.position=object.position.add(offset);}}
this.prevPosition=pos;this.needRedraw=true;}
else if(this.pressed)
{if(this.groupingSelect)
{var newPos=new Point(pos.x,pos.y);this.app.SetSelectionRect(new Rect(newPos.min(this.prevPosition),newPos.max(this.prevPosition)));this.SelectObjectInRect(this.app.GetSelectionRect());this.needRedraw=true;if(!this.selectedLogRect)
{userAction("GroupSelected.SelectRect");this.selectedLogRect=true;}}
else
{this.app.onCanvasMove((new Point(pos.x,pos.y)).subtract(this.prevPosition).multiply(this.app.canvasScale));this.needRedraw=true;}}}
DefaultHandler.prototype.MouseDown=function(pos)
{this.dragObject=null;var selectedObject=this.GetSelectedObject(pos);var severalSelect=g_ctrlPressed;if(selectedObject==null||(!severalSelect&&!this.selectedObjects.includes(selectedObject)))
{this.selectedObject=null;this.selectedObjects=[];this.groupingSelect=g_ctrlPressed;}
if((severalSelect||this.selectedObjects.includes(selectedObject))&&(this.selectedObjects.length>0||this.selectedObject!=null)&&selectedObject!=null)
{if(this.selectedObjects.length==0)
{this.selectedObjects.push(this.selectedObject);this.selectedObject=null;this.selectedObjects.push(selectedObject);}
else if(!this.selectedObjects.includes(selectedObject))
{this.selectedObjects.push(selectedObject);}
else if(severalSelect&&this.selectedObjects.includes(selectedObject))
{var index=this.selectedObjects.indexOf(selectedObject);this.selectedObjects.splice(index,1);}
if(!this.selectedLogCtrl)
{userAction("GroupSelected.SelectCtrl");this.selectedLogCtrl=true;}}
else
{if(selectedObject!=null)
{this.selectedObject=selectedObject;}
if((selectedObject instanceof BaseVertex)&&selectedObject!=null)
{this.dragObject=selectedObject;this.message=g_moveCursorForMoving;}}
this.needRedraw=true;this.pressed=true;this.prevPosition=pos;this.app.canvas.style.cursor="move";}
DefaultHandler.prototype.MouseUp=function(pos)
{this.saveUndo=false;this.message=g_textsSelectAndMove+" <span class=\"hidden-phone\">"+g_selectGroupText+"</span>"+" <span class=\"hidden-phone\">"+g_useContextMenuText+"</span>";this.dragObject=null;this.pressed=false;this.app.canvas.style.cursor="auto";this.app.SetSelectionRect(null);this.groupingSelect=false;if(this.selectedObject!=null&&(this.selectedObject instanceof BaseVertex))
{this.message=g_textsSelectAndMove
+"<div style=\"float:right;position: relative;\">"
+"<button type=\"button\" class=\"btn btn-outline-secondary dropdown-toggle btn-sm menu-text white-btn\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\">"
+" "+g_action+" <span class=\"caret\"></span>"
+"</button>"
+"<ul class=\"dropdown-menu\" style=\"z-index:15; position: absolute;\">"
+" <li><a href=\"#\" class=\"dropdown-item\" id=\"renameButton\">"+g_renameVertex+"</a></li>"
+" <li><a href=\"#\" class=\"dropdown-item\" id=\"changeCommonStyle\">"+g_commonVertexStyle+"</a></li>"
+" <li><a href=\"#\" class=\"dropdown-item\" id=\"changeSelectedStyle\">"+g_selectedVertexStyle+"</a></li>"
+"</ul>"
+"</div>";var handler=this;var callback=function(enumType){handler.RenameVertex(enumType.GetVertexText(0),handler.selectedObject);userAction("RenameVertex");};$('#message').unbind();$('#message').on('click','#renameButton',function(){var customEnum=new TextEnumVerticesCustom(handler.app);customEnum.ShowDialog(callback,g_rename,g_renameVertex,handler.selectedObject.mainText);});$('#message').on('click','#changeCommonStyle',function(){var selectedVertices=handler.app.GetSelectedVertices();var setupVertexStyle=new SetupVertexStyle(handler.app);setupVertexStyle.show(0,selectedVertices);});$('#message').on('click','#changeSelectedStyle',function(){var selectedVertices=handler.app.GetSelectedVertices();var setupVertexStyle=new SetupVertexStyle(handler.app);setupVertexStyle.show(1,selectedVertices);});}
else if(this.selectedObject!=null&&(this.selectedObject instanceof BaseEdge))
{this.message=g_textsSelectAndMove
+"<span style=\"float:right;\"><button type=\"button\" id=\"incCurvel\" class=\"btn btn-outline-secondary btn-sm menu-text white-btn\"> + </button>"
+" "+g_curveEdge+" "
+"<button type=\"button\" id=\"decCurvel\" class=\"btn btn-outline-secondary btn-sm menu-text white-btn\"> - </button> &nbsp; "
+"<div style=\"float:right;position: relative;\">"
+"<button type=\"button\" class=\"btn btn-outline-secondary dropdown-toggle btn-sm menu-text white-btn\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\">"
+" "+g_action+" <span class=\"caret\"></span>"
+" </button>"
+"<ul class=\"dropdown-menu dropdown-menu-right\" style=\"z-index:15; position: absolute;\">"
+" <li><a class=\"dropdown-item\" href=\"javascript:;\" id=\"editEdge\">"+g_editWeight+"</a></li>"
+" <li><a class=\"dropdown-item\" href=\"javascript:;\" id=\"changeCommonStyle\">"+g_commonEdgeStyle+"</a></li>"
+" <li><a class=\"dropdown-item\" href=\"javascript:;\" id=\"changeSelectedStyle\">"+g_selectedEdgeStyle+"</a></li>"
+"</ul>"
+"</div>";var handler=this;$('#message').unbind();$('#message').on('click','#editEdge',function(){handler.ShowEditEdgeDialog(handler.selectedObject);});$('#message').on('click','#incCurvel',function(){handler.app.PushToStack("ChangeCurvelEdge");handler.selectedObject.model.ChangeCurveValue(DefaultHandler.prototype.curveValue);handler.needRedraw=true;handler.app.redrawGraph();userAction("Edge.Bend");});$('#message').on('click','#decCurvel',function(){handler.app.PushToStack("ChangeCurvelEdge");handler.selectedObject.model.ChangeCurveValue(-DefaultHandler.prototype.curveValue);handler.needRedraw=true;handler.app.redrawGraph();userAction("Edge.Bend");});$('#message').on('click','#changeCommonStyle',function(){var selectedEdges=handler.app.GetSelectedEdges();var setupVertexStyle=new SetupEdgeStyle(handler.app);setupVertexStyle.show(0,selectedEdges);});$('#message').on('click','#changeSelectedStyle',function(){var selectedEdges=handler.app.GetSelectedEdges();var setupVertexStyle=new SetupEdgeStyle(handler.app);setupVertexStyle.show(1,selectedEdges);});}
else if(this.selectedObjects.length>0)
{this.message=g_dragGroupText+" <span class=\"hidden-phone\">"+g_selectGroupText+"</span>";var hasVertices=false;var hasEdges=false;for(var i=0;i<this.selectedObjects.length;i++)
{var object=this.selectedObjects[i];if(object instanceof BaseVertex)
{hasVertices=true;}
else if(object instanceof BaseEdge)
{hasEdges=true;}}
this.message=this.message+"<span style=\"float:right;position: relative;\">";this.message=this.message
+"<button type=\"button\" id=\"DublicateSelected\" class=\"btn btn-outline-secondary btn-sm menu-text white-btn\">"
+g_copyGroupeButton+"</button> &nbsp &nbsp"
+"<button type=\"button\" id=\"RemoveSelected\" class=\"btn btn-outline-secondary btn-sm menu-text white-btn\">"
+g_removeGroupeButton+"</button>"
this.message=this.message
+" &nbsp &nbsp <button type=\"button\" class=\"btn btn-outline-secondary dropdown-toggle btn-sm menu-text white-btn\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\">"
+" "+g_action+" <span class=\"caret\"></span>"
+" </button>"
+"<ul class=\"dropdown-menu dropdown-menu-right\" style=\"z-index:15; position: absolute;\">";if(hasEdges){this.message=this.message+" <li><a href=\"javascript:;\" id=\"changeCommonStyleEdge\" class=\"dropdown-item\">"+g_commonEdgeStyle+"</a></li>";this.message=this.message+" <li><a href=\"javascript:;\" id=\"changeSelectedStyleEdge\" class=\"dropdown-item\">"+g_selectedEdgeStyle+"</a></li>";}
if(hasVertices){this.message=this.message+" <li><a href=\"javascript:;\" id=\"changeCommonStyleVertex\" class=\"dropdown-item\">"+g_commonVertexStyle+"</a></li>";this.message=this.message+" <li><a href=\"javascript:;\" id=\"changeSelectedStyleVertex\" class=\"dropdown-item\">"+g_selectedVertexStyle+"</a></li>";}
this.message=this.message
+"</ul>"
+"</span>";var handler=this;$('#message').unbind();$('#message').on('click','#DublicateSelected',function(){handler.app.PushToStack("DublicateSelection");userAction("GroupSelected.Dublicate");var newSelected=[];var copyVertex={};for(var i=0;i<handler.selectedObjects.length;i++)
{var object=handler.selectedObjects[i];if(object instanceof BaseVertex)
{var newObject=new BaseVertex()
newObject.copyFrom(object);newObject.vertexEnumType=null;handler.app.AddNewVertex(newObject);var vertex=newObject;var diameter=(new VertexModel()).diameter;vertex.position.offset(diameter,diameter);newSelected.push(vertex);copyVertex[object.id]=vertex;}}
for(var i=0;i<handler.selectedObjects.length;i++)
{var object=handler.selectedObjects[i];if(object instanceof BaseEdge)
{var newObject=new BaseEdge()
newObject.copyFrom(object);var toNewVertex=false;if(newObject.vertex1.id in copyVertex)
{newObject.vertex1=copyVertex[newObject.vertex1.id];toNewVertex=true;}
if(newObject.vertex2.id in copyVertex)
{newObject.vertex2=copyVertex[newObject.vertex2.id];toNewVertex=true;}
handler.app.AddNewEdge(newObject);if(!toNewVertex)
{var neighborEdges=handler.app.graph.getNeighborEdges(newObject);if(neighborEdges.length>=1)
{var curve=handler.app.GetAvailableCurveValue(neighborEdges,newObject);newObject.model.SetCurveValue(curve);}}
newSelected.push(newObject);}}
handler.selectedObjects=newSelected;handler.needRedraw=true;handler.app.redrawGraph();});$('#message').on('click','#RemoveSelected',function(){handler.app.PushToStack("RemoveSelection");userAction("GroupSelected.Remove");for(var i=0;i<handler.selectedObjects.length;i++)
handler.app.DeleteObject(handler.selectedObjects[i]);handler.selectedObjects=[];handler.needRedraw=true;handler.app.redrawGraph();handler.message=g_textsSelectAndMove+" <span class=\"hidden-phone\">"+g_selectGroupText+"</span>";});if(hasEdges){$('#message').on('click','#changeCommonStyleEdge',function(){var selectedEdges=handler.app.GetSelectedEdges();var setupVertexStyle=new SetupEdgeStyle(handler.app);setupVertexStyle.show(0,selectedEdges);});$('#message').on('click','#changeSelectedStyleEdge',function(){var selectedEdges=handler.app.GetSelectedEdges();var setupVertexStyle=new SetupEdgeStyle(handler.app);setupVertexStyle.show(1,selectedEdges);});}
if(hasVertices){$('#message').on('click','#changeCommonStyleVertex',function(){var selectedVertices=handler.app.GetSelectedVertices();var setupVertexStyle=new SetupVertexStyle(handler.app);setupVertexStyle.show(0,selectedVertices);});$('#message').on('click','#changeSelectedStyleVertex',function(){var selectedVertices=handler.app.GetSelectedVertices();var setupVertexStyle=new SetupVertexStyle(handler.app);setupVertexStyle.show(1,selectedVertices);});}}
this.needRedraw=true;}
DefaultHandler.prototype.GetSelectedGroup=function(object)
{return(object==this.dragObject)||(object==this.selectedObject)?1:0||this.selectedObjects.includes(object);}
DefaultHandler.prototype.SelectObjectInRect=function(rect)
{this.selectedObjects=[];var vertices=this.app.graph.vertices;for(var i=0;i<vertices.length;i++)
{if(rect.isIn(vertices[i].position)&&!this.selectedObjects.includes(vertices[i]))
this.selectedObjects.push(vertices[i]);}
var edges=this.app.graph.edges;for(var i=0;i<edges.length;i++)
{var edge=edges[i];if(rect.isIn(edge.vertex1.position)&&rect.isIn(edge.vertex2.position)&&!this.selectedObjects.includes(edge))
this.selectedObjects.push(edge);}}
doInclude([include("features/base_handler/index.js")])
function AddGraphHandler(app)
{this.removeStack=true;BaseHandler.apply(this,arguments);this.message=g_clickToAddVertex;this.addContextMenu();}
AddGraphHandler.prototype=Object.create(BaseHandler.prototype);AddGraphHandler.prototype.MouseDown=function(pos)
{this.app.PushToStack("Add");this.app.CreateNewGraph(pos.x,pos.y);this.needRedraw=true;this.inited=false;}
AddGraphHandler.prototype.InitControls=function()
{var enumVertexsText=document.getElementById("enumVertexsText");if(enumVertexsText)
{var enumsList=this.app.GetEnumVerticesList();for(var i=0;i<enumsList.length;i++)
{var option=document.createElement('option');option.text=enumsList[i]["text"];option.value=enumsList[i]["value"];enumVertexsText.add(option,i);if(enumsList[i]["select"])
{enumVertexsText.selectedIndex=i;}}
var addGraphHandler=this;enumVertexsText.onchange=function(){addGraphHandler.ChangedType();};}}
AddGraphHandler.prototype.ChangedType=function()
{var enumVertexsText=document.getElementById("enumVertexsText");this.app.SetEnumVerticesType(enumVertexsText.options[enumVertexsText.selectedIndex].value);}
doInclude([include("features/base_handler/index.js")])
function ConnectionGraphHandler(app)
{this.removeStack=true;BaseHandler.apply(this,arguments);this.SelectFirst();this.addContextMenu();}
ConnectionGraphHandler.prototype=Object.create(BaseHandler.prototype);ConnectionGraphHandler.prototype.firstObject=null;ConnectionGraphHandler.prototype.GetSelectedVertex=function()
{return(this.firstObject instanceof BaseVertex)?this.firstObject:null;}
ConnectionGraphHandler.prototype.AddNewEdge=function(selectedObject,isDirect)
{let newEdge=this.app.CreateNewArc(this.firstObject,selectedObject,isDirect,document.getElementById('EdgeWeight').value,$("#RadiosReplaceEdge").prop("checked"),document.getElementById('EdgeLable').value);if($("#CheckSaveDefaultEdge").prop("checked")){let defaultEdge=new BaseEdge();defaultEdge.copyFrom(this.app.graph.edges[newEdge]);this.app.setDefaultEdge(defaultEdge);}
this.SelectFirst();this.app.NeedRedraw();}
ConnectionGraphHandler.prototype.AddDefaultEdge=function(selectedObject)
{let defaultEdge=this.app.getDefaultEdge();let newEdge=this.app.CreateNewArc(this.firstObject,selectedObject,defaultEdge.isDirect,defaultEdge.weight,false,defaultEdge.upText);this.app.graph.edges[newEdge].useWeight=defaultEdge.useWeight;this.SelectFirst();this.app.NeedRedraw();userAction("CreateDefaultEdge");}
ConnectionGraphHandler.prototype.SelectVertex=function(selectedObject)
{if(this.firstObject)
{var direct=false;var handler=this;if(!this.app.hasDefaultEdge()||!document.getElementById('useDefaultEdge').checked){this.ShowCreateEdgeDialog(this.firstObject,selectedObject,function(firstVertex,secondVertex,direct){handler.AddNewEdge(secondVertex,direct);});}else{handler.AddDefaultEdge(selectedObject);}}
else
{this.SelectSecond(selectedObject);}
this.needRedraw=true;}
ConnectionGraphHandler.prototype.MouseDown=function(pos)
{$('#message').unbind();var selectedObject=this.GetSelectedGraph(pos);if(selectedObject&&(selectedObject instanceof BaseVertex))
{this.SelectVertex(selectedObject);}
else
{this.SelectFirst();this.needRedraw=true;}}
ConnectionGraphHandler.prototype.GetSelectedGroup=function(object)
{return(object==this.firstObject)?1:0;}
ConnectionGraphHandler.prototype.SelectFirst=function()
{this.firstObject=null;this.message=g_selectFirstVertexToConnect+this.GetUseDefaultEdgeCheckBox()+
this.GetSelect2VertexMenu();this.message=this.AppendSpecialSctionsButton(this.message);}
ConnectionGraphHandler.prototype.SelectSecond=function(selectedObject)
{this.firstObject=selectedObject;this.message=g_selectSecondVertexToConnect+this.GetUseDefaultEdgeCheckBox()+
this.GetSelect2VertexMenu();this.message=this.AppendSpecialSctionsButton(this.message);}
ConnectionGraphHandler.prototype.SelectFirstVertexMenu=function(vertex1Text,vertex)
{this.firstObject=null;this.SelectVertex(vertex);}
ConnectionGraphHandler.prototype.UpdateFirstVertexMenu=function(vertex1Text)
{if(this.firstObject)
{vertex1Text.value=this.firstObject.mainText;}}
ConnectionGraphHandler.prototype.SelectSecondVertexMenu=function(vertex2Text,vertex)
{this.SelectVertex(vertex);}
ConnectionGraphHandler.prototype.UpdateSecondVertexMenu=function(vertex2Text)
{if(this.secondObject)
{vertex2Text.value=this.secondObject.mainText;}}
ConnectionGraphHandler.prototype.AppendSpecialSctionsButton=function(baseMessage)
{let hasEdges=this.app.graph.hasEdges();if(!hasEdges)return baseMessage;let hasDirectedEdges=this.app.graph.hasDirectEdge();let hasUndirectedEdges=this.app.graph.hasUndirectEdge();let handler=this;$('#message').on('click','#reverseAll',function(){handler.app.PushToStack("ReverseAllEdges");handler.app.graph.reverseAllEdges();handler.app.redrawGraph();userAction("ReverseAllEdges");});$('#message').on('click','#makeAllUndirected',function(){handler.app.PushToStack("makeAllEdgesUndirected");handler.app.graph.makeAllEdgesUndirected();handler.app.redrawGraph();userAction("makeAllEdgesUndirected");});$('#message').on('click','#makeAllDirected',function(){handler.app.PushToStack("makeAllEdgesDirected");handler.app.graph.makeAllEdgesDirected();handler.app.redrawGraph();userAction("makeAllEdgesDirected");});return"<div class=\"dropdown\" style=\"float:right; position: relative; margin-left: 8px\">"
+"<button type=\"button\" class=\"btn btn-outline-secondary dropdown-toggle btn-sm menu-text white-btn\" id=\"dropdownMenuForEdges\" data-bs-toggle=\"dropdown\" saria-expanded=\"false\">"
+g_additionalActions+" <span class=\"caret\"></span>"
+" </button> "
+"<ul class=\"dropdown-menu dropdown-menu-right\" style=\"z-index:15; position: absolute;\" aria-labelledby=\"dropdownMenuForEdges\">"
+(hasDirectedEdges?" <li><a href=\"javascript:;\" class=\"dropdown-item\" id=\"reverseAll\">"+g_reverseAllEdges+"</a></li>":"")
+(hasDirectedEdges?" <li><a href=\"javascript:;\" class=\"dropdown-item\" id=\"makeAllUndirected\">"+g_makeAllUndirected+"</a></li>":"")
+(hasUndirectedEdges?" <li><a href=\"javascript:;\" class=\"dropdown-item\" id=\"makeAllDirected\">"+g_makeAllDirected+"</a></li>":"")
+"</ul>"
+"</div> "+baseMessage;}
ConnectionGraphHandler.checkUseDefaultEdge=function(elem,app)
{app.setUseDefaultEdge(elem.checked);app.updateMessage();};ConnectionGraphHandler.prototype.GetUseDefaultEdgeCheckBox=function(){if(!this.app.hasDefaultEdge()){return"";}
return" <div class=\"messageSwitcher\" style=\"display:inline\">"+"<span id=\"switcher\"><input type=\"checkbox\" id=\"useDefaultEdge\" >"+"<label for=\"useDefaultEdge\" class=\"Switcher\"></label></span> <label for=\"useDefaultEdge\" class=\"switcherText\">"+g_reuseSavedEdge+"</label>"+"</div>";}
ConnectionGraphHandler.prototype.InitControls=function(){BaseHandler.prototype.InitControls.call(this)
if(!this.app.hasDefaultEdge()){return;}
let app=this.app;$('#useDefaultEdge').unbind();$('#useDefaultEdge').change(function(){app.setUseDefaultEdge(this.checked);});$("#useDefaultEdge").prop("checked",this.app.getUseDefaultEdge());}
doInclude([include("features/base_handler/index.js")])
function DeleteGraphHandler(app)
{this.removeStack=true;BaseHandler.apply(this,arguments);this.message=g_selectObjectToDelete;this.addContextMenu();}
DeleteGraphHandler.prototype=Object.create(BaseHandler.prototype);DeleteGraphHandler.prototype.MouseDown=function(pos)
{var selectedObject=this.GetSelectedObject(pos);if(!this.app.IsCorrectObject(selectedObject))
return;this.app.PushToStack("Delete");this.app.DeleteObject(selectedObject);this.needRedraw=true;}
function DeleteAllHandler(app)
{BaseHandler.apply(this,arguments);}
DeleteAllHandler.prototype=Object.create(BaseHandler.prototype);DeleteAllHandler.prototype.clear=function()
{this.app.PushToStack("DeleteAll");this.app.CreateNewGraphObject();this.needRedraw=true;}
doInclude([include("features/base_handler/index.js")])
function AlgorithmGraphHandler(app,algorithm)
{BaseHandler.apply(this,arguments);this.algorithm=algorithm;this.SaveUpText();this.UpdateResultAndMessage();}
AlgorithmGraphHandler.prototype=Object.create(BaseHandler.prototype);AlgorithmGraphHandler.prototype.MouseMove=function(pos){}
AlgorithmGraphHandler.prototype.MouseDown=function(pos)
{this.app.setRenderPath([]);if(this.algorithm.instance())
{this.app.SetDefaultHandler();}
else
{var selectedObject=this.GetSelectedGraph(pos);if(selectedObject&&(selectedObject instanceof BaseVertex))
{if(this.algorithm.selectVertex(selectedObject))
{this.needRedraw=true;}
this.UpdateResultAndMessage();}
else if(selectedObject&&(selectedObject instanceof BaseEdge))
{if(this.algorithm.selectEdge(selectedObject))
{this.needRedraw=true;}
this.UpdateResultAndMessage();}
else
{if(this.algorithm.deselectAll())
{this.needRedraw=true;this.UpdateResultAndMessage();}}}}
AlgorithmGraphHandler.prototype.MouseUp=function(pos){}
AlgorithmGraphHandler.prototype.GetSelectedGroup=function(object)
{return this.algorithm.getObjectSelectedGroup(object);}
AlgorithmGraphHandler.prototype.RestoreAll=function()
{this.app.setRenderPath([]);if(this.algorithm.needRestoreUpText())
{this.RestoreUpText();}
if(this.algorithm.wantRestore())
{this.algorithm.restore();}}
AlgorithmGraphHandler.prototype.SaveUpText=function()
{this.vertexUpText={};var graph=this.app.graph;for(i=0;i<graph.vertices.length;i++)
{this.vertexUpText[graph.vertices[i].id]=graph.vertices[i].upText;}}
AlgorithmGraphHandler.prototype.RestoreUpText=function()
{var graph=this.app.graph;for(i=0;i<graph.vertices.length;i++)
{if(graph.vertices[i].id in this.vertexUpText)
{graph.vertices[i].upText=this.vertexUpText[graph.vertices[i].id];}}}
AlgorithmGraphHandler.prototype.UpdateResultAndMessage=function()
{var self=this;result=this.algorithm.result(function(result)
{self.message=self.algorithm.getMessage(g_language);self.app.resultCallback(result);});this.app.resultCallback(result);this.message=this.algorithm.getMessage(g_language);}
AlgorithmGraphHandler.prototype.InitControls=function()
{this.algorithm.messageWasChanged();}
AlgorithmGraphHandler.prototype.GetMessage=function()
{return this.algorithm.getMessage(g_language);}
doInclude([include("features/base_handler/index.js"),include("features/graph_preview/index.js"),])
function SelectGraphDialog(app,originalGraph,originalGraphStyle,autoSavedGraph,autoSavedGraphStyle,originalCallback,autoSaveCallback)
{BaseHandler.apply(this,arguments);this.message="";this.originalGraph=originalGraph;this.autoSavedGraph=autoSavedGraph;this.originalCallback=originalCallback;this.autoSaveCallback=autoSaveCallback;this.originalGraphStyle=originalGraphStyle;this.autoSavedGraphStyle=autoSavedGraphStyle;}
SelectGraphDialog.prototype=Object.create(BaseHandler.prototype);SelectGraphDialog.prototype.show=function()
{var handler=this;var dialogButtons={};var graph=this.app.graph;var app=this.app;dialogButtons[g_originalGraph]={text:g_originalGraph,class:"MarginLeft",click:function(){handler.originalGraphPreview=null;handler.originalGraph=null;handler.autoSavedGraph=null;handler.originalCallback();$(this).dialog("destroy");}};dialogButtons[g_autoSavedGraph]=function(){handler.originalGraphPreview=null;handler.originalGraph=null;handler.autoSavedGraph=null;handler.autoSaveCallback();$(this).dialog("destroy");};$("#autoSaveOrOriginalGraph").dialog({resizable:false,height:"auto",width:"auto",modal:true,title:g_selectGraphToLoad,buttons:dialogButtons,dialogClass:'EdgeDialog',close:function(event,ui)
{handler.originalCallback();}});let originalGraphPositionUpdate=function(pos,scale)
{handler.autoSavedGraphPreview.canvasScale=scale;handler.autoSavedGraphPreview.canvasPosition=pos;handler.autoSavedGraphPreview.redraw();};let autoSavedGraphPreviewUpdate=function(pos,scale)
{handler.originalGraphPreview.canvasScale=scale;handler.originalGraphPreview.canvasPosition=pos;handler.originalGraphPreview.redraw();};this.originalGraphPreview=new GraphPreview(this.originalGraph,this.originalGraphStyle,document.getElementById("OriginalGraphpPreview"),originalGraphPositionUpdate);this.autoSavedGraphPreview=new GraphPreview(this.autoSavedGraph,this.autoSavedGraphStyle,document.getElementById("AutoSaveGraphpPreview"),autoSavedGraphPreviewUpdate);}
function GraphPreview(graph,style,canvas,positionUpdateCallback)
{this.graph=graph;this.style=style;this.canvas=canvas;this.canvasScale=1.0;this.canvasPosition=new Point(0,0);this.prevMousePos=null;this.positionUpdateCallback=positionUpdateCallback;this.AutoAdjustViewport();let canvasParent=canvas.parentNode;let zoomPlusArray=canvasParent.getElementsByClassName("zoom-plus");let preview=this;let one_scale=1.2;let zoomFunc=function(real_scale)
{let oldRealW=preview.getRealWidth();let oldRealH=preview.getRealHeight();preview.canvasScale=preview.canvasScale*real_scale;let realW=preview.getRealWidth();let realH=preview.getRealHeight();preview.canvasPosition=preview.canvasPosition.add(new Point((-oldRealW+realW)/2,(-oldRealH+realH)/2));preview.redraw();preview.callPositionUpdateCallback();};if(zoomPlusArray.length>0)
{this.zoomPlusButton=zoomPlusArray[0];this.zoomPlusButton.onclick=function()
{zoomFunc(one_scale);};}
let zoomMinusArray=canvasParent.getElementsByClassName("zoom-minus");if(zoomMinusArray.length>0)
{this.zoomMinusButton=zoomMinusArray[0];this.zoomMinusButton.onclick=function()
{zoomFunc(1.0/one_scale);};}
this.canvas.onmousemove=function(e)
{return preview.CanvasOnMouseMove(e);}
this.canvas.onmousedown=function(e)
{return preview.CanvasOnMouseDown(e);}
this.canvas.onmouseup=function(e)
{return preview.CanvasOnMouseUp(e);}
this.canvas.onwheel=function(e)
{var e=window.event||e;var delta=Math.max(-1,Math.min(1,(e.wheelDelta||-e.detail)));if(delta>0)
{zoomFunc(one_scale);}
else
{zoomFunc(1.0/one_scale);}}
this.canvas.removeEventListener("touchstart",touchHandler,true);this.canvas.removeEventListener("touchmove",touchHandler,true);this.canvas.removeEventListener("touchend",touchHandler,true);this.canvas.removeEventListener("touchcancel",touchHandler,true);this.canvas.addEventListener("touchstart",touchHandler,true);this.canvas.addEventListener("touchmove",touchHandler,true);this.canvas.addEventListener("touchend",touchHandler,true);this.canvas.addEventListener("touchcancel",touchHandler,true);this.redraw();setTimeout(function()
{this.redraw();}.bind(this),1000);}
GraphPreview.prototype.redraw=function()
{const ctx=this.canvas.getContext("2d");ctx.save();ctx.scale(this.canvasScale,this.canvasScale);ctx.translate(this.canvasPosition.x,this.canvasPosition.y);this.redrawGraph(ctx,this.canvasPosition);ctx.restore();}
GraphPreview.prototype.getRealWidth=function()
{return this.canvas.width/this.canvasScale;}
GraphPreview.prototype.getRealHeight=function()
{return this.canvas.height/this.canvasScale;}
GraphPreview.prototype.redrawGraph=function(context,backgroundPosition)
{var backgroundDrawer=new BaseBackgroundDrawer(context);backgroundDrawer.Draw(this.style.backgroundCommonStyle,Math.max(this.canvas.width,this.getRealWidth()),Math.max(this.canvas.height,this.getRealHeight()),backgroundPosition,this.canvasScale);for(i=0;i<this.graph.edges.length;i++)
{let edge=this.graph.edges[i];var currentStyle=null;if(edge.hasOwnStyleFor(0))
currentStyle=edge.getStyleFor(0);else
currentStyle=this.style.edgeCommonStyle;edge.currentStyle=currentStyle;}
for(i=0;i<this.graph.vertices.length;i++)
{var currentStyle=null;let vetrex=this.graph.vertices[i];if(vetrex.hasOwnStyleFor(0))
currentStyle=vetrex.getStyleFor(0);else
currentStyle=this.style.vertexCommonStyle;this.graph.vertices[i].currentStyle=currentStyle;}
for(i=0;i<this.graph.edges.length;i++)
{let edge=this.graph.edges[i];var arcDrawer=this.GetBaseArcDrawer(context,edge);arcDrawer.Draw(edge,edge.currentStyle.GetStyle({},edge));}
var graphDrawer=new BaseVertexDrawer(context);for(i=0;i<this.graph.vertices.length;i++)
{let vertex=this.graph.vertices[i];graphDrawer.Draw(this.graph.vertices[i],vertex.currentStyle.GetStyle({},vertex));}}
GraphPreview.prototype.GetBaseArcDrawer=function(context,edge)
{var arcDrawer=new BaseEdgeDrawer(context);if(edge.model.type==EdgeModels.curve)
{var curvedArcDrawer=new CurvedArcDrawer(context,edge.model);arcDrawer=new BaseEdgeDrawer(context,{drawArc:curvedArcDrawer,startArrowDirection:curvedArcDrawer,finishArrowDirection:curvedArcDrawer,textCenterObject:curvedArcDrawer,getPointOnArc:curvedArcDrawer});}
return arcDrawer;}
GraphPreview.prototype.AutoAdjustViewport=function()
{graphBBox=this.graph.getGraphBBox();bboxCenter=graphBBox.center();bboxSize=graphBBox.size();if(bboxSize.length()>0)
{if(bboxSize.x>this.getRealWidth()||bboxSize.y>this.getRealHeight())
{this.canvasScale=Math.min(this.getRealWidth()/bboxSize.x,this.getRealHeight()/bboxSize.y);}
if(graphBBox.minPoint.x<0.0||graphBBox.minPoint.y<0.0||graphBBox.maxPoint.x>this.getRealWidth()||graphBBox.maxPoint.y>this.getRealHeight())
{this.canvasPosition=graphBBox.minPoint.inverse();}}}
GraphPreview.prototype.CanvasOnMouseMove=function(e)
{if(this.prevMousePos==null)
{return;}
var pos=this.getMousePos(this.canvas,e);let newPos=(new Point(pos.x,pos.y)).subtract(this.prevMousePos).multiply(this.canvasScale);this.canvasPosition=this.canvasPosition.add(newPos.multiply(1/this.canvasScale));this.redraw();this.callPositionUpdateCallback();}
GraphPreview.prototype.CanvasOnMouseDown=function(e)
{if(e.which!==1)return;var pos=this.getMousePos(this.canvas,e);this.prevMousePos=pos;}
GraphPreview.prototype.CanvasOnMouseUp=function(e)
{if(e.which!==1)return;this.prevMousePos=null;}
GraphPreview.prototype.getMousePos=function(canvas,e)
{var rect=canvas.getBoundingClientRect();return new Point((e.clientX-rect.left)/this.canvasScale-this.canvasPosition.x,(e.clientY-rect.top)/this.canvasScale-this.canvasPosition.y);}
GraphPreview.prototype.callPositionUpdateCallback=function()
{if(this.positionUpdateCallback!=null)
{this.positionUpdateCallback(this.canvasPosition,this.canvasScale);}}
{let modulDir="features/serialization/";doInclude([include("model/GraphMLCreator.js",modulDir)])}
function GraphMLCreator(nodes,arcs,ignoreNodes={})
{this.nodes=nodes;this.arcs=arcs;this.ignoreNodes=ignoreNodes;}
GraphMLCreator.prototype.GetXMLString=function()
{var mainHeader="<?xml version=\"1.0\" encoding=\"UTF-8\"?><graphml>";var directedHeader="<graph id=\"Graph\" edgedefault=\"directed\">";var undirectedHeader="<graph id=\"Graph\" edgedefault=\"undirected\">";var defaultWeight=1.0;var weightKeyId="\"d0\"";var weightNode="<key id="+weightKeyId+" for=\"node\" attr.name=\"weight\" attr.type=\"double\">"+"<default>"+defaultWeight+"</default>"+"</key>";var xmlBody="";for(var i=0;i<this.nodes.length;i++)
{if(!this.ignoreNodes.hasOwnProperty(this.nodes[i].id))
xmlBody=xmlBody+"<node id=\""+this.nodes[i].id+"\"/>";}
var hasDirected=false;for(var i=0;i<this.arcs.length;i++)
{if(this.arcs[i].isDirect)
{hasDirected=true;break;}}
for(var i=0;i<this.arcs.length;i++)
{var weightData="";var arc=this.arcs[i];if(this.arcs[i].weight!=defaultWeight)
{weightData="<data key="+weightKeyId+">"+arc.weight+"</data>";}
xmlBody=xmlBody+"<edge source=\""+arc.vertex1.id+"\" target=\""
+arc.vertex2.id+"\" "+
(arc.isDirect!=hasDirected?(hasDirected?"directed=\"false\"":"directed=\"true\""):"")+" id=\""+arc.id+"\"";xmlBody=xmlBody+((weightData!="")?">"+weightData+"</edge>":"/>")}
xml=mainHeader+weightNode+(hasDirected?directedHeader:undirectedHeader)+xmlBody+"</graph></graphml>"
return xml;}
function BaseEnumVertices(app,startNumber)
{this.app=app;this.startNumber=startNumber;}
BaseEnumVertices.prototype.GetVertexText=function(id)
{return this.startNumber+id;}
BaseEnumVertices.prototype.GetVertexTextAsync=function(callback)
{callback(this);}
BaseEnumVertices.prototype.GetText=function()
{return this.startNumber+", "+(this.startNumber+1)+", "+(this.startNumber+2)+"...";}
BaseEnumVertices.prototype.GetValue=function()
{return"Numbers"+this.startNumber;}
function TextEnumTitle(app,title)
{BaseEnumVertices.apply(this,arguments);this.pattern="";this.title=title;}
TextEnumTitle.prototype=Object.create(BaseEnumVertices.prototype);TextEnumTitle.prototype.GetVertexText=function(id)
{return this.title;}
function TextEnumVertices(app)
{BaseEnumVertices.apply(this,arguments);this.pattern="ABCDEFGHIJKLMNOPQRSTUVWXYZ";}
TextEnumVertices.prototype=Object.create(BaseEnumVertices.prototype);TextEnumVertices.prototype.GetVertexText=function(id)
{var res="";res=this.pattern[id%this.pattern.length]+res;while(id>=this.pattern.length)
{id=Math.floor(id/this.pattern.length)-1;res=this.pattern[id%this.pattern.length]+res;}
return res;}
TextEnumVertices.prototype.GetText=function()
{return"A, B, ... Z";}
TextEnumVertices.prototype.GetValue=function()
{return"Latin";}
function TextEnumVerticesCyr(app)
{TextEnumVertices.apply(this,arguments);this.pattern="АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";}
TextEnumVerticesCyr.prototype=Object.create(TextEnumVertices.prototype);TextEnumVerticesCyr.prototype.GetText=function()
{return"А, Б, ... Я";}
TextEnumVerticesCyr.prototype.GetValue=function()
{return"Cyrillic";}
function TextEnumVerticesGreek(app)
{TextEnumVertices.apply(this,arguments);this.pattern="ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ";}
TextEnumVerticesGreek.prototype=Object.create(TextEnumVertices.prototype);TextEnumVerticesGreek.prototype.GetText=function()
{return"Α, Β, ... Ω";}
TextEnumVerticesGreek.prototype.GetValue=function()
{return"Greek";}
function TextEnumVerticesCustom(app)
{BaseEnumVertices.apply(this,arguments);this.pattern="";}
TextEnumVerticesCustom.prototype=Object.create(BaseEnumVertices.prototype);TextEnumVerticesCustom.prototype.GetText=function()
{return g_customEnumVertex;}
TextEnumVerticesCustom.prototype.GetValue=function()
{return"Custom";}
TextEnumVerticesCustom.prototype.GetVertexTextAsync=function(callback)
{this.ShowDialog(callback,g_addVertex,g_addVertex,"A");}
TextEnumVerticesCustom.prototype.ShowDialog=function(callback,buttonText,titleTitle,title)
{var dialogButtons={};app=this.app;dialogButtons[buttonText]=function(){app.PushToStack("RenameVertex");callback(new TextEnumTitle(app,$("#VertexTitle").val()));$(this).dialog("close");};$("#addVertex").dialog({resizable:false,height:"auto",width:"auto",modal:true,title:titleTitle,buttons:dialogButtons,dialogClass:'EdgeDialog',open:function(){$(this).off('submit').on('submit',function(){return false;});$("#VertexTitle").val(title);$("#VertexTitle").focus();}});}
var g_textsSelectAndMove="Drag objects";var g_moveCursorForMoving="Move cursor";var g_clickToAddVertex="Click to add vertex";var g_selectFirstVertexToConnect="Select first vertex to connect";var g_selectSecondVertexToConnect="Select second vertex to connect";var g_selectStartVertexForShortPath="Select start vertex for shortest path";var g_selectFinishVertexForShortPath="Select finish vertex for shortest path";var g_shortestPathResult="Shortest path is %d";var g_pathNotExists="Path does not exists";var g_selectObjectToDelete="Select object to delete";var g_addEdge="Add edge";var g_orintEdge="Directed";var g_notOrintEdge="Undirected";var g_adjacencyMatrixText="Adjacency Matrix";var g_save="Save";var g_cancel="Cancel";var g_save_graph="Save Graph";var g_shortestDistance="lowest-distance is ";var g_incidenceMatrixText="Incidence Matrix";var g_save_dialog="Save dialog";var g_close="close";var g_sickConnectedComponent="Sick connected component is ";var g_connectedComponent="Connected component is ";var g_what_do_you_think="What do you think about site?";var g_name="Name";var g_feedback="Feedback";var g_send="Send";var g_write_to_us="Write to us";var g_fixMatrix="Fix matrix";var g_readMatrixHelp="Matrix format help";var g_matrixWrongFormat="Matrix is wrong";var g_pairWrongFormat="Edge List is wrong";var g_fix="Fix"
var g_save_image_dialog="Save graph image";var g_fullReport="Full report";var g_shortReport="Short report";var g_hasEulerianLoop="Graph has Eulerian Loop";var g_hasNotEulerianLoop="Graph has not Eulerian Loop";var g_hasEulerianPath="Graph has Eulerian Path";var g_hasNotEulerianPath="Graph has not Eulerian Path";var g_processing="Processing...";var g_customEnumVertex="Custom";var g_addVertex="Add vertex";var g_renameVertex="Rename vertex";var g_rename="Rename";var g_language="en";var g_editWeight="Edit weight";var g_noWeight="No weight";var g_groupRename="Group rename";var g_vote="Vote";var g_recommendAlgorithm="Recommend algorithm";var g_graphOfMinDist="Graph of minimal distances.";var g_checkToSave="Check to save";var g_showDistMatrix="Show Distance matrix";var g_minDistMatrixText="Minimal distances matrix";var g_selectStartVertexForMaxFlow="Select source vertex for max flow";var g_selectFinishVertexForMaxFlow="Select sink vertex for max flow";var g_maxFlowResult="Maximum flow from %2 to %3 is %1";var g_flowNotExists="Flow from %1 to %2 does not exists";var g_sourceVertex="Source";var g_sinkVertex="Sink";var g_hasHamiltonianLoop="Graph has Hamiltonian Loop";var g_hasNotHamiltonianLoop="Graph has not Hamiltonian Loop";var g_hasHamiltonianPath="Graph has Hamiltonian Path";var g_hasNotHamiltonianPath="Graph has not Hamiltonian Path";var g_startTraversal="Select start traversal vector";var g_traversalOrder="Traversal order: ";var g_curveEdge="Curved edge";var g_Undo="Undo";var g_default="default";var g_vertexDraw="Vertex draw style";var g_edgeDraw="Edge draw style";var g_backgroundStyle="Background style";var g_GraphIsMultiMessage="Graph is multigraph";var g_GraphIsGeneralMessage="";var g_DefaultWeightPreset="no weight";var g_dragGroupText="Drag group.";var g_selectGroupText="Select using ctrl";var g_copyGroupeButton="Duplicate";var g_removeGroupeButton="Remove objects";var g_BFSName="Breadth-first search";var g_ColoringName="Graph coloring";var g_findConnectedComponent="Find connected components";var g_DFSName="Depth-first search";var g_EulerinLoopName="Find Eulerian cycle";var g_EulerinPath="Find Eulerian path";var g_FloidName="FloydWarshall algorithm";var g_GraphReorder="Arrange the graph";var g_HamiltoianCycleName="Find Hamiltonian cycle";var g_HamiltonianPath="Find Hamiltonian path";var g_MaxFlowName="Find Maximum flow";var g_minimumSpanningTree="Search of minimum spanning tree";var g_modernGraphStyleName="Visualization based on weight";var g_RadiusAndDiameter="Search graph radius and diameter";var g_findShortPathName="Find shortest path using Dijkstra's algorithm";var g_findShortPathBellmanFordName="Find shortest path using BellmanFord algorithm";var g_VerticesDegreeName="Calculate vertices degree";var g_SpanningTreeResult="Min Spanning Tree is";var g_SpanningTreeIgnoreDir="We ignored edges direction for calculation";var g_SpanningTreeNotConnected="Graph is not connected";var g_selectFirstGraphIsomorphismCheck="Select first graph for isomorphic check. Click to any node of graph";var g_selectSecondGraphIsomorphismCheck="Select second graph for isomorphic check. Click to any node of graph";var g_selectFirstGraphPatternCheck="Select a template graph by clicking to any node of graph";var g_selectSecondGraphForSearchSubgraph="Choose a graph in which we will look for isomorphic subgraphs. Click to any node of this graph";var g_graphsIsomorph="Graphs are isomorphic";var g_graphsNotIsomorph="Graphs are not isomorphic";var g_numberOfIsomorphSubgraphIs="Number of isomorphic subgraphs are ";var g_graphHasNoIsomorphSubgraph="Graph don't contain isomorphic subgraphs";var g_searchIsomorphSubgraph="Search isomorphic subgraphs";var g_subgraphNo="Isomorphic subgraph # ";var g_graphHasNoAtleast2Graphs="To use the algorithm, you need to create 2 separate graphs";var g_IsomorphismCheck="Check Graphs Isomorphism";var g_graphIsDisconnected="Graph is disconnected";var g_graphIsTrivial="Graph contains only one vertex";var g_graphRadius="Graph radius";var g_graphDiameter="Graph diameter";var g_vertexCentral="Central";var g_vertexPeripheral="Peripheral";var g_maximumDegreeOfGraph="The maximum degree of a graph is";var g_colorNumber="Color number is";var g_done="Done";var g_action="Action";var g_commonEdgeStyle="Common Edge Style";var g_selectedEdgeStyle="Selected Edge Style";var g_commonVertexStyle="Common Vertex Style";var g_selectedVertexStyle="Selected Vertex Style";var g_findAllPathes="Find all paths";var g_numberOfPathesFrom="Number of paths from "
var g_to=" to ";var g_are=" are ";var g_pathN="Path #";var g_selectFinishVertex="Select finish vertex";var g_selectStartVertex="Select start vertex";var g_findAllPathesFromVertex="Find all shortest paths from vertex";var g_distanceFrom="Distance from ";var g_pathTo="Path to ";var g_useContextMenuText="Use context menu for addition actions."
var g_findLongestPath="Find the longest path";var g_LengthOfLongestPathFrom="Length of the longest path from ";var g_additionalActions="Additional actions";var g_reverseAllEdges="Reverse all edges";var g_makeAllUndirected="Make all edges undirected";var g_makeAllDirected="Make all edges directed";var g_reuseSavedEdge="Reuse saved edge";var g_MaxClique="Max Clique";var g_MaxCliqueNotFound="Max Clique is not found";var g_MaxCliqueSizeIs="Max Clique size is ";var g_MaxCliqueContains=". Clique contains these vertecies: ";var g_wrongImageFormatPNGAndJPEG="Wrong image format. We support only JPEG and PNG.";var g_wrongImageSizeP1="Image size is too big. Image size must be less than {0} pixels.";var g_originalGraph="Original graph";var g_autoSavedGraph="Autosaved graph";var g_selectGraphToLoad="Would you like to load original graph or autosaved graph?";function loadTexts()
{g_textsSelectAndMove=document.getElementById("SelectAndMoveObject").innerHTML;g_moveCursorForMoving=document.getElementById("MoveCursorForMoving").innerHTML;g_clickToAddVertex=document.getElementById("clickToAddVertex").innerHTML;g_selectFirstVertexToConnect=document.getElementById("selectFisrtVertextToConnect").innerHTML;g_selectSecondVertexToConnect=document.getElementById("selectSecondVertextToConnect").innerHTML;g_selectStartVertexForShortPath=document.getElementById("selectStartShortPathVertex").innerHTML;g_selectFinishVertexForShortPath=document.getElementById("selectFinishShortPathVertex").innerHTML;g_shortestPathResult=document.getElementById("shortPathResult").innerHTML;g_pathNotExists=document.getElementById("pathNotExists").innerHTML;g_selectObjectToDelete=document.getElementById("selectObjectToDelete").innerHTML;g_addEdge=document.getElementById("AddEdge").innerHTML;g_orintEdge=document.getElementById("OrintEdge").innerHTML;g_notOrintEdge=document.getElementById("NotOrintdge").innerHTML;g_adjacencyMatrixText=document.getElementById("AdjacencyMatrixText").innerHTML;g_save=document.getElementById("Save").innerHTML;g_cancel=document.getElementById("Cancel").innerHTML;g_shortestDistance=document.getElementById("shortestDist").innerHTML;g_incidenceMatrixText=document.getElementById("IncidenceMatrixText").innerHTML;g_save_dialog=document.getElementById("saveDialogTitle").innerHTML;g_close=document.getElementById("closeButton").innerHTML;g_sickConnectedComponent=document.getElementById("sickConnectedComponentResult").innerHTML;g_connectedComponent=document.getElementById("connectedComponentResult").innerHTML;g_what_do_you_think=document.getElementById("whatDoYouThink").innerHTML;g_name=document.getElementById("name").innerHTML;g_feedback=document.getElementById("feedback").innerHTML;g_send=document.getElementById("send").innerHTML;g_write_to_us=document.getElementById("writeToUs").innerHTML;g_fixMatrix=document.getElementById("fixMatrixButton").innerHTML;g_readMatrixHelp=document.getElementById("matrixHelp").innerHTML;g_matrixWrongFormat=document.getElementById("wronMatrixTitle").innerHTML;g_save_image_dialog=document.getElementById("saveImageDialogTitle").innerHTML;g_fullReport=document.getElementById("fullReport").innerHTML;g_shortReport=document.getElementById("shortReport").innerHTML;g_hasEulerianLoop=document.getElementById("hasEulerianLoop").innerHTML;g_hasNotEulerianLoop=document.getElementById("hasNotEulerianLoop").innerHTML;g_processing=document.getElementById("processing").innerHTML;g_customEnumVertex=document.getElementById("customEnumVertex").innerHTML;g_addVertex=document.getElementById("addVertexText").innerHTML;g_renameVertex=document.getElementById("renameVertex").innerHTML;g_rename=document.getElementById("renameText").innerHTML;g_language=document.getElementById("currentLanguage").innerHTML;g_editWeight=document.getElementById("editWeight").innerHTML;g_noWeight=document.getElementById("noWeight").innerHTML;g_groupRename=document.getElementById("groupeRenameText").innerHTML;g_vote=document.getElementById("voteText").innerHTML;g_recommendAlgorithm=document.getElementById("recommend_algorithm").innerHTML;g_hasEulerianPath=document.getElementById("hasEulerianPath").innerHTML;g_hasNotEulerianPath=document.getElementById("hasNotEulerianPath").innerHTML;g_graphOfMinDist=document.getElementById("graphOfMinDist").innerHTML;g_checkToSave=document.getElementById("checkToSave").innerHTML;g_showDistMatrix=document.getElementById("showDistMatrix").innerHTML;g_minDistMatrixText=document.getElementById("distMatrixText").innerHTML;g_selectStartVertexForMaxFlow=document.getElementById("selectStartVertexForMaxFlow").innerHTML;g_selectFinishVertexForMaxFlow=document.getElementById("selectFinishVertexForMaxFlow").innerHTML;g_maxFlowResult=document.getElementById("maxFlowResult").innerHTML;g_flowNotExists=document.getElementById("flowNotExists").innerHTML;g_sourceVertex=document.getElementById("sourceVertex").innerHTML;g_sinkVertex=document.getElementById("sinkVertex").innerHTML;g_hasHamiltonianLoop=document.getElementById("hasHamiltonianLoop").innerHTML;g_hasNotHamiltonianLoop=document.getElementById("hasNotHamiltonianLoop").innerHTML;g_hasHamiltonianPath=document.getElementById("hasHamiltonianPath").innerHTML;g_hasNotHamiltonianPath=document.getElementById("hasNotHamiltonianPath").innerHTML;g_startTraversal=document.getElementById("startTraversal").innerHTML;g_traversalOrder=document.getElementById("traversalOrder").innerHTML;g_curveEdge=document.getElementById("curveEdge").innerHTML;g_Undo=document.getElementById("undoTranslate").innerHTML;g_save_graph=document.getElementById("saveGraph").innerHTML;g_default=document.getElementById("default").innerHTML;g_vertexDraw=document.getElementById("vertexDrawStyle").innerHTML;g_edgeDraw=document.getElementById("edgeDrawStyle").innerHTML;g_backgroundStyle=document.getElementById("backgroundStyle").innerHTML;g_GraphIsMultiMessage=document.getElementById("graphIsMultiMessage").innerHTML;g_GraphIsGeneralMessage=document.getElementById("graphIsGeneralMessage").innerHTML;g_DefaultWeightPreset=document.getElementById("defaultWeightPreset").innerHTML;var isMac=navigator.platform.toUpperCase().indexOf('MAC')>=0;if(isMac)
g_selectGroupText=document.getElementById("selectGroupMac").innerHTML;else
g_selectGroupText=document.getElementById("selectGroupWin").innerHTML;g_dragGroupText=document.getElementById("dragSelectedGroup").innerHTML;g_copyGroupeButton=document.getElementById("copySelectedGroup").innerHTML;g_removeGroupeButton=document.getElementById("removeSelectedGroup").innerHTML;g_BFSName=document.getElementById("BFSName").innerHTML;g_ColoringName=document.getElementById("ColoringName").innerHTML;g_findConnectedComponent=document.getElementById("findConnectedComponent").innerHTML;g_DFSName=document.getElementById("DFSName").innerHTML;g_EulerinLoopName=document.getElementById("EulerinLoopName").innerHTML;g_EulerinPath=document.getElementById("EulerinPath").innerHTML;g_FloidName=document.getElementById("FloidName").innerHTML;g_GraphReorder=document.getElementById("GraphReorder").innerHTML;g_HamiltoianCycleName=document.getElementById("HamiltoianCycleName").innerHTML;g_HamiltonianPath=document.getElementById("HamiltonianPath").innerHTML;g_MaxFlowName=document.getElementById("MaxFlowName").innerHTML;g_minimumSpanningTree=document.getElementById("minimumSpanningTree").innerHTML;g_modernGraphStyleName=document.getElementById("modernGraphStyleName").innerHTML;g_RadiusAndDiameter=document.getElementById("RadiusAndDiameter").innerHTML;g_findShortPathName=document.getElementById("findShortPathName").innerHTML;g_findShortPathBellmanFordName=document.getElementById("findShortPathBellmanFordName").innerHTML;g_VerticesDegreeName=document.getElementById("VerticesDegreeName").innerHTML;g_SpanningTreeResult=document.getElementById("MinSpanningTreeResult").innerHTML;g_SpanningTreeIgnoreDir=document.getElementById("MinSpanningIgnoreDir").innerHTML;g_SpanningTreeNotConnected=document.getElementById("MinSpanningNotConnected").innerHTML;g_selectFirstGraphIsomorphismCheck=document.getElementById("SelectFirstGraphIsomorphismCheck").innerHTML;g_selectSecondGraphIsomorphismCheck=document.getElementById("SelectSecondGraphIsomorphismCheck").innerHTML;g_selectFirstGraphPatternCheck=document.getElementById("SelectFirstGraphPatternCheck").innerHTML;g_selectSecondGraphForSearchSubgraph=document.getElementById("SelectSecondGraphForSearchSubgraph").innerHTML;g_graphsIsomorph=document.getElementById("GraphsIsomorph").innerHTML;g_graphsNotIsomorph=document.getElementById("GraphsNotIsomorph").innerHTML;g_numberOfIsomorphSubgraphIs=document.getElementById("NumberOfIsomorphSubgraphIs").innerHTML;g_graphHasNoIsomorphSubgraph=document.getElementById("GraphHasNoIsomorphSubgraph").innerHTML;g_searchIsomorphSubgraph=document.getElementById("SearchIsomorphSubgraph").innerHTML;g_subgraphNo=document.getElementById("SubgraphNo").innerHTML;g_graphHasNoAtleast2Graphs=document.getElementById("GraphHasNoAtleast2Graphs").innerHTML;g_IsomorphismCheck=document.getElementById("IsomorphismCheck").innerHTML;g_graphIsDisconnected=document.getElementById("GraphIsDisconnected").innerHTML;g_graphIsTrivial=document.getElementById("GraphIsTrivial").innerHTML;g_graphRadius=document.getElementById("GraphRadius").innerHTML;g_graphDiameter=document.getElementById("GraphDiameter").innerHTML;g_vertexCentral=document.getElementById("VertexCentral").innerHTML;g_vertexPeripheral=document.getElementById("VertexPeripheral").innerHTML;g_maximumDegreeOfGraph=document.getElementById("MaximumDegreeOfGraph").innerHTML;g_colorNumber=document.getElementById("ColorNumber").innerHTML;g_done=document.getElementById("Done").innerHTML;g_action=document.getElementById("ActionText").innerHTML;g_commonEdgeStyle=document.getElementById("CommonEdgeStyleText").innerHTML;g_selectedEdgeStyle=document.getElementById("SelectedEdgeStyleText").innerHTML;g_commonVertexStyle=document.getElementById("CommonVertexStyleText").innerHTML;g_selectedVertexStyle=document.getElementById("SelectedVertexStyleText").innerHTML;g_findAllPathes=document.getElementById("FindAllPathes").innerHTML;g_numberOfPathesFrom=document.getElementById("NumberOfPathesFrom").innerHTML;g_to=document.getElementById("To").innerHTML;g_are=document.getElementById("Are").innerHTML;g_pathN=document.getElementById("PathN").innerHTML;g_selectFinishVertex=document.getElementById("SelectFinishVertex").innerHTML;g_selectStartVertex=document.getElementById("SelectStartVertex").innerHTML;g_findAllPathesFromVertex=document.getElementById("findAllPathsFromVertex").innerHTML;g_distanceFrom=document.getElementById("distanceFrom").innerHTML;g_pathTo=document.getElementById("pathTo").innerHTML;g_useContextMenuText=document.getElementById("UseContextMenuText").innerHTML;g_findLongestPath=document.getElementById("findLongestPath").innerHTML;g_LengthOfLongestPathFrom=document.getElementById("LengthOfLongestPathFrom").innerHTML;g_additionalActions=document.getElementById("additionlActions").innerHTML;g_reverseAllEdges=document.getElementById("reverseAllEdges").innerHTML;g_makeAllUndirected=document.getElementById("makeAllUndirected").innerHTML;g_makeAllDirected=document.getElementById("makeAllDirected").innerHTML;g_pairWrongFormat=document.getElementById("pairWrongFormat").innerHTML;g_fix=document.getElementById("fixButton").innerHTML;g_reuseSavedEdge=document.getElementById("reuseSavedEdge").innerHTML;g_MaxClique=document.getElementById("maxClique").innerHTML;g_MaxCliqueNotFound=document.getElementById("maxCliqueNotFound").innerHTML;g_MaxCliqueSizeIs=document.getElementById("maxCliqueSizeIs").innerHTML;g_MaxCliqueContains=document.getElementById("maxCliqueContains").innerHTML;g_wrongImageFormatPNGAndJPEG=document.getElementById("wrongImageFormatPNGAndJPEG").innerHTML;g_wrongImageSizeP1=document.getElementById("wrongImageSizeP1").innerHTML;g_originalGraph=document.getElementById("originalGraph").innerHTML;g_autoSavedGraph=document.getElementById("autoSavedGraph").innerHTML;g_selectGraphToLoad=document.getElementById("selectGraphToLoad").innerHTML;}
function UndoStack(maxUndoStackSize){this.undoStack=[];this.maxUndoStackSize=maxUndoStackSize;}
UndoStack.prototype.PushToStack=function(actionName,dataToSave)
{var object={};object.actionName=actionName;object.data=dataToSave;this.undoStack.push(object);while(this.undoStack.length>this.maxUndoStackSize)
{this.undoStack.shift();}}
UndoStack.prototype.Undo=function()
{if(this.IsUndoStackEmpty())
return null;var state=this.undoStack.pop();return state.data;}
UndoStack.prototype.ClearUndoStack=function()
{this.undoStack=[];}
UndoStack.prototype.IsUndoStackEmpty=function()
{return(this.undoStack.length<=0);}
var DiskSaveLoad=function(){};DiskSaveLoad.LoadGraphFromDisk=function(graphName,callback)
{$.ajax({type:"GET",url:"/"+SiteDir+"backend/loadGraph.php?name="+graphName}).done(callback);}
DiskSaveLoad.SaveSVGGraphOnDisk=function(imageName,svgText,callback)
{$.ajax({type:"POST",url:"/"+SiteDir+"backend/saveSvg.php?name="+imageName,data:svgText,dataType:"text",contentType:"text/xml; charset=utf-8",success:callback});return imageName;}
DiskSaveLoad.SaveGraphOnDisk=function(savedGraphName,graphAsString,callback)
{$.ajax({type:"POST",url:"/"+SiteDir+"backend/saveGraph.php?name="+savedGraphName,data:graphAsString,dataType:"text"}).done(callback);}
DiskSaveLoad.SaveGraphImageOnDisk=function(imageName,rectParams,imageBase64Data,callback)
{$.ajax({type:"POST",url:"/"+SiteDir+"backend/saveImage.php?name="+imageName+rectParams,data:{base64data:imageBase64Data},dataType:"text",success:callback});}
DiskSaveLoad.SaveAutoSaveGraphOnDisk=function(savedGraphName,graphAsString,callback)
{$.ajax({type:"POST",url:"/"+SiteDir+"backend/saveGraph.php?name=autosave_"+savedGraphName,data:graphAsString,dataType:"text"}).done(callback);}
DiskSaveLoad.LoadAutoSaveGraphFromDisk=function(graphName,callback)
{$.ajax({type:"GET",url:"/"+SiteDir+"backend/loadGraph.php?name=autosave_"+graphName}).done(callback);}
DiskSaveLoad.RemoveAutoSaveGraphFromDisk=function(graphName,callback)
{$.ajax({type:"GET",url:"/"+SiteDir+"backend/removeGraph.php?name=autosave_"+graphName}).done(callback);}
var globalApplication=null;function Application(document,window,listener)
{this.document=document;this.listener=listener;this.canvas=this.document.getElementById('canvas');this.handler=new DefaultHandler(this);this.savedGraphName="";this.currentEnumVerticesType=new BaseEnumVertices(this,1);this.findPathReport=1;this.isTimerRender=false;globalApplication=this;this.renderPath=[];this.renderTimer=0;this.renderPathLength=0;this.renderPathCounter=0;this.renderPathLoops=0;this.enumVerticesTextList=[new BaseEnumVertices(this,1),new BaseEnumVertices(this,0),new TextEnumVertices(this),new TextEnumVerticesCyr(this),new TextEnumVerticesGreek(this),new TextEnumVerticesCustom(this)];this.SetDefaultTransformations();this.algorithmsValues={};this.undoStack=new UndoStack(this.maxUndoStackSize);this.style=new GraphFullStyle(function()
{this.redrawGraph();}.bind(this));this.edgePrintCommonStyle=new CommonPrintEdgeStyle();this.edgePrintSelectedStyles=FullArrayCopy(DefaultPrintSelectedEdgeStyles);this.vertexPrintCommonStyle=new CommonPrintVertexStyle();this.vertexPrintSelectedVertexStyles=FullArrayCopy(DefaultPrintSelectedGraphStyles);this.backgroundPrintStyle=new PrintBackgroundStyle();this.renderPathWithEdges=false;this.edgePresets=[1,3,5,7,11,42];this.maxEdgePresets=6;this.selectionRect=null;this.processEmscriptenFunction=null;this.defaultEdge=null;this.useDefaultEdge=false;this.lastSavedAutoSave="";this.lastGraphName="";this.lastUsedGraphs=[];};Application.prototype.graph=new Graph();Application.prototype.dragObject=-1;Application.prototype.handler=null;Application.prototype.status={};Application.prototype.graphNameLength=16;Application.prototype.maxUndoStackSize=8;Application.prototype.maxAutosaveSizeForCookie=2000;Application.prototype.autosaveTimeInterval=1000*60;Application.prototype.styliedGraphNamePostfix="ZZcst";Application.prototype.maxLastUsedGraphCount=5;Application.prototype.getMousePos=function(canvas,e)
{var rect=canvas.getBoundingClientRect();return{x:(e.clientX-rect.left)/this.canvasScale-this.canvasPosition.x,y:(e.clientY-rect.top)/this.canvasScale-this.canvasPosition.y};}
Application.prototype.redrawGraph=function()
{if(!this.isTimerRender)
{this._redrawGraphInWindow();this.GraphTypeChanged();}}
Application.prototype.redrawGraphTimer=function()
{if(this.isTimerRender)
{var context=this._redrawGraphInWindow();if(this.renderPath.length>1)
{context.save();context.scale(this.canvasScale,this.canvasScale);context.translate(this.canvasPosition.x,this.canvasPosition.y);var movePixelStep=16;var currentLength=0;var i=0
for(i=0;i<this.renderPath.length-1;i++)
{var edge=null;if(this.renderPathWithEdges)
{edge=this.graph.FindEdgeById(this.renderPath[i+1]);i++;}
else if(this.renderMinPath)
{edge=this.graph.FindEdgeMin(this.renderPath[i],this.renderPath[i+1]);}
else
{edge=this.graph.FindEdge(this.renderPath[i],this.renderPath[i+1]);}
currentLength+=edge.GetPixelLength();if(currentLength>this.renderPathCounter)
{currentLength-=edge.GetPixelLength();break;}}
if(i>=this.renderPath.length-1)
{i=0;if(this.renderPathWithEdges)
i=1;this.renderPathCounter=0;currentLength=0;this.renderPathLoops+=1;}
var edge=null;var currentVertexId=this.renderPath[i];if(this.renderPathWithEdges)
{edge=this.graph.FindEdgeById(this.renderPath[i]);currentVertexId=this.renderPath[i-1];}
else if(this.renderMinPath)
{edge=this.graph.FindEdgeMin(this.renderPath[i],this.renderPath[i+1]);}
else
{edge=this.graph.FindEdge(this.renderPath[i],this.renderPath[i+1]);}
var progress=(this.renderPathCounter-currentLength)/edge.GetPixelLength();this.RedrawEdgeProgress(context,edge,edge.vertex1.id==currentVertexId?progress:1.0-progress);this.renderPathCounter+=movePixelStep;context.restore();}}
if(this.renderPathLoops>=5)
{this.stopRenderTimer();}}
Application.prototype._redrawGraphInWindow=function()
{var context=this.canvas.getContext('2d');context.save();context.scale(this.canvasScale,this.canvasScale);context.translate(this.canvasPosition.x,this.canvasPosition.y);this._RedrawGraph(context,{width:this.canvas.width,height:this.canvas.height,scale:this.canvasScale},this.canvasPosition,this.style.backgroundCommonStyle,true);context.restore();return context;}
Application.prototype._OffscreenRedrawGraph=function()
{var bbox=this.graph.getGraphBBox();var canvas=document.createElement('canvas');canvas.width=bbox.size().x;canvas.height=bbox.size().y;var context=canvas.getContext('2d');context.save();context.translate(bbox.minPoint.inverse().x,bbox.minPoint.inverse().y);this._RedrawGraph(context,{width:canvas.width,height:canvas.height,scale:1.0},bbox.minPoint.inverse(),this.style.backgroundCommonStyle,false);context.restore();return canvas;}
Application.prototype._PrintRedrawGraph=function()
{var bbox=this.graph.getGraphBBox();var canvas=document.createElement('canvas');canvas.width=bbox.size().x;canvas.height=bbox.size().y;var context=canvas.getContext('2d');context.save();context.translate(bbox.minPoint.inverse().x,bbox.minPoint.inverse().y);this._RedrawGraph(context,{width:canvas.width,height:canvas.height,scale:1.0},bbox.minPoint.inverse(),this.backgroundPrintStyle,false,this.vertexPrintCommonStyle,this.vertexPrintSelectedVertexStyles,this.edgePrintCommonStyle,this.edgePrintSelectedStyles);context.restore();return canvas;}
Application.prototype._printToSVG=function()
{var bbox=this.graph.getGraphBBox();var context=new C2S(bbox.size().x,bbox.size().y);context.save();context.translate(bbox.minPoint.inverse().x,bbox.minPoint.inverse().y);this._RedrawGraph(context,{width:bbox.size().x,height:bbox.size().y,scale:1.0},bbox.minPoint.inverse(),this.style.backgroundCommonStyle,false);context.restore();return context.getSerializedSvg();}
Application.prototype.updateRenderPathLength=function()
{this.renderPathLength=0;this.renderPathCounter=0;if(this.renderPath.length>1)
{for(var i=0;i<this.renderPath.length-1;i++)
{var edge=null;if(this.renderPathWithEdges)
{edge=this.graph.FindEdgeById(this.renderPath[i+1]);i++;}
else
{edge=this.graph.FindEdge(this.renderPath[i],this.renderPath[i+1]);}
this.renderPathLength+=edge.GetPixelLength();}}}
Application.prototype.startRenderTimer=function()
{this.updateRenderPathLength();this.renderTimer=window.setInterval(function(){globalApplication.redrawGraphTimer();},50);this.isTimerRender=true;this.renderPathLoops=0;}
Application.prototype.stopRenderTimer=function()
{if(this.isTimerRender)
{window.clearInterval(this.renderTimer);this.isTimerRender=false;this.renderPathLoops=0;}}
Application.prototype.setRenderPath=function(renderPath,renderMinPath)
{this.renderPath=renderPath;this.renderMinPath=renderMinPath;this.renderPathWithEdges=false;if(this.renderPath.length>0)
{this.startRenderTimer();}
else
{this.stopRenderTimer();}}
Application.prototype.setRenderPathWithEdges=function(renderPath)
{this.renderPath=renderPath;this.renderMinPath=false;this.renderPathWithEdges=true;if(this.renderPath.length>0)
{this.startRenderTimer();}
else
{this.stopRenderTimer();}}
Application.prototype.GetBaseArcDrawer=function(context,edge)
{var arcDrawer=new BaseEdgeDrawer(context);if(edge.model.type==EdgeModels.curve)
{var curvedArcDrawer=new CurvedArcDrawer(context,edge.model);arcDrawer=new BaseEdgeDrawer(context,{drawArc:curvedArcDrawer,startArrowDirection:curvedArcDrawer,finishArrowDirection:curvedArcDrawer,textCenterObject:curvedArcDrawer,getPointOnArc:curvedArcDrawer});}
return arcDrawer;}
Application.prototype.UpdateEdgeCurrentStyle=function(edge,ForceCommonStyle,ForceSelectedStyle)
{var commonStyle=(ForceCommonStyle===undefined)?this.style.edgeCommonStyle:ForceCommonStyle;var selectedStyle=(ForceSelectedStyle===undefined)?this.style.edgeSelectedStyles:ForceSelectedStyle;var selectedGroup=this.handler.GetSelectedGroup(edge);var selected=false;if(selectedGroup>0)
{selectedGroup=(selectedGroup-1)%selectedStyle.length;selected=true;}
var currentStyle=null;if(edge.hasOwnStyleFor((selected?1:0)+selectedGroup))
currentStyle=edge.getStyleFor((selected?1:0)+selectedGroup);else
currentStyle=selected?selectedStyle[selectedGroup]:commonStyle;edge.currentStyle=currentStyle;}
Application.prototype.RedrawEdge=function(context,edge)
{var curvedArcDrawer=new CurvedArcDrawer(context,edge.model)
var arcDrawer=this.GetBaseArcDrawer(context,edge);this._RedrawEdge(edge,arcDrawer);}
Application.prototype._RedrawEdge=function(edge,arcDrawer,commonStyle,selectedStyles)
{this._RedrawEdgeWithStyle(edge,edge.currentStyle,arcDrawer,commonStyle,selectedStyles);}
Application.prototype._RedrawEdgeWithStyle=function(edge,style,arcDrawer,commonStyle,selectedStyles)
{arcDrawer.Draw(edge,style.GetStyle({},edge));}
Application.prototype.RedrawEdgeProgress=function(context,edge,progress)
{var progressDraw=new ProgressArcDrawer(context,this.GetBaseArcDrawer(context,edge),progress);var arcDrawer=new BaseEdgeDrawer(context,{drawObject:progressDraw});this._RedrawEdge(edge,arcDrawer,this.style.edgeCommonStyle,this.style.edgeSelectedStyles);}
Application.prototype.UpdateEdgesCurrentStyle=function(ForceCommonStyle,ForceSelectedStyle)
{for(i=0;i<this.graph.edges.length;i++)
{this.UpdateEdgeCurrentStyle(this.graph.edges[i],ForceCommonStyle,ForceSelectedStyle);}}
Application.prototype.RedrawEdges=function(context)
{for(i=0;i<this.graph.edges.length;i++)
{this.RedrawEdge(context,this.graph.edges[i]);}}
Application.prototype.RedrawNodes=function(context)
{var graphDrawer=new BaseVertexDrawer(context);for(i=0;i<this.graph.vertices.length;i++)
{graphDrawer.Draw(this.graph.vertices[i],this.graph.vertices[i].currentStyle.GetStyle({},this.graph.vertices[i]));}}
Application.prototype.UpdateNodesCurrentStyle=function(ForceCommonStyle,ForceSelectedStyle)
{var force=ForceCommonStyle!==undefined||ForceSelectedStyle!==undefined;var commonStyle=(ForceCommonStyle===undefined)?this.style.vertexCommonStyle:ForceCommonStyle;var selectedStyle=(ForceSelectedStyle===undefined)?this.style.vertexSelectedVertexStyles:ForceSelectedStyle;for(i=0;i<this.graph.vertices.length;i++)
{var selectedGroup=this.handler.GetSelectedGroup(this.graph.vertices[i]);var selected=false;if(selectedGroup>0)
{selectedGroup=(selectedGroup-1)%selectedStyle.length;selected=true;}
var currentStyle=null;if(this.graph.vertices[i].hasOwnStyleFor((selected?1:0)+selectedGroup)&&!force)
currentStyle=this.graph.vertices[i].getStyleFor((selected?1:0)+selectedGroup);else
currentStyle=selected?selectedStyle[selectedGroup]:commonStyle;this.graph.vertices[i].currentStyle=currentStyle;}}
Application.prototype.RedrawSelectionRect=function(context)
{context.lineWidth=1.0/this.canvasScale;context.strokeStyle=this.style.edgeSelectedStyles[0].strokeStyle;context.setLineDash([6,3]);context.beginPath();context.rect(this.selectionRect.left(),this.selectionRect.top(),this.selectionRect.size().x,this.selectionRect.size().y);context.closePath();context.stroke();context.setLineDash([]);}
Application.prototype.updateMessage=function()
{this.listener.updateMessage(this.handler.GetMessage());this.handler.InitControls();}
Application.prototype.CanvasOnMouseMove=function(e)
{var pos=this.getMousePos(this.canvas,e);this.handler.MouseMove(pos);if(this.handler.IsNeedRedraw())
{this.handler.RestRedraw();this.redrawGraph();}
this.updateMessage();}
Application.prototype.CanvasOnMouseDown=function(e)
{if(e.which!==1)return;var pos=this.getMousePos(this.canvas,e);this.handler.MouseDown(pos);if(this.handler.IsNeedRedraw())
{this.handler.RestRedraw();this.redrawGraph();}
this.updateMessage();}
Application.prototype.CanvasOnMouseUp=function(e)
{if(e.which!==1)return;var pos=this.getMousePos(this.canvas,e);this.handler.MouseUp(pos);if(this.handler.IsNeedRedraw())
{this.handler.RestRedraw();this.redrawGraph();}
this.updateMessage();}
Application.prototype.multCanvasScale=function(factor,zoom_to=null)
{if(zoom_to)
{var pos1=this.getMousePos(this.canvas,zoom_to);this.canvasScale*=factor;var pos2=this.getMousePos(this.canvas,zoom_to);this.canvasPosition=this.canvasPosition.add(new Point(pos2.x-pos1.x,pos2.y-pos1.y));}
else
{var oldRealWidth=this.GetRealWidth();var oldRealHeight=this.GetRealHeight();this.canvasScale*=factor;this.canvasPosition=this.canvasPosition.add(new Point((this.GetRealWidth()-oldRealWidth)/2.0,(this.GetRealHeight()-oldRealHeight)/2.0));}
this.redrawGraph();}
Application.prototype.setCanvasScale=function(factor)
{var oldRealWidth=this.GetRealWidth();var oldRealHeight=this.GetRealHeight();this.canvasScale=factor;this.canvasPosition=this.canvasPosition.add(new Point((this.GetRealWidth()-oldRealWidth)/2.0,(this.GetRealHeight()-oldRealHeight)/2.0));this.redrawGraph();}
Application.prototype.onCanvasMove=function(point)
{this.canvasPosition=this.canvasPosition.add(point.multiply(1/this.canvasScale));this.redrawGraph();}
Application.prototype.AddNewVertex=function(vertex)
{return this.graph.AddNewVertex(vertex);}
Application.prototype.AddNewEdge=function(edge,replaceIfExists)
{return this.graph.AddNewEdge(edge,replaceIfExists);}
Application.prototype.CreateNewGraph=function(x,y)
{var app=this;this.currentEnumVerticesType.GetVertexTextAsync(function(enumType)
{app.graph.AddNewVertex(new BaseVertex(x,y,enumType));app.redrawGraph();});}
Application.prototype.CreateNewGraphEx=function(x,y,vertexEnume)
{return this.graph.AddNewVertex(new BaseVertex(x,y,vertexEnume));}
Application.prototype.CreateNewArc=function(graph1,graph2,isDirect,weight,replaceIfExist,upText)
{var edge=this.AddNewEdge(new BaseEdge(graph1,graph2,isDirect,weight,upText),replaceIfExist);this.graph.FixEdgeCurve(edge);var edgeObject=this.graph.edges[edge];if(edgeObject.useWeight)
this.UpdateEdgePresets(edgeObject.weight);return edge;}
Application.prototype.DeleteEdge=function(edgeObject)
{var vertex1=edgeObject.vertex1;var vertex2=edgeObject.vertex2;var hasPair=this.graph.hasPair(edgeObject);this.graph.DeleteEdge(edgeObject);if(hasPair)
{var pairEdges=this.FindAllEdges(vertex2.id,vertex1.id);if(pairEdges.length==1&&pairEdges[0].model.default)
pairEdges[0].model.type=EdgeModels.line;}}
Application.prototype.DeleteVertex=function(graphObject)
{this.graph.DeleteVertex(graphObject);}
Application.prototype.DeleteObject=function(object)
{if(object instanceof BaseVertex)
{this.DeleteVertex(object);}
else if(object instanceof BaseEdge)
{this.DeleteEdge(object);}}
Application.prototype.IsCorrectObject=function(object)
{return(object instanceof BaseVertex)||(object instanceof BaseEdge);}
Application.prototype.FindVertex=function(id)
{return this.graph.FindVertex(id);}
Application.prototype.FindEdge=function(id1,id2)
{return this.graph.FindEdge(id1,id2);}
Application.prototype.FindEdgeAny=function(id1,id2)
{return this.graph.FindEdgeAny(id1,id2);}
Application.prototype.FindAllEdges=function(id1,id2)
{return this.graph.FindAllEdges(id1,id2);}
Application.prototype.SetHandler=function(newHandler)
{if(this.handler)
{this.handler.RestoreAll();}
this.handler=newHandler;this.ToDefaultStateAndRedraw();}
Application.prototype.ToDefaultStateAndRedraw=function()
{this.setRenderPath([]);this.updateMessage();this.redrawGraph();}
Application.prototype.getParameterByName=function(name)
{name=name.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var regex=new RegExp("[\\?&]"+name+"=([^&#]*)"),results=regex.exec(location.search);return results===null?"":decodeURIComponent(results[1].replace(/\+/g," "));}
Application.prototype.onPostLoadEvent=function()
{this.SetEnumVerticesType(document.cookie.replace(/(?:(?:^|.*;\s*)enumType\s*\=\s*([^;]*).*$)|^.*$/,"$1"));var wasLoad=false;let startAutoSave=true;var matrix=document.getElementById("inputMatrix").innerHTML;var separator=document.getElementById("separator").innerHTML=="space"?" ":",";console.log(matrix);console.log("separator: \""+separator+"\"");matrix=(matrix.length<=0)?this.getParameterByName("matrix"):matrix;if(matrix.length>0)
{if(!this.SetAdjacencyMatrixSmart(matrix,separator))
{userAction("AdjacencyMatrix.Failed");this.listener.ShowAdjacencyMatrixErrorDialog(matrix);}
else
{userAction("AdjacencyMatrix.Success");}
this.updateMessage();this.redrawGraph();wasLoad=true;}
var matrix=document.getElementById("inputIncidenceMatrix").innerHTML;matrix=(matrix.length<=0)?this.getParameterByName("incidenceMatrix"):matrix;if(matrix.length>0)
{if(!this.SetIncidenceMatrixSmart(matrix))
{userAction("IncidenceMatrix.Failed");this.listener.ShowIncidenceMatrixErrorDialog(matrix);}
else
{userAction("IncidenceMatrix.Success");}
this.updateMessage();this.redrawGraph();wasLoad=true;}
var pairs=document.getElementById("inputPair").innerHTML;if(pairs.length>0)
{pairs=pairs.replaceAll('&gt;','>');pairs=pairs.replaceAll('&lt;','<');if(!this.SetPairSmart(pairs))
{userAction("Pair.Failed");this.listener.ShowPairErrorDialog(pairs);}
else
{userAction("Pair.Success");}
this.updateMessage();this.redrawGraph();wasLoad=true;}
if(!wasLoad)
{var graphName=this.getParameterByName("graph");var is_user_graph=graphName.length>0;if(!is_user_graph)
{graphName=document.cookie.replace(/(?:(?:^|.*;\s*)graphName\s*\=\s*([^;]*).*$)|^.*$/,"$1");}
if(!is_user_graph&&this.hasAutoSave())
{userAction("LoadGraphFromAutoSave");this.loadAutoSave();}
else if(graphName.length>0)
{if(this.getAutoSaveRefGraphCookie()==graphName)
{this.showSelectGraphDialog(graphName);console.log("Show select graph dialog");startAutoSave=false;}
else
{userAction("LoadGraphFromDisk");this.LoadGraphFromDisk(graphName);}}}
if(this.undoStack.IsUndoStackEmpty())
document.getElementById('GraphUndo').style.display='none';this.updateMessage();this.redrawGraph();if(startAutoSave)
{this.startAutoSaveTimer();}}
Application.prototype.onLoad=function()
{this.canvas=this.document.getElementById('canvas');this.SetDefaultHandler()
this.updateMessage();this.redrawGraph();this.LoadLastUsedGraphsFromCookie();this.UpdateLastUsedGraphsMenu();}
Application.prototype.NeedRedraw=function()
{this.updateMessage();this.redrawGraph();}
Application.prototype.SetStatus=function(name,value)
{this.status[name]=value;}
Application.prototype.GetStatus=function()
{return this.status[name];}
Application.prototype.GetAdjacencyMatrix=function()
{return this.graph.GetAdjacencyMatrixStr();}
Application.prototype.TestAdjacencyMatrix=function(matrix,rowsObj,colsObj,separator)
{if(separator===undefined)
{separator=",";}
return this.graph.TestAdjacencyMatrix(matrix,rowsObj,colsObj,separator);}
Application.prototype.SetAdjacencyMatrix=function(matrix,separator)
{if(separator===undefined)
{separator=",";}
var res=true;var r={};var c={};if(!this.TestAdjacencyMatrix(matrix,r,c,separator))
{$.get("/"+SiteDir+"backend/addFailedMatrix.php?text=adjacency&matrix="+encodeURIComponent(matrix),function(data){;});res=false;}
this.graph.SetAdjacencyMatrix(matrix,new Point(this.GetRealWidth(),this.GetRealHeight()),this.currentEnumVerticesType,separator);this.AutoAdjustViewport();this.redrawGraph();return res;}
Application.prototype.SetPair=function(pair)
{var res=true;var r={};var c={};if(!this.TestPair(pair))
{$.get("/"+SiteDir+"backend/addFailedMatrix.php?text=pair&matrix="+encodeURIComponent(pair),function(data){;});res=false;}
this.graph.SetPair(pair,new Point(this.GetRealWidth(),this.GetRealHeight()),this.currentEnumVerticesType);this.AutoAdjustViewport();this.redrawGraph();return res;}
Application.prototype.GetIncidenceMatrix=function()
{return this.graph.GetIncidenceMatrix();}
Application.prototype.TestIncidenceMatrix=function(matrix,rowsObj,colsObj)
{return this.graph.TestIncidenceMatrix(matrix,rowsObj,colsObj);}
Application.prototype.TestPair=function(pair)
{return this.graph.TestPair(pair);}
Application.prototype.SetIncidenceMatrix=function(matrix)
{var res=true;var r={};var c={};if(!this.TestIncidenceMatrix(matrix,r,c))
{$.get("/"+SiteDir+"backend/addFailedMatrix.php?text=incidence&matrix="+encodeURIComponent(matrix),function(data){;});res=false;}
this.graph.SetIncidenceMatrix(matrix,new Point(this.GetRealWidth(),this.GetRealHeight()),this.currentEnumVerticesType);this.AutoAdjustViewport();this.redrawGraph();return res;}
Application.prototype.Test=function()
{this.graph.VerticesReposition(new Point(this.GetRealWidth(),this.GetRealHeight()),this.graph.vertices);this.redrawGraph();}
Application.prototype.SetAdjacencyMatrixSmart=function(matrix,separator)
{if(separator===undefined)
{separator=",";}
var res=false;if(this.TestAdjacencyMatrix(matrix,{},{},separator))
{res=this.SetAdjacencyMatrix(matrix,separator);}
else if(this.TestIncidenceMatrix(matrix,{},{}))
{res=this.SetIncidenceMatrix(matrix);}
else
{res=this.SetAdjacencyMatrix(matrix);}
return res;}
Application.prototype.SetIncidenceMatrixSmart=function(matrix)
{var res=false;if(this.TestIncidenceMatrix(matrix,{},{}))
{res=this.SetIncidenceMatrix(matrix);}
else if(this.TestAdjacencyMatrix(matrix,{},{}))
{res=this.SetAdjacencyMatrix(matrix);}
else
{res=this.SetIncidenceMatrix(matrix);}
return res;}
Application.prototype.SetPairSmart=function(pair)
{var res=false;if(this.TestPair(pair))
{res=this.SetPair(pair);}
else
{res=false;}
return res;}
Application.prototype.SaveGraphOnDisk=function()
{var graphAsString=this.graph.SaveToXML(this.SaveUserSettings());var app=this;if(this.savedGraphName.length<=0)
{this.savedGraphName=this.GetNewGraphName();}
DiskSaveLoad.SaveGraphOnDisk(this.savedGraphName,graphAsString,function(msg)
{document.cookie="graphName="+app.savedGraphName;app.removeAutosave();app.lastGraphName=app.savedGraphName;app.PushLastUsedGraph(app.savedGraphName);});}
Application.prototype.SaveGraphImageOnDisk=function(showDialogCallback)
{var imageName=this.GetNewName();this.stopRenderTimer();this.redrawGraph();var bbox=this.graph.getGraphBBox();var rectParams="";if(this.IsGraphFitOnViewport())
{var canvasWidth=this.GetRealWidth();var canvasHeight=this.GetRealHeight();var canvasPositionInverse=this.canvasPosition.inverse();var pos=bbox.minPoint.subtract(canvasPositionInverse);rectParams="&x="+Math.round(pos.x*this.canvasScale)+"&y="+Math.round(pos.y*this.canvasScale)
+"&width="+Math.round(bbox.size().x*this.canvasScale)+"&height="+Math.round(bbox.size().y*this.canvasScale);}
var imageBase64Data=this.canvas.toDataURL();DiskSaveLoad.SaveGraphImageOnDisk(imageName,rectParams,imageBase64Data,showDialogCallback);return imageName;}
Application.prototype.SaveFullGraphImageOnDisk=function(showDialogCallback,forPrint)
{var imageName=this.GetNewName();this.stopRenderTimer();var canvas=forPrint?this._PrintRedrawGraph():this._OffscreenRedrawGraph();var bbox=this.graph.getGraphBBox();var rectParams="";rectParams="&x=0"+"&y=0"+"&width="+bbox.size().x+"&height="+bbox.size().y;var imageBase64Data=canvas.toDataURL();DiskSaveLoad.SaveGraphImageOnDisk(imageName,rectParams,imageBase64Data,showDialogCallback);return imageName;}
Application.prototype.SaveSVGGraphOnDisk=function(showDialogCallback)
{var imageName=this.GetNewName();this.stopRenderTimer();var svgText=this._printToSVG();DiskSaveLoad.SaveSVGGraphOnDisk(imageName,svgText,showDialogCallback);return imageName;}
Application.prototype.LoadGraphFromString=function(str)
{var graph=new Graph();var userSettings={};graph.LoadFromXML(str,userSettings);if(userSettings.hasOwnProperty("data")&&userSettings["data"].length>0)
this.LoadUserSettings(userSettings["data"]);this.SetDefaultTransformations();this.graph=graph;if(this.graph.isNeedReposition())
{this.graph.VerticesReposition(new Point(this.GetRealWidth(),this.GetRealHeight()),this.graph.vertices);}
this.AutoAdjustViewport();this.updateMessage();this.redrawGraph();}
Application.prototype.LoadNewGraphFromString=function(str)
{this.LoadGraphFromString(str);this.lastGraphName="";}
Application.prototype.LoadGraphFromDisk=function(graphName)
{var app=this;DiskSaveLoad.LoadGraphFromDisk(graphName,function(msg)
{app.LoadGraphFromString(msg);app.removeAutosave();app.lastGraphName=graphName;});}
Application.prototype.GetNewGraphName=function()
{var name=this.GetNewName();if(this.style.isVertexCommonStyleCustom||this.style.isVertexSelectedVertexStylesCustom||this.style.isBackgroundCommonStyleCustom||this.style.isEdgeCommonStyleCustom||this.style.isEdgeSelectedStylesCustom)
{name=name+this.styliedGraphNamePostfix;}
return name;}
Application.prototype.GetNewName=function()
{var name="";var possible="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";for(var i=0;i<this.graphNameLength;i++)
{name+=possible.charAt(Math.floor(Math.random()*possible.length));}
return name;}
Application.prototype.GetGraphName=function()
{return this.savedGraphName;}
Application.prototype.SetDefaultHandler=function()
{this.listener.SetDefaultHandler();}
Application.prototype.GetEnumVerticesList=function()
{var res=[];for(var i=0;i<this.enumVerticesTextList.length;i++)
{var one={};one["text"]=this.enumVerticesTextList[i].GetText();one["value"]=this.enumVerticesTextList[i].GetValue();one["select"]=this.enumVerticesTextList[i].GetValue()==this.currentEnumVerticesType.GetValue();res.push(one);}
return res;}
Application.prototype.SetEnumVerticesType=function(value)
{for(var i=0;i<this.enumVerticesTextList.length;i++)
{if(this.enumVerticesTextList[i].GetValue()==value)
{this.currentEnumVerticesType=this.enumVerticesTextList[i];document.cookie="enumType="+value;break;}}}
Application.prototype.SetFindPathReport=function(value)
{this.findPathReport=value;}
Application.prototype.GetFindPathReport=function()
{return this.findPathReport;}
Application.prototype.GetRealWidth=function()
{return this.canvas.width/this.canvasScale;}
Application.prototype.GetRealHeight=function()
{return this.canvas.height/this.canvasScale;}
Application.prototype.SetDefaultTransformations=function()
{this.canvasScale=1.0;this.canvasPosition=new Point(0,0);}
Application.prototype.AutoAdjustViewport=function()
{graphBBox=this.graph.getGraphBBox();bboxCenter=graphBBox.center();bboxSize=graphBBox.size();if(bboxSize.length()>0)
{if(bboxSize.x>this.GetRealWidth()||bboxSize.y>this.GetRealHeight())
{this.canvasScale=Math.min(this.GetRealWidth()/bboxSize.x,this.GetRealHeight()/bboxSize.y);}
if(graphBBox.minPoint.x<0.0||graphBBox.minPoint.y<0.0||graphBBox.maxPoint.x>this.GetRealWidth()||graphBBox.maxPoint.y>this.GetRealHeight())
{this.canvasPosition=graphBBox.minPoint.inverse();}}}
Application.prototype.OnAutoAdjustViewport=function()
{this.SetDefaultTransformations();this.AutoAdjustViewport();this.redrawGraph();}
Application.prototype.getAlgorithmNames=function()
{var res=[];for(var i=0;i<g_Algorithms.length;i++)
{factory=g_Algorithms[i];var obj={};oneFactory=factory(this.graph);obj.name=oneFactory.getName(g_language);obj.id=oneFactory.getId();obj.priority=oneFactory.getPriority();obj.category=oneFactory.getCategory();res.push(obj);}
res.sort(function(a,b){return a.priority-b.priority;});return res;}
Application.prototype.resultCallback=function(paths)
{console.log(paths);if((paths instanceof Object)&&"paths"in paths)
{this.setRenderPath(paths["paths"][0],"minPath"in paths);}
else if((paths instanceof Object)&&"pathsWithEdges"in paths)
{this.setRenderPathWithEdges(paths["pathsWithEdges"][0]);}
this.updateMessage();this.redrawGraph();}
Application.prototype.GetCurrentValue=function(paramName,defaultValue)
{return(paramName in this.algorithmsValues)?this.algorithmsValues[paramName]:defaultValue;}
Application.prototype.SetCurrentValue=function(paramName,value)
{this.algorithmsValues[paramName]=value;}
Application.prototype.IsGraphFitOnViewport=function()
{res=true;graphBBox=this.graph.getGraphBBox();var canvasWidth=this.GetRealWidth();var canvasHeight=this.GetRealHeight();var canvasPositionInverse=this.canvasPosition.inverse();return(Math.floor(canvasPositionInverse.x)<=Math.floor(graphBBox.minPoint.x)&&Math.floor(canvasPositionInverse.y)<=Math.floor(graphBBox.minPoint.y)&&Math.floor(canvasPositionInverse.x+canvasWidth)>=Math.floor(graphBBox.maxPoint.x)&&Math.floor(canvasPositionInverse.y+canvasHeight)>=Math.floor(graphBBox.maxPoint.y));}
Application.prototype.PushToStack=function(actionName)
{this.undoStack.PushToStack(actionName,this.graph.SaveToXML(this.SaveUserSettings()));document.getElementById('GraphUndo').style.display='inline-block';}
Application.prototype.Undo=function()
{let data=this.undoStack.Undo();if(data==null)
return;this.graph=new Graph();var userSettings={};this.graph.LoadFromXML(data,userSettings);if(userSettings.hasOwnProperty("data")&&userSettings["data"].length>0)
this.LoadUserSettings(userSettings["data"]);this.redrawGraph();if(this.undoStack.IsUndoStackEmpty())
document.getElementById('GraphUndo').style.display='none';}
Application.prototype.SaveUserSettings=function()
{return"{"+this.style.Save()+"}";}
Application.prototype.LoadUserSettings=function(json)
{this.style.Load(json);}
Application.prototype.SetVertexStyle=function(index,style)
{if(index==0)
{this.style.vertexCommonStyle=style;this.style.isVertexCommonStyleCustom=true;}
else
{this.style.vertexSelectedVertexStyles[index-1]=style;this.style.isVertexSelectedVertexStylesCustom=true;}}
Application.prototype.ResetVertexStyle=function(index)
{if(index==0)
{this.style.vertexCommonStyle=new CommonVertexStyle();this.style.isVertexCommonStyleCustom=false;}
else
{this.style.vertexSelectedVertexStyles=FullArrayCopy(DefaultSelectedGraphStyles);this.style.isVertexSelectedVertexStylesCustom=false;}}
Application.prototype.SetEdgeStyle=function(index,style)
{if(index==0)
{this.style.edgeCommonStyle=style;this.style.isEdgeCommonStyleCustom=true;}
else
{this.style.edgeSelectedStyles[index-1]=style;this.style.isEdgeSelectedStylesCustom=true;}}
Application.prototype.ResetEdgeStyle=function(index)
{if(index==0)
{this.style.edgeCommonStyle=new CommonEdgeStyle();this.style.isEdgeCommonStyleCustom=false;}
else
{this.style.edgeSelectedStyles=FullArrayCopy(DefaultSelectedEdgeStyles);this.style.isEdgeSelectedStylesCustom=false;}}
Application.prototype.SetBackgroundStyle=function(style)
{this.style.backgroundCommonStyle=style;this.style.isBackgroundCommonStyleCustom=true;}
Application.prototype.ResetBackgroundStyle=function()
{this.style.backgroundCommonStyle=new CommonBackgroundStyle();this.style.isBackgroundCommonStyleCustom=false;}
Application.prototype.GetAvailableCurveValue=function(neighborEdges,originalEdge)
{return this.graph.GetAvailableCurveValue(neighborEdges,originalEdge);}
Application.prototype.GraphTypeChanged=function()
{this.listener.OnGraphTypeChanged(this.graph.isMulti());}
Application.prototype.UpdateEdgePresets=function(weight)
{var oldPresets=this.edgePresets;this.edgePresets=[1];oldPresets.unshift(weight);for(var i=0;i<oldPresets.length;i++)
{var k=oldPresets[i];if(!this.edgePresets.includes(k))
this.edgePresets.push(k);if(this.edgePresets.length>=this.maxEdgePresets)
break;}}
Application.prototype.GetEdgePresets=function()
{return this.edgePresets;}
Application.prototype.SetSelectionRect=function(rect)
{this.selectionRect=rect;}
Application.prototype.GetSelectionRect=function(rect)
{return this.selectionRect;}
Application.prototype.GetStyle=function(type,styleName,object,index)
{var correctIndex=index;if(correctIndex==undefined)
correctIndex=0;if(type=="vertex")
{if(styleName=="common")
{return object!==undefined?object.getStyleFor(0):this.style.vertexCommonStyle;}
else if(styleName=="selected")
{return object!==undefined&&object.hasOwnStyleFor(correctIndex+1)?object.getStyleFor(correctIndex+1):this.style.vertexSelectedVertexStyles[correctIndex];}
else if(styleName=="printed")
{return this.vertexPrintCommonStyle;}
else if(styleName=="printedSelected")
{return this.vertexPrintSelectedVertexStyles[correctIndex];}
return null;}
else if(type=="edge")
{if(styleName=="common")
{return object!==undefined?object.getStyleFor(0):this.style.edgeCommonStyle;}
else if(styleName=="selected")
{return object!==undefined&&object.hasOwnStyleFor(correctIndex+1)?object.getStyleFor(correctIndex+1):this.style.edgeSelectedStyles[correctIndex];}
else if(styleName=="printed")
{return this.edgePrintCommonStyle;}
else if(styleName=="printedSelected")
{return this.edgePrintSelectedStyles[correctIndex];}
return null;}
return null;}
Application.prototype._RedrawGraph=function(context,canvasParams,backgroundPosition,backgroundStyle,bDrawSelectedRect,forceVertexCommon,forceVertexSelected,forceEdgeCommon,forceEdgeSelected)
{var backgroundDrawer=new BaseBackgroundDrawer(context);backgroundDrawer.Draw(backgroundStyle,Math.max(canvasParams.width,this.GetRealWidth()),Math.max(canvasParams.height,this.GetRealHeight()),backgroundPosition,canvasParams.scale);this.UpdateEdgesCurrentStyle(forceEdgeCommon,forceEdgeSelected);this.UpdateNodesCurrentStyle(forceVertexCommon,forceVertexSelected);this.RedrawEdges(context);this.RedrawNodes(context);if(bDrawSelectedRect&&this.selectionRect!=null)
this.RedrawSelectionRect(context);}
Application.prototype.GetSelectedVertices=function()
{var res=[];for(i=0;i<this.graph.vertices.length;i++)
{if(this.handler.GetSelectedGroup(this.graph.vertices[i])>0)
{res.push(this.graph.vertices[i]);}}
return res;}
Application.prototype.GetSelectedEdges=function()
{var res=[];for(i=0;i<this.graph.edges.length;i++)
{if(this.handler.GetSelectedGroup(this.graph.edges[i])>0)
{res.push(this.graph.edges[i]);}}
return res;}
Application.prototype.SetDefaultVertexSize=function(diameter)
{var oldDefaultDiameter=this.GetDefaultVertexSize();this.style.defaultVertexSize=diameter;for(i=0;i<this.graph.vertices.length;i++)
{if(this.graph.vertices[i].model.diameter==oldDefaultDiameter)
{this.graph.vertices[i].model.diameter=diameter;}}}
Application.prototype.GetDefaultVertexSize=function(diameter)
{if(this.style.defaultVertexSize!=null)
return this.style.defaultVertexSize;else
return defaultVertexDiameter;}
Application.prototype.ResetVertexSize=function()
{this.style.defaultVertexSize=null;for(i=0;i<this.graph.vertices.length;i++)
{this.graph.vertices[i].model.diameter=this.GetDefaultVertexSize();}}
Application.prototype.SetDefaultEdgeWidth=function(width)
{var oldDefaultWidth=this.GetDefaultEdgeWidth();this.style.defaultEdgeWidth=width;for(i=0;i<this.graph.edges.length;i++)
{if(this.graph.edges[i].model.width==oldDefaultWidth)
{this.graph.edges[i].model.width=width;}}}
Application.prototype.GetDefaultEdgeWidth=function(diameter)
{if(this.style.defaultEdgeWidth!=null)
return this.style.defaultEdgeWidth;else
return defaultEdgeWidth;}
Application.prototype.ResetEdgeWidth=function()
{this.style.defaultEdgeWidth=null;for(i=0;i<this.graph.edges.length;i++)
{this.graph.edges[i].model.width=this.GetDefaultEdgeWidth();}}
Application.prototype.setEmscripten=function(processFunction)
{this.processEmscriptenFunction=processFunction;console.log("Emscripten set");}
Application.prototype.isSupportEmscripten=function()
{return this.processEmscriptenFunction!=null;}
Application.prototype.processEmscripten=function(inputData)
{return this.processEmscriptenFunction(inputData);}
Application.prototype.setDefaultEdge=function(defaultEdge)
{this.defaultEdge=defaultEdge;}
Application.prototype.hasDefaultEdge=function()
{return this.defaultEdge!=null;}
Application.prototype.getDefaultEdge=function()
{return this.defaultEdge;}
Application.prototype.setUseDefaultEdge=function(value)
{this.useDefaultEdge=value;}
Application.prototype.getUseDefaultEdge=function()
{return this.useDefaultEdge;}
Application.prototype.loadGraphFromZippedBase64=function(base64Str,callback)
{decompress_base64_zip_into_text(base64Str,callback);}
Application.prototype.isAutoSaveGraphName=function(str)
{return str.length>0&&str.length<=this.graphNameLength+this.styliedGraphNamePostfix.length;}
Application.prototype.saveAutoSave=function(graphXML,callback)
{compress_text_into_zip_base64(graphXML,function(base64Str){if(this.lastSavedAutoSave==base64Str)
{if(callback)
{callback();}
return;}
if(base64Str.length<this.maxAutosaveSizeForCookie)
{this.setAutoSaveCookie(base64Str);let saveGraphData=this.getAutoSaveCookie();if(saveGraphData==base64Str)
{this.lastSavedAutoSave=base64Str;console.log("Auto save to cookie");if(callback)
{callback();}
return;}
else
{console.log("Failed to save autosave to cookie");this.removeAutoSaveCookie();}}
let autoSaveGraphName=this.getAutoSaveCookie();if(!this.isAutoSaveGraphName(autoSaveGraphName))
{autoSaveGraphName=this.GetNewGraphName();}
let app=this;DiskSaveLoad.SaveAutoSaveGraphOnDisk(autoSaveGraphName,graphXML,function(msg)
{app.setAutoSaveCookie(autoSaveGraphName);app.lastSavedAutoSave=base64Str;if(callback)
{callback();}
console.log("Auto save to file");}.bind(base64Str));}.bind(this));}
Application.prototype.hasAutoSave=function()
{let autoSaveData=this.getAutoSaveCookie();return(autoSaveData.length>0);}
Application.prototype.loadAutoSave=function(callback)
{let app=this;this.getAutoSaveGraph(function(xmlGraph){app.LoadGraphFromString(xmlGraph);app.lastGraphName=app.getAutoSaveRefGraphCookie();if(callback)
{callback();}});}
Application.prototype.getAutoSaveGraph=function(callback)
{let autoSaveData=this.getAutoSaveCookie();if(autoSaveData.length<0)
{console.log("Auto save to cookie is empty");return;}
let app=this;if(!this.isAutoSaveGraphName(autoSaveData))
{this.loadGraphFromZippedBase64(autoSaveData,function(xmlGraph){console.log("Load graph from cookie");if(callback)
{callback(xmlGraph);}});return;}
DiskSaveLoad.LoadAutoSaveGraphFromDisk(autoSaveData,function(xmlGraph)
{if(callback)
{callback(xmlGraph);}});}
Application.prototype.removeAutosave=function(callback)
{let autoSaveData=this.getAutoSaveCookie();this.lastSavedAutoSave="";let app=this;if(autoSaveData.length<0)
{console.log("Auto save to cookie is empty");return;}
if(!this.isAutoSaveGraphName(autoSaveData))
{app.removeAutoSaveCookie();console.log("Remove auto save from cookie");if(callback)
{callback();}
return;}
DiskSaveLoad.RemoveAutoSaveGraphFromDisk(autoSaveData,function(msg)
{app.removeAutoSaveCookie();console.log("Remove auto save file");if(callback)
{callback();}});}
Application.prototype.setAutoSaveCookie=function(value)
{var now=new Date();var time=now.getTime();var expireTime=time+1000*3600*24*7;now.setTime(expireTime);document.cookie='auto_save='+value+';expires='+now.toUTCString()+';path=/';document.cookie='auto_save_ref_graph='+this.lastGraphName+';expires='+now.toUTCString()+';path=/';}
Application.prototype.removeAutoSaveCookie=function(value)
{document.cookie="auto_save=;path=/";document.cookie="auto_save_ref_graph=;path=/";}
Application.prototype.getAutoSaveCookie=function(value)
{return document.cookie.replace(/(?:(?:^|.*;\s*)auto_save\s*\=\s*([^;]*).*$)|^.*$/,"$1");}
Application.prototype.getAutoSaveRefGraphCookie=function(value)
{return document.cookie.replace(/(?:(?:^|.*;\s*)auto_save_ref_graph\s*\=\s*([^;]*).*$)|^.*$/,"$1");}
Application.prototype.CreateNewGraphObject=function()
{this.graph=new Graph();this.savedGraphName="";this.lastGraphName="";}
Application.prototype.showSelectGraphDialog=function(graphName)
{let app=this;DiskSaveLoad.LoadGraphFromDisk(graphName,function(graphOriginXML)
{app.getAutoSaveGraph(function(xmlGraph){let remove_id_from_xml=function(graphXML)
{graphXML=graphXML.replace(/uidEdge=\"([0-9]+)\"/i,"")
graphXML=graphXML.replaceAll(/id=\"([0-9]+)\"/g,"")
return graphXML;};if(remove_id_from_xml(xmlGraph)==remove_id_from_xml(graphOriginXML))
{app.onSelectOgirinalGraph(graphName);return;}
var autosaveGraph=new Graph();var userSettings1={};autosaveGraph.LoadFromXML(xmlGraph,userSettings1);let styleAutoSave=new GraphFullStyle(null);if(userSettings1.hasOwnProperty("data")&&userSettings1["data"].length>0)
styleAutoSave.Load(userSettings1["data"]);var originalGraph=new Graph();var userSettings2={};originalGraph.LoadFromXML(graphOriginXML,userSettings2);let styleOriginal=new GraphFullStyle(null);if(userSettings2.hasOwnProperty("data")&&userSettings2["data"].length>0)
styleOriginal.Load(userSettings2["data"]);(new SelectGraphDialog(app,originalGraph,styleOriginal,autosaveGraph,styleAutoSave,function(){app.onSelectOgirinalGraph(graphName);},function(){app.onSelectAutosaveGraph();})).show();});});}
Application.prototype.startAutoSaveTimer=function()
{setInterval(function()
{var graphXML=this.graph.SaveToXML(this.SaveUserSettings());this.saveAutoSave(graphXML);}.bind(this),this.autosaveTimeInterval);}
Application.prototype.onSelectOgirinalGraph=function(graphName)
{this.LoadGraphFromDisk(graphName);this.startAutoSaveTimer();userAction("LoadGraphFromDisk_userSelect");console.log("User selected original graph");}
Application.prototype.onSelectAutosaveGraph=function()
{this.loadAutoSave();this.startAutoSaveTimer();userAction("LoadGraphFromAutoSave_userSelect");console.log("User selected auto-save graph");}
Application.prototype.UpdateLastUsedGraphsMenu=function()
{let isEmpty=this.lastUsedGraphs.length==0;document.getElementById('LastUsedGraphsMenu').style.display=isEmpty?'none':'block';let graphsList=document.getElementById('LastUsedGraphsList');graphsList.innerHTML='';if(isEmpty)
{return;}
let FormatGraphName=function(graph)
{let MAX_GRAPH_NAME_LENGTH=20;let graphName=graph.graph;if(graphName.length>MAX_GRAPH_NAME_LENGTH)
{graphName=graphName.substring(0,MAX_GRAPH_NAME_LENGTH/2)+"..."+
graphName.substring(graphName.length-MAX_GRAPH_NAME_LENGTH/2);}
return graphName+" "+"<span class=\"bi bi-clock\"></span>"+
graph.date.toLocaleDateString(g_language+"-"+g_language);};for(let i=0;i<this.lastUsedGraphs.length;i++)
{let graph=this.lastUsedGraphs[i];graphsList.innerHTML=graphsList.innerHTML+"<li>"+"<a class=\"dropdown-item btn btn-sm\" href=\"./?graph="+graph.graph+"\" role=\"button\">"+
FormatGraphName(graph)+"</a>"+"</li>";}}
Application.prototype.PushLastUsedGraph=function(graphName)
{let graph={graph:graphName,date:new Date()};let index=this.lastUsedGraphs.findIndex(function(item){return item.graph==graphName;});if(index>=0)
{this.UpdateLastUsedGraphsMenu();return;}
this.lastUsedGraphs.unshift(graph);if(this.lastUsedGraphs.length>this.maxLastUsedGraphCount)
{this.lastUsedGraphs.pop();}
this.SaveLastUsedGraphsToCookie();this.UpdateLastUsedGraphsMenu();}
Application.prototype.SaveLastUsedGraphsToCookie=function()
{let graphs=JSON.stringify(this.lastUsedGraphs);var now=new Date();var time=now.getTime();var expireTime=time+1000*3600*24*7;now.setTime(expireTime);document.cookie="lastUsedGraphs="+graphs+';expires='+now.toUTCString()+";path=/";}
Application.prototype.LoadLastUsedGraphsFromCookie=function()
{let graphs=document.cookie.replace(/(?:(?:^|.*;\s*)lastUsedGraphs\s*\=\s*([^;]*).*$)|^.*$/,"$1");if(graphs.length>0)
{this.lastUsedGraphs=JSON.parse(graphs);for(let i=0;i<this.lastUsedGraphs.length;i++)
{let graph=this.lastUsedGraphs[i];graph.date=new Date(graph.date);}}}
var waitCounter=false;var userAction=function(str)
{if(typeof window.yaCounter25827098!=="undefined")
{console.log(g_language+"/"+str);window.yaCounter25827098.hit(window.location.protocol+"//"+window.location.hostname+(g_language!="ru"?"/"+g_language:"")+"/UserAction#"+str);}
else if(!waitCounter)
{waitCounter=true;setTimeout(function()
{userAction(str);},2000);}}
var g_ctrlPressed=false;function Editor(document,window){let self=this;this.application=new Application(document,window,self);this.fullscreen=false;this.buttonsList=['AddGraph','ConnectGraphs','DeleteObject','Default'];}
Editor.prototype.initMouseActions=function(){let self=this;this.application.canvas.onmousemove=function(e)
{return self.application.CanvasOnMouseMove(e);};this.application.canvas.onmousedown=function(e)
{return self.application.CanvasOnMouseDown(e);};this.application.canvas.onmouseup=function(e)
{return self.application.CanvasOnMouseUp(e);}
this.application.canvas.onwheel=function(e)
{var e=window.event||e;var delta=Math.max(-1,Math.min(1,(e.wheelDelta||-e.detail)));if(delta>0)
{self.application.multCanvasScale(1.3,e);}
else
{self.application.multCanvasScale(1.0/1.3,e);}}}
Editor.prototype.initKeyActions=function(){let self=this;function getCharCode(event){if(event.which==null){return event.keyCode;}
if(event.which!=0&&event.charCode!=0){return event.which;}
return null;}
function getChar(event){return String.fromCharCode(getCharCode(event));}
function selectHandler(buttonName,handler)
{userAction(buttonName+"_shortcut");self.restButtons(buttonName);self.application.SetHandler(handler);}
document.onkeypress=function(e)
{if(event.defaultPrevented||($('#addVertex').hasClass('ui-dialog-content')&&$('#addVertex').dialog('isOpen'))||($('#adjacencyMatrix').hasClass('ui-dialog-content')&&$('#adjacencyMatrix').dialog('isOpen'))||($('#addEdge').hasClass('ui-dialog-content')&&$('#addEdge').dialog('isOpen'))||($('#incidenceMatrix').hasClass('ui-dialog-content')&&$('#incidenceMatrix').dialog('isOpen'))||($('#saveDialog').hasClass('ui-dialog-content')&&$('#saveDialog').dialog('isOpen'))||($('#saveImageDialog').hasClass('ui-dialog-content')&&$('#saveImageDialog').dialog('isOpen'))||($('#GroupRenameDialog').hasClass('ui-dialog-content')&&$('#GroupRenameDialog').dialog('isOpen'))||$('#developerTools').css("display")!="none"||($('#NeedAlgorithm').hasClass('ui-dialog-content')&&$('#NeedAlgorithm').dialog('isOpen')))
{console.log("prevent");return;}
var key=getChar(event);var code=getCharCode(event);console.log(key+" code="+code);var evtobj=window.event?event:e;var isCtrl=evtobj?evtobj.ctrlKey:false;var moveValue=10;if(code==61||code==43)
{self.application.multCanvasScale(1.5);}
else if(code==45)
{self.application.multCanvasScale(1/1.5);}
else if(key=='w'||key=='ц')
{self.application.onCanvasMove(new Point(0,moveValue));}
else if(key=='s'||key=='ы')
{self.application.onCanvasMove(new Point(0,-moveValue));}
else if(key=='a'||key=='ф')
{self.application.onCanvasMove(new Point(moveValue,0));}
else if(key=='d'||key=='в')
{self.application.onCanvasMove(new Point(-moveValue,0));}
else if(key=='v'||key=='м')
{selectHandler('AddGraph',new AddGraphHandler(self.application));}
else if(key=='e'||key=='у')
{selectHandler('ConnectGraphs',new ConnectionGraphHandler(self.application));}
else if(key=='r'||key=='к')
{selectHandler('DeleteObject',new DeleteGraphHandler(self.application));}
else if(key=='m'||key=='ь')
{selectHandler('Default',new DefaultHandler(self.application));}
else if(code==26&&isCtrl)
{userAction("Key_GraphUndo");self.application.Undo();}}
$(document).keydown(function(event){if(event.which=="17"||event.which=="91")
g_ctrlPressed=true;});$(document).keyup(function(){g_ctrlPressed=false;});}
Editor.prototype.initButtonActions=function()
{let self=this;document.getElementById('ShowAdjacencyMatrix').onclick=function()
{userAction(this.id);var showAdjacencyMatrix=new ShowAdjacencyMatrix(self.application);showAdjacencyMatrix.show();}
document.getElementById('ShowIncidenceMatrix').onclick=function()
{userAction(this.id);var showIncidenceMatrix=new ShowIncidenceMatrix(self.application);showIncidenceMatrix.show();}
document.getElementById('ShowDistanceMatrix').onclick=function()
{userAction(this.id);var showDistanceMatrix=new ShowDistanceMatrix(self.application);showDistanceMatrix.show();}
document.getElementById('GroupRename').onclick=function()
{userAction(this.id);var groupRenameVertices=new GroupRenameVertices(self.application);groupRenameVertices.show();}
document.getElementById('groupRenameButton').onclick=function()
{userAction(this.id);var groupRenameVertices=new GroupRenameVertices(self.application);groupRenameVertices.show();}
document.getElementById('Default').onclick=function()
{userAction(this.id);self.restButtons('Default');self.application.SetHandler(new DefaultHandler(self.application));document.getElementById('Default').className="btn btn-primary btn-sm";}
document.getElementById('AddGraph').onclick=function()
{userAction(this.id);self.restButtons('AddGraph');self.application.SetHandler(document.getElementById('AddGraph').className!=""?new AddGraphHandler(self.application):new DefaultHandler(self.application));}
document.getElementById('ConnectGraphs').onclick=function()
{userAction(this.id);self.restButtons('ConnectGraphs');self.application.SetHandler(document.getElementById('ConnectGraphs').className!=""?new ConnectionGraphHandler(self.application):new DefaultHandler(self.application));}
document.getElementById('DeleteObject').onclick=function()
{userAction(this.id);self.restButtons('DeleteObject');self.application.SetHandler(document.getElementById('DeleteObject').className!=""?new DeleteGraphHandler(self.application):new DefaultHandler(self.application));}
document.getElementById('DeleteAll').onclick=function()
{userAction(this.id);var removeAll=new DeleteAllHandler(self.application);removeAll.clear();self.application.ToDefaultStateAndRedraw();}
document.getElementById('SaveGraph').onclick=function()
{userAction(this.id);var savedDialogGraphHandler=new SavedDialogGraphHandler(self.application);savedDialogGraphHandler.show();}
document.getElementById('NewGraph').onclick=function()
{userAction(this.id);var removeAll=new DeleteAllHandler(self.application);removeAll.clear();self.application.ToDefaultStateAndRedraw();self.application.SetDefaultTransformations();}
document.getElementById('SaveGraphImage').onclick=function()
{userAction(this.id);var savedDialogGraphImageHandler=new SavedDialogGraphImageHandler(self.application);savedDialogGraphImageHandler.showWorkspace();}
document.getElementById('SaveFullGraphImage').onclick=function()
{userAction(this.id);var savedDialogGraphImageHandler=new SavedDialogGraphImageHandler(self.application);savedDialogGraphImageHandler.showFullgraph();}
document.getElementById('SavePrintGraphImage').onclick=function()
{userAction(this.id);var savedDialogGraphImageHandler=new SavedDialogGraphImageHandler(self.application);savedDialogGraphImageHandler.showPrint();}
document.getElementById('SaveSvgGraphImage').onclick=function()
{userAction(this.id);var savedDialogGraphImageHandler=new SavedDialogGraphImageHandler(self.application);savedDialogGraphImageHandler.showSvg();}
document.getElementById('Zoom100').onclick=function()
{userAction(this.id);self.application.setCanvasScale(1.0);}
document.getElementById('Zoom50').onclick=function()
{userAction(this.id);self.application.setCanvasScale(50/100);}
document.getElementById('Zoom25').onclick=function()
{userAction(this.id);self.application.setCanvasScale(25/100);}
document.getElementById('ZoomFit').onclick=function()
{userAction(this.id);self.application.OnAutoAdjustViewport();}
document.getElementById('ZoomIn').onclick=function()
{userAction(this.id);self.application.multCanvasScale(1.5);}
document.getElementById('ZoomOut').onclick=function()
{userAction(this.id);self.application.multCanvasScale(1.0/1.5);}
document.getElementById('MoveWorspace').onclick=function()
{userAction(this.id);self.restButtons('Default');self.application.SetHandler(new DefaultHandler(self.application));document.getElementById('Default').className="btn btn-primary btn-sm";}
document.getElementById('SetupVertexStyle').onclick=function()
{userAction(this.id);var setupVertexStyle=new SetupVertexStyle(self.application);setupVertexStyle.show(0);}
document.getElementById('SetupVertexStyleSelected').onclick=function()
{userAction(this.id);var setupVertexStyle=new SetupVertexStyle(self.application);setupVertexStyle.show(1);}
document.getElementById('SetupEdgeStyle').onclick=function()
{userAction(this.id);var setupEdgeStyle=new SetupEdgeStyle(self.application);setupEdgeStyle.show(0);}
document.getElementById('SetupEdgeStyleSelected').onclick=function()
{userAction(this.id);var setupEdgeStyle=new SetupEdgeStyle(self.application);setupEdgeStyle.show(1);}
document.getElementById('SetupBackgroundStyle').onclick=function()
{userAction(this.id);var setupBackgroundStyle=new SetupBackgroundStyle(self.application);setupBackgroundStyle.show();}
document.getElementById('GraphUndo').onclick=function()
{userAction(this.id);self.application.Undo();}
document.getElementById('runUserScript').onclick=function()
{}
document.getElementById('submitUserScript').onclick=function()
{var script=document.getElementById('userScript');var data="message="+script.value+"&";$.ajax({type:"POST",url:"/feedback",data:data});$("#sentAlgorithm").dialog({resizable:false,height:"auto",width:400,modal:true,dialogClass:'EdgeDialog'});}
document.getElementById('devToolsZoom').onclick=function()
{var devTools=document.getElementById('developerTools');if(devTools.hasOwnProperty("isMin")&&!devTools["isMin"])
{devTools["isMin"]=true;devTools.style.width="30%";}
else
{devTools["isMin"]=false;devTools.style.width="100%";}}
document.getElementById('ExportGraph').onclick=function()
{userAction(this.id);var graphAsString=self.application.graph.SaveToXML("");var savedGraphName=self.application.GetNewGraphName();var element=document.createElement('a');element.setAttribute('href','data:text/plain;charset=utf-8,'+encodeURIComponent(graphAsString));element.setAttribute('download',"graph_"+savedGraphName+".graphml");element.style.display='none';document.body.appendChild(element);element.click();document.body.removeChild(element);}
document.getElementById('ImportGraph').onclick=function()
{userAction(this.id);if(ImportGraphFiles){ImportGraphFiles.click();}}
document.getElementById('openAlgorithmList').onclick=function()
{return;}
document.getElementById('Fullscreen').onclick=function()
{var idList=["h1Header","h1Text","navigation","footerContent","bottom_adv"];self.fullscreen=!self.fullscreen
userAction(self.fullscreen?"fullscreen_on":"fullscreen_off");for(var i=0;i<idList.length;i++){let element=document.getElementById(idList[i]);if(!element)continue;if(self.fullscreen)
element.style.display="none";else
element.style.display="block";}
document.getElementById("mainContainer").className=self.fullscreen?"container-fluid page-wrap":"container page-wrap";document.getElementById("FullscreenIcon").className=self.fullscreen?"bi bi-fullscreen-exit":"bi bi-arrows-fullscreen";resizeCanvas();}}
Editor.prototype.initVoteButton=function()
{let self=this;if(document.getElementById('VoteButton')!==null)
document.getElementById('VoteButton').onclick=function()
{var dialogButtons={};for(var i=0;i<6&&document.getElementById('vote'+i)!==null;i++)
{document.getElementById('vote'+i)["voteIndex"]=i;document.getElementById('vote'+i).onclick=function()
{console.log("Vote"+self["voteIndex"]);$.ajax({type:"GET",url:"/"+SiteDir+"backend/vote.php?index="+self["voteIndex"],dataType:"text"});$("#voteDialog").dialog('close');$("#VoteButton").hide();}}
dialogButtons[g_close]=function(){$(self).dialog("close");};$("#voteDialog").dialog({resizable:false,title:g_vote,width:400,modal:true,dialogClass:'EdgeDialog',buttons:dialogButtons,});}}
Editor.prototype.initAlgorithmList=function()
{return;let showHideCategory=function(button,elementsListName){let width=$(button).width();let elementsList=$(elementsListName);var hideMark=button.querySelector('span[name="hideMark"]')
var showMark=button.querySelector('span[name="showMark"]')
if(elementsList.is(":visible")){elementsList.hide();$(hideMark).show();$(showMark).hide();}else{elementsList.show();$(hideMark).hide();$(showMark).show();}
$(button).width(width);userAction("algCategory_"+elementsListName);}
$(document.getElementById("algorithmCategoryBtn1").querySelector('span[name="hideMark"]')).hide();$(document.getElementById("algorithmCategoryBtn0").querySelector('span[name="hideMark"]')).hide();$('#algorithmCategoryBtn1').click(function(){showHideCategory(this,"#algorithmCategoryElements1");});$('#algorithmCategoryBtn0').click(function(){showHideCategory(this,"#algorithmCategoryElements0");});}
Editor.prototype.init=function()
{this.application.onLoad();this.initMouseActions();this.initKeyActions();this.initButtonActions();this.initVoteButton();let self=this;loadAsyncAlgorithms(function(){self.createAlgorithmMenu();});var devTools=document.getElementById('developerTools');devTools.style.left=0;resizeCanvas();this.application.onPostLoadEvent();this.initAlgorithmList();}
Editor.prototype.redraw=function(){this.application.redrawGraph();}
Editor.prototype.createAlgorithmMenu=function()
{let self=this;var algorithmBaseId="Algo";var algorithms=this.application.getAlgorithmNames();var index=0;for(var i=0;i<algorithms.length;i++)
{algorithm=algorithms[i];var list=document.getElementById("algorithmCategoryElements"+algorithm.category);var item=document.getElementById("algTopic"+algorithm.category);var clone=item.cloneNode(true);var button=clone.getElementsByTagName("a")[0];var textSpan=button.getElementsByTagName("span")[1];button.id=algorithm.id;textSpan.innerHTML=algorithm.name;clone.style.display="block";button.onclick=function(e)
{e["closeThisMenu"]=true;userAction(this.id);self.restButtons("");self.application.SetHandler(new AlgorithmGraphHandler(self.application,g_Algorithms[g_AlgorithmIds.indexOf(this.id)](self.application.graph,self.application)));}
var eventData={};eventData.index=i;eventData.object=clone;eventData.algorithm=algorithm;$("#openAlgorithmList").bind('click',eventData,function(_eventData){var data=_eventData.data;var algorithm=g_Algorithms[g_AlgorithmIds.indexOf(data.algorithm.id)](self.application.graph,self.application);if((self.application.graph.isMulti()&&!algorithm.IsSupportMultiGraph())||(self.application.graph.hasNegative()&&!algorithm.IsSupportNegativeWeight()))
{$(data.object).hide();}
else
{$(data.object).show();var textSpan=data.object.getElementsByTagName("span")[1];textSpan.innerHTML=algorithm.getName();}});list.insertBefore(clone,document.getElementById("insert"+algorithm.category));index++;}}
Editor.prototype.restButtons=function(me)
{var needSetDefault=false;for(let i=0;i<this.buttonsList.length;i++)
{if(this.buttonsList[i]!=me)
{document.getElementById(this.buttonsList[i]).className="btn btn-outline-secondary btn-sm";}
else
{if(document.getElementById(this.buttonsList[i]).className!="btn btn-outline-secondary btn-sm")
{needSetDefault=true;}}}
if(me!="")
{if(needSetDefault)
{document.getElementById(me).className="btn btn-primary btn-sm";}
else
{document.getElementById(me).className="btn btn-primary btn-sm";}}}
Editor.prototype.ShowIncidenceMatrixErrorDialog=function(matrix)
{var dialogButtons={};matrixRes=matrix.replace(/\n/g,'%0A');dialogButtons[g_readMatrixHelp]=function(){window.location.assign(g_language=="ru"?"./wiki/Справка/МатрицаИнцидентности#matrixFormat":"./wiki/Help/IncidenceMatrix#matrixFormat");};dialogButtons[g_fixMatrix]=function(){window.location.assign("./create_graph_by_incidence_matrix?incidenceMatrix="+matrixRes);};dialogButtons[g_close]=function(){$(this).dialog("close");};$("#matrixErrorInc").dialog({resizable:false,title:g_matrixWrongFormat,width:400,modal:true,dialogClass:'EdgeDialog',buttons:dialogButtons,});}
Editor.prototype.ShowPairErrorDialog=function(pair)
{var dialogButtons={};pair=pair.replaceAll(/\n/g,'%0A');pair=pair.replaceAll('>','&gt;');pair=pair.replaceAll('<','&lt;');dialogButtons[g_readMatrixHelp]=function(){window.location.assign(g_language=="ru"?"./wiki/Справка/СписокРебер":"./wiki/Help/EdgeList");};dialogButtons[g_fix]=function(){window.location.assign("./create_graph_by_edge_list?pair="+pair);};dialogButtons[g_close]=function(){$(this).dialog("close");};$("#pairErrorInc").dialog({resizable:false,title:g_pairWrongFormat,width:400,modal:true,dialogClass:'EdgeDialog',buttons:dialogButtons,});}
Editor.prototype.ShowAdjacencyMatrixErrorDialog=function(matrix)
{var dialogButtons={};matrixRes=matrix.replace(/\n/g,'%0A');dialogButtons[g_readMatrixHelp]=function(){window.location.assign(g_language=="ru"?"./wiki/Справка/МатрицаСмежности#matrixFormat":"./wiki/Help/AdjacencyMatrix#matrixFormat");};dialogButtons[g_fixMatrix]=function(){window.location.assign("./create_graph_by_matrix?matrix="+matrixRes);};dialogButtons[g_close]=function(){$(this).dialog("close");};$("#matrixError").dialog({resizable:false,title:g_matrixWrongFormat,width:400,modal:true,dialogClass:'EdgeDialog',buttons:dialogButtons,});}
Editor.prototype.SetDefaultHandler=function()
{this.restButtons('Default');this.application.SetHandler(new DefaultHandler(this.application));}
Editor.prototype.OnGraphTypeChanged=function(isMulti)
{$("#CanvasMessage").text(isMulti?g_GraphIsMultiMessage:g_GraphIsGeneralMessage);}
Editor.prototype.updateMessage=function(message)
{$("#message").html(message);}
let DisableEmscripten=false;let PostLoadedCalled=false;let editor=new Editor(document,window);function resizeCanvas()
{var adv=document.getElementById('bottom_info');var canvas=document.getElementById('canvas');canvas.width=document.getElementById('canvasSection').offsetWidth;var mainContainer=document.getElementById('mainContainer');var offset=(mainContainer.offsetTop+mainContainer.offsetHeight)-(canvas.offsetTop+canvas.offsetHeight)+
($("#footerContent").css("display")==='block'?0:24);canvas.height=$(window).height()-document.getElementById('canvas').offsetTop-
(adv&&$("#bottom_info").css("display")==='block'?document.getElementById('bottom_info').offsetHeight:0)-
($("#footer").css("display")==='block'?document.getElementById('footer').offsetHeight:0)-offset;editor.redraw();}
function touchHandler(event)
{var touches=event.changedTouches,first=touches[0],type="";switch(event.type)
{case"touchstart":type="mousedown";break;case"touchmove":type="mousemove";break;case"touchend":type="mouseup";break;default:return;}
var simulatedEvent=document.createEvent("MouseEvent");simulatedEvent.initMouseEvent(type,true,true,window,1,first.screenX,first.screenY,first.clientX,first.clientY,false,false,false,false,0,null);first.target.dispatchEvent(simulatedEvent);event.preventDefault();}
function handelImportGraph(files){var graphFileToLoad=files[0];var fileReader=new FileReader();fileReader.onload=function(fileLoadedEvent){var textFromFileLoaded=fileLoadedEvent.target.result;editor.application.LoadNewGraphFromString(textFromFileLoaded);editor.application.saveAutoSave(textFromFileLoaded);ImportGraphFiles.value="";};fileReader.readAsText(graphFileToLoad,"UTF-8");}
function postLoadPage()
{if(!PostLoadedCalled)
{loadTexts();editor.init();PostLoadedCalled=true;}}
$(document).ready(function()
{window.onresize=function(event)
{resizeCanvas();}
document.getElementById('canvas').addEventListener("touchstart",touchHandler,true);document.getElementById('canvas').addEventListener("touchmove",touchHandler,true);document.getElementById('canvas').addEventListener("touchend",touchHandler,true);document.getElementById('canvas').addEventListener("touchcancel",touchHandler,true);var isMobile=navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i);if(!isMobile&&!DisableEmscripten){let fullPathToGraphffoline="features/graphoffline/Graphoffline.Emscripten.js"+"?v="+globalVersion;doIncludeAsync([include(fullPathToGraphffoline),],()=>{Module['onRuntimeInitialized']=onRuntimeInitialized;var process=Module.cwrap('ProcessAlgorithm','string',['string']);function onRuntimeInitialized(){editor.application.setEmscripten(process);}})}});moduleLoader.endCacheLoading();