diff --git a/core/func/main.php b/core/func/main.php
index 6d70b58..91fcf54 100755
--- a/core/func/main.php
+++ b/core/func/main.php
@@ -173,11 +173,15 @@
return SITE_ROOT . "{$dir}{$uri}";
}
- function RootCacheJS($uri = '', $version = '') {
+ function RootCacheJS($uri = '') {
global $g_config;
-
- return Root(($g_config['use_js_cache'] ? $uri . ".cache" :
- $uri) . "?v=" . $version);
+
+ $cacheFilePath = Root($uri . ".cache");
+ $filePath = Root($uri);
+ $cacheExists = file_exists("." . $cacheFilePath);
+ $finalFileName = $cacheExists && $g_config['use_js_cache'] ? $cacheFilePath : $filePath;
+
+ return $finalFileName . "?v=" . $g_config['engine_version'];
}
/**
diff --git a/lang/en/home.php b/lang/en/home.php
index 849143a..d279c55 100755
--- a/lang/en/home.php
+++ b/lang/en/home.php
@@ -145,6 +145,8 @@
$g_lang["opensource_message"] = "Our project is now open source. More details...";
+ $g_lang["we_are_improving"] = "We are improving Graphonline, if you faced with any problem please let us know: admin@graphonline.ru";
+
$g_lang["settings"] = "Settings";
$g_lang["common_vertex_settings"] = "Common vertices";
$g_lang["selected_vertex_settings"] = "Selected vertices";
diff --git a/lang/ru/home.php b/lang/ru/home.php
index 1f0a34d..4bc1450 100755
--- a/lang/ru/home.php
+++ b/lang/ru/home.php
@@ -148,6 +148,8 @@
$g_lang["opensource_message"] = "Наш проект стал проектом с открытым исходным кодом. Подробнее...";
+ $g_lang["we_are_improving"] = "Мы улучшаем Graphonline, если вы столкнулись с проблемами напишете нам: admin@graphonline.ru";
+
$g_lang["settings"] = "Настройки";
$g_lang["common_vertex_settings"] = "Обычных вершин";
$g_lang["selected_vertex_settings"] = "Выделенных вершин";
diff --git a/script/EventHandlers.js b/script/EventHandlers.js
deleted file mode 100644
index bef5e7f..0000000
--- a/script/EventHandlers.js
+++ /dev/null
@@ -1,2501 +0,0 @@
-/**
- *
- * This event handlers.
- *
- *
- */
-
-/**
- * Base Handler.
- *
- */
-
-function BaseHandler(app)
-{
- this.app = app;
- this.app.setRenderPath([]);
-
- if (this.removeStack) {
- this.removeContextMenu();
- }
- this.contextMenuObject = null;
- this.contextMenuPoint = null;
- //this.app.ClearUndoStack();
-}
-
-// Need redraw or nor.
-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)
-{
- // Selected Graph.
- var res = null;
- for (var i = 0; i < this.app.graph.vertices.length; i ++)
- {
- if (this.app.graph.vertices[i].HitTest(pos))
- {
- // Select last of them.
- res = this.app.graph.vertices[i];
- }
- }
-
-
- return res;
-}
-
-BaseHandler.prototype.GetSelectedArc = function(pos)
-{
- // Selected Arc.
- 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)))
- return edge;
- }
-
- return null;
-}
-
-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 = "" +
- "";
-}
-
-BaseHandler.prototype.GetSelect2VertexMenu = function()
-{
- return "" +
- this.GetSelectVertexMenu("Vertex1") + " → " + this.GetSelectVertexMenu("Vertex2") + "";
-}
-
-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);
- //handler.AddNewEdge(selectedObject, true);
- $( this ).dialog( "close" );
- };
- dialogButtons[g_notOrintEdge] = function() {
- handler.app.PushToStack("Connect");
- addEdgeCallBack(firstVertex, secondVertex, false);
- //handler.AddNewEdge(selectedObject, false);
- $( this ).dialog( "close" );
- };
-
- var edgePresets = this.app.GetEdgePresets();
- var presetsStr = "" + g_DefaultWeightPreset + "";
-
- for(var i = 0; i < edgePresets.length; i ++)
- {
- var edgePreset = edgePresets[i];
- presetsStr += "" + edgePreset + "";
- }
- 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;
- });
-
- // Focues weight
- 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 = "" + g_DefaultWeightPreset + "";
-
- for(var i = 0; i < edgePresets.length; i ++)
- {
- var edgePreset = edgePresets[i];
- presetsStr += "" + edgePreset + "";
- }
- 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;
- });
- }
- });
-}
-
-/**
- * Default handler.
- * Select using mouse, drag.
- *
- */
-function DefaultHandler(app)
-{
- this.removeStack = true;
- BaseHandler.apply(this, arguments);
- this.message = g_textsSelectAndMove + " " + g_selectGroupText + "" + " " + g_useContextMenuText + "";
- 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();
-}
-
-// inheritance.
-DefaultHandler.prototype = Object.create(BaseHandler.prototype);
-// Is pressed
-DefaultHandler.prototype.pressed = false;
-// Curve change value.
-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)
- {
- // Rect select.
- 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
- {
- // Move work space
- 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 + " " + g_selectGroupText + "" + " " + g_useContextMenuText + "";
- 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
- + "
"
- + ""
- + ""
- + "
";
-
- 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
- + ""
- + " " + g_curveEdge + " "
- + " "
- + ""
- + ""
- + ""
- + "
";
-
- 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 + " " + g_selectGroupText + "";
-
- 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 + "";
-
- this.message = this.message
- + "    "
- + ""
-
- this.message = this.message
- + "     "
- + ""
- + "";
-
- var handler = this;
- $('#message').unbind();
-
- $('#message').on('click', '#DublicateSelected', function(){
- handler.app.PushToStack("DublicateSelection");
-
- userAction("GroupSelected.Dublicate");
-
- var newSelected = [];
- var copyVertex = {};
-
- // Copy vertex
- 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;
- }
- }
-
- // Copy edge
- 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 + " " + g_selectGroupText + "";
- });
-
- 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]);
- }
-
- // Selected Arc.
- 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);
- }
-}
-
-
-/**
- * Add Graph handler.
- *
- */
-function AddGraphHandler(app)
-{
- this.removeStack = true;
- BaseHandler.apply(this, arguments);
- this.message = g_clickToAddVertex;
- this.addContextMenu();
-}
-
-// inheritance.
-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);
-}
-
-
-
-/**
- * Connection Graph handler.
- *
- */
-function ConnectionGraphHandler(app)
-{
- this.removeStack = true;
- BaseHandler.apply(this, arguments);
- this.SelectFirst();
- this.addContextMenu();
-}
-
-// inheritance.
-ConnectionGraphHandler.prototype = Object.create(BaseHandler.prototype);
-// First selected.
-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 ""
- + " "
- + ""
- + "
" + baseMessage;
-}
-
-ConnectionGraphHandler.checkUseDefaultEdge = function (elem, app)
-{
- app.setUseDefaultEdge(elem.checked);
- app.updateMessage();
-};
-
-ConnectionGraphHandler.prototype.GetUseDefaultEdgeCheckBox = function() {
- if (!this.app.hasDefaultEdge()) {
- return "";
- }
-
- return " " +
- "" +
- " " +
- "
";
-}
-
-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());
-}
-
-
-/**
- * Delete Graph handler.
- *
- */
-function DeleteGraphHandler(app)
-{
- this.removeStack = true;
- BaseHandler.apply(this, arguments);
- this.message = g_selectObjectToDelete;
- this.addContextMenu();
-}
-
-// inheritance.
-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;
-}
-
-/**
- * Delete Graph handler.
- *
- */
-function DeleteAllHandler(app)
-{
- BaseHandler.apply(this, arguments);
-}
-
-// inheritance.
-DeleteAllHandler.prototype = Object.create(BaseHandler.prototype);
-
-DeleteAllHandler.prototype.clear = function()
-{
- this.app.PushToStack("DeleteAll");
-
- // Selected Graph.
- this.app.graph = new Graph();
- this.app.savedGraphName = "";
- this.needRedraw = true;
-}
-
-
-/**
- * Save/Load graph from matrix.
- *
- */
-function ShowAdjacencyMatrix(app)
-{
- BaseHandler.apply(this, arguments);
- this.message = "";
-}
-
-// inheritance.
-ShowAdjacencyMatrix.prototype = Object.create(BaseHandler.prototype);
-// First selected.
-ShowAdjacencyMatrix.prototype.firstObject = null;
-// Path
-ShowAdjacencyMatrix.prototype.pathObjects = null;
-
-ShowAdjacencyMatrix.prototype.show = function()
-{
- var handler = this;
- var dialogButtons = {};
-
- $('#AdjacencyMatrixField').unbind();
- $( "#AdjacencyMatrixField" ).on('keyup change', function (eventObject)
- {
- if (!handler.app.TestAdjacencyMatrix($( "#AdjacencyMatrixField" ).val(), [], []))
- {
- $( "#BadMatrixFormatMessage" ).show();
- }
- else
- {
- $( "#BadMatrixFormatMessage" ).hide();
- }
- });
-
- dialogButtons[g_save] = function() {
- handler.app.PushToStack("ChangeAdjacencyMatrix");
- handler.app.SetAdjacencyMatrixSmart($( "#AdjacencyMatrixField" ).val());
- $( this ).dialog( "close" );
- };
- dialogButtons[g_cancel] = function() {
- $( this ).dialog( "close" );
- };
-
- $( "#AdjacencyMatrixField" ).val(this.app.GetAdjacencyMatrix());
- $( "#BadMatrixFormatMessage" ).hide();
-
- if (this.app.graph.isMulti())
- $( "#AdjacencyMatrixMultiGraphDesc").show();
- else
- $( "#AdjacencyMatrixMultiGraphDesc").hide();
-
- $( "#adjacencyMatrix" ).dialog({
- resizable: false,
- height: "auto",
- width: "auto",
- modal: true,
- title: g_adjacencyMatrixText,
- buttons: dialogButtons,
- dialogClass: 'EdgeDialog'
- });
-}
-
-
-/**
- * Save/Load graph from Incidence matrix.
- *
- */
-function ShowIncidenceMatrix(app)
-{
- BaseHandler.apply(this, arguments);
- this.message = "";
-}
-
-// inheritance.
-ShowIncidenceMatrix.prototype = Object.create(BaseHandler.prototype);
-// First selected.
-ShowIncidenceMatrix.prototype.firstObject = null;
-// Path
-ShowIncidenceMatrix.prototype.pathObjects = null;
-
-ShowIncidenceMatrix.prototype.show = function()
-{
- var handler = this;
- var dialogButtons = {};
-
- $('#IncidenceMatrixField').unbind();
- $( "#IncidenceMatrixField" ).on('keyup change', function (eventObject)
- {
- if (!handler.app.TestIncidenceMatrix($( "#IncidenceMatrixField" ).val(), [], []))
- {
- $( "#BadIncidenceMatrixFormatMessage" ).show();
- }
- else
- {
- $( "#BadIncidenceMatrixFormatMessage" ).hide();
- }
- });
-
- dialogButtons[g_save] = function() {
- handler.app.PushToStack("IncidenceMatrixChanged");
- handler.app.SetIncidenceMatrixSmart($( "#IncidenceMatrixField" ).val());
- $( this ).dialog( "close" );
- };
- dialogButtons[g_cancel] = function() {
- $( this ).dialog( "close" );
- };
-
- $( "#IncidenceMatrixField" ).val(this.app.GetIncidenceMatrix());
- $( "#BadIncidenceMatrixFormatMessage" ).hide();
-
- $( "#incidenceMatrix" ).dialog({
- resizable: false,
- height: "auto",
- width: "auto",
- modal: true,
- title: g_incidenceMatrixText,
- buttons: dialogButtons,
- dialogClass: 'EdgeDialog'
- });
-}
-
-
-/**
- * Show distance matrix.
- *
- */
-function ShowDistanceMatrix(app)
-{
- BaseHandler.apply(this, arguments);
- this.app = app;
- this.message = "";
-}
-
-// inheritance.
-ShowDistanceMatrix.prototype = Object.create(BaseHandler.prototype);
-// First selected.
-ShowDistanceMatrix.prototype.firstObject = null;
-// Path
-ShowDistanceMatrix.prototype.pathObjects = null;
-
-ShowDistanceMatrix.prototype.GetIncidenceMatrix = function (rawMatrix)
-{
- var matrix = "";
- for (var i = 0; i < rawMatrix.length; i++)
- {
- for (var j = 0; j < rawMatrix[i].length; j++)
- {
- if (i == j)
- {
- matrix += "0";
- }
- else if ((new Graph()).infinity == rawMatrix[i][j])
- {
- matrix += '\u221E';
- }
- else
- {
- matrix += rawMatrix[i][j];
- }
-
- if (j != rawMatrix[i].length - 1)
- {
- matrix += ", ";
- }
-
- }
- matrix = matrix + "\n";
- }
-
- return matrix;
-}
-
-ShowDistanceMatrix.prototype.show = function()
-{
- var handler = this;
- var dialogButtons = {};
-
- dialogButtons[g_close] = function() {
- $( this ).dialog( "close" );
- };
-
- var handler = g_Algorithms[g_AlgorithmIds.indexOf("OlegSh.FloidAlgorithm")](this.app.graph, this.app);
-
- $( "#FloidMatrixField" ).val(this.GetIncidenceMatrix(handler.resultMatrix()));
-
- $( "#floidMatrix" ).dialog({
- resizable: false,
- height: "auto",
- width: "auto",
- modal: true,
- title: g_minDistMatrixText,
- buttons: dialogButtons,
- dialogClass: 'EdgeDialog'
- });
-}
-
-/**
- * Save dialog Graph handler.
- *
- */
-function SavedDialogGraphHandler(app)
-{
- BaseHandler.apply(this, arguments);
- this.message = "";
-}
-
-// inheritance.
-SavedDialogGraphHandler.prototype = Object.create(BaseHandler.prototype);
-// First selected.
-SavedDialogGraphHandler.prototype.firstObject = null;
-// Path
-SavedDialogGraphHandler.prototype.pathObjects = null;
-// Objects.
-SavedDialogGraphHandler.prototype.objects = null;
-
-SavedDialogGraphHandler.prototype.show = function(object)
-{
- this.app.SaveGraphOnDisk();
-
- var dialogButtons = {};
-
- dialogButtons[g_close] = function() {
- $( this ).dialog( "close" );
- };
-
- document.getElementById('GraphName').value = "http://" + window.location.host + window.location.pathname +
- "?graph=" + this.app.GetGraphName();
-
- document.getElementById('GraphName').select();
-
- document.getElementById("ShareSavedGraph").innerHTML =
- document.getElementById("ShareSavedGraph").innerHTML.replace(/graph=([A-Za-z]*)/g, "graph=" + this.app.GetGraphName());
-
- $( "#saveDialog" ).dialog({
- resizable: false,
- height: "auto",
- width: "auto",
- modal: true,
- title: g_save_dialog,
- buttons: dialogButtons,
- dialogClass: 'EdgeDialog'
- });
-
-}
-
-/**
- * Save dialog Graph handler.
- *
- */
-function SavedDialogGraphImageHandler(app)
-{
- BaseHandler.apply(this, arguments);
- this.message = "";
- this.imageName = "";
-}
-
-// inheritance.
-SavedDialogGraphImageHandler.prototype = Object.create(BaseHandler.prototype);
-// First selected.
-SavedDialogGraphImageHandler.prototype.firstObject = null;
-// Path
-SavedDialogGraphImageHandler.prototype.pathObjects = null;
-// Objects.
-SavedDialogGraphImageHandler.prototype.objects = null;
-
-SavedDialogGraphImageHandler.prototype.showDialogCallback = function (imageExtension)
-{
- var dialogButtons = {};
-
- dialogButtons[g_close] = function() {
- $( this ).dialog( "close" );
- };
-
- var fileLocation = "tmp/saved/" + this.imageName.substr(0, 2) + "/"+ this.imageName + "." + imageExtension
-
- document.getElementById("showSavedImageGraph").src = "/" + fileLocation;
- document.getElementById("showSavedImageGraphRef").href = "/" + fileLocation;
- //document.getElementById("showSavedImageGraph").src = document.getElementById("showSavedImageGraph").src.replace(/tmp\/saved\/([A-Za-z]*)\/([A-Za-z]*).png/g, fileLocation);
- document.getElementById("ShareSavedImageGraph").innerHTML =
- document.getElementById("ShareSavedImageGraph").innerHTML.replace(/tmp\/saved\/([A-Za-z]*)\/([A-Za-z]*).png/g, fileLocation);
-
- document.getElementById("SaveImageLinks").innerHTML =
- document.getElementById("SaveImageLinks").innerHTML.replace(/tmp\/saved\/([A-Za-z]*)\/([A-Za-z]*).png/g, fileLocation);
-
- $( "#saveImageDialog" ).dialog({
- resizable: false,
- height: "auto",
- width: "auto",
- modal: true,
- title: g_save_image_dialog,
- buttons: dialogButtons,
- dialogClass: 'EdgeDialog'
- });
-
-}
-
-SavedDialogGraphImageHandler.prototype.showWorkspace = function()
-{
- var object = this;
- var callback = function() {
- object.showDialogCallback("png");
- };
-
- this.imageName = this.app.SaveGraphImageOnDisk(callback);
-}
-
-SavedDialogGraphImageHandler.prototype.showFullgraph = function()
-{
- var object = this;
- var callback = function() {
- object.showDialogCallback("png");
- };
-
- this.imageName = this.app.SaveFullGraphImageOnDisk(callback, false);
-}
-
-SavedDialogGraphImageHandler.prototype.showPrint = function()
-{
- var object = this;
- var callback = function() {
- object.showDialogCallback("png");
- };
-
- this.imageName = this.app.SaveFullGraphImageOnDisk(callback, true);
-}
-
-SavedDialogGraphImageHandler.prototype.showSvg = function()
-{
- var object = this;
- var callback = function() {
- object.showDialogCallback("svg");
- };
-
- this.imageName = this.app.SaveSVGGraphOnDisk(callback);
-}
-
-/**
- * Algorithm Graph handler.
- *
- */
-function AlgorithmGraphHandler(app, algorithm)
-{
- BaseHandler.apply(this, arguments);
- this.algorithm = algorithm;
- this.SaveUpText();
-
- this.UpdateResultAndMessage();
-}
-
-// inheritance.
-AlgorithmGraphHandler.prototype = Object.create(BaseHandler.prototype);
-
-// Rest this handler.
-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);
-}
-
-
-/**
- * Groupe rename vertices.
- *
- */
-function GroupRenameVertices(app)
-{
- BaseHandler.apply(this, arguments);
- this.message = "";
-}
-
-// inheritance.
-GroupRenameVertices.prototype = Object.create(BaseHandler.prototype);
-// First selected.
-GroupRenameVertices.prototype.firstObject = null;
-// Path
-GroupRenameVertices.prototype.pathObjects = null;
-
-GroupRenameVertices.prototype.show = function()
-{
- var handler = this;
- var dialogButtons = {};
- var graph = this.app.graph;
- var app = this.app;
-
- dialogButtons[g_save] = function() {
- app.PushToStack("Rename");
-
- var titlesList = $( "#VertextTitleList" ).val().split('\n');
- for (i = 0; i < Math.min(graph.vertices.length, titlesList.length); i ++)
- {
- graph.vertices[i].mainText = titlesList[i];
- }
- app.redrawGraph();
- $( this ).dialog( "close" );
- };
- dialogButtons[g_cancel] = function() {
- $( this ).dialog( "close" );
- };
-
- var titleList = "";
- for (i = 0; i < graph.vertices.length; i ++)
- {
- titleList = titleList + graph.vertices[i].mainText + "\n";
- }
-
- $( "#VertextTitleList" ).val(titleList);
-
- $( "#GroupRenameDialog" ).dialog({
- resizable: false,
- height: "auto",
- width: "auto",
- modal: true,
- title: g_groupRename,
- buttons: dialogButtons,
- dialogClass: 'EdgeDialog'
- });
-}
-
-
-/**
- * Setup Vertex Style rename vertices.
- *
- */
-function SetupVertexStyle(app)
-{
- BaseHandler.apply(this, arguments);
- this.message = "";
-}
-
-// inheritance.
-SetupVertexStyle.prototype = Object.create(BaseHandler.prototype);
-
-SetupVertexStyle.prototype.show = function(index, selectedVertices)
-{
- var handler = this;
- var dialogButtons = {};
- var graph = this.app.graph;
- var app = this.app;
- this.forAll = selectedVertices == null;
- var forAll = this.forAll;
- var self = this;
-
- var applyIndex = function(index)
- {
- self.index = index;
- self.originStyle = (self.index == 0 ? app.vertexCommonStyle : app.vertexSelectedVertexStyles[self.index - 1]);
- if (!forAll)
- {
- self.originStyle = selectedVertices[0].getStyleFor(self.index);
- }
- self.style = FullObjectCopy(self.originStyle);
- }
-
- applyIndex(index);
-
- var fillFields = function()
- {
- var fullStyle = self.style.GetStyle({}, forAll ? undefined : selectedVertices[0]);
-
- $( "#vertexFillColor" ).val(fullStyle.fillStyle);
- $( "#vertexStrokeColor" ).val(fullStyle.strokeStyle);
- $( "#vertexTextColor" ).val(fullStyle.mainTextColor);
- $( "#upVertexTextColor" ).val(fullStyle.upTextColor);
- $( "#vertexStrokeSize" ).val(fullStyle.lineWidth);
- $( "#vertexShape" ).val(fullStyle.shape);
- $( "#vertexSize" ).val(forAll ? app.GetDefaultVertexSize() : selectedVertices[0].model.diameter);
- $( "#commonTextPosition" ).val(fullStyle.commonTextPosition);
-
- if (self.index > 0 || self.index == "all")
- {
- $( "#VertexSelectedIndexForm" ).show();
- $( "#vertexSelectedIndex" ).val(self.index);
- }
- else
- {
- $( "#VertexSelectedIndexForm" ).hide();
- }
-
- // Fill color presets.
- var stylesArray = [];
- stylesArray.push(app.vertexCommonStyle);
-
- for (i = 0; i < app.vertexSelectedVertexStyles.length; i ++)
- stylesArray.push(app.vertexSelectedVertexStyles[i]);
-
- var colorSet = {};
- for (i = 0; i < stylesArray.length; i ++)
- {
- var style = stylesArray[i];
- if (style.hasOwnProperty('strokeStyle'))
- colorSet[style.strokeStyle] = 1;
- if (style.hasOwnProperty('fillStyle'))
- colorSet[style.fillStyle] = 1;
- if (style.hasOwnProperty('mainTextColor'))
- colorSet[style.mainTextColor] = 1;
- if (style.hasOwnProperty('upTextColor'))
- colorSet[style.upTextColor] = 1;
- }
-
- $("#vertexFillColorPreset").find('option').remove();
- $("#upVertexTextColorPreset").find('option').remove();
- $("#vertexTextColorPreset").find('option').remove();
- $("#vertexStrokeColorPreset").find('option').remove();
- for (const property in colorSet)
- {
- $("#vertexFillColorPreset").append(new Option(property));
- $("#upVertexTextColorPreset").append(new Option(property));
- $("#vertexTextColorPreset").append(new Option(property));
- $("#vertexStrokeColorPreset").append(new Option(property));
- }
- }
-
- var redrawVertex = function()
- {
- var fullStyle = self.style.GetStyle({}, forAll ? undefined : selectedVertices[0]);
-
- if (fullStyle.fillStyle != $( "#vertexFillColor" ).val())
- self.style.fillStyle = $( "#vertexFillColor" ).val();
-
- if (fullStyle.strokeStyle != $( "#vertexStrokeColor" ).val())
- self.style.strokeStyle = $( "#vertexStrokeColor" ).val();
-
- if (fullStyle.mainTextColor != $( "#vertexTextColor" ).val())
- self.style.mainTextColor = $( "#vertexTextColor" ).val();
-
- if (fullStyle.lineWidth != $( "#vertexStrokeSize" ).val())
- self.style.lineWidth = parseInt($( "#vertexStrokeSize" ).val());
-
- if (fullStyle.shape != $( "#vertexShape" ).val())
- self.style.shape = parseInt($( "#vertexShape" ).val());
-
- if (fullStyle.upTextColor != $( "#upVertexTextColor" ).val())
- self.style.upTextColor = $( "#upVertexTextColor" ).val();
-
- if (fullStyle.commonTextPosition != $( "#commonTextPosition" ).val())
- self.style.commonTextPosition = $( "#commonTextPosition" ).val();
-
- var diameter = parseInt($( "#vertexSize" ).val());
-
- var canvas = document.getElementById( "VertexPreview" );
- var context = canvas.getContext('2d');
-
- context.save();
-
- var backgroundDrawer = new BaseBackgroundDrawer(context);
- backgroundDrawer.Draw(app.backgroundCommonStyle, canvas.width, canvas.height, new Point(0, 0), 1.0);
-
- var graphDrawer = new BaseVertexDrawer(context);
- var baseVertex = new BaseVertex(canvas.width / 2, canvas.height / 2, new BaseEnumVertices(this));
- baseVertex.mainText = "1";
- baseVertex.upText = "Up Text";
- baseVertex.model.diameter = diameter;
-
- if (!forAll)
- baseVertex.ownStyles = selectedVertices[0].ownStyles;
-
- graphDrawer.Draw(baseVertex, self.style.GetStyle({}, baseVertex));
-
- context.restore();
- }
-
- var changeIndex = function()
- {
- var val = $( "#vertexSelectedIndex" ).val();
- if (val == "all")
- {
- applyIndex(1);
- self.index = "all";
- fillFields();
- }
- else
- {
- var index = parseInt(val);
- self.index = index;
- applyIndex(index);
- fillFields();
- }
- redrawVertex();
- }
-
- var applyDiameter = function(diameter)
- {
- if (forAll)
- {
- app.SetDefaultVertexSize(diameter);
- }
- else
- {
- selectedVertices.forEach(function(vertex) {
- vertex.model.diameter = diameter;
- });
- }
- };
-
- dialogButtons[g_default] =
- {
- text : g_default,
- class : "MarginLeft",
- click : function() {
-
- app.PushToStack("ChangeStyle");
-
- applyDiameter(forAll ? (new VertexModel()).diameter : app.GetDefaultVertexSize());
-
- var indexes = [];
- if (self.index == "all")
- {
- for (i = 0; i < app.vertexSelectedVertexStyles.length; i ++)
- indexes.push(i + 1);
- }
- else
- indexes.push(self.index);
-
-
- if (forAll)
- {
- indexes.forEach(function(index) {
- app.ResetVertexStyle(index);
- });
- }
- else
- {
- selectedVertices.forEach(function(vertex) {
- indexes.forEach(function(index) {
- vertex.resetOwnStyle(index);
- });
- });
- }
- app.redrawGraph();
- $( this ).dialog( "close" );
- }
- };
-
- dialogButtons[g_save] = function() {
-
- app.PushToStack("ChangeStyle");
-
- applyDiameter(parseInt($( "#vertexSize" ).val()));
-
- var indexes = [];
- if (self.index == "all")
- {
- indexes.push({index : 1, style : self.style});
- for (i = 1; i < app.vertexSelectedVertexStyles.length; i ++)
- {
- var style = (new BaseVertexStyle());
- style.baseStyles.push("selected");
- indexes.push({index : i + 1, style : style});
- }
-
- self.style.baseStyles = [];
- self.style.baseStyles = self.style.baseStyles.concat((new SelectedVertexStyle0()).baseStyles);
- }
- else
- indexes.push({index : self.index, style : self.style});
-
- if (forAll)
- {
- indexes.forEach(function(index) {
- app.SetVertexStyle(index.index, index.style);
- });
- }
- else
- {
- if (JSON.stringify(self.originStyle) !== JSON.stringify(self.style))
- {
- selectedVertices.forEach(function(vertex) {
- indexes.forEach(function(index) {
- vertex.setOwnStyle(index.index, index.style);
- });
- });
- }
- }
- app.redrawGraph();
- $( this ).dialog( "close" );
- };
- dialogButtons[g_cancel] = function() {
- $( this ).dialog( "close" );
- };
-
- fillFields();
-
- $( "#SetupVertexStyleDialog" ).dialog({
- resizable: false,
- height: "auto",
- width: "auto",
- modal: true,
- title: g_vertexDraw,
- buttons: dialogButtons,
- dialogClass: 'EdgeDialog'
- });
-
- redrawVertex();
-
- $( "#vertexFillColor" ).unbind();
- $( "#vertexStrokeColor" ).unbind();
- $( "#vertexTextColor" ).unbind();
- $( "#upVertexTextColor" ).unbind();
- $( "#vertexStrokeSize" ).unbind();
- $( "#vertexShape" ).unbind();
- $( "#vertexSize" ).unbind();
- $( "#commonTextPosition" ).unbind();
- $( "#vertexSelectedIndex" ).unbind();
-
- $( "#vertexFillColor" ).change(redrawVertex);
- $( "#vertexStrokeColor" ).change(redrawVertex);
- $( "#vertexTextColor" ).change(redrawVertex);
- $( "#vertexStrokeSize" ).change(redrawVertex);
- $( "#vertexShape" ).change(redrawVertex);
- $( "#vertexSize" ).change(redrawVertex);
- $( "#upVertexTextColor" ).change(redrawVertex);
- $( "#commonTextPosition" ).change(redrawVertex);
- $( "#vertexSelectedIndex" ).change(changeIndex);
-}
-
-/**
- * Setup Vertex Style rename vertices.
- *
- */
-function SetupEdgeStyle(app)
-{
- BaseHandler.apply(this, arguments);
- this.message = "";
-}
-
-// inheritance.
-SetupEdgeStyle.prototype = Object.create(BaseHandler.prototype);
-
-SetupEdgeStyle.prototype.show = function(index, selectedEdges)
-{
- var handler = this;
- var dialogButtons = {};
- var graph = this.app.graph;
- var app = this.app;
- this.forAll = selectedEdges == null;
- var forAll = this.forAll;
-
- var self = this;
-
- var applyIndex = function(index)
- {
- self.index = index;
- var originStyle = (self.index == 0 ? app.edgeCommonStyle : app.edgeSelectedStyles[self.index - 1]);
- if (!forAll)
- {
- originStyle = selectedEdges[0].getStyleFor(self.index);
- }
- self.style = FullObjectCopy(originStyle);
- }
-
- applyIndex(index);
-
- var fillFields = function()
- {
- var fullStyle = self.style.GetStyle({}, forAll ? undefined : selectedEdges[0]);
-
- $( "#edgeFillColor" ).val(fullStyle.fillStyle);
- $( "#edgeStrokeColor" ).val(fullStyle.strokeStyle);
- $( "#edgeTextColor" ).val(fullStyle.weightText);
- $( "#edgeStyle" ).val(fullStyle.lineDash);
- $( "#edgeWidth" ).val(forAll ? app.GetDefaultEdgeWidth() : selectedEdges[0].model.width);
-
- $( "#weightEdgeTextColor" ).val(fullStyle.additionalTextColor);
- $( "#weightTextPosition" ).val(fullStyle.weightPosition);
-
- if (self.index > 0 || self.index == "all")
- {
- $( "#EdgeSelectedIndexForm" ).show();
- $( "#edgeSelectedIndex" ).val(self.index);
- }
- else
- {
- $( "#EdgeSelectedIndexForm" ).hide();
- }
-
- // Fill color presets.
- var stylesArray = [];
- stylesArray.push(app.edgeCommonStyle);
-
- for (i = 0; i < app.edgeSelectedStyles.length; i ++)
- stylesArray.push(app.edgeSelectedStyles[i]);
-
- var colorSet = {};
- for (i = 0; i < stylesArray.length; i ++)
- {
- var style = stylesArray[i];
- if (style.hasOwnProperty('strokeStyle'))
- colorSet[style.strokeStyle] = 1;
- if (style.hasOwnProperty('fillStyle'))
- colorSet[style.fillStyle] = 1;
- if (style.hasOwnProperty('additionalTextColor'))
- colorSet[style.additionalTextColor] = 1;
- }
-
- $("#edgeFillColorPreset").find('option').remove();
- $("#weightEdgeTextColorPreset").find('option').remove();
- $("#edgeTextColorPreset").find('option').remove();
- $("#edgeStrokeColorPreset").find('option').remove();
- for (const property in colorSet)
- {
- $("#edgeFillColorPreset").append(new Option(property));
- $("#weightEdgeTextColorPreset").append(new Option(property));
- $("#edgeTextColorPreset").append(new Option(property));
- $("#edgeStrokeColorPreset").append(new Option(property));
- }
- }
-
- var redrawVertex = function()
- {
- var fullStyle = self.style.GetStyle({}, forAll ? undefined : selectedEdges[0]);
-
- if (fullStyle.fillStyle != $( "#edgeFillColor" ).val())
- self.style.fillStyle = $( "#edgeFillColor" ).val();
-
- if (fullStyle.strokeStyle != $( "#edgeStrokeColor" ).val())
- self.style.strokeStyle = $( "#edgeStrokeColor" ).val();
-
- if (fullStyle.weightText != $( "#edgeTextColor" ).val())
- self.style.weightText = $( "#edgeTextColor" ).val();
-
- if (fullStyle.lineDash != $( "#edgeStyle" ).val())
- self.style.lineDash = $( "#edgeStyle" ).val();
-
- if (fullStyle.additionalTextColor != $( "#weightEdgeTextColor" ).val())
- self.style.additionalTextColor = $( "#weightEdgeTextColor" ).val();
-
- if (fullStyle.weightPosition != $( "#weightTextPosition" ).val())
- self.style.weightPosition = $( "#weightTextPosition" ).val();
-
- var edgeWidth = parseInt($( "#edgeWidth" ).val());
-
- var canvas = document.getElementById( "EdgePreview" );
- var context = canvas.getContext('2d');
-
- context.save();
-
- var backgroundDrawer = new BaseBackgroundDrawer(context);
- backgroundDrawer.Draw(app.backgroundCommonStyle, canvas.width, canvas.height, new Point(0, 0), 1.0);
-
- var graphDrawer = new BaseEdgeDrawer(context);
- var baseVertex1 = new BaseVertex(0, canvas.height / 2, new BaseEnumVertices(this));
- var baseVertex2 = new BaseVertex(canvas.width, canvas.height / 2, new BaseEnumVertices(this));
-
- baseVertex1.currentStyle = baseVertex1.getStyleFor(0);
- baseVertex2.currentStyle = baseVertex2.getStyleFor(0);
-
- var baseEdge = new BaseEdge(baseVertex1, baseVertex2, true, 10, "Text");
-
- if (!forAll)
- baseEdge.ownStyles = selectedEdges[0].ownStyles;
-
- baseEdge.model.width = edgeWidth;
-
- graphDrawer.Draw(baseEdge, self.style.GetStyle({}, baseEdge));
-
- context.restore();
- }
-
- var changeIndex = function()
- {
- var val = $( "#edgeSelectedIndex" ).val();
- if (val == "all")
- {
- applyIndex(1);
- self.index = "all";
- fillFields();
- }
- else
- {
- var index = parseInt(val);
- self.index = index;
- applyIndex(index);
- fillFields();
- }
-
- redrawVertex();
- }
-
- var applyWidth = function(width)
- {
- if (forAll)
- {
- app.SetDefaultEdgeWidth(width);
- }
- else
- {
- selectedEdges.forEach(function(edge) {
- edge.model.width = width;
- });
- }
- };
-
- dialogButtons[g_default] =
- {
- text : g_default,
- class : "MarginLeft",
- click : function() {
- app.PushToStack("ChangeStyle");
-
- applyWidth(forAll ? (new EdgeModel()).width : app.GetDefaultEdgeWidth());
- var indexes = [];
- if (self.index == "all")
- {
- for (i = 0; i < app.edgeSelectedStyles.length; i ++)
- indexes.push(i + 1);
- }
- else
- indexes.push(self.index);
-
- if (forAll)
- {
- indexes.forEach(function(index) {
- app.ResetEdgeStyle(index);
- });
- }
- else
- {
- selectedEdges.forEach(function(edge) {
- indexes.forEach(function(index) {
- edge.resetOwnStyle(index);
- });
- });
- }
-
- app.redrawGraph();
- $( this ).dialog( "close" );
- }
- };
-
- dialogButtons[g_save] = function() {
-
- app.PushToStack("ChangeStyle");
-
- applyWidth(parseInt($( "#edgeWidth" ).val()));
-
- var indexes = [];
- if (self.index == "all")
- {
- indexes.push({index : 1, style : self.style});
-
- for (i = 1; i < app.edgeSelectedStyles.length; i ++)
- {
- var style = (new BaseEdgeStyle());
- style.baseStyles.push("selected");
- indexes.push({index : i + 1, style : style});
- }
-
- self.style.baseStyles = [];
- self.style.baseStyles = self.style.baseStyles.concat((new SelectedEdgeStyle0()).baseStyles);
- }
- else
- indexes.push({index : self.index, style : self.style});
-
- if (forAll)
- {
- indexes.forEach(function(index) {
- app.SetEdgeStyle(index.index, index.style);
- });
- }
- else
- {
- selectedEdges.forEach(function(edge) {
- indexes.forEach(function(index) {
- edge.setOwnStyle(index.index, index.style);
- });
- });
- }
- app.redrawGraph();
- $( this ).dialog( "close" );
- };
- dialogButtons[g_cancel] = function() {
- $( this ).dialog( "close" );
- };
-
- fillFields();
-
- $( "#SetupEdgeStyleDialog" ).dialog({
- resizable: false,
- height: "auto",
- width: "auto",
- modal: true,
- title: g_edgeDraw,
- buttons: dialogButtons,
- dialogClass: 'EdgeDialog'
- });
-
- redrawVertex();
-
- $( "#edgeFillColor" ).unbind();
- $( "#edgeStrokeColor" ).unbind();
- $( "#edgeTextColor" ).unbind();
- $( "#edgeStyle" ).unbind();
- $( "#edgeWidth" ).unbind();
- $( "#weightEdgeTextColor" ).unbind();
- $( "#weightTextPosition" ).unbind();
- $( "#edgeSelectedIndex" ).unbind();
-
- $( "#edgeFillColor" ).change(redrawVertex);
- $( "#edgeStrokeColor" ).change(redrawVertex);
- $( "#edgeTextColor" ).change(redrawVertex);
- $( "#edgeStyle" ).change(redrawVertex);
- $( "#edgeWidth" ).change(redrawVertex);
- $( "#weightEdgeTextColor" ).change(redrawVertex);
- $( "#weightTextPosition" ).change(redrawVertex);
- $( "#edgeSelectedIndex" ).change(changeIndex);
-}
-
-/**
- * Setup Background Style rename vertices.
- *
- */
-function SetupBackgroundStyle(app)
-{
- BaseHandler.apply(this, arguments);
- this.message = "";
- this.maxImageSize = 2048;
-}
-
-// inheritance.
-SetupBackgroundStyle.prototype = Object.create(BaseHandler.prototype);
-
-
-SetupBackgroundStyle.prototype.handleImportBackgroundFile = function(files, updateBackgroundCallback) {
- var graphFileToLoad = files[0];
- var re = /(?:\.([^.]+))?$/;
- var imageExtension = re.exec(graphFileToLoad.name)[1].toLowerCase();
-
- if (!(imageExtension == "png" || imageExtension == "jpg" || imageExtension == "jpeg")) {
- $("#UploadBackgroundImageError").html(g_wrongImageFormatPNGAndJPEG);
- $("#UploadBackgroundImageError").show();
- return;
- }
-
- let self = this;
- var fileReader = new FileReader();
- fileReader.onload = function(fileLoadedEvent){
- var textFromFileLoaded = fileLoadedEvent.target.result;
- var image = new Image();
- image.onload = function() {
- console.log(this.width + 'x' + this.height);
- if (this.width > self.maxImageSize || this.height > self.maxImageSize) {
- $("#UploadBackgroundImageError").html(formatString(g_wrongImageSizeP1, [self.maxImageSize]));
- $("#UploadBackgroundImageError").show();
- return;
- }
- updateBackgroundCallback(image);
- }
- image.src = 'data:image/' + imageExtension + ';base64' + textFromFileLoaded;
- ImportBackgroundImage.value = "";
- };
-
- fileReader.readAsDataURL(graphFileToLoad);
-}
-
-SetupBackgroundStyle.prototype.show = function()
-{
- var handler = this;
- var dialogButtons = {};
- var graph = this.app.graph;
- var app = this.app;
- var style = FullObjectCopy(app.backgroundCommonStyle);
-
- var fillFields = function()
- {
- $( "#backgroundColor" ).val(style.commonColor);
- $( "#backgroundTransporent" ).val(style.commonOpacity);
- }
-
- var redrawVertex = function()
- {
- style.commonColor = $( "#backgroundColor" ).val();
- style.commonOpacity = $( "#backgroundTransporent" ).val();
-
- var canvas = document.getElementById( "BackgroundPreview" );
- var context = canvas.getContext('2d');
-
- context.save();
- let bestScale = 1.0;
- if (style.image != null) {
- let wScale = canvas.width / style.image.width;
- let hScale = canvas.height / style.image.height;
- bestScale = Math.min(wScale, hScale);
- context.scale(bestScale, bestScale);
- }
- var backgroundDrawer = new BaseBackgroundDrawer(context);
- backgroundDrawer.Draw(style, canvas.width, canvas.height, new Point(0, 0), bestScale);
-
- context.restore();
-
- if (style.image != null) {
- $( "#RemoveBackgroundFile" ).show();
- } else {
- $( "#RemoveBackgroundFile" ).hide();
- }
- }
-
- var loadFile = function() {
- userAction("background_loadFromFile");
-
- if (ImportBackgroundImage) {
- ImportBackgroundImage.click();
- }
- }
-
- var updateBackgroundImage = function(image) {
- style.image = image;
- $("#UploadBackgroundImageError").hide();
- redrawVertex();
- }
-
- var clearBackgroundImage = function() {
- style.image = null;
- $("#UploadBackgroundImageError").hide();
- redrawVertex();
- }
-
- dialogButtons[g_default] =
- {
- text : g_default,
- class : "MarginLeft",
- click : function() {
-
- app.PushToStack("ChangeBackground");
-
- app.ResetBackgroundStyle();
- app.redrawGraph();
- $( this ).dialog( "close" );
- }
- };
-
- dialogButtons[g_save] = function() {
- app.PushToStack("ChangeBackground");
- app.SetBackgroundStyle(style);
- app.redrawGraph();
- $( this ).dialog( "close" );
- };
- dialogButtons[g_cancel] = function() {
- $( this ).dialog( "close" );
- };
-
- fillFields();
-
- $( "#SetupBackgroundStyleDialog" ).dialog({
- resizable: false,
- height: "auto",
- width: "auto",
- modal: true,
- title: g_backgroundStyle,
- buttons: dialogButtons,
- dialogClass: 'EdgeDialog'
- });
-
- try {
- redrawVertex();
- } catch (error) {
- console.error(error);
- }
-
- $( "#backgroundColor" ).unbind();
- $( "#backgroundTransporent" ).unbind();
- $( "#LoadBackgroundFile" ).unbind();
- $( "#ImportBackgroundImage" ).unbind();
- $( "#RemoveBackgroundFile" ).unbind();
-
- $( "#backgroundColor" ).change(redrawVertex);
- $( "#backgroundTransporent" ).change(redrawVertex);
- $( "#LoadBackgroundFile" ).click(loadFile);
- $( "#ImportBackgroundImage" ).change( function () {handler.handleImportBackgroundFile(this.files, updateBackgroundImage);});
- $( "#RemoveBackgroundFile" ).click(clearBackgroundImage);
-}
diff --git a/script/entities/edge/api/index.js b/script/entities/edge/api/index.js
new file mode 100644
index 0000000..4ac9016
--- /dev/null
+++ b/script/entities/edge/api/index.js
@@ -0,0 +1,9 @@
+
+{
+let modulDir = "entities/edge/";
+
+doInclude ([
+ include ("model/BaseEdge.js", modulDir),
+ include ("model/EdgeModel.js", modulDir)
+])
+}
\ No newline at end of file
diff --git a/script/BaseEdge.js b/script/entities/edge/model/BaseEdge.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/BaseEdge.js
rename to script/entities/edge/model/BaseEdge.js
diff --git a/script/EdgeModel.js b/script/entities/edge/model/EdgeModel.js
old mode 100755
new mode 100644
similarity index 99%
rename from script/EdgeModel.js
rename to script/entities/edge/model/EdgeModel.js
index 88a5988..c67c5cb
--- a/script/EdgeModel.js
+++ b/script/entities/edge/model/EdgeModel.js
@@ -31,7 +31,7 @@ EdgeModel.prototype.SaveToXML = function ()
{
return "model_width=\"" + this.width + "\" " +
"model_type=\"" + this.type + "\" " +
- "model_curveValue=\"" + this.curveValue + "\" "
+ "model_curveValue=\"" + this.curveValue + "\" " +
"model_default=\"" + this.default + "\" ";
}
diff --git a/script/entities/graph/api/index.js b/script/entities/graph/api/index.js
new file mode 100644
index 0000000..0f7eb79
--- /dev/null
+++ b/script/entities/graph/api/index.js
@@ -0,0 +1,11 @@
+
+{
+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)
+])
+}
\ No newline at end of file
diff --git a/script/Graph.js b/script/entities/graph/model/Graph.js
similarity index 100%
rename from script/Graph.js
rename to script/entities/graph/model/Graph.js
diff --git a/script/entities/vertex/api/index.js b/script/entities/vertex/api/index.js
new file mode 100644
index 0000000..fa308de
--- /dev/null
+++ b/script/entities/vertex/api/index.js
@@ -0,0 +1,8 @@
+{
+let modulDir = "entities/vertex/";
+
+doInclude ([
+ include ("model/BaseVertex.js", modulDir),
+ include ("model/VertexModel.js", modulDir)
+])
+}
\ No newline at end of file
diff --git a/script/BaseVertex.js b/script/entities/vertex/model/BaseVertex.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/BaseVertex.js
rename to script/entities/vertex/model/BaseVertex.js
diff --git a/script/VertexModel.js b/script/entities/vertex/model/VertexModel.js
old mode 100755
new mode 100644
similarity index 81%
rename from script/VertexModel.js
rename to script/entities/vertex/model/VertexModel.js
index 68849fd..aa19b40
--- a/script/VertexModel.js
+++ b/script/entities/vertex/model/VertexModel.js
@@ -3,7 +3,7 @@
*
*/
- const defaultVertexDiameter = 30;
+const defaultVertexDiameter = 30;
function VertexModel()
{
diff --git a/script/features/add_vertices_handler/index.js b/script/features/add_vertices_handler/index.js
new file mode 100644
index 0000000..95eebf5
--- /dev/null
+++ b/script/features/add_vertices_handler/index.js
@@ -0,0 +1,59 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Add Graph handler.
+ *
+ */
+function AddGraphHandler(app)
+{
+ this.removeStack = true;
+ BaseHandler.apply(this, arguments);
+ this.message = g_clickToAddVertex;
+ this.addContextMenu();
+}
+
+// inheritance.
+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);
+}
diff --git a/script/features/algorithm_handler/index.js b/script/features/algorithm_handler/index.js
new file mode 100644
index 0000000..222267d
--- /dev/null
+++ b/script/features/algorithm_handler/index.js
@@ -0,0 +1,131 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Algorithm Graph handler.
+ *
+ */
+function AlgorithmGraphHandler(app, algorithm)
+{
+ BaseHandler.apply(this, arguments);
+ this.algorithm = algorithm;
+ this.SaveUpText();
+
+ this.UpdateResultAndMessage();
+}
+
+// inheritance.
+AlgorithmGraphHandler.prototype = Object.create(BaseHandler.prototype);
+
+// Rest this handler.
+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);
+}
diff --git a/script/features/algorithms/api/index.js b/script/features/algorithms/api/index.js
new file mode 100644
index 0000000..3fb8875
--- /dev/null
+++ b/script/features/algorithms/api/index.js
@@ -0,0 +1,35 @@
+{
+let modulDir = "features/algorithms/";
+
+doInclude ([
+ include ("model/Algorithms.js", modulDir),
+ include ("model/BaseTraversal.js", modulDir)
+])
+
+function loadAsyncAlgorithms(onFinish) {
+ 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);
+}
+
+}
\ No newline at end of file
diff --git a/script/Algorithms.js b/script/features/algorithms/model/Algorithms.js
similarity index 96%
rename from script/Algorithms.js
rename to script/features/algorithms/model/Algorithms.js
index 76de20c..b4d3a43 100644
--- a/script/Algorithms.js
+++ b/script/features/algorithms/model/Algorithms.js
@@ -1,305 +1,305 @@
-/**
- * File for algorithms.
- *
- */
-
-// Return list of 'vertex = [connected vertices]'
-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;
-}
-
-// Global array of all algorithms.
-var g_Algorithms = [];
-var g_AlgorithmIds = [];
-
-// Call this function to register your factory algorithm.
-function RegisterAlgorithm (factory)
-{
- g_Algorithms.push(factory);
- g_AlgorithmIds.push(factory(null).getId());
-}
-
-// Base algorithm class.
-function BaseAlgorithm (graph, app)
-{
- this.graph = graph;
- this.app = app;
-}
-
-// @return name of algorithm. For now we supports only 2 locals: "ru" and "en"
-BaseAlgorithm.prototype.getName = function(local)
-{
- return "unknown_name_" + local;
-}
-
-// @return id of algorithm. Please use format: "your id"."algorithm id". Ex. "OlegSh.ConnectedComponent"
-BaseAlgorithm.prototype.getId = function()
-{
- return "unknown.unknown";
-}
-
-// @return message for user.
-BaseAlgorithm.prototype.getMessage = function(local)
-{
- return "unknown_message_" + local;
-}
-
-// calls when user select vertex.
-// @return true if you allow to select this object or false.
-BaseAlgorithm.prototype.selectVertex = function(vertex)
-{
- return false;
-}
-
-// calls when user select edge.
-// @return true if you allow to select this object or false.
-BaseAlgorithm.prototype.selectEdge = function(edge)
-{
- return false;
-}
-
-// user click to workspace.
-// @return true if you allow to deselect all
-BaseAlgorithm.prototype.deselectAll = function()
-{
- return true;
-}
-
-// get result of algorithm.
-// If result if not ready, please return null.
-// It will be called after each user action.
-// Please return true, if you done.
-BaseAlgorithm.prototype.result = function(resultCallback)
-{
- return null;
-}
-
-// If you no need to get feedback from user, return true.
-// In this case result will calls once.
-BaseAlgorithm.prototype.instance = function()
-{
- return true;
-}
-
-// @return false, if you change up text and do not want to restore it back.
-BaseAlgorithm.prototype.needRestoreUpText = function()
-{
- return true;
-}
-
-// @return true, if you change restore graph after use.
-BaseAlgorithm.prototype.wantRestore = function()
-{
- return false;
-}
-
-// calls this method if wantRestore return true.
-BaseAlgorithm.prototype.restore = function()
-{
-}
-
-// @return 0, if object is not selected, in other case return groupe of selection.
-BaseAlgorithm.prototype.getObjectSelectedGroup = function(object)
-{
- return 0;
-}
-
-// This method is called, when messages was updated on html page.
-BaseAlgorithm.prototype.messageWasChanged = function() {}
-
-// Algorithm priority in menu
-BaseAlgorithm.prototype.getPriority = function()
-{
- return 0;
-}
-
-// Algorithm support multi graph
-BaseAlgorithm.prototype.IsSupportMultiGraph = function()
-{
- return false;
-}
-
-BaseAlgorithm.prototype.getCategory = function()
-{
- return 0;
-}
-
-/**
- * Default handler.
- * Select using mouse, drag.
- *
- */
-function BaseAlgorithmEx(graph, app)
-{
- BaseAlgorithm.apply(this, arguments);
-}
-
-// inheritance.
-BaseAlgorithmEx.prototype = Object.create(BaseAlgorithm.prototype);
-
-BaseAlgorithmEx.prototype.CalculateAlgorithm = function(algorithmName, otherParams, resultCallback, ignoreSeparateNodes = false)
-{
- 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);
-
- resultCallback(pathObjects, properties, result);
- };
-
- if (this.app.isSupportEmscripten()) {
- console.log("Use Emscripten");
- var delimiter = "";
- var processData = algorithmName + delimiter + xml +
- delimiter + "report" + delimiter + "xml";
- otherParams.forEach ( (param) => processData += delimiter + param.name + delimiter + param.value);
- var res = this.app.processEmscripten(processData);
- processResult(res);
- } else {
- console.log("Use new CGI");
- 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);
- });
- }
-
- 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;
-}
-
-
+/**
+ * File for algorithms.
+ *
+ */
+
+// Return list of 'vertex = [connected vertices]'
+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;
+}
+
+// Global array of all algorithms.
+var g_Algorithms = [];
+var g_AlgorithmIds = [];
+
+// Call this function to register your factory algorithm.
+function RegisterAlgorithm (factory)
+{
+ g_Algorithms.push(factory);
+ g_AlgorithmIds.push(factory(null).getId());
+}
+
+// Base algorithm class.
+function BaseAlgorithm (graph, app)
+{
+ this.graph = graph;
+ this.app = app;
+}
+
+// @return name of algorithm. For now we supports only 2 locals: "ru" and "en"
+BaseAlgorithm.prototype.getName = function(local)
+{
+ return "unknown_name_" + local;
+}
+
+// @return id of algorithm. Please use format: "your id"."algorithm id". Ex. "OlegSh.ConnectedComponent"
+BaseAlgorithm.prototype.getId = function()
+{
+ return "unknown.unknown";
+}
+
+// @return message for user.
+BaseAlgorithm.prototype.getMessage = function(local)
+{
+ return "unknown_message_" + local;
+}
+
+// calls when user select vertex.
+// @return true if you allow to select this object or false.
+BaseAlgorithm.prototype.selectVertex = function(vertex)
+{
+ return false;
+}
+
+// calls when user select edge.
+// @return true if you allow to select this object or false.
+BaseAlgorithm.prototype.selectEdge = function(edge)
+{
+ return false;
+}
+
+// user click to workspace.
+// @return true if you allow to deselect all
+BaseAlgorithm.prototype.deselectAll = function()
+{
+ return true;
+}
+
+// get result of algorithm.
+// If result if not ready, please return null.
+// It will be called after each user action.
+// Please return true, if you done.
+BaseAlgorithm.prototype.result = function(resultCallback)
+{
+ return null;
+}
+
+// If you no need to get feedback from user, return true.
+// In this case result will calls once.
+BaseAlgorithm.prototype.instance = function()
+{
+ return true;
+}
+
+// @return false, if you change up text and do not want to restore it back.
+BaseAlgorithm.prototype.needRestoreUpText = function()
+{
+ return true;
+}
+
+// @return true, if you change restore graph after use.
+BaseAlgorithm.prototype.wantRestore = function()
+{
+ return false;
+}
+
+// calls this method if wantRestore return true.
+BaseAlgorithm.prototype.restore = function()
+{
+}
+
+// @return 0, if object is not selected, in other case return groupe of selection.
+BaseAlgorithm.prototype.getObjectSelectedGroup = function(object)
+{
+ return 0;
+}
+
+// This method is called, when messages was updated on html page.
+BaseAlgorithm.prototype.messageWasChanged = function() {}
+
+// Algorithm priority in menu
+BaseAlgorithm.prototype.getPriority = function()
+{
+ return 0;
+}
+
+// Algorithm support multi graph
+BaseAlgorithm.prototype.IsSupportMultiGraph = function()
+{
+ return false;
+}
+
+BaseAlgorithm.prototype.getCategory = function()
+{
+ return 0;
+}
+
+/**
+ * Default handler.
+ * Select using mouse, drag.
+ *
+ */
+function BaseAlgorithmEx(graph, app)
+{
+ BaseAlgorithm.apply(this, arguments);
+}
+
+// inheritance.
+BaseAlgorithmEx.prototype = Object.create(BaseAlgorithm.prototype);
+
+BaseAlgorithmEx.prototype.CalculateAlgorithm = function(algorithmName, otherParams, resultCallback, ignoreSeparateNodes = false)
+{
+ 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);
+
+ resultCallback(pathObjects, properties, result);
+ };
+
+ if (this.app.isSupportEmscripten()) {
+ console.log("Use Emscripten");
+ var delimiter = "";
+ var processData = algorithmName + delimiter + xml +
+ delimiter + "report" + delimiter + "xml";
+ otherParams.forEach ( (param) => processData += delimiter + param.name + delimiter + param.value);
+ var res = this.app.processEmscripten(processData);
+ processResult(res);
+ } else {
+ console.log("Use new CGI");
+ 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);
+ });
+ }
+
+ 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;
+}
+
+
diff --git a/script/BaseTraversal.js b/script/features/algorithms/model/BaseTraversal.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/BaseTraversal.js
rename to script/features/algorithms/model/BaseTraversal.js
diff --git a/script/plugins/BFS.js b/script/features/algorithms/model/plugins/BFS.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/BFS.js
rename to script/features/algorithms/model/plugins/BFS.js
diff --git a/script/plugins/Coloring.js b/script/features/algorithms/model/plugins/Coloring.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/Coloring.js
rename to script/features/algorithms/model/plugins/Coloring.js
diff --git a/script/plugins/ConnectedComponent.js b/script/features/algorithms/model/plugins/ConnectedComponent.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/ConnectedComponent.js
rename to script/features/algorithms/model/plugins/ConnectedComponent.js
diff --git a/script/plugins/DFS.js b/script/features/algorithms/model/plugins/DFS.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/DFS.js
rename to script/features/algorithms/model/plugins/DFS.js
diff --git a/script/plugins/EulerianLoop.js b/script/features/algorithms/model/plugins/EulerianLoop.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/EulerianLoop.js
rename to script/features/algorithms/model/plugins/EulerianLoop.js
diff --git a/script/plugins/EulerianPath.js b/script/features/algorithms/model/plugins/EulerianPath.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/EulerianPath.js
rename to script/features/algorithms/model/plugins/EulerianPath.js
diff --git a/script/plugins/FindAllPatches.js b/script/features/algorithms/model/plugins/FindAllPatches.js
similarity index 100%
rename from script/plugins/FindAllPatches.js
rename to script/features/algorithms/model/plugins/FindAllPatches.js
diff --git a/script/plugins/FindLongestPath.js b/script/features/algorithms/model/plugins/FindLongestPath.js
similarity index 100%
rename from script/plugins/FindLongestPath.js
rename to script/features/algorithms/model/plugins/FindLongestPath.js
diff --git a/script/plugins/FindShortPatchsFromOne.js b/script/features/algorithms/model/plugins/FindShortPatchsFromOne.js
similarity index 100%
rename from script/plugins/FindShortPatchsFromOne.js
rename to script/features/algorithms/model/plugins/FindShortPatchsFromOne.js
diff --git a/script/plugins/Floid.js b/script/features/algorithms/model/plugins/Floid.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/Floid.js
rename to script/features/algorithms/model/plugins/Floid.js
diff --git a/script/plugins/GraphReorder.js b/script/features/algorithms/model/plugins/GraphReorder.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/GraphReorder.js
rename to script/features/algorithms/model/plugins/GraphReorder.js
diff --git a/script/plugins/HamiltonianLoop.js b/script/features/algorithms/model/plugins/HamiltonianLoop.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/HamiltonianLoop.js
rename to script/features/algorithms/model/plugins/HamiltonianLoop.js
diff --git a/script/plugins/HamiltonianPath.js b/script/features/algorithms/model/plugins/HamiltonianPath.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/HamiltonianPath.js
rename to script/features/algorithms/model/plugins/HamiltonianPath.js
diff --git a/script/plugins/IsomorphismCheck.js b/script/features/algorithms/model/plugins/IsomorphismCheck.js
similarity index 100%
rename from script/plugins/IsomorphismCheck.js
rename to script/features/algorithms/model/plugins/IsomorphismCheck.js
diff --git a/script/plugins/MaxClique.js b/script/features/algorithms/model/plugins/MaxClique.js
similarity index 100%
rename from script/plugins/MaxClique.js
rename to script/features/algorithms/model/plugins/MaxClique.js
diff --git a/script/plugins/MaxFlow.js b/script/features/algorithms/model/plugins/MaxFlow.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/MaxFlow.js
rename to script/features/algorithms/model/plugins/MaxFlow.js
diff --git a/script/plugins/MinimumSpanningTree.js b/script/features/algorithms/model/plugins/MinimumSpanningTree.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/MinimumSpanningTree.js
rename to script/features/algorithms/model/plugins/MinimumSpanningTree.js
diff --git a/script/plugins/ModernGraphStyle.js b/script/features/algorithms/model/plugins/ModernGraphStyle.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/ModernGraphStyle.js
rename to script/features/algorithms/model/plugins/ModernGraphStyle.js
diff --git a/script/plugins/RadiusAndDiameter.js b/script/features/algorithms/model/plugins/RadiusAndDiameter.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/RadiusAndDiameter.js
rename to script/features/algorithms/model/plugins/RadiusAndDiameter.js
diff --git a/script/plugins/ShortestPath.js b/script/features/algorithms/model/plugins/ShortestPath.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/ShortestPath.js
rename to script/features/algorithms/model/plugins/ShortestPath.js
diff --git a/script/plugins/VerticesDegree.js b/script/features/algorithms/model/plugins/VerticesDegree.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/plugins/VerticesDegree.js
rename to script/features/algorithms/model/plugins/VerticesDegree.js
diff --git a/script/plugins/disable/NeedAlgorithm.js b/script/features/algorithms/model/plugins/disable/NeedAlgorithm.js
similarity index 100%
rename from script/plugins/disable/NeedAlgorithm.js
rename to script/features/algorithms/model/plugins/disable/NeedAlgorithm.js
diff --git a/script/features/base_handler/index.js b/script/features/base_handler/index.js
new file mode 100644
index 0000000..7fe5224
--- /dev/null
+++ b/script/features/base_handler/index.js
@@ -0,0 +1,457 @@
+/**
+ * Base Handler.
+ *
+ */
+function BaseHandler(app)
+{
+ this.app = app;
+ this.app.setRenderPath([]);
+
+ if (this.removeStack) {
+ this.removeContextMenu();
+ }
+ this.contextMenuObject = null;
+ this.contextMenuPoint = null;
+ //this.app.ClearUndoStack();
+}
+
+// Need redraw or nor.
+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)
+{
+ // Selected Graph.
+ var res = null;
+ for (var i = 0; i < this.app.graph.vertices.length; i ++)
+ {
+ if (this.app.graph.vertices[i].HitTest(pos))
+ {
+ // Select last of them.
+ res = this.app.graph.vertices[i];
+ }
+ }
+
+
+ return res;
+}
+
+BaseHandler.prototype.GetSelectedArc = function(pos)
+{
+ // Selected Arc.
+ 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)))
+ return edge;
+ }
+
+ return null;
+}
+
+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 = "" +
+ "";
+}
+
+BaseHandler.prototype.GetSelect2VertexMenu = function()
+{
+ return "" +
+ this.GetSelectVertexMenu("Vertex1") + " → " + this.GetSelectVertexMenu("Vertex2") + "";
+}
+
+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);
+ //handler.AddNewEdge(selectedObject, true);
+ $( this ).dialog( "close" );
+ };
+ dialogButtons[g_notOrintEdge] = function() {
+ handler.app.PushToStack("Connect");
+ addEdgeCallBack(firstVertex, secondVertex, false);
+ //handler.AddNewEdge(selectedObject, false);
+ $( this ).dialog( "close" );
+ };
+
+ var edgePresets = this.app.GetEdgePresets();
+ var presetsStr = "" + g_DefaultWeightPreset + "";
+
+ for(var i = 0; i < edgePresets.length; i ++)
+ {
+ var edgePreset = edgePresets[i];
+ presetsStr += "" + edgePreset + "";
+ }
+ 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;
+ });
+
+ // Focues weight
+ 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 = "" + g_DefaultWeightPreset + "";
+
+ for(var i = 0; i < edgePresets.length; i ++)
+ {
+ var edgePreset = edgePresets[i];
+ presetsStr += "" + edgePreset + "";
+ }
+ 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;
+ });
+ }
+ });
+}
diff --git a/script/features/connect_vertices_handler/index.js b/script/features/connect_vertices_handler/index.js
new file mode 100644
index 0000000..198c994
--- /dev/null
+++ b/script/features/connect_vertices_handler/index.js
@@ -0,0 +1,226 @@
+
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Connection Graph handler.
+ *
+ */
+function ConnectionGraphHandler(app)
+{
+ this.removeStack = true;
+ BaseHandler.apply(this, arguments);
+ this.SelectFirst();
+ this.addContextMenu();
+}
+
+// inheritance.
+ConnectionGraphHandler.prototype = Object.create(BaseHandler.prototype);
+// First selected.
+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 ""
+ + " "
+ + ""
+ + "
" + baseMessage;
+}
+
+ConnectionGraphHandler.checkUseDefaultEdge = function (elem, app)
+{
+ app.setUseDefaultEdge(elem.checked);
+ app.updateMessage();
+};
+
+ConnectionGraphHandler.prototype.GetUseDefaultEdgeCheckBox = function() {
+ if (!this.app.hasDefaultEdge()) {
+ return "";
+ }
+
+ return " " +
+ "" +
+ " " +
+ "
";
+}
+
+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());
+}
diff --git a/script/features/default_handler/index.js b/script/features/default_handler/index.js
new file mode 100644
index 0000000..29b8ffa
--- /dev/null
+++ b/script/features/default_handler/index.js
@@ -0,0 +1,431 @@
+
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Default handler.
+ * Select using mouse, drag.
+ *
+ */
+function DefaultHandler(app)
+{
+ this.removeStack = true;
+ BaseHandler.apply(this, arguments);
+ this.message = g_textsSelectAndMove + " " + g_selectGroupText + "" + " " + g_useContextMenuText + "";
+ 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();
+}
+
+// inheritance.
+DefaultHandler.prototype = Object.create(BaseHandler.prototype);
+// Is pressed
+DefaultHandler.prototype.pressed = false;
+// Curve change value.
+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)
+ {
+ // Rect select.
+ 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
+ {
+ // Move work space
+ 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 + " " + g_selectGroupText + "" + " " + g_useContextMenuText + "";
+ 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
+ + ""
+ + ""
+ + ""
+ + "
";
+
+ 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
+ + ""
+ + " " + g_curveEdge + " "
+ + " "
+ + ""
+ + ""
+ + ""
+ + "
";
+
+ 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 + " " + g_selectGroupText + "";
+
+ 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 + "";
+
+ this.message = this.message
+ + "    "
+ + ""
+
+ this.message = this.message
+ + "     "
+ + ""
+ + "";
+
+ var handler = this;
+ $('#message').unbind();
+
+ $('#message').on('click', '#DublicateSelected', function(){
+ handler.app.PushToStack("DublicateSelection");
+
+ userAction("GroupSelected.Dublicate");
+
+ var newSelected = [];
+ var copyVertex = {};
+
+ // Copy vertex
+ 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;
+ }
+ }
+
+ // Copy edge
+ 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 + " " + g_selectGroupText + "";
+ });
+
+ 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]);
+ }
+
+ // Selected Arc.
+ 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);
+ }
+}
diff --git a/script/features/delete_objects_handler/index.js b/script/features/delete_objects_handler/index.js
new file mode 100644
index 0000000..db6ceea
--- /dev/null
+++ b/script/features/delete_objects_handler/index.js
@@ -0,0 +1,52 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Delete Graph handler.
+ *
+ */
+function DeleteGraphHandler(app)
+{
+ this.removeStack = true;
+ BaseHandler.apply(this, arguments);
+ this.message = g_selectObjectToDelete;
+ this.addContextMenu();
+}
+
+// inheritance.
+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;
+}
+
+/**
+ * Delete Graph handler.
+ *
+ */
+function DeleteAllHandler(app)
+{
+ BaseHandler.apply(this, arguments);
+}
+
+// inheritance.
+DeleteAllHandler.prototype = Object.create(BaseHandler.prototype);
+
+DeleteAllHandler.prototype.clear = function()
+{
+ this.app.PushToStack("DeleteAll");
+
+ // Selected Graph.
+ this.app.graph = new Graph();
+ this.app.savedGraphName = "";
+ this.needRedraw = true;
+}
diff --git a/script/features/draw_graph/api/index.js b/script/features/draw_graph/api/index.js
new file mode 100644
index 0000000..2b94a2c
--- /dev/null
+++ b/script/features/draw_graph/api/index.js
@@ -0,0 +1,10 @@
+{
+let modulDir = "features/draw_graph/";
+
+doInclude ([
+ include ("model/BaseBackgroundDrawer.js", modulDir),
+ include ("model/BaseEdgeDrawer.js", modulDir),
+ include ("model/BaseVertexDrawer.js", modulDir)
+])
+
+}
\ No newline at end of file
diff --git a/script/BaseBackgroundDrawer.js b/script/features/draw_graph/model/BaseBackgroundDrawer.js
similarity index 100%
rename from script/BaseBackgroundDrawer.js
rename to script/features/draw_graph/model/BaseBackgroundDrawer.js
diff --git a/script/BaseEdgeDrawer.js b/script/features/draw_graph/model/BaseEdgeDrawer.js
similarity index 100%
rename from script/BaseEdgeDrawer.js
rename to script/features/draw_graph/model/BaseEdgeDrawer.js
diff --git a/script/BaseVertexDrawer.js b/script/features/draw_graph/model/BaseVertexDrawer.js
similarity index 100%
rename from script/BaseVertexDrawer.js
rename to script/features/draw_graph/model/BaseVertexDrawer.js
diff --git a/script/EnumVertices.js b/script/features/enum_vertices/EnumVertices.js
old mode 100755
new mode 100644
similarity index 95%
rename from script/EnumVertices.js
rename to script/features/enum_vertices/EnumVertices.js
index 7395a98..bb2ac75
--- a/script/EnumVertices.js
+++ b/script/features/enum_vertices/EnumVertices.js
@@ -1,201 +1,201 @@
-/*
- Classes for creating text for vertices.
-*/
-
-
-/**
- * Base Enum Vertices.
- *
- */
-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;
-}
-
-
-// inheritance.
-TextEnumTitle.prototype = Object.create(BaseEnumVertices.prototype);
-
-TextEnumTitle.prototype.GetVertexText = function(id)
-{
- return this.title;
-}
-
-
-
-/**
- * Text Enum
- *
- */
-function TextEnumVertices(app)
-{
- BaseEnumVertices.apply(this, arguments);
- this.pattern = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-}
-
-
-// inheritance.
-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";
-}
-
-/**
- * Text Enum
- *
- */
-function TextEnumVerticesCyr(app)
-{
- TextEnumVertices.apply(this, arguments);
- this.pattern = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
-}
-
-
-// inheritance.
-TextEnumVerticesCyr.prototype = Object.create(TextEnumVertices.prototype);
-
-TextEnumVerticesCyr.prototype.GetText = function()
-{
- return "А, Б, ... Я";
-}
-
-TextEnumVerticesCyr.prototype.GetValue = function()
-{
- return "Cyrillic";
-}
-
-
-/**
- * Text Enum
- *
- */
-function TextEnumVerticesGreek(app)
-{
- TextEnumVertices.apply(this, arguments);
- this.pattern = "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ";
-}
-
-
-// inheritance.
-TextEnumVerticesGreek.prototype = Object.create(TextEnumVertices.prototype);
-
-TextEnumVerticesGreek.prototype.GetText = function()
-{
- return "Α, Β, ... Ω";
-}
-
-TextEnumVerticesGreek.prototype.GetValue = function()
-{
- return "Greek";
-}
-
-/**
- * Text Enum
- *
- */
-function TextEnumVerticesCustom(app)
-{
- BaseEnumVertices.apply(this, arguments);
- this.pattern = "";
-}
-
-
-
-// inheritance.
-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();
- }
- });
-}
+/*
+ Classes for creating text for vertices.
+*/
+
+
+/**
+ * Base Enum Vertices.
+ *
+ */
+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;
+}
+
+
+// inheritance.
+TextEnumTitle.prototype = Object.create(BaseEnumVertices.prototype);
+
+TextEnumTitle.prototype.GetVertexText = function(id)
+{
+ return this.title;
+}
+
+
+
+/**
+ * Text Enum
+ *
+ */
+function TextEnumVertices(app)
+{
+ BaseEnumVertices.apply(this, arguments);
+ this.pattern = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+}
+
+
+// inheritance.
+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";
+}
+
+/**
+ * Text Enum
+ *
+ */
+function TextEnumVerticesCyr(app)
+{
+ TextEnumVertices.apply(this, arguments);
+ this.pattern = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
+}
+
+
+// inheritance.
+TextEnumVerticesCyr.prototype = Object.create(TextEnumVertices.prototype);
+
+TextEnumVerticesCyr.prototype.GetText = function()
+{
+ return "А, Б, ... Я";
+}
+
+TextEnumVerticesCyr.prototype.GetValue = function()
+{
+ return "Cyrillic";
+}
+
+
+/**
+ * Text Enum
+ *
+ */
+function TextEnumVerticesGreek(app)
+{
+ TextEnumVertices.apply(this, arguments);
+ this.pattern = "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ";
+}
+
+
+// inheritance.
+TextEnumVerticesGreek.prototype = Object.create(TextEnumVertices.prototype);
+
+TextEnumVerticesGreek.prototype.GetText = function()
+{
+ return "Α, Β, ... Ω";
+}
+
+TextEnumVerticesGreek.prototype.GetValue = function()
+{
+ return "Greek";
+}
+
+/**
+ * Text Enum
+ *
+ */
+function TextEnumVerticesCustom(app)
+{
+ BaseEnumVertices.apply(this, arguments);
+ this.pattern = "";
+}
+
+
+
+// inheritance.
+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();
+ }
+ });
+}
diff --git a/script/Graphoffline.Emscripten.js b/script/features/graphoffline/Graphoffline.Emscripten.js
similarity index 100%
rename from script/Graphoffline.Emscripten.js
rename to script/features/graphoffline/Graphoffline.Emscripten.js
diff --git a/script/Graphoffline.Emscripten.wasm b/script/features/graphoffline/Graphoffline.Emscripten.wasm
similarity index 100%
rename from script/Graphoffline.Emscripten.wasm
rename to script/features/graphoffline/Graphoffline.Emscripten.wasm
diff --git a/script/features/group_rename_handler/index.js b/script/features/group_rename_handler/index.js
new file mode 100644
index 0000000..9189a12
--- /dev/null
+++ b/script/features/group_rename_handler/index.js
@@ -0,0 +1,61 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Groupe rename vertices.
+ *
+ */
+function GroupRenameVertices(app)
+{
+ BaseHandler.apply(this, arguments);
+ this.message = "";
+}
+
+// inheritance.
+GroupRenameVertices.prototype = Object.create(BaseHandler.prototype);
+// First selected.
+GroupRenameVertices.prototype.firstObject = null;
+// Path
+GroupRenameVertices.prototype.pathObjects = null;
+
+GroupRenameVertices.prototype.show = function()
+{
+ var handler = this;
+ var dialogButtons = {};
+ var graph = this.app.graph;
+ var app = this.app;
+
+ dialogButtons[g_save] = function() {
+ app.PushToStack("Rename");
+
+ var titlesList = $( "#VertextTitleList" ).val().split('\n');
+ for (i = 0; i < Math.min(graph.vertices.length, titlesList.length); i ++)
+ {
+ graph.vertices[i].mainText = titlesList[i];
+ }
+ app.redrawGraph();
+ $( this ).dialog( "close" );
+ };
+ dialogButtons[g_cancel] = function() {
+ $( this ).dialog( "close" );
+ };
+
+ var titleList = "";
+ for (i = 0; i < graph.vertices.length; i ++)
+ {
+ titleList = titleList + graph.vertices[i].mainText + "\n";
+ }
+
+ $( "#VertextTitleList" ).val(titleList);
+
+ $( "#GroupRenameDialog" ).dialog({
+ resizable: false,
+ height: "auto",
+ width: "auto",
+ modal: true,
+ title: g_groupRename,
+ buttons: dialogButtons,
+ dialogClass: 'EdgeDialog'
+ });
+}
diff --git a/script/features/saved_graph_handler/index.js b/script/features/saved_graph_handler/index.js
new file mode 100644
index 0000000..891cf9f
--- /dev/null
+++ b/script/features/saved_graph_handler/index.js
@@ -0,0 +1,52 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Save dialog Graph handler.
+ *
+ */
+function SavedDialogGraphHandler(app)
+{
+ BaseHandler.apply(this, arguments);
+ this.message = "";
+}
+
+// inheritance.
+SavedDialogGraphHandler.prototype = Object.create(BaseHandler.prototype);
+// First selected.
+SavedDialogGraphHandler.prototype.firstObject = null;
+// Path
+SavedDialogGraphHandler.prototype.pathObjects = null;
+// Objects.
+SavedDialogGraphHandler.prototype.objects = null;
+
+SavedDialogGraphHandler.prototype.show = function(object)
+{
+ this.app.SaveGraphOnDisk();
+
+ var dialogButtons = {};
+
+ dialogButtons[g_close] = function() {
+ $( this ).dialog( "close" );
+ };
+
+ document.getElementById('GraphName').value = "http://" + window.location.host + window.location.pathname +
+ "?graph=" + this.app.GetGraphName();
+
+ document.getElementById('GraphName').select();
+
+ document.getElementById("ShareSavedGraph").innerHTML =
+ document.getElementById("ShareSavedGraph").innerHTML.replace(/graph=([A-Za-z]*)/g, "graph=" + this.app.GetGraphName());
+
+ $( "#saveDialog" ).dialog({
+ resizable: false,
+ height: "auto",
+ width: "auto",
+ modal: true,
+ title: g_save_dialog,
+ buttons: dialogButtons,
+ dialogClass: 'EdgeDialog'
+ });
+
+}
diff --git a/script/features/saved_graph_image_handler/index.js b/script/features/saved_graph_image_handler/index.js
new file mode 100644
index 0000000..be82aea
--- /dev/null
+++ b/script/features/saved_graph_image_handler/index.js
@@ -0,0 +1,94 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Save dialog Graph handler.
+ *
+ */
+function SavedDialogGraphImageHandler(app)
+{
+ BaseHandler.apply(this, arguments);
+ this.message = "";
+ this.imageName = "";
+}
+
+// inheritance.
+SavedDialogGraphImageHandler.prototype = Object.create(BaseHandler.prototype);
+// First selected.
+SavedDialogGraphImageHandler.prototype.firstObject = null;
+// Path
+SavedDialogGraphImageHandler.prototype.pathObjects = null;
+// Objects.
+SavedDialogGraphImageHandler.prototype.objects = null;
+
+SavedDialogGraphImageHandler.prototype.showDialogCallback = function (imageExtension)
+{
+ var dialogButtons = {};
+
+ dialogButtons[g_close] = function() {
+ $( this ).dialog( "close" );
+ };
+
+ var fileLocation = "tmp/saved/" + this.imageName.substr(0, 2) + "/"+ this.imageName + "." + imageExtension
+
+ document.getElementById("showSavedImageGraph").src = "/" + fileLocation;
+ document.getElementById("showSavedImageGraphRef").href = "/" + fileLocation;
+ //document.getElementById("showSavedImageGraph").src = document.getElementById("showSavedImageGraph").src.replace(/tmp\/saved\/([A-Za-z]*)\/([A-Za-z]*).png/g, fileLocation);
+ document.getElementById("ShareSavedImageGraph").innerHTML =
+ document.getElementById("ShareSavedImageGraph").innerHTML.replace(/tmp\/saved\/([A-Za-z]*)\/([A-Za-z]*).png/g, fileLocation);
+
+ document.getElementById("SaveImageLinks").innerHTML =
+ document.getElementById("SaveImageLinks").innerHTML.replace(/tmp\/saved\/([A-Za-z]*)\/([A-Za-z]*).png/g, fileLocation);
+
+ $( "#saveImageDialog" ).dialog({
+ resizable: false,
+ height: "auto",
+ width: "auto",
+ modal: true,
+ title: g_save_image_dialog,
+ buttons: dialogButtons,
+ dialogClass: 'EdgeDialog'
+ });
+
+}
+
+SavedDialogGraphImageHandler.prototype.showWorkspace = function()
+{
+ var object = this;
+ var callback = function() {
+ object.showDialogCallback("png");
+ };
+
+ this.imageName = this.app.SaveGraphImageOnDisk(callback);
+}
+
+SavedDialogGraphImageHandler.prototype.showFullgraph = function()
+{
+ var object = this;
+ var callback = function() {
+ object.showDialogCallback("png");
+ };
+
+ this.imageName = this.app.SaveFullGraphImageOnDisk(callback, false);
+}
+
+SavedDialogGraphImageHandler.prototype.showPrint = function()
+{
+ var object = this;
+ var callback = function() {
+ object.showDialogCallback("png");
+ };
+
+ this.imageName = this.app.SaveFullGraphImageOnDisk(callback, true);
+}
+
+SavedDialogGraphImageHandler.prototype.showSvg = function()
+{
+ var object = this;
+ var callback = function() {
+ object.showDialogCallback("svg");
+ };
+
+ this.imageName = this.app.SaveSVGGraphOnDisk(callback);
+}
diff --git a/script/features/serialization/api/index.js b/script/features/serialization/api/index.js
new file mode 100644
index 0000000..a41b9e0
--- /dev/null
+++ b/script/features/serialization/api/index.js
@@ -0,0 +1,8 @@
+{
+let modulDir = "features/serialization/";
+
+doInclude ([
+ include ("model/GraphMLCreator.js", modulDir)
+])
+
+}
\ No newline at end of file
diff --git a/script/GraphMLCreator.js b/script/features/serialization/model/GraphMLCreator.js
similarity index 100%
rename from script/GraphMLCreator.js
rename to script/features/serialization/model/GraphMLCreator.js
diff --git a/script/features/setup_background_style/index.js b/script/features/setup_background_style/index.js
new file mode 100644
index 0000000..3511885
--- /dev/null
+++ b/script/features/setup_background_style/index.js
@@ -0,0 +1,167 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Setup Background Style rename vertices.
+ *
+ */
+function SetupBackgroundStyle(app)
+{
+ BaseHandler.apply(this, arguments);
+ this.message = "";
+ this.maxImageSize = 2048;
+}
+
+// inheritance.
+SetupBackgroundStyle.prototype = Object.create(BaseHandler.prototype);
+
+
+SetupBackgroundStyle.prototype.handleImportBackgroundFile = function(files, updateBackgroundCallback) {
+ var graphFileToLoad = files[0];
+ var re = /(?:\.([^.]+))?$/;
+ var imageExtension = re.exec(graphFileToLoad.name)[1].toLowerCase();
+
+ if (!(imageExtension == "png" || imageExtension == "jpg" || imageExtension == "jpeg")) {
+ $("#UploadBackgroundImageError").html(g_wrongImageFormatPNGAndJPEG);
+ $("#UploadBackgroundImageError").show();
+ return;
+ }
+
+ let self = this;
+ var fileReader = new FileReader();
+ fileReader.onload = function(fileLoadedEvent){
+ var textFromFileLoaded = fileLoadedEvent.target.result;
+ var image = new Image();
+ image.onload = function() {
+ console.log(this.width + 'x' + this.height);
+ if (this.width > self.maxImageSize || this.height > self.maxImageSize) {
+ $("#UploadBackgroundImageError").html(formatString(g_wrongImageSizeP1, [self.maxImageSize]));
+ $("#UploadBackgroundImageError").show();
+ return;
+ }
+ updateBackgroundCallback(image);
+ }
+ image.src = 'data:image/' + imageExtension + ';base64' + textFromFileLoaded;
+ ImportBackgroundImage.value = "";
+ };
+
+ fileReader.readAsDataURL(graphFileToLoad);
+}
+
+SetupBackgroundStyle.prototype.show = function()
+{
+ var handler = this;
+ var dialogButtons = {};
+ var graph = this.app.graph;
+ var app = this.app;
+ var style = FullObjectCopy(app.backgroundCommonStyle);
+
+ var fillFields = function()
+ {
+ $( "#backgroundColor" ).val(style.commonColor);
+ $( "#backgroundTransporent" ).val(style.commonOpacity);
+ }
+
+ var redrawVertex = function()
+ {
+ style.commonColor = $( "#backgroundColor" ).val();
+ style.commonOpacity = $( "#backgroundTransporent" ).val();
+
+ var canvas = document.getElementById( "BackgroundPreview" );
+ var context = canvas.getContext('2d');
+
+ context.save();
+ let bestScale = 1.0;
+ if (style.image != null) {
+ let wScale = canvas.width / style.image.width;
+ let hScale = canvas.height / style.image.height;
+ bestScale = Math.min(wScale, hScale);
+ context.scale(bestScale, bestScale);
+ }
+ var backgroundDrawer = new BaseBackgroundDrawer(context);
+ backgroundDrawer.Draw(style, canvas.width, canvas.height, new Point(0, 0), bestScale);
+
+ context.restore();
+
+ if (style.image != null) {
+ $( "#RemoveBackgroundFile" ).show();
+ } else {
+ $( "#RemoveBackgroundFile" ).hide();
+ }
+ }
+
+ var loadFile = function() {
+ userAction("background_loadFromFile");
+
+ if (ImportBackgroundImage) {
+ ImportBackgroundImage.click();
+ }
+ }
+
+ var updateBackgroundImage = function(image) {
+ style.image = image;
+ $("#UploadBackgroundImageError").hide();
+ redrawVertex();
+ }
+
+ var clearBackgroundImage = function() {
+ style.image = null;
+ $("#UploadBackgroundImageError").hide();
+ redrawVertex();
+ }
+
+ dialogButtons[g_default] =
+ {
+ text : g_default,
+ class : "MarginLeft",
+ click : function() {
+
+ app.PushToStack("ChangeBackground");
+
+ app.ResetBackgroundStyle();
+ app.redrawGraph();
+ $( this ).dialog( "close" );
+ }
+ };
+
+ dialogButtons[g_save] = function() {
+ app.PushToStack("ChangeBackground");
+ app.SetBackgroundStyle(style);
+ app.redrawGraph();
+ $( this ).dialog( "close" );
+ };
+ dialogButtons[g_cancel] = function() {
+ $( this ).dialog( "close" );
+ };
+
+ fillFields();
+
+ $( "#SetupBackgroundStyleDialog" ).dialog({
+ resizable: false,
+ height: "auto",
+ width: "auto",
+ modal: true,
+ title: g_backgroundStyle,
+ buttons: dialogButtons,
+ dialogClass: 'EdgeDialog'
+ });
+
+ try {
+ redrawVertex();
+ } catch (error) {
+ console.error(error);
+ }
+
+ $( "#backgroundColor" ).unbind();
+ $( "#backgroundTransporent" ).unbind();
+ $( "#LoadBackgroundFile" ).unbind();
+ $( "#ImportBackgroundImage" ).unbind();
+ $( "#RemoveBackgroundFile" ).unbind();
+
+ $( "#backgroundColor" ).change(redrawVertex);
+ $( "#backgroundTransporent" ).change(redrawVertex);
+ $( "#LoadBackgroundFile" ).click(loadFile);
+ $( "#ImportBackgroundImage" ).change( function () {handler.handleImportBackgroundFile(this.files, updateBackgroundImage);});
+ $( "#RemoveBackgroundFile" ).click(clearBackgroundImage);
+}
diff --git a/script/features/setup_edge_style/index.js b/script/features/setup_edge_style/index.js
new file mode 100644
index 0000000..e324464
--- /dev/null
+++ b/script/features/setup_edge_style/index.js
@@ -0,0 +1,295 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Setup Vertex Style rename vertices.
+ *
+ */
+function SetupEdgeStyle(app)
+{
+ BaseHandler.apply(this, arguments);
+ this.message = "";
+}
+
+// inheritance.
+SetupEdgeStyle.prototype = Object.create(BaseHandler.prototype);
+
+SetupEdgeStyle.prototype.show = function(index, selectedEdges)
+{
+ var handler = this;
+ var dialogButtons = {};
+ var graph = this.app.graph;
+ var app = this.app;
+ this.forAll = selectedEdges == null;
+ var forAll = this.forAll;
+
+ var self = this;
+
+ var applyIndex = function(index)
+ {
+ self.index = index;
+ var originStyle = (self.index == 0 ? app.edgeCommonStyle : app.edgeSelectedStyles[self.index - 1]);
+ if (!forAll)
+ {
+ originStyle = selectedEdges[0].getStyleFor(self.index);
+ }
+ self.style = FullObjectCopy(originStyle);
+ }
+
+ applyIndex(index);
+
+ var fillFields = function()
+ {
+ var fullStyle = self.style.GetStyle({}, forAll ? undefined : selectedEdges[0]);
+
+ $( "#edgeFillColor" ).val(fullStyle.fillStyle);
+ $( "#edgeStrokeColor" ).val(fullStyle.strokeStyle);
+ $( "#edgeTextColor" ).val(fullStyle.weightText);
+ $( "#edgeStyle" ).val(fullStyle.lineDash);
+ $( "#edgeWidth" ).val(forAll ? app.GetDefaultEdgeWidth() : selectedEdges[0].model.width);
+
+ $( "#weightEdgeTextColor" ).val(fullStyle.additionalTextColor);
+ $( "#weightTextPosition" ).val(fullStyle.weightPosition);
+
+ if (self.index > 0 || self.index == "all")
+ {
+ $( "#EdgeSelectedIndexForm" ).show();
+ $( "#edgeSelectedIndex" ).val(self.index);
+ }
+ else
+ {
+ $( "#EdgeSelectedIndexForm" ).hide();
+ }
+
+ // Fill color presets.
+ var stylesArray = [];
+ stylesArray.push(app.edgeCommonStyle);
+
+ for (i = 0; i < app.edgeSelectedStyles.length; i ++)
+ stylesArray.push(app.edgeSelectedStyles[i]);
+
+ var colorSet = {};
+ for (i = 0; i < stylesArray.length; i ++)
+ {
+ var style = stylesArray[i];
+ if (style.hasOwnProperty('strokeStyle'))
+ colorSet[style.strokeStyle] = 1;
+ if (style.hasOwnProperty('fillStyle'))
+ colorSet[style.fillStyle] = 1;
+ if (style.hasOwnProperty('additionalTextColor'))
+ colorSet[style.additionalTextColor] = 1;
+ }
+
+ $("#edgeFillColorPreset").find('option').remove();
+ $("#weightEdgeTextColorPreset").find('option').remove();
+ $("#edgeTextColorPreset").find('option').remove();
+ $("#edgeStrokeColorPreset").find('option').remove();
+ for (const property in colorSet)
+ {
+ $("#edgeFillColorPreset").append(new Option(property));
+ $("#weightEdgeTextColorPreset").append(new Option(property));
+ $("#edgeTextColorPreset").append(new Option(property));
+ $("#edgeStrokeColorPreset").append(new Option(property));
+ }
+ }
+
+ var redrawVertex = function()
+ {
+ var fullStyle = self.style.GetStyle({}, forAll ? undefined : selectedEdges[0]);
+
+ if (fullStyle.fillStyle != $( "#edgeFillColor" ).val())
+ self.style.fillStyle = $( "#edgeFillColor" ).val();
+
+ if (fullStyle.strokeStyle != $( "#edgeStrokeColor" ).val())
+ self.style.strokeStyle = $( "#edgeStrokeColor" ).val();
+
+ if (fullStyle.weightText != $( "#edgeTextColor" ).val())
+ self.style.weightText = $( "#edgeTextColor" ).val();
+
+ if (fullStyle.lineDash != $( "#edgeStyle" ).val())
+ self.style.lineDash = $( "#edgeStyle" ).val();
+
+ if (fullStyle.additionalTextColor != $( "#weightEdgeTextColor" ).val())
+ self.style.additionalTextColor = $( "#weightEdgeTextColor" ).val();
+
+ if (fullStyle.weightPosition != $( "#weightTextPosition" ).val())
+ self.style.weightPosition = $( "#weightTextPosition" ).val();
+
+ var edgeWidth = parseInt($( "#edgeWidth" ).val());
+
+ var canvas = document.getElementById( "EdgePreview" );
+ var context = canvas.getContext('2d');
+
+ context.save();
+
+ var backgroundDrawer = new BaseBackgroundDrawer(context);
+ backgroundDrawer.Draw(app.backgroundCommonStyle, canvas.width, canvas.height, new Point(0, 0), 1.0);
+
+ var graphDrawer = new BaseEdgeDrawer(context);
+ var baseVertex1 = new BaseVertex(0, canvas.height / 2, new BaseEnumVertices(this));
+ var baseVertex2 = new BaseVertex(canvas.width, canvas.height / 2, new BaseEnumVertices(this));
+
+ baseVertex1.currentStyle = baseVertex1.getStyleFor(0);
+ baseVertex2.currentStyle = baseVertex2.getStyleFor(0);
+
+ var baseEdge = new BaseEdge(baseVertex1, baseVertex2, true, 10, "Text");
+
+ if (!forAll)
+ baseEdge.ownStyles = selectedEdges[0].ownStyles;
+
+ baseEdge.model.width = edgeWidth;
+
+ graphDrawer.Draw(baseEdge, self.style.GetStyle({}, baseEdge));
+
+ context.restore();
+ }
+
+ var changeIndex = function()
+ {
+ var val = $( "#edgeSelectedIndex" ).val();
+ if (val == "all")
+ {
+ applyIndex(1);
+ self.index = "all";
+ fillFields();
+ }
+ else
+ {
+ var index = parseInt(val);
+ self.index = index;
+ applyIndex(index);
+ fillFields();
+ }
+
+ redrawVertex();
+ }
+
+ var applyWidth = function(width)
+ {
+ if (forAll)
+ {
+ app.SetDefaultEdgeWidth(width);
+ }
+ else
+ {
+ selectedEdges.forEach(function(edge) {
+ edge.model.width = width;
+ });
+ }
+ };
+
+ dialogButtons[g_default] =
+ {
+ text : g_default,
+ class : "MarginLeft",
+ click : function() {
+ app.PushToStack("ChangeStyle");
+
+ applyWidth(forAll ? (new EdgeModel()).width : app.GetDefaultEdgeWidth());
+ var indexes = [];
+ if (self.index == "all")
+ {
+ for (i = 0; i < app.edgeSelectedStyles.length; i ++)
+ indexes.push(i + 1);
+ }
+ else
+ indexes.push(self.index);
+
+ if (forAll)
+ {
+ indexes.forEach(function(index) {
+ app.ResetEdgeStyle(index);
+ });
+ }
+ else
+ {
+ selectedEdges.forEach(function(edge) {
+ indexes.forEach(function(index) {
+ edge.resetOwnStyle(index);
+ });
+ });
+ }
+
+ app.redrawGraph();
+ $( this ).dialog( "close" );
+ }
+ };
+
+ dialogButtons[g_save] = function() {
+
+ app.PushToStack("ChangeStyle");
+
+ applyWidth(parseInt($( "#edgeWidth" ).val()));
+
+ var indexes = [];
+ if (self.index == "all")
+ {
+ indexes.push({index : 1, style : self.style});
+
+ for (i = 1; i < app.edgeSelectedStyles.length; i ++)
+ {
+ var style = (new BaseEdgeStyle());
+ style.baseStyles.push("selected");
+ indexes.push({index : i + 1, style : style});
+ }
+
+ self.style.baseStyles = [];
+ self.style.baseStyles = self.style.baseStyles.concat((new SelectedEdgeStyle0()).baseStyles);
+ }
+ else
+ indexes.push({index : self.index, style : self.style});
+
+ if (forAll)
+ {
+ indexes.forEach(function(index) {
+ app.SetEdgeStyle(index.index, index.style);
+ });
+ }
+ else
+ {
+ selectedEdges.forEach(function(edge) {
+ indexes.forEach(function(index) {
+ edge.setOwnStyle(index.index, index.style);
+ });
+ });
+ }
+ app.redrawGraph();
+ $( this ).dialog( "close" );
+ };
+ dialogButtons[g_cancel] = function() {
+ $( this ).dialog( "close" );
+ };
+
+ fillFields();
+
+ $( "#SetupEdgeStyleDialog" ).dialog({
+ resizable: false,
+ height: "auto",
+ width: "auto",
+ modal: true,
+ title: g_edgeDraw,
+ buttons: dialogButtons,
+ dialogClass: 'EdgeDialog'
+ });
+
+ redrawVertex();
+
+ $( "#edgeFillColor" ).unbind();
+ $( "#edgeStrokeColor" ).unbind();
+ $( "#edgeTextColor" ).unbind();
+ $( "#edgeStyle" ).unbind();
+ $( "#edgeWidth" ).unbind();
+ $( "#weightEdgeTextColor" ).unbind();
+ $( "#weightTextPosition" ).unbind();
+ $( "#edgeSelectedIndex" ).unbind();
+
+ $( "#edgeFillColor" ).change(redrawVertex);
+ $( "#edgeStrokeColor" ).change(redrawVertex);
+ $( "#edgeTextColor" ).change(redrawVertex);
+ $( "#edgeStyle" ).change(redrawVertex);
+ $( "#edgeWidth" ).change(redrawVertex);
+ $( "#weightEdgeTextColor" ).change(redrawVertex);
+ $( "#weightTextPosition" ).change(redrawVertex);
+ $( "#edgeSelectedIndex" ).change(changeIndex);
+}
diff --git a/script/features/setup_vertex_style/index.js b/script/features/setup_vertex_style/index.js
new file mode 100644
index 0000000..ef5c1ca
--- /dev/null
+++ b/script/features/setup_vertex_style/index.js
@@ -0,0 +1,299 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Setup Vertex Style rename vertices.
+ *
+ */
+function SetupVertexStyle(app)
+{
+ BaseHandler.apply(this, arguments);
+ this.message = "";
+}
+
+// inheritance.
+SetupVertexStyle.prototype = Object.create(BaseHandler.prototype);
+
+SetupVertexStyle.prototype.show = function(index, selectedVertices)
+{
+ var handler = this;
+ var dialogButtons = {};
+ var graph = this.app.graph;
+ var app = this.app;
+ this.forAll = selectedVertices == null;
+ var forAll = this.forAll;
+ var self = this;
+
+ var applyIndex = function(index)
+ {
+ self.index = index;
+ self.originStyle = (self.index == 0 ? app.vertexCommonStyle : app.vertexSelectedVertexStyles[self.index - 1]);
+ if (!forAll)
+ {
+ self.originStyle = selectedVertices[0].getStyleFor(self.index);
+ }
+ self.style = FullObjectCopy(self.originStyle);
+ }
+
+ applyIndex(index);
+
+ var fillFields = function()
+ {
+ var fullStyle = self.style.GetStyle({}, forAll ? undefined : selectedVertices[0]);
+
+ $( "#vertexFillColor" ).val(fullStyle.fillStyle);
+ $( "#vertexStrokeColor" ).val(fullStyle.strokeStyle);
+ $( "#vertexTextColor" ).val(fullStyle.mainTextColor);
+ $( "#upVertexTextColor" ).val(fullStyle.upTextColor);
+ $( "#vertexStrokeSize" ).val(fullStyle.lineWidth);
+ $( "#vertexShape" ).val(fullStyle.shape);
+ $( "#vertexSize" ).val(forAll ? app.GetDefaultVertexSize() : selectedVertices[0].model.diameter);
+ $( "#commonTextPosition" ).val(fullStyle.commonTextPosition);
+
+ if (self.index > 0 || self.index == "all")
+ {
+ $( "#VertexSelectedIndexForm" ).show();
+ $( "#vertexSelectedIndex" ).val(self.index);
+ }
+ else
+ {
+ $( "#VertexSelectedIndexForm" ).hide();
+ }
+
+ // Fill color presets.
+ var stylesArray = [];
+ stylesArray.push(app.vertexCommonStyle);
+
+ for (i = 0; i < app.vertexSelectedVertexStyles.length; i ++)
+ stylesArray.push(app.vertexSelectedVertexStyles[i]);
+
+ var colorSet = {};
+ for (i = 0; i < stylesArray.length; i ++)
+ {
+ var style = stylesArray[i];
+ if (style.hasOwnProperty('strokeStyle'))
+ colorSet[style.strokeStyle] = 1;
+ if (style.hasOwnProperty('fillStyle'))
+ colorSet[style.fillStyle] = 1;
+ if (style.hasOwnProperty('mainTextColor'))
+ colorSet[style.mainTextColor] = 1;
+ if (style.hasOwnProperty('upTextColor'))
+ colorSet[style.upTextColor] = 1;
+ }
+
+ $("#vertexFillColorPreset").find('option').remove();
+ $("#upVertexTextColorPreset").find('option').remove();
+ $("#vertexTextColorPreset").find('option').remove();
+ $("#vertexStrokeColorPreset").find('option').remove();
+ for (const property in colorSet)
+ {
+ $("#vertexFillColorPreset").append(new Option(property));
+ $("#upVertexTextColorPreset").append(new Option(property));
+ $("#vertexTextColorPreset").append(new Option(property));
+ $("#vertexStrokeColorPreset").append(new Option(property));
+ }
+ }
+
+ var redrawVertex = function()
+ {
+ var fullStyle = self.style.GetStyle({}, forAll ? undefined : selectedVertices[0]);
+
+ if (fullStyle.fillStyle != $( "#vertexFillColor" ).val())
+ self.style.fillStyle = $( "#vertexFillColor" ).val();
+
+ if (fullStyle.strokeStyle != $( "#vertexStrokeColor" ).val())
+ self.style.strokeStyle = $( "#vertexStrokeColor" ).val();
+
+ if (fullStyle.mainTextColor != $( "#vertexTextColor" ).val())
+ self.style.mainTextColor = $( "#vertexTextColor" ).val();
+
+ if (fullStyle.lineWidth != $( "#vertexStrokeSize" ).val())
+ self.style.lineWidth = parseInt($( "#vertexStrokeSize" ).val());
+
+ if (fullStyle.shape != $( "#vertexShape" ).val())
+ self.style.shape = parseInt($( "#vertexShape" ).val());
+
+ if (fullStyle.upTextColor != $( "#upVertexTextColor" ).val())
+ self.style.upTextColor = $( "#upVertexTextColor" ).val();
+
+ if (fullStyle.commonTextPosition != $( "#commonTextPosition" ).val())
+ self.style.commonTextPosition = $( "#commonTextPosition" ).val();
+
+ var diameter = parseInt($( "#vertexSize" ).val());
+
+ var canvas = document.getElementById( "VertexPreview" );
+ var context = canvas.getContext('2d');
+
+ context.save();
+
+ var backgroundDrawer = new BaseBackgroundDrawer(context);
+ backgroundDrawer.Draw(app.backgroundCommonStyle, canvas.width, canvas.height, new Point(0, 0), 1.0);
+
+ var graphDrawer = new BaseVertexDrawer(context);
+ var baseVertex = new BaseVertex(canvas.width / 2, canvas.height / 2, new BaseEnumVertices(this));
+ baseVertex.mainText = "1";
+ baseVertex.upText = "Up Text";
+ baseVertex.model.diameter = diameter;
+
+ if (!forAll)
+ baseVertex.ownStyles = selectedVertices[0].ownStyles;
+
+ graphDrawer.Draw(baseVertex, self.style.GetStyle({}, baseVertex));
+
+ context.restore();
+ }
+
+ var changeIndex = function()
+ {
+ var val = $( "#vertexSelectedIndex" ).val();
+ if (val == "all")
+ {
+ applyIndex(1);
+ self.index = "all";
+ fillFields();
+ }
+ else
+ {
+ var index = parseInt(val);
+ self.index = index;
+ applyIndex(index);
+ fillFields();
+ }
+ redrawVertex();
+ }
+
+ var applyDiameter = function(diameter)
+ {
+ if (forAll)
+ {
+ app.SetDefaultVertexSize(diameter);
+ }
+ else
+ {
+ selectedVertices.forEach(function(vertex) {
+ vertex.model.diameter = diameter;
+ });
+ }
+ };
+
+ dialogButtons[g_default] =
+ {
+ text : g_default,
+ class : "MarginLeft",
+ click : function() {
+
+ app.PushToStack("ChangeStyle");
+
+ applyDiameter(forAll ? (new VertexModel()).diameter : app.GetDefaultVertexSize());
+
+ var indexes = [];
+ if (self.index == "all")
+ {
+ for (i = 0; i < app.vertexSelectedVertexStyles.length; i ++)
+ indexes.push(i + 1);
+ }
+ else
+ indexes.push(self.index);
+
+
+ if (forAll)
+ {
+ indexes.forEach(function(index) {
+ app.ResetVertexStyle(index);
+ });
+ }
+ else
+ {
+ selectedVertices.forEach(function(vertex) {
+ indexes.forEach(function(index) {
+ vertex.resetOwnStyle(index);
+ });
+ });
+ }
+ app.redrawGraph();
+ $( this ).dialog( "close" );
+ }
+ };
+
+ dialogButtons[g_save] = function() {
+
+ app.PushToStack("ChangeStyle");
+
+ applyDiameter(parseInt($( "#vertexSize" ).val()));
+
+ var indexes = [];
+ if (self.index == "all")
+ {
+ indexes.push({index : 1, style : self.style});
+ for (i = 1; i < app.vertexSelectedVertexStyles.length; i ++)
+ {
+ var style = (new BaseVertexStyle());
+ style.baseStyles.push("selected");
+ indexes.push({index : i + 1, style : style});
+ }
+
+ self.style.baseStyles = [];
+ self.style.baseStyles = self.style.baseStyles.concat((new SelectedVertexStyle0()).baseStyles);
+ }
+ else
+ indexes.push({index : self.index, style : self.style});
+
+ if (forAll)
+ {
+ indexes.forEach(function(index) {
+ app.SetVertexStyle(index.index, index.style);
+ });
+ }
+ else
+ {
+ if (JSON.stringify(self.originStyle) !== JSON.stringify(self.style))
+ {
+ selectedVertices.forEach(function(vertex) {
+ indexes.forEach(function(index) {
+ vertex.setOwnStyle(index.index, index.style);
+ });
+ });
+ }
+ }
+ app.redrawGraph();
+ $( this ).dialog( "close" );
+ };
+ dialogButtons[g_cancel] = function() {
+ $( this ).dialog( "close" );
+ };
+
+ fillFields();
+
+ $( "#SetupVertexStyleDialog" ).dialog({
+ resizable: false,
+ height: "auto",
+ width: "auto",
+ modal: true,
+ title: g_vertexDraw,
+ buttons: dialogButtons,
+ dialogClass: 'EdgeDialog'
+ });
+
+ redrawVertex();
+
+ $( "#vertexFillColor" ).unbind();
+ $( "#vertexStrokeColor" ).unbind();
+ $( "#vertexTextColor" ).unbind();
+ $( "#upVertexTextColor" ).unbind();
+ $( "#vertexStrokeSize" ).unbind();
+ $( "#vertexShape" ).unbind();
+ $( "#vertexSize" ).unbind();
+ $( "#commonTextPosition" ).unbind();
+ $( "#vertexSelectedIndex" ).unbind();
+
+ $( "#vertexFillColor" ).change(redrawVertex);
+ $( "#vertexStrokeColor" ).change(redrawVertex);
+ $( "#vertexTextColor" ).change(redrawVertex);
+ $( "#vertexStrokeSize" ).change(redrawVertex);
+ $( "#vertexShape" ).change(redrawVertex);
+ $( "#vertexSize" ).change(redrawVertex);
+ $( "#upVertexTextColor" ).change(redrawVertex);
+ $( "#commonTextPosition" ).change(redrawVertex);
+ $( "#vertexSelectedIndex" ).change(changeIndex);
+}
diff --git a/script/features/show_adjacency_matrix/index.js b/script/features/show_adjacency_matrix/index.js
new file mode 100644
index 0000000..a8653d7
--- /dev/null
+++ b/script/features/show_adjacency_matrix/index.js
@@ -0,0 +1,66 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Save/Load graph from matrix.
+ *
+ */
+function ShowAdjacencyMatrix(app)
+{
+ BaseHandler.apply(this, arguments);
+ this.message = "";
+}
+
+// inheritance.
+ShowAdjacencyMatrix.prototype = Object.create(BaseHandler.prototype);
+// First selected.
+ShowAdjacencyMatrix.prototype.firstObject = null;
+// Path
+ShowAdjacencyMatrix.prototype.pathObjects = null;
+
+ShowAdjacencyMatrix.prototype.show = function()
+{
+ var handler = this;
+ var dialogButtons = {};
+
+ $('#AdjacencyMatrixField').unbind();
+ $( "#AdjacencyMatrixField" ).on('keyup change', function (eventObject)
+ {
+ if (!handler.app.TestAdjacencyMatrix($( "#AdjacencyMatrixField" ).val(), [], []))
+ {
+ $( "#BadMatrixFormatMessage" ).show();
+ }
+ else
+ {
+ $( "#BadMatrixFormatMessage" ).hide();
+ }
+ });
+
+ dialogButtons[g_save] = function() {
+ handler.app.PushToStack("ChangeAdjacencyMatrix");
+ handler.app.SetAdjacencyMatrixSmart($( "#AdjacencyMatrixField" ).val());
+ $( this ).dialog( "close" );
+ };
+ dialogButtons[g_cancel] = function() {
+ $( this ).dialog( "close" );
+ };
+
+ $( "#AdjacencyMatrixField" ).val(this.app.GetAdjacencyMatrix());
+ $( "#BadMatrixFormatMessage" ).hide();
+
+ if (this.app.graph.isMulti())
+ $( "#AdjacencyMatrixMultiGraphDesc").show();
+ else
+ $( "#AdjacencyMatrixMultiGraphDesc").hide();
+
+ $( "#adjacencyMatrix" ).dialog({
+ resizable: false,
+ height: "auto",
+ width: "auto",
+ modal: true,
+ title: g_adjacencyMatrixText,
+ buttons: dialogButtons,
+ dialogClass: 'EdgeDialog'
+ });
+}
diff --git a/script/features/show_distance_matrix/index.js b/script/features/show_distance_matrix/index.js
new file mode 100644
index 0000000..2ce1c0b
--- /dev/null
+++ b/script/features/show_distance_matrix/index.js
@@ -0,0 +1,77 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Show distance matrix.
+ *
+ */
+function ShowDistanceMatrix(app)
+{
+ BaseHandler.apply(this, arguments);
+ this.app = app;
+ this.message = "";
+}
+
+// inheritance.
+ShowDistanceMatrix.prototype = Object.create(BaseHandler.prototype);
+// First selected.
+ShowDistanceMatrix.prototype.firstObject = null;
+// Path
+ShowDistanceMatrix.prototype.pathObjects = null;
+
+ShowDistanceMatrix.prototype.GetIncidenceMatrix = function (rawMatrix)
+{
+ var matrix = "";
+ for (var i = 0; i < rawMatrix.length; i++)
+ {
+ for (var j = 0; j < rawMatrix[i].length; j++)
+ {
+ if (i == j)
+ {
+ matrix += "0";
+ }
+ else if ((new Graph()).infinity == rawMatrix[i][j])
+ {
+ matrix += '\u221E';
+ }
+ else
+ {
+ matrix += rawMatrix[i][j];
+ }
+
+ if (j != rawMatrix[i].length - 1)
+ {
+ matrix += ", ";
+ }
+
+ }
+ matrix = matrix + "\n";
+ }
+
+ return matrix;
+}
+
+ShowDistanceMatrix.prototype.show = function()
+{
+ var handler = this;
+ var dialogButtons = {};
+
+ dialogButtons[g_close] = function() {
+ $( this ).dialog( "close" );
+ };
+
+ var handler = g_Algorithms[g_AlgorithmIds.indexOf("OlegSh.FloidAlgorithm")](this.app.graph, this.app);
+
+ $( "#FloidMatrixField" ).val(this.GetIncidenceMatrix(handler.resultMatrix()));
+
+ $( "#floidMatrix" ).dialog({
+ resizable: false,
+ height: "auto",
+ width: "auto",
+ modal: true,
+ title: g_minDistMatrixText,
+ buttons: dialogButtons,
+ dialogClass: 'EdgeDialog'
+ });
+}
diff --git a/script/features/show_incidence_matrix/index.js b/script/features/show_incidence_matrix/index.js
new file mode 100644
index 0000000..e4bd53c
--- /dev/null
+++ b/script/features/show_incidence_matrix/index.js
@@ -0,0 +1,61 @@
+doInclude ([
+ include ("features/base_handler/index.js")
+])
+
+/**
+ * Save/Load graph from Incidence matrix.
+ *
+ */
+function ShowIncidenceMatrix(app)
+{
+ BaseHandler.apply(this, arguments);
+ this.message = "";
+}
+
+// inheritance.
+ShowIncidenceMatrix.prototype = Object.create(BaseHandler.prototype);
+// First selected.
+ShowIncidenceMatrix.prototype.firstObject = null;
+// Path
+ShowIncidenceMatrix.prototype.pathObjects = null;
+
+ShowIncidenceMatrix.prototype.show = function()
+{
+ var handler = this;
+ var dialogButtons = {};
+
+ $('#IncidenceMatrixField').unbind();
+ $( "#IncidenceMatrixField" ).on('keyup change', function (eventObject)
+ {
+ if (!handler.app.TestIncidenceMatrix($( "#IncidenceMatrixField" ).val(), [], []))
+ {
+ $( "#BadIncidenceMatrixFormatMessage" ).show();
+ }
+ else
+ {
+ $( "#BadIncidenceMatrixFormatMessage" ).hide();
+ }
+ });
+
+ dialogButtons[g_save] = function() {
+ handler.app.PushToStack("IncidenceMatrixChanged");
+ handler.app.SetIncidenceMatrixSmart($( "#IncidenceMatrixField" ).val());
+ $( this ).dialog( "close" );
+ };
+ dialogButtons[g_cancel] = function() {
+ $( this ).dialog( "close" );
+ };
+
+ $( "#IncidenceMatrixField" ).val(this.app.GetIncidenceMatrix());
+ $( "#BadIncidenceMatrixFormatMessage" ).hide();
+
+ $( "#incidenceMatrix" ).dialog({
+ resizable: false,
+ height: "auto",
+ width: "auto",
+ modal: true,
+ title: g_incidenceMatrixText,
+ buttons: dialogButtons,
+ dialogClass: 'EdgeDialog'
+ });
+}
diff --git a/script/merge.php b/script/merge.php
index 26f6e05..66cba03 100755
--- a/script/merge.php
+++ b/script/merge.php
@@ -1,34 +1,18 @@
+Update cache
+
");
+ foreach ($cacheList as &$page) {
+ $date = date('d.m.Y H:i:s', filemtime("../$page.cache"));
+ echo ("$page $date");
+ }
+ echo ("");
+?>
-file_put_contents($outputFilename, file_get_contents("utils.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("texts.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("point.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("EdgeModel.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("VertexModel.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("BaseVertex.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("BaseEdge.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("BaseVertexDrawer.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("BaseEdgeDrawer.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("BaseBackgroundDrawer.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("Algorithms.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("EventHandlers.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("GraphMLCreator.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("Graph.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("EnumVertices.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("Application.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("main.js"), FILE_APPEND);
-file_put_contents($outputFilename, file_get_contents("BaseTraversal.js"), FILE_APPEND);
-
-if (file_exists($outputFilename))
-{
- echo ("File exists");
-}
-else
-{
- echo ("File not exists");
-}
-
-?>
\ No newline at end of file
diff --git a/script/pack.php b/script/pack.php
new file mode 100644
index 0000000..1691b80
--- /dev/null
+++ b/script/pack.php
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/script/pages/create_graph_by_edge_list/api/index.js b/script/pages/create_graph_by_edge_list/api/index.js
new file mode 100644
index 0000000..3faf481
--- /dev/null
+++ b/script/pages/create_graph_by_edge_list/api/index.js
@@ -0,0 +1,9 @@
+// Global version needs to force reload scripts from server.
+globalVersion = 75;
+
+{
+ let modulDir = "pages/create_graph_by_edge_list/";
+
+ doInclude ([
+ include ("entities/graph/api/index.js")]);
+}
\ No newline at end of file
diff --git a/script/pages/create_graph_by_edge_list/api/index.js.cache b/script/pages/create_graph_by_edge_list/api/index.js.cache
new file mode 100644
index 0000000..932c582
--- /dev/null
+++ b/script/pages/create_graph_by_edge_list/api/index.js.cache
@@ -0,0 +1,594 @@
+moduleLoader.beginCacheLoading(["/script/entities/graph/api/index.js?v=75","/script/shared/point.js?v=75","/script/entities/edge/api/index.js?v=75","/script/entities/edge/model/BaseEdge.js?v=75","/script/entities/edge/model/EdgeModel.js?v=75","/script/entities/vertex/api/index.js?v=75","/script/entities/vertex/model/BaseVertex.js?v=75","/script/entities/vertex/model/VertexModel.js?v=75","/script/entities/graph/model/Graph.js?v=75",]);globalVersion=75;{let modulDir="pages/create_graph_by_edge_list/";doInclude([include("entities/graph/api/index.js")]);}
+{let modulDir="entities/graph/";doInclude([include("shared/point.js"),include("entities/edge/api/index.js"),include("entities/vertex/api/index.js"),include("model/Graph.js",modulDir)])}function Point(x,y){this.x=x||0;this.y=y||0;};Point.prototype.x=null;Point.prototype.y=null;Point.prototype.add=function(v){return new Point(this.x+v.x,this.y+v.y);};Point.prototype.addValue=function(v){return new Point(this.x+v,this.y+v);};Point.prototype.clone=function(){return new Point(this.x,this.y);};Point.prototype.degreesTo=function(v){var dx=this.x-v.x;var dy=this.y-v.y;var angle=Math.atan2(dy,dx);return angle*(180/Math.PI);};Point.prototype.distance=function(v){return Math.sqrt(this.distanceSqr(v));};Point.prototype.distanceSqr=function(v){var x=this.x-v.x;var y=this.y-v.y;return x*x+y*y;};Point.prototype.equals=function(toCompare){return this.x==toCompare.x&&this.y==toCompare.y;};Point.prototype.interpolate=function(v,f){return new Point((this.x+v.x)*f,(this.y+v.y)*f);};Point.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y);};Point.prototype.normalize=function(thickness){var l=this.length();this.x=this.x/l*thickness;this.y=this.y/l*thickness;return new Point(this.x,this.y);};Point.prototype.normalizeCopy=function(thickness){var l=this.length();return new Point(this.x/l*thickness,this.y/l*thickness);};Point.prototype.orbit=function(origin,arcWidth,arcHeight,degrees){var radians=degrees*(Math.PI/180);this.x=origin.x+arcWidth*Math.cos(radians);this.y=origin.y+arcHeight*Math.sin(radians);};Point.prototype.rotate=function(center,degrees){var radians=degrees*(Math.PI/180);offset=this.subtract(center);this.x=offset.x*Math.cos(radians)-offset.y*Math.sin(radians);this.y=offset.x*Math.sin(radians)+offset.y*Math.cos(radians);this.x=this.x+center.x;this.y=this.y+center.y;return this;};Point.prototype.offset=function(dx,dy){this.x+=dx;this.y+=dy;};Point.prototype.subtract=function(v){return new Point(this.x-v.x,this.y-v.y);};Point.prototype.subtractValue=function(value){return new Point(this.x-value,this.y-value);};Point.prototype.multiply=function(value){return new Point(this.x*value,this.y*value);};Point.prototype.toString=function(){return"(x="+this.x+", y="+this.y+")";};Point.prototype.normal=function(){return new Point(-this.y,this.x);};Point.prototype.min=function(point)
+{return new Point(Math.min(this.x,point.x),Math.min(this.y,point.y));};Point.prototype.max=function(point)
+{return new Point(Math.max(this.x,point.x),Math.max(this.y,point.y));};Point.prototype.inverse=function()
+{return new Point(-this.x,-this.y);};Point.prototype.cross=function(point)
+{return this.x*point.y-this.y*point.x;};Point.interpolate=function(pt1,pt2,f){return new Point(pt1.x*(1.0-f)+pt2.x*f,pt1.y*(1.0-f)+pt2.y*f);};Point.polar=function(len,angle){return new Point(len*Math.cos(angle),len*Math.sin(angle));};Point.distance=function(pt1,pt2){var x=pt1.x-pt2.x;var y=pt1.y-pt2.y;return Math.sqrt(x*x+y*y);};Point.center=function(pt1,pt2){return new Point((pt1.x+pt2.x)/2.0,(pt1.y+pt2.y)/2.0);};Point.toString=function(){return x+" "+y;}
+Point.projection=function(point,line1,line2)
+{var x=line2.y-line1.y;var y=line1.x-line2.x;var l=(line1.cross(line2)+line1.cross(point)+line2.cross(point))/(x*(line2.y-line1.y)+y*(line1.x-line2.x));var res=new Point(point.x+x*l,point.y+y*l);return res;}
+Point.hitTest=function(pt11,pt12,pt21,pt22)
+{var res=null;var n=0.0;var x1=pt11.x;var y1=pt11.y;var x2=pt12.x;var y2=pt12.y;var x3=pt21.x;var y3=pt21.y;var x4=pt22.x;var y4=pt22.y;if(y2-y1!=0.0)
+{var q=(x2-x1)/(y1-y2);var sn=(x3-x4)+(y3-y4)*q;if(sn==0.0)
+{return res;}
+var fn=(x3-x1)+(y3-y1)*q;n=fn/sn;}
+else
+{if((y3-y4)==0.0)
+{return res;}
+n=(y3-y1)/(y3-y4);}
+res=new Point(x3+(x4-x3)*n,y3+(y4-y3)*n);var epsilon=1E-5;if(!(res.x>=Math.min(x1,x2)-epsilon&&res.x>=Math.min(x3,x4)-epsilon&&res.x<=Math.max(x1,x2)+epsilon&&res.x<=Math.max(x3,x4)+epsilon&&res.y>=Math.min(y1,y2)-epsilon&&res.y>=Math.min(y3,y4)-epsilon&&res.y<=Math.max(y1,y2)+epsilon&&res.y<=Math.max(y3,y4)+epsilon))
+{res=null;}
+return res;}
+function Rect(minPoint,maxPoint){this.minPoint=minPoint;this.maxPoint=maxPoint;};Rect.prototype.center=function()
+{return Point.center(this.minPoint,this.maxPoint);};Rect.prototype.size=function()
+{return this.maxPoint.subtract(this.minPoint);};Rect.prototype.left=function()
+{return this.minPoint.x;};Rect.prototype.top=function()
+{return this.minPoint.y;};Rect.prototype.isIn=function(v)
+{return this.minPoint.x<=v.x&&this.minPoint.y<=v.y&&this.maxPoint.x>v.x&&this.maxPoint.y>v.y;};{let modulDir="entities/edge/";doInclude([include("model/BaseEdge.js",modulDir),include("model/EdgeModel.js",modulDir)])}
+function BaseEdge(vertex1,vertex2,isDirect,weight,upText)
+{this.vertex1=vertex1;this.vertex2=vertex2;this.arrayStyleStart="";this.arrayStyleFinish="";this.isDirect=isDirect;this.weight=0;this.text="";this.useWeight=false;this.id=0;this.model=new EdgeModel();if(upText===undefined)
+this.upText="";else
+this.upText=upText;if(weight!==undefined)
+this.SetWeight(weight);this.ownStyles={};}
+BaseEdge.prototype.copyFrom=function(other)
+{this.vertex1=other.vertex1;this.vertex2=other.vertex2;this.arrayStyleStart=other.arrayStyleStart;this.arrayStyleFinish=other.arrayStyleFinish;this.isDirect=other.isDirect;this.weight=other.weight;this.text=other.text;this.useWeight=other.useWeight;this.id=other.id;this.model=new EdgeModel();this.model.copyFrom(other.model);this.upText=other.upText;this.ownStyles=FullObjectCopy(other.ownStyles);}
+BaseEdge.prototype.SaveToXML=function()
+{return"0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+
+this.model.SaveToXML()+">";}
+BaseEdge.prototype.LoadFromXML=function(xml,graph)
+{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'));this.isDirect=xml.attr('isDirect')=="true";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 shape=data.vertex.currentStyle.GetStyle({},data.vertex).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,data.vertex.mainText);pointsVertex1.push(pointsVertex1[0]);for(var i=0;i=0)?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:parseFloat(xml.attr("model_default"));}
+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);else if(this.type==EdgeModels.curve)
+return this.HitTestCurve(position1,position2,mousePos);return false;}
+EdgeModel.prototype.HitTestLine=function(position1,position2,mousePos,factor)
+{if(factor===undefined)
+{factor=1.0;}
+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*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=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 BaseVertex(x,y,vertexEnumType)
+{this.position=new Point(x,y);this.id=0;this.mainText="";this.upText="";this.vertexEnumType=vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=false;this.ownStyles={};};BaseVertex.prototype.position=new Point(0,0);BaseVertex.prototype.copyFrom=function(other)
+{this.position=new Point(other.position.x,other.position.y);this.id=other.id;this.mainText=other.mainText;this.upText=other.upText;this.vertexEnumType=other.vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=other.hasUndefinedPosition;this.ownStyles=FullObjectCopy(other.ownStyles);}
+BaseVertex.prototype.SaveToXML=function()
+{return"0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+"size=\""+this.model.diameter+"\" "+">";}
+BaseVertex.prototype.LoadFromXML=function(xml)
+{var xmlX=xml.attr('positionX');var xmlY=xml.attr('positionY');this.hasUndefinedPosition=(typeof xmlX==='undefined')||(typeof xmlY==='undefined');this.position=new Point(parseFloat(xmlX),parseFloat(xmlY));this.id=xml.attr('id');this.mainText=xml.attr('mainText');this.upText=xml.attr('upText');if(typeof this.mainText==='undefined')
+this.mainText=this.id;else
+this.mainText=gDecodeFromHTML(this.mainText);if(typeof this.upText==='undefined')
+this.upText="";else
+this.upText=gDecodeFromHTML(this.upText);var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
+{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
+{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
+{if(this.ownStyles[index].ShouldLoad(field))
+this.ownStyles[index][field]=parsedSave[indexField][field];}}}
+var size=xml.attr('size');if(typeof size!=='undefined')
+this.model.diameter=parseInt(size);}
+BaseVertex.prototype.SetId=function(id)
+{this.id=id;if(this.vertexEnumType!=null)
+this.mainText=this.vertexEnumType.GetVertexText(id);}
+BaseVertex.prototype.diameterFactor=function()
+{return new Point(1.0+(this.mainText.length?this.mainText.length/8.0:0),1.5);}
+BaseVertex.prototype.IsUndefinedPosition=function()
+{return this.hasUndefinedPosition;}
+BaseVertex.prototype.HitTest=function(pos)
+{var shape=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).shape:VertexCircleShape;var width=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).lineWidth:0;if(shape==VertexCircleShape)
+{return this.position.distance(pos)-1)
+{this.edges.splice(index,1);}
+this.isMultiGraph=this.checkMutiGraph();}
+Graph.prototype.DeleteVertex=function(vertexObject)
+{var index=this.vertices.indexOf(vertexObject);if(index>-1)
+{for(var i=0;i-1)
+{for(var i=0;imaxWeight)
+{res=edge;maxWeight=edge.weight;}}}
+return res;}
+Graph.prototype.FindEdgeMinIgnoreDirection=function(id1,id2)
+{var res=null;var minWeight=this.infinity;for(var i=0;i.+$/g,/^.+<.+$/g,/^.+-\(\d+\.?\d+\)-.+$/g,/^.+-\(\d+\.?\d+\)\>.+$/g,/^.+<\(\d+\.?\d+\)\-.+$/g];let res=true;for(let i=0;i0||cols[j][vertexIndex]>0)&&j!=vertexIndex)
+{relatedVertex.push(this.vertices[j]);}}
+var diameter=(new VertexModel()).diameter;if(relatedVertex.length>1)
+{for(var j=0;jmaxDistance)
+{var force=(otherVertex.position.subtract(currentVertex.object.position)).normalize(edgeGravityKof*(distance-maxDistance));currentVertex.net_force=currentVertex.net_force.add(force);}}}
+var distanceToCenter=centerPoint.distance(currentVertex.object.position);var force=centerPoint.subtract(currentVertex.object.position).normalize(distanceToCenter*kCenterForce);currentVertex.net_force=currentVertex.net_force.add(force);currentVertex.velocity=currentVertex.velocity.add(currentVertex.net_force);}
+bChanged=false;for(i=0;ivelocityMax)
+{velocity=velocity.normalize(velocityMax);}
+v.object.position=v.object.position.add(velocity);if(velocity.length()>=1)
+{bChanged=true;}}
+k++;}
+var bbox=this.getGraphBBox();if(bbox.size().length()>viewportSize.length()*1000)
+{for(i=0;i=this.vertices.length)
+{var newPos=this.GetRandomPositionOfVertex(matrix,j,viewportSize);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
+if(cols[i][j]>0)
+{var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[i],this.vertices[j],cols[i][j]!=cols[j][i],cols[i][j],true);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
+{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+for(var i=rows.length;i(.+)$/g,/^(.+)<(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)-(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)\>(.+)$/g,/^(.+)<\((\d+|\d+\.?\d+)\)\-(.+)$/g,];let bWeightGraph=false;var newVertices=[];for(var i=0;i=0;--j){if(!line.match(regExp[j])){continue;}
+let groupes=Array.from(line.matchAll(regExp[j]));let groupe=groupes[0];let vetext1Title=groupe[1];let vertex1=this.FindVertexByTitle(vetext1Title);if(vertex1==null){let newPosition=this.GetRandomPosition(viewportSize);vertex1=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex1.mainText=vetext1Title;newVertices.push(vertex1);}
+let vetext2Title=groupe[j<=2?2:3];let vertex2=this.FindVertexByTitle(vetext2Title);if(vertex2==null){let newPosition=this.GetRandomPosition(viewportSize);vertex2=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex2.mainText=vetext2Title;newVertices.push(vertex2);}
+let isDirect=j==1||j==2||j==4||j==5;let weight=1;if(j>2){weight=groupe[2];bWeightGraph=true;}
+let isRevertEdge=j==2||j==5;let nEdgeIndex=this.AddNewEdgeSafe(isRevertEdge?vertex2:vertex1,isRevertEdge?vertex1:vertex2,isDirect,weight,false);this.FixEdgeCurve(nEdgeIndex);break;}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+this.VerticesReposition(viewportSize,newVertices);}}
+Graph.prototype.TestIncidenceMatrix=function(matrix,rowsObj,colsObj,separator)
+{if(separator===undefined)
+{separator=",";}
+var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j=this.vertices.length)
+{var newPos=new Point(0,0);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
+if(cols[j][i]!=0)
+{edgeValue.push(cols[j][i]);edgeIndex.push(j);}}
+if(edgeIndex.length==1)
+{edgeValue.push(edgeValue[0]);edgeIndex.push(edgeIndex[0]);}
+if(edgeIndex.length==2)
+{if(edgeValue[0]!=edgeValue[1])
+{if(edgeValue[1]>0)
+{edgeValue=edgeValue.swap(0,1);edgeIndex=edgeIndex.swap(0,1);}}
+var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[edgeIndex[0]],this.vertices[edgeIndex[1]],edgeValue[0]!=edgeValue[1],Math.abs(edgeValue[1]),false);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
+{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+for(var i=cols.length;i0)
+{res.push(line.substr(0,i));}
+if(i==0)
+{i=1;}
+line=line.substr(i,line.length-i);i=-1;}}
+if(line.length>0)
+{res.push(line);}}
+else
+{for(i=0;i";var header="";var xmlBody="";for(var i=0;i0)
+{additionalField=""}
+return mainHeader+header+xmlBody+""+additionalField+"";}
+Graph.prototype.LoadFromXML=function(xmlText,additionalData)
+{xmlDoc=$.parseXML(xmlText);var $xml=$(xmlDoc);$graphs=$xml.find("graph");var loadedGraphId=0;var loadedEdgeId=0;$graphs.each(function(){loadedGraphId=parseInt($(this).attr('uidGraph'));loadedEdgeId=parseInt($(this).attr('uidEdge'));});if(isNaN(loadedEdgeId))
+{loadedEdgeId=this.edgesOffset;}else if(loadedEdgeId0;}
+Graph.prototype.clampPositions=function(viewportSize)
+{var diameter=(new VertexModel()).diameter;for(i=0;i=2)
+{var curve=this.GetAvailableCurveValue(neighborEdges,edgeObject);if(edgeObject.model.default)
+{edgeObject.model.type=EdgeModels.curve;edgeObject.model.curveValue=curve;}}}
+Graph.prototype.GetAvailableCurveValue=function(neighborEdges,originalEdge)
+{var values=[];for(var i=0;i=Math.min(x1,x2)-epsilon&&res.x>=Math.min(x3,x4)-epsilon&&res.x<=Math.max(x1,x2)+epsilon&&res.x<=Math.max(x3,x4)+epsilon&&res.y>=Math.min(y1,y2)-epsilon&&res.y>=Math.min(y3,y4)-epsilon&&res.y<=Math.max(y1,y2)+epsilon&&res.y<=Math.max(y3,y4)+epsilon))
+{res=null;}
+return res;}
+function Rect(minPoint,maxPoint){this.minPoint=minPoint;this.maxPoint=maxPoint;};Rect.prototype.center=function()
+{return Point.center(this.minPoint,this.maxPoint);};Rect.prototype.size=function()
+{return this.maxPoint.subtract(this.minPoint);};Rect.prototype.left=function()
+{return this.minPoint.x;};Rect.prototype.top=function()
+{return this.minPoint.y;};Rect.prototype.isIn=function(v)
+{return this.minPoint.x<=v.x&&this.minPoint.y<=v.y&&this.maxPoint.x>v.x&&this.maxPoint.y>v.y;};{let modulDir="entities/edge/";doInclude([include("model/BaseEdge.js",modulDir),include("model/EdgeModel.js",modulDir)])}
+function BaseEdge(vertex1,vertex2,isDirect,weight,upText)
+{this.vertex1=vertex1;this.vertex2=vertex2;this.arrayStyleStart="";this.arrayStyleFinish="";this.isDirect=isDirect;this.weight=0;this.text="";this.useWeight=false;this.id=0;this.model=new EdgeModel();if(upText===undefined)
+this.upText="";else
+this.upText=upText;if(weight!==undefined)
+this.SetWeight(weight);this.ownStyles={};}
+BaseEdge.prototype.copyFrom=function(other)
+{this.vertex1=other.vertex1;this.vertex2=other.vertex2;this.arrayStyleStart=other.arrayStyleStart;this.arrayStyleFinish=other.arrayStyleFinish;this.isDirect=other.isDirect;this.weight=other.weight;this.text=other.text;this.useWeight=other.useWeight;this.id=other.id;this.model=new EdgeModel();this.model.copyFrom(other.model);this.upText=other.upText;this.ownStyles=FullObjectCopy(other.ownStyles);}
+BaseEdge.prototype.SaveToXML=function()
+{return"0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+
+this.model.SaveToXML()+">";}
+BaseEdge.prototype.LoadFromXML=function(xml,graph)
+{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'));this.isDirect=xml.attr('isDirect')=="true";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 shape=data.vertex.currentStyle.GetStyle({},data.vertex).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,data.vertex.mainText);pointsVertex1.push(pointsVertex1[0]);for(var i=0;i=0)?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:parseFloat(xml.attr("model_default"));}
+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);else if(this.type==EdgeModels.curve)
+return this.HitTestCurve(position1,position2,mousePos);return false;}
+EdgeModel.prototype.HitTestLine=function(position1,position2,mousePos,factor)
+{if(factor===undefined)
+{factor=1.0;}
+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*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=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 BaseVertex(x,y,vertexEnumType)
+{this.position=new Point(x,y);this.id=0;this.mainText="";this.upText="";this.vertexEnumType=vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=false;this.ownStyles={};};BaseVertex.prototype.position=new Point(0,0);BaseVertex.prototype.copyFrom=function(other)
+{this.position=new Point(other.position.x,other.position.y);this.id=other.id;this.mainText=other.mainText;this.upText=other.upText;this.vertexEnumType=other.vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=other.hasUndefinedPosition;this.ownStyles=FullObjectCopy(other.ownStyles);}
+BaseVertex.prototype.SaveToXML=function()
+{return"0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+"size=\""+this.model.diameter+"\" "+">";}
+BaseVertex.prototype.LoadFromXML=function(xml)
+{var xmlX=xml.attr('positionX');var xmlY=xml.attr('positionY');this.hasUndefinedPosition=(typeof xmlX==='undefined')||(typeof xmlY==='undefined');this.position=new Point(parseFloat(xmlX),parseFloat(xmlY));this.id=xml.attr('id');this.mainText=xml.attr('mainText');this.upText=xml.attr('upText');if(typeof this.mainText==='undefined')
+this.mainText=this.id;else
+this.mainText=gDecodeFromHTML(this.mainText);if(typeof this.upText==='undefined')
+this.upText="";else
+this.upText=gDecodeFromHTML(this.upText);var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
+{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
+{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
+{if(this.ownStyles[index].ShouldLoad(field))
+this.ownStyles[index][field]=parsedSave[indexField][field];}}}
+var size=xml.attr('size');if(typeof size!=='undefined')
+this.model.diameter=parseInt(size);}
+BaseVertex.prototype.SetId=function(id)
+{this.id=id;if(this.vertexEnumType!=null)
+this.mainText=this.vertexEnumType.GetVertexText(id);}
+BaseVertex.prototype.diameterFactor=function()
+{return new Point(1.0+(this.mainText.length?this.mainText.length/8.0:0),1.5);}
+BaseVertex.prototype.IsUndefinedPosition=function()
+{return this.hasUndefinedPosition;}
+BaseVertex.prototype.HitTest=function(pos)
+{var shape=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).shape:VertexCircleShape;var width=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).lineWidth:0;if(shape==VertexCircleShape)
+{return this.position.distance(pos)-1)
+{this.edges.splice(index,1);}
+this.isMultiGraph=this.checkMutiGraph();}
+Graph.prototype.DeleteVertex=function(vertexObject)
+{var index=this.vertices.indexOf(vertexObject);if(index>-1)
+{for(var i=0;i-1)
+{for(var i=0;imaxWeight)
+{res=edge;maxWeight=edge.weight;}}}
+return res;}
+Graph.prototype.FindEdgeMinIgnoreDirection=function(id1,id2)
+{var res=null;var minWeight=this.infinity;for(var i=0;i.+$/g,/^.+<.+$/g,/^.+-\(\d+\.?\d+\)-.+$/g,/^.+-\(\d+\.?\d+\)\>.+$/g,/^.+<\(\d+\.?\d+\)\-.+$/g];let res=true;for(let i=0;i0||cols[j][vertexIndex]>0)&&j!=vertexIndex)
+{relatedVertex.push(this.vertices[j]);}}
+var diameter=(new VertexModel()).diameter;if(relatedVertex.length>1)
+{for(var j=0;jmaxDistance)
+{var force=(otherVertex.position.subtract(currentVertex.object.position)).normalize(edgeGravityKof*(distance-maxDistance));currentVertex.net_force=currentVertex.net_force.add(force);}}}
+var distanceToCenter=centerPoint.distance(currentVertex.object.position);var force=centerPoint.subtract(currentVertex.object.position).normalize(distanceToCenter*kCenterForce);currentVertex.net_force=currentVertex.net_force.add(force);currentVertex.velocity=currentVertex.velocity.add(currentVertex.net_force);}
+bChanged=false;for(i=0;ivelocityMax)
+{velocity=velocity.normalize(velocityMax);}
+v.object.position=v.object.position.add(velocity);if(velocity.length()>=1)
+{bChanged=true;}}
+k++;}
+var bbox=this.getGraphBBox();if(bbox.size().length()>viewportSize.length()*1000)
+{for(i=0;i=this.vertices.length)
+{var newPos=this.GetRandomPositionOfVertex(matrix,j,viewportSize);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
+if(cols[i][j]>0)
+{var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[i],this.vertices[j],cols[i][j]!=cols[j][i],cols[i][j],true);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
+{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+for(var i=rows.length;i(.+)$/g,/^(.+)<(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)-(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)\>(.+)$/g,/^(.+)<\((\d+|\d+\.?\d+)\)\-(.+)$/g,];let bWeightGraph=false;var newVertices=[];for(var i=0;i=0;--j){if(!line.match(regExp[j])){continue;}
+let groupes=Array.from(line.matchAll(regExp[j]));let groupe=groupes[0];let vetext1Title=groupe[1];let vertex1=this.FindVertexByTitle(vetext1Title);if(vertex1==null){let newPosition=this.GetRandomPosition(viewportSize);vertex1=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex1.mainText=vetext1Title;newVertices.push(vertex1);}
+let vetext2Title=groupe[j<=2?2:3];let vertex2=this.FindVertexByTitle(vetext2Title);if(vertex2==null){let newPosition=this.GetRandomPosition(viewportSize);vertex2=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex2.mainText=vetext2Title;newVertices.push(vertex2);}
+let isDirect=j==1||j==2||j==4||j==5;let weight=1;if(j>2){weight=groupe[2];bWeightGraph=true;}
+let isRevertEdge=j==2||j==5;let nEdgeIndex=this.AddNewEdgeSafe(isRevertEdge?vertex2:vertex1,isRevertEdge?vertex1:vertex2,isDirect,weight,false);this.FixEdgeCurve(nEdgeIndex);break;}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+this.VerticesReposition(viewportSize,newVertices);}}
+Graph.prototype.TestIncidenceMatrix=function(matrix,rowsObj,colsObj,separator)
+{if(separator===undefined)
+{separator=",";}
+var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j=this.vertices.length)
+{var newPos=new Point(0,0);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
+if(cols[j][i]!=0)
+{edgeValue.push(cols[j][i]);edgeIndex.push(j);}}
+if(edgeIndex.length==1)
+{edgeValue.push(edgeValue[0]);edgeIndex.push(edgeIndex[0]);}
+if(edgeIndex.length==2)
+{if(edgeValue[0]!=edgeValue[1])
+{if(edgeValue[1]>0)
+{edgeValue=edgeValue.swap(0,1);edgeIndex=edgeIndex.swap(0,1);}}
+var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[edgeIndex[0]],this.vertices[edgeIndex[1]],edgeValue[0]!=edgeValue[1],Math.abs(edgeValue[1]),false);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
+{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+for(var i=cols.length;i0)
+{res.push(line.substr(0,i));}
+if(i==0)
+{i=1;}
+line=line.substr(i,line.length-i);i=-1;}}
+if(line.length>0)
+{res.push(line);}}
+else
+{for(i=0;i";var header="";var xmlBody="";for(var i=0;i0)
+{additionalField=""}
+return mainHeader+header+xmlBody+""+additionalField+"";}
+Graph.prototype.LoadFromXML=function(xmlText,additionalData)
+{xmlDoc=$.parseXML(xmlText);var $xml=$(xmlDoc);$graphs=$xml.find("graph");var loadedGraphId=0;var loadedEdgeId=0;$graphs.each(function(){loadedGraphId=parseInt($(this).attr('uidGraph'));loadedEdgeId=parseInt($(this).attr('uidEdge'));});if(isNaN(loadedEdgeId))
+{loadedEdgeId=this.edgesOffset;}else if(loadedEdgeId0;}
+Graph.prototype.clampPositions=function(viewportSize)
+{var diameter=(new VertexModel()).diameter;for(i=0;i=2)
+{var curve=this.GetAvailableCurveValue(neighborEdges,edgeObject);if(edgeObject.model.default)
+{edgeObject.model.type=EdgeModels.curve;edgeObject.model.curveValue=curve;}}}
+Graph.prototype.GetAvailableCurveValue=function(neighborEdges,originalEdge)
+{var values=[];for(var i=0;i=Math.min(x1,x2)-epsilon&&res.x>=Math.min(x3,x4)-epsilon&&res.x<=Math.max(x1,x2)+epsilon&&res.x<=Math.max(x3,x4)+epsilon&&res.y>=Math.min(y1,y2)-epsilon&&res.y>=Math.min(y3,y4)-epsilon&&res.y<=Math.max(y1,y2)+epsilon&&res.y<=Math.max(y3,y4)+epsilon))
+{res=null;}
+return res;}
+function Rect(minPoint,maxPoint){this.minPoint=minPoint;this.maxPoint=maxPoint;};Rect.prototype.center=function()
+{return Point.center(this.minPoint,this.maxPoint);};Rect.prototype.size=function()
+{return this.maxPoint.subtract(this.minPoint);};Rect.prototype.left=function()
+{return this.minPoint.x;};Rect.prototype.top=function()
+{return this.minPoint.y;};Rect.prototype.isIn=function(v)
+{return this.minPoint.x<=v.x&&this.minPoint.y<=v.y&&this.maxPoint.x>v.x&&this.maxPoint.y>v.y;};{let modulDir="entities/edge/";doInclude([include("model/BaseEdge.js",modulDir),include("model/EdgeModel.js",modulDir)])}
+function BaseEdge(vertex1,vertex2,isDirect,weight,upText)
+{this.vertex1=vertex1;this.vertex2=vertex2;this.arrayStyleStart="";this.arrayStyleFinish="";this.isDirect=isDirect;this.weight=0;this.text="";this.useWeight=false;this.id=0;this.model=new EdgeModel();if(upText===undefined)
+this.upText="";else
+this.upText=upText;if(weight!==undefined)
+this.SetWeight(weight);this.ownStyles={};}
+BaseEdge.prototype.copyFrom=function(other)
+{this.vertex1=other.vertex1;this.vertex2=other.vertex2;this.arrayStyleStart=other.arrayStyleStart;this.arrayStyleFinish=other.arrayStyleFinish;this.isDirect=other.isDirect;this.weight=other.weight;this.text=other.text;this.useWeight=other.useWeight;this.id=other.id;this.model=new EdgeModel();this.model.copyFrom(other.model);this.upText=other.upText;this.ownStyles=FullObjectCopy(other.ownStyles);}
+BaseEdge.prototype.SaveToXML=function()
+{return"0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+
+this.model.SaveToXML()+">";}
+BaseEdge.prototype.LoadFromXML=function(xml,graph)
+{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'));this.isDirect=xml.attr('isDirect')=="true";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 shape=data.vertex.currentStyle.GetStyle({},data.vertex).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,data.vertex.mainText);pointsVertex1.push(pointsVertex1[0]);for(var i=0;i=0)?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:parseFloat(xml.attr("model_default"));}
+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);else if(this.type==EdgeModels.curve)
+return this.HitTestCurve(position1,position2,mousePos);return false;}
+EdgeModel.prototype.HitTestLine=function(position1,position2,mousePos,factor)
+{if(factor===undefined)
+{factor=1.0;}
+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*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=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 BaseVertex(x,y,vertexEnumType)
+{this.position=new Point(x,y);this.id=0;this.mainText="";this.upText="";this.vertexEnumType=vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=false;this.ownStyles={};};BaseVertex.prototype.position=new Point(0,0);BaseVertex.prototype.copyFrom=function(other)
+{this.position=new Point(other.position.x,other.position.y);this.id=other.id;this.mainText=other.mainText;this.upText=other.upText;this.vertexEnumType=other.vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=other.hasUndefinedPosition;this.ownStyles=FullObjectCopy(other.ownStyles);}
+BaseVertex.prototype.SaveToXML=function()
+{return"0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+"size=\""+this.model.diameter+"\" "+">";}
+BaseVertex.prototype.LoadFromXML=function(xml)
+{var xmlX=xml.attr('positionX');var xmlY=xml.attr('positionY');this.hasUndefinedPosition=(typeof xmlX==='undefined')||(typeof xmlY==='undefined');this.position=new Point(parseFloat(xmlX),parseFloat(xmlY));this.id=xml.attr('id');this.mainText=xml.attr('mainText');this.upText=xml.attr('upText');if(typeof this.mainText==='undefined')
+this.mainText=this.id;else
+this.mainText=gDecodeFromHTML(this.mainText);if(typeof this.upText==='undefined')
+this.upText="";else
+this.upText=gDecodeFromHTML(this.upText);var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
+{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
+{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
+{if(this.ownStyles[index].ShouldLoad(field))
+this.ownStyles[index][field]=parsedSave[indexField][field];}}}
+var size=xml.attr('size');if(typeof size!=='undefined')
+this.model.diameter=parseInt(size);}
+BaseVertex.prototype.SetId=function(id)
+{this.id=id;if(this.vertexEnumType!=null)
+this.mainText=this.vertexEnumType.GetVertexText(id);}
+BaseVertex.prototype.diameterFactor=function()
+{return new Point(1.0+(this.mainText.length?this.mainText.length/8.0:0),1.5);}
+BaseVertex.prototype.IsUndefinedPosition=function()
+{return this.hasUndefinedPosition;}
+BaseVertex.prototype.HitTest=function(pos)
+{var shape=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).shape:VertexCircleShape;var width=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).lineWidth:0;if(shape==VertexCircleShape)
+{return this.position.distance(pos)-1)
+{this.edges.splice(index,1);}
+this.isMultiGraph=this.checkMutiGraph();}
+Graph.prototype.DeleteVertex=function(vertexObject)
+{var index=this.vertices.indexOf(vertexObject);if(index>-1)
+{for(var i=0;i-1)
+{for(var i=0;imaxWeight)
+{res=edge;maxWeight=edge.weight;}}}
+return res;}
+Graph.prototype.FindEdgeMinIgnoreDirection=function(id1,id2)
+{var res=null;var minWeight=this.infinity;for(var i=0;i.+$/g,/^.+<.+$/g,/^.+-\(\d+\.?\d+\)-.+$/g,/^.+-\(\d+\.?\d+\)\>.+$/g,/^.+<\(\d+\.?\d+\)\-.+$/g];let res=true;for(let i=0;i0||cols[j][vertexIndex]>0)&&j!=vertexIndex)
+{relatedVertex.push(this.vertices[j]);}}
+var diameter=(new VertexModel()).diameter;if(relatedVertex.length>1)
+{for(var j=0;jmaxDistance)
+{var force=(otherVertex.position.subtract(currentVertex.object.position)).normalize(edgeGravityKof*(distance-maxDistance));currentVertex.net_force=currentVertex.net_force.add(force);}}}
+var distanceToCenter=centerPoint.distance(currentVertex.object.position);var force=centerPoint.subtract(currentVertex.object.position).normalize(distanceToCenter*kCenterForce);currentVertex.net_force=currentVertex.net_force.add(force);currentVertex.velocity=currentVertex.velocity.add(currentVertex.net_force);}
+bChanged=false;for(i=0;ivelocityMax)
+{velocity=velocity.normalize(velocityMax);}
+v.object.position=v.object.position.add(velocity);if(velocity.length()>=1)
+{bChanged=true;}}
+k++;}
+var bbox=this.getGraphBBox();if(bbox.size().length()>viewportSize.length()*1000)
+{for(i=0;i=this.vertices.length)
+{var newPos=this.GetRandomPositionOfVertex(matrix,j,viewportSize);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
+if(cols[i][j]>0)
+{var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[i],this.vertices[j],cols[i][j]!=cols[j][i],cols[i][j],true);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
+{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+for(var i=rows.length;i(.+)$/g,/^(.+)<(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)-(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)\>(.+)$/g,/^(.+)<\((\d+|\d+\.?\d+)\)\-(.+)$/g,];let bWeightGraph=false;var newVertices=[];for(var i=0;i=0;--j){if(!line.match(regExp[j])){continue;}
+let groupes=Array.from(line.matchAll(regExp[j]));let groupe=groupes[0];let vetext1Title=groupe[1];let vertex1=this.FindVertexByTitle(vetext1Title);if(vertex1==null){let newPosition=this.GetRandomPosition(viewportSize);vertex1=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex1.mainText=vetext1Title;newVertices.push(vertex1);}
+let vetext2Title=groupe[j<=2?2:3];let vertex2=this.FindVertexByTitle(vetext2Title);if(vertex2==null){let newPosition=this.GetRandomPosition(viewportSize);vertex2=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex2.mainText=vetext2Title;newVertices.push(vertex2);}
+let isDirect=j==1||j==2||j==4||j==5;let weight=1;if(j>2){weight=groupe[2];bWeightGraph=true;}
+let isRevertEdge=j==2||j==5;let nEdgeIndex=this.AddNewEdgeSafe(isRevertEdge?vertex2:vertex1,isRevertEdge?vertex1:vertex2,isDirect,weight,false);this.FixEdgeCurve(nEdgeIndex);break;}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+this.VerticesReposition(viewportSize,newVertices);}}
+Graph.prototype.TestIncidenceMatrix=function(matrix,rowsObj,colsObj,separator)
+{if(separator===undefined)
+{separator=",";}
+var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j=this.vertices.length)
+{var newPos=new Point(0,0);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
+if(cols[j][i]!=0)
+{edgeValue.push(cols[j][i]);edgeIndex.push(j);}}
+if(edgeIndex.length==1)
+{edgeValue.push(edgeValue[0]);edgeIndex.push(edgeIndex[0]);}
+if(edgeIndex.length==2)
+{if(edgeValue[0]!=edgeValue[1])
+{if(edgeValue[1]>0)
+{edgeValue=edgeValue.swap(0,1);edgeIndex=edgeIndex.swap(0,1);}}
+var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[edgeIndex[0]],this.vertices[edgeIndex[1]],edgeValue[0]!=edgeValue[1],Math.abs(edgeValue[1]),false);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
+{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+for(var i=cols.length;i0)
+{res.push(line.substr(0,i));}
+if(i==0)
+{i=1;}
+line=line.substr(i,line.length-i);i=-1;}}
+if(line.length>0)
+{res.push(line);}}
+else
+{for(i=0;i";var header="";var xmlBody="";for(var i=0;i0)
+{additionalField=""}
+return mainHeader+header+xmlBody+""+additionalField+"";}
+Graph.prototype.LoadFromXML=function(xmlText,additionalData)
+{xmlDoc=$.parseXML(xmlText);var $xml=$(xmlDoc);$graphs=$xml.find("graph");var loadedGraphId=0;var loadedEdgeId=0;$graphs.each(function(){loadedGraphId=parseInt($(this).attr('uidGraph'));loadedEdgeId=parseInt($(this).attr('uidEdge'));});if(isNaN(loadedEdgeId))
+{loadedEdgeId=this.edgesOffset;}else if(loadedEdgeId0;}
+Graph.prototype.clampPositions=function(viewportSize)
+{var diameter=(new VertexModel()).diameter;for(i=0;i=2)
+{var curve=this.GetAvailableCurveValue(neighborEdges,edgeObject);if(edgeObject.model.default)
+{edgeObject.model.type=EdgeModels.curve;edgeObject.model.curveValue=curve;}}}
+Graph.prototype.GetAvailableCurveValue=function(neighborEdges,originalEdge)
+{var values=[];for(var i=0;i0?element.value:"0")+", ";}
+matrix=matrix+"\n";}
+return matrix;}
+function getCharCode(event)
+{if(event.which==null)
+{return event.keyCode;}
+if(event.which!=0)
+{return event.which;}
+return null;}
+function getChar(event)
+{var k=getCharCode(event)
+return String.fromCharCode(k);}
+function CopyMatrixToTextInput(event)
+{document.getElementById("AdjacencyMatrixFieldPage").value=PackMatrix();if(event)
+{var key=getChar(event);var code=getCharCode(event);console.log(key+" code="+code);if(g_ctrlPressed)
+{var moveFocus=function(offsetX,offsetY)
+{var focused_element=document.activeElement;if(focused_element&&focused_element.name.includes("field"))
+{var name=focused_element.name;var coords=name.replace('field','').split("_");if(coords.length==2)
+{var focusName="field"+(parseInt(coords[0])+offsetY)+"_"+(parseInt(coords[1])+offsetX)
+var element=document.getElementsByName(focusName)[0];if(element)
+{element.focus();}}}}
+switch(code)
+{case 38:{moveFocus(0,-1);break;}
+case 40:{moveFocus(0,1);break;}
+case 37:{moveFocus(-1,0);break;}
+case 39:{moveFocus(1,0);break;}}}}}
+function _ShowTextInput()
+{$("#AdjacencyMatrixFieldPage").show();$("#MatrixForm").hide();$("#TextDescription").show();$("#MatrixDescription").hide();$("#idSeparatorList").show();}
+function _ShowMatrixInput()
+{$("#MatrixForm").show();$("#AdjacencyMatrixFieldPage").hide();$("#TextDescription").hide();$("#MatrixDescription").show();$("#idSeparatorList").hide();}
+function ShowTextInput()
+{_ShowTextInput();document.getElementById("showMatrix").className="btn btn-default";document.getElementById("showText").className="btn btn-default active";}
+function ShowMatrixInput()
+{_ShowMatrixInput();document.getElementById("showMatrix").className="btn btn-default active";document.getElementById("showText").className="btn btn-default";}
+function CopyMatrixToMatrixInput()
+{var graph=new Graph();var colsObj={};var rowsObj={};if(graph.TestAdjacencyMatrix($("#AdjacencyMatrixFieldPage").val(),rowsObj,colsObj))
+{var rows=rowsObj.rows;var cols=colsObj.cols;for(var i=g_MatrixSize;i 0 ? element.value : "0") + ", ";
+ }
+ matrix = matrix + "\n";
+ }
+ return matrix;
+}
+
+function getCharCode(event)
+{
+ if (event.which == null)
+ { // IE
+ return event.keyCode;
+ }
+
+ if (event.which != 0)
+ { // ��� ����� IE
+ return event.which; // ���������
+ }
+
+ return null; // ����. ������
+}
+
+function getChar(event)
+{
+ var k = getCharCode(event)
+ return String.fromCharCode(k); // ���������
+}
+
+function CopyMatrixToTextInput(event)
+{
+ document.getElementById("AdjacencyMatrixFieldPage").value = PackMatrix();
+
+ // Move between cells.
+ if (event)
+ {
+ var key = getChar(event);
+ var code = getCharCode(event);
+ console.log(key + " code=" + code);
+ if (g_ctrlPressed)
+ {
+ var moveFocus = function(offsetX, offsetY)
+ {
+ var focused_element = document.activeElement;
+
+ if (focused_element && focused_element.name.includes("field"))
+ {
+ var name = focused_element.name;
+ var coords = name.replace('field','').split("_");
+ if (coords.length == 2)
+ {
+ var focusName = "field" + (parseInt(coords[0]) + offsetY) + "_" + (parseInt(coords[1]) + offsetX)
+ var element = document.getElementsByName(focusName)[0];
+ if (element)
+ {
+ element.focus();
+ }
+ }
+ }
+ }
+ switch (code)
+ {
+ case 38: // Up
+ {
+ moveFocus(0, -1);
+ break;
+ }
+ case 40: // Down
+ {
+ moveFocus(0, 1);
+ break;
+ }
+ case 37: // Left
+ {
+ moveFocus(-1, 0);
+ break;
+ }
+ case 39: // Right
+ {
+ moveFocus(1, 0);
+ break;
+ }
+ }
+
+ }
+ }
+}
+
+function _ShowTextInput()
+{
+ $( "#AdjacencyMatrixFieldPage" ).show();
+ $( "#MatrixForm" ).hide();
+ $( "#TextDescription").show();
+ $( "#MatrixDescription").hide();
+ $( "#idSeparatorList").show();
+}
+
+function _ShowMatrixInput()
+{
+ $( "#MatrixForm" ).show();
+ $( "#AdjacencyMatrixFieldPage" ).hide();
+ $( "#TextDescription").hide();
+ $( "#MatrixDescription").show();
+ $( "#idSeparatorList").hide();
+}
+
+function ShowTextInput()
+{
+ _ShowTextInput();
+ document.getElementById("showMatrix").className = "btn btn-default";
+ document.getElementById("showText").className = "btn btn-default active";
+}
+
+function ShowMatrixInput()
+{
+ _ShowMatrixInput();
+ document.getElementById("showMatrix").className = "btn btn-default active";
+ document.getElementById("showText").className = "btn btn-default";
+}
+
+function CopyMatrixToMatrixInput()
+{
+ var graph = new Graph();
+
+ var colsObj = {};
+ var rowsObj = {};
+
+ if (graph.TestAdjacencyMatrix($( "#AdjacencyMatrixFieldPage" ).val(), rowsObj, colsObj))
+ {
+ var rows = rowsObj.rows;
+ var cols = colsObj.cols;
+
+ for (var i = g_MatrixSize; i < rows.length; i++)
+ {
+ IncSize();
+ }
+
+ for (var i = 0; i < rows.length; i++)
+ {
+ for (var j = 0; j < rows.length; j++)
+ {
+ var element = document.getElementsByName("field" + i + "_"+ j)[0];
+ element.value = cols[i][j];
+ }
+ }
+ }
+ else
+ {
+ ShowTextInput();
+ }
+}
+
+function CreateInputElement(col, row)
+{
+ var input = document.createElement("input");
+ input.type = "text";
+ input.size = 3;
+ input.name = "field" + col + "_" + row;
+ input.value = 0;
+ input.onkeyup = function(event) {CopyMatrixToTextInput(event);};
+
+ return input;
+}
+
+function InsertBeforeElement(element, beforeName, space)
+{
+ var parent = document.getElementsByName(beforeName)[0].parentNode;
+ var beforeElement = document.getElementsByName(beforeName)[0];
+ parent.insertBefore(element, beforeElement);
+
+ if (space)
+ {
+ // Insert space
+ parent.insertBefore(document.createTextNode( '\u00A0' ), beforeElement);
+ }
+}
+
+function IncSize()
+{
+ // End one more line:
+ for (var i = 0; i < g_MatrixSize; i ++)
+ {
+ var input = CreateInputElement(g_MatrixSize, i);
+ InsertBeforeElement(input, "matrixEnd", true);
+ }
+ var br = document.createElement("br");
+ br.setAttribute("name", "row" + g_MatrixSize);
+ InsertBeforeElement(br, "matrixEnd", false);
+
+ for (var i = 0; i < g_MatrixSize + 1; i ++)
+ {
+ var input = CreateInputElement(i, g_MatrixSize);
+ InsertBeforeElement(input, "row" + i, g_MatrixSize);
+ }
+ g_MatrixSize++;
+ CopyMatrixToTextInput();
+}
+
+function checkFormat()
+{
+ var graph = new Graph();
+ var separator = $("#spaceSep").is(':checked') ? " " : ",";
+
+ if (!graph.TestAdjacencyMatrix($( "#AdjacencyMatrixFieldPage" ).val(), [], [], separator))
+ {
+ $( "#BadFormatMessage" ).show();
+ }
+ else
+ {
+ $( "#BadFormatMessage" ).hide();
+ }
+}
+
+window.onload = function ()
+{
+
+ if (document.getElementById('CreateByAdjacencyMatrix'))
+ {
+ document.getElementById('CreateByAdjacencyMatrix').onclick = function ()
+ {
+ $("#matrixForm").submit();
+ //window.location = "./?matrix=" + $( "#AdjacencyMatrixFieldPage" ).val().replace(/\n/g,'%0A');
+ }
+ }
+
+
+ $( "#AdjacencyMatrixFieldPage" ).on('keyup change', function (eventObject)
+ {
+ checkFormat();
+ });
+
+ $( "#BadFormatMessage" ).hide();
+ $( "#AdjacencyMatrixFieldPage" ).hide();
+
+ $( "#showMatrix" ).on('click', function (eventObject)
+ {
+ _ShowMatrixInput();
+ });
+
+ $( "#showText" ).on('click', function (eventObject)
+ {
+ _ShowTextInput();
+ });
+
+ $('input:radio[name="separator"]').change( function(){
+ checkFormat()
+ });
+
+ CopyMatrixToMatrixInput();
+
+ $(document).keydown(function(event) {
+ if (event.which == "17" || event.which == "91")
+ g_ctrlPressed = true;
+ });
+
+ $(document).keyup(function(event) {
+ if (event.which == "17" || event.which == "91")
+ g_ctrlPressed = false;
+ });
+}
\ No newline at end of file
diff --git a/script/pages/editor/api/index.js b/script/pages/editor/api/index.js
new file mode 100644
index 0000000..dfd1506
--- /dev/null
+++ b/script/pages/editor/api/index.js
@@ -0,0 +1,55 @@
+
+// Global version needs to force reload scripts from server.
+globalVersion = 75;
+
+{
+ let asyncFilesLoad = null;
+ function onloadEditor() {
+ console.log("onload() call");
+ asyncFilesLoad();
+ preLoadPage();
+ postLoadPage();
+ }
+
+ let modulDir = "pages/editor/";
+
+ doInclude ([
+ include ("shared/utils.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/serialization/api/index.js"),
+
+ include ("features/enum_vertices/EnumVertices.js"),
+
+ include ("model/texts.js", modulDir),
+ include ("model/Application.js", modulDir),
+ include ("ui/main.js", modulDir)],
+ onloadEditor);
+
+
+ asyncFilesLoad = function () {
+ 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"),
+ ]);
+ }
+
+}
\ No newline at end of file
diff --git a/script/pages/editor/api/index.js.cache b/script/pages/editor/api/index.js.cache
new file mode 100644
index 0000000..71c29a0
--- /dev/null
+++ b/script/pages/editor/api/index.js.cache
@@ -0,0 +1,2031 @@
+moduleLoader.beginCacheLoading(["/script/shared/utils.js?v=75","/script/entities/graph/api/index.js?v=75","/script/shared/point.js?v=75","/script/entities/edge/api/index.js?v=75","/script/entities/edge/model/BaseEdge.js?v=75","/script/entities/edge/model/EdgeModel.js?v=75","/script/entities/vertex/api/index.js?v=75","/script/entities/vertex/model/BaseVertex.js?v=75","/script/entities/vertex/model/VertexModel.js?v=75","/script/entities/graph/model/Graph.js?v=75","/script/features/draw_graph/api/index.js?v=75","/script/features/draw_graph/model/BaseBackgroundDrawer.js?v=75","/script/features/draw_graph/model/BaseEdgeDrawer.js?v=75","/script/features/draw_graph/model/BaseVertexDrawer.js?v=75","/script/features/algorithms/api/index.js?v=75","/script/features/algorithms/model/Algorithms.js?v=75","/script/features/algorithms/model/BaseTraversal.js?v=75","/script/features/base_handler/index.js?v=75","/script/features/default_handler/index.js?v=75","/script/features/add_vertices_handler/index.js?v=75","/script/features/connect_vertices_handler/index.js?v=75","/script/features/delete_objects_handler/index.js?v=75","/script/features/algorithm_handler/index.js?v=75","/script/features/serialization/api/index.js?v=75","/script/features/serialization/model/GraphMLCreator.js?v=75","/script/features/enum_vertices/EnumVertices.js?v=75","/script/pages/editor/model/texts.js?v=75","/script/pages/editor/model/Application.js?v=75","/script/pages/editor/ui/main.js?v=75",]);globalVersion=75;{let asyncFilesLoad=null;function onloadEditor(){console.log("onload() call");asyncFilesLoad();preLoadPage();postLoadPage();}
+let modulDir="pages/editor/";doInclude([include("shared/utils.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/serialization/api/index.js"),include("features/enum_vertices/EnumVertices.js"),include("model/texts.js",modulDir),include("model/Application.js",modulDir),include("ui/main.js",modulDir)],onloadEditor);asyncFilesLoad=function(){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"),]);}}
+function gEncodeToHTML(str)
+{if(typeof str!=='string')
+return str;return str.replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"').replace(/'/g,''');}
+function gDecodeFromHTML(str)
+{if(typeof str!=='string')
+return str;return str.replace(/'/g,"'").replace(/"/g,'"').replace(/>/g,'>').replace(/</g,'<').replace(/&/g,'&');}
+function FullObjectCopy(obj)
+{var newObj=Object.create(Object.getPrototypeOf(obj));return Object.assign(newObj,obj);}
+function FullArrayCopy(arr)
+{var res=[];arr.forEach(function(element){var copyElement=FullObjectCopy(element);res.push(copyElement);});return res;}
+function formatString(string,params){return string.replace(/{(\d+)}/g,(match,index)=>{return typeof params[index]!=='undefined'?params[index]:match;});}
+{let modulDir="entities/graph/";doInclude([include("shared/point.js"),include("entities/edge/api/index.js"),include("entities/vertex/api/index.js"),include("model/Graph.js",modulDir)])}function Point(x,y){this.x=x||0;this.y=y||0;};Point.prototype.x=null;Point.prototype.y=null;Point.prototype.add=function(v){return new Point(this.x+v.x,this.y+v.y);};Point.prototype.addValue=function(v){return new Point(this.x+v,this.y+v);};Point.prototype.clone=function(){return new Point(this.x,this.y);};Point.prototype.degreesTo=function(v){var dx=this.x-v.x;var dy=this.y-v.y;var angle=Math.atan2(dy,dx);return angle*(180/Math.PI);};Point.prototype.distance=function(v){return Math.sqrt(this.distanceSqr(v));};Point.prototype.distanceSqr=function(v){var x=this.x-v.x;var y=this.y-v.y;return x*x+y*y;};Point.prototype.equals=function(toCompare){return this.x==toCompare.x&&this.y==toCompare.y;};Point.prototype.interpolate=function(v,f){return new Point((this.x+v.x)*f,(this.y+v.y)*f);};Point.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y);};Point.prototype.normalize=function(thickness){var l=this.length();this.x=this.x/l*thickness;this.y=this.y/l*thickness;return new Point(this.x,this.y);};Point.prototype.normalizeCopy=function(thickness){var l=this.length();return new Point(this.x/l*thickness,this.y/l*thickness);};Point.prototype.orbit=function(origin,arcWidth,arcHeight,degrees){var radians=degrees*(Math.PI/180);this.x=origin.x+arcWidth*Math.cos(radians);this.y=origin.y+arcHeight*Math.sin(radians);};Point.prototype.rotate=function(center,degrees){var radians=degrees*(Math.PI/180);offset=this.subtract(center);this.x=offset.x*Math.cos(radians)-offset.y*Math.sin(radians);this.y=offset.x*Math.sin(radians)+offset.y*Math.cos(radians);this.x=this.x+center.x;this.y=this.y+center.y;return this;};Point.prototype.offset=function(dx,dy){this.x+=dx;this.y+=dy;};Point.prototype.subtract=function(v){return new Point(this.x-v.x,this.y-v.y);};Point.prototype.subtractValue=function(value){return new Point(this.x-value,this.y-value);};Point.prototype.multiply=function(value){return new Point(this.x*value,this.y*value);};Point.prototype.toString=function(){return"(x="+this.x+", y="+this.y+")";};Point.prototype.normal=function(){return new Point(-this.y,this.x);};Point.prototype.min=function(point)
+{return new Point(Math.min(this.x,point.x),Math.min(this.y,point.y));};Point.prototype.max=function(point)
+{return new Point(Math.max(this.x,point.x),Math.max(this.y,point.y));};Point.prototype.inverse=function()
+{return new Point(-this.x,-this.y);};Point.prototype.cross=function(point)
+{return this.x*point.y-this.y*point.x;};Point.interpolate=function(pt1,pt2,f){return new Point(pt1.x*(1.0-f)+pt2.x*f,pt1.y*(1.0-f)+pt2.y*f);};Point.polar=function(len,angle){return new Point(len*Math.cos(angle),len*Math.sin(angle));};Point.distance=function(pt1,pt2){var x=pt1.x-pt2.x;var y=pt1.y-pt2.y;return Math.sqrt(x*x+y*y);};Point.center=function(pt1,pt2){return new Point((pt1.x+pt2.x)/2.0,(pt1.y+pt2.y)/2.0);};Point.toString=function(){return x+" "+y;}
+Point.projection=function(point,line1,line2)
+{var x=line2.y-line1.y;var y=line1.x-line2.x;var l=(line1.cross(line2)+line1.cross(point)+line2.cross(point))/(x*(line2.y-line1.y)+y*(line1.x-line2.x));var res=new Point(point.x+x*l,point.y+y*l);return res;}
+Point.hitTest=function(pt11,pt12,pt21,pt22)
+{var res=null;var n=0.0;var x1=pt11.x;var y1=pt11.y;var x2=pt12.x;var y2=pt12.y;var x3=pt21.x;var y3=pt21.y;var x4=pt22.x;var y4=pt22.y;if(y2-y1!=0.0)
+{var q=(x2-x1)/(y1-y2);var sn=(x3-x4)+(y3-y4)*q;if(sn==0.0)
+{return res;}
+var fn=(x3-x1)+(y3-y1)*q;n=fn/sn;}
+else
+{if((y3-y4)==0.0)
+{return res;}
+n=(y3-y1)/(y3-y4);}
+res=new Point(x3+(x4-x3)*n,y3+(y4-y3)*n);var epsilon=1E-5;if(!(res.x>=Math.min(x1,x2)-epsilon&&res.x>=Math.min(x3,x4)-epsilon&&res.x<=Math.max(x1,x2)+epsilon&&res.x<=Math.max(x3,x4)+epsilon&&res.y>=Math.min(y1,y2)-epsilon&&res.y>=Math.min(y3,y4)-epsilon&&res.y<=Math.max(y1,y2)+epsilon&&res.y<=Math.max(y3,y4)+epsilon))
+{res=null;}
+return res;}
+function Rect(minPoint,maxPoint){this.minPoint=minPoint;this.maxPoint=maxPoint;};Rect.prototype.center=function()
+{return Point.center(this.minPoint,this.maxPoint);};Rect.prototype.size=function()
+{return this.maxPoint.subtract(this.minPoint);};Rect.prototype.left=function()
+{return this.minPoint.x;};Rect.prototype.top=function()
+{return this.minPoint.y;};Rect.prototype.isIn=function(v)
+{return this.minPoint.x<=v.x&&this.minPoint.y<=v.y&&this.maxPoint.x>v.x&&this.maxPoint.y>v.y;};{let modulDir="entities/edge/";doInclude([include("model/BaseEdge.js",modulDir),include("model/EdgeModel.js",modulDir)])}
+function BaseEdge(vertex1,vertex2,isDirect,weight,upText)
+{this.vertex1=vertex1;this.vertex2=vertex2;this.arrayStyleStart="";this.arrayStyleFinish="";this.isDirect=isDirect;this.weight=0;this.text="";this.useWeight=false;this.id=0;this.model=new EdgeModel();if(upText===undefined)
+this.upText="";else
+this.upText=upText;if(weight!==undefined)
+this.SetWeight(weight);this.ownStyles={};}
+BaseEdge.prototype.copyFrom=function(other)
+{this.vertex1=other.vertex1;this.vertex2=other.vertex2;this.arrayStyleStart=other.arrayStyleStart;this.arrayStyleFinish=other.arrayStyleFinish;this.isDirect=other.isDirect;this.weight=other.weight;this.text=other.text;this.useWeight=other.useWeight;this.id=other.id;this.model=new EdgeModel();this.model.copyFrom(other.model);this.upText=other.upText;this.ownStyles=FullObjectCopy(other.ownStyles);}
+BaseEdge.prototype.SaveToXML=function()
+{return"0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+
+this.model.SaveToXML()+">";}
+BaseEdge.prototype.LoadFromXML=function(xml,graph)
+{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'));this.isDirect=xml.attr('isDirect')=="true";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 shape=data.vertex.currentStyle.GetStyle({},data.vertex).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,data.vertex.mainText);pointsVertex1.push(pointsVertex1[0]);for(var i=0;i=0)?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:parseFloat(xml.attr("model_default"));}
+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);else if(this.type==EdgeModels.curve)
+return this.HitTestCurve(position1,position2,mousePos);return false;}
+EdgeModel.prototype.HitTestLine=function(position1,position2,mousePos,factor)
+{if(factor===undefined)
+{factor=1.0;}
+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*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=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 BaseVertex(x,y,vertexEnumType)
+{this.position=new Point(x,y);this.id=0;this.mainText="";this.upText="";this.vertexEnumType=vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=false;this.ownStyles={};};BaseVertex.prototype.position=new Point(0,0);BaseVertex.prototype.copyFrom=function(other)
+{this.position=new Point(other.position.x,other.position.y);this.id=other.id;this.mainText=other.mainText;this.upText=other.upText;this.vertexEnumType=other.vertexEnumType;this.model=new VertexModel();this.hasUndefinedPosition=other.hasUndefinedPosition;this.ownStyles=FullObjectCopy(other.ownStyles);}
+BaseVertex.prototype.SaveToXML=function()
+{return"0)?"ownStyles = \""+gEncodeToHTML(JSON.stringify(this.ownStyles))+"\" ":"")+"size=\""+this.model.diameter+"\" "+">";}
+BaseVertex.prototype.LoadFromXML=function(xml)
+{var xmlX=xml.attr('positionX');var xmlY=xml.attr('positionY');this.hasUndefinedPosition=(typeof xmlX==='undefined')||(typeof xmlY==='undefined');this.position=new Point(parseFloat(xmlX),parseFloat(xmlY));this.id=xml.attr('id');this.mainText=xml.attr('mainText');this.upText=xml.attr('upText');if(typeof this.mainText==='undefined')
+this.mainText=this.id;else
+this.mainText=gDecodeFromHTML(this.mainText);if(typeof this.upText==='undefined')
+this.upText="";else
+this.upText=gDecodeFromHTML(this.upText);var ownStyle=xml.attr('ownStyles');if(typeof ownStyle!=='undefined')
+{var parsedSave=gDecodeFromHTML(JSON.parse(ownStyle));for(var indexField in parsedSave)
+{var index=parseInt(indexField);this.ownStyles[index]=FullObjectCopy(this.getStyleFor(index));for(var field in parsedSave[indexField])
+{if(this.ownStyles[index].ShouldLoad(field))
+this.ownStyles[index][field]=parsedSave[indexField][field];}}}
+var size=xml.attr('size');if(typeof size!=='undefined')
+this.model.diameter=parseInt(size);}
+BaseVertex.prototype.SetId=function(id)
+{this.id=id;if(this.vertexEnumType!=null)
+this.mainText=this.vertexEnumType.GetVertexText(id);}
+BaseVertex.prototype.diameterFactor=function()
+{return new Point(1.0+(this.mainText.length?this.mainText.length/8.0:0),1.5);}
+BaseVertex.prototype.IsUndefinedPosition=function()
+{return this.hasUndefinedPosition;}
+BaseVertex.prototype.HitTest=function(pos)
+{var shape=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).shape:VertexCircleShape;var width=this.hasOwnProperty('currentStyle')?this.currentStyle.GetStyle({},this).lineWidth:0;if(shape==VertexCircleShape)
+{return this.position.distance(pos)-1)
+{this.edges.splice(index,1);}
+this.isMultiGraph=this.checkMutiGraph();}
+Graph.prototype.DeleteVertex=function(vertexObject)
+{var index=this.vertices.indexOf(vertexObject);if(index>-1)
+{for(var i=0;i-1)
+{for(var i=0;imaxWeight)
+{res=edge;maxWeight=edge.weight;}}}
+return res;}
+Graph.prototype.FindEdgeMinIgnoreDirection=function(id1,id2)
+{var res=null;var minWeight=this.infinity;for(var i=0;i.+$/g,/^.+<.+$/g,/^.+-\(\d+\.?\d+\)-.+$/g,/^.+-\(\d+\.?\d+\)\>.+$/g,/^.+<\(\d+\.?\d+\)\-.+$/g];let res=true;for(let i=0;i0||cols[j][vertexIndex]>0)&&j!=vertexIndex)
+{relatedVertex.push(this.vertices[j]);}}
+var diameter=(new VertexModel()).diameter;if(relatedVertex.length>1)
+{for(var j=0;jmaxDistance)
+{var force=(otherVertex.position.subtract(currentVertex.object.position)).normalize(edgeGravityKof*(distance-maxDistance));currentVertex.net_force=currentVertex.net_force.add(force);}}}
+var distanceToCenter=centerPoint.distance(currentVertex.object.position);var force=centerPoint.subtract(currentVertex.object.position).normalize(distanceToCenter*kCenterForce);currentVertex.net_force=currentVertex.net_force.add(force);currentVertex.velocity=currentVertex.velocity.add(currentVertex.net_force);}
+bChanged=false;for(i=0;ivelocityMax)
+{velocity=velocity.normalize(velocityMax);}
+v.object.position=v.object.position.add(velocity);if(velocity.length()>=1)
+{bChanged=true;}}
+k++;}
+var bbox=this.getGraphBBox();if(bbox.size().length()>viewportSize.length()*1000)
+{for(i=0;i=this.vertices.length)
+{var newPos=this.GetRandomPositionOfVertex(matrix,j,viewportSize);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
+if(cols[i][j]>0)
+{var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[i],this.vertices[j],cols[i][j]!=cols[j][i],cols[i][j],true);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
+{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+for(var i=rows.length;i(.+)$/g,/^(.+)<(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)-(.+)$/g,/^(.+)-\((\d+|\d+\.?\d+)\)\>(.+)$/g,/^(.+)<\((\d+|\d+\.?\d+)\)\-(.+)$/g,];let bWeightGraph=false;var newVertices=[];for(var i=0;i=0;--j){if(!line.match(regExp[j])){continue;}
+let groupes=Array.from(line.matchAll(regExp[j]));let groupe=groupes[0];let vetext1Title=groupe[1];let vertex1=this.FindVertexByTitle(vetext1Title);if(vertex1==null){let newPosition=this.GetRandomPosition(viewportSize);vertex1=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex1.mainText=vetext1Title;newVertices.push(vertex1);}
+let vetext2Title=groupe[j<=2?2:3];let vertex2=this.FindVertexByTitle(vetext2Title);if(vertex2==null){let newPosition=this.GetRandomPosition(viewportSize);vertex2=this.vertices[this.AddNewVertex(new BaseVertex(newPosition.x,newPosition.y,currentEnumVerticesType))];vertex2.mainText=vetext2Title;newVertices.push(vertex2);}
+let isDirect=j==1||j==2||j==4||j==5;let weight=1;if(j>2){weight=groupe[2];bWeightGraph=true;}
+let isRevertEdge=j==2||j==5;let nEdgeIndex=this.AddNewEdgeSafe(isRevertEdge?vertex2:vertex1,isRevertEdge?vertex1:vertex2,isDirect,weight,false);this.FixEdgeCurve(nEdgeIndex);break;}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+this.VerticesReposition(viewportSize,newVertices);}}
+Graph.prototype.TestIncidenceMatrix=function(matrix,rowsObj,colsObj,separator)
+{if(separator===undefined)
+{separator=",";}
+var bGoodFormat=true;rowsObj.rows=[];rowsObj.rows=matrix.split("\n");for(j=0;j=this.vertices.length)
+{var newPos=new Point(0,0);newVertices.push(new BaseVertex(newPos.x,newPos.y,currentEnumVerticesType));this.AddNewVertex(newVertices[newVertices.length-1]);}
+if(cols[j][i]!=0)
+{edgeValue.push(cols[j][i]);edgeIndex.push(j);}}
+if(edgeIndex.length==1)
+{edgeValue.push(edgeValue[0]);edgeIndex.push(edgeIndex[0]);}
+if(edgeIndex.length==2)
+{if(edgeValue[0]!=edgeValue[1])
+{if(edgeValue[1]>0)
+{edgeValue=edgeValue.swap(0,1);edgeIndex=edgeIndex.swap(0,1);}}
+var nEdgeIndex=this.AddNewEdgeSafe(this.vertices[edgeIndex[0]],this.vertices[edgeIndex[1]],edgeValue[0]!=edgeValue[1],Math.abs(edgeValue[1]),false);this.FixEdgeCurve(nEdgeIndex);if(nEdgeIndex>=0)
+{bWeightGraph=bWeightGraph||this.edges[nEdgeIndex].weight!=1;}}}
+if(!bWeightGraph)
+{this.edges.forEach(function(part,index,theArray){theArray[index].useWeight=false;});}
+for(var i=cols.length;i0)
+{res.push(line.substr(0,i));}
+if(i==0)
+{i=1;}
+line=line.substr(i,line.length-i);i=-1;}}
+if(line.length>0)
+{res.push(line);}}
+else
+{for(i=0;i";var header="";var xmlBody="";for(var i=0;i0)
+{additionalField=""}
+return mainHeader+header+xmlBody+""+additionalField+"";}
+Graph.prototype.LoadFromXML=function(xmlText,additionalData)
+{xmlDoc=$.parseXML(xmlText);var $xml=$(xmlDoc);$graphs=$xml.find("graph");var loadedGraphId=0;var loadedEdgeId=0;$graphs.each(function(){loadedGraphId=parseInt($(this).attr('uidGraph'));loadedEdgeId=parseInt($(this).attr('uidEdge'));});if(isNaN(loadedEdgeId))
+{loadedEdgeId=this.edgesOffset;}else if(loadedEdgeId0;}
+Graph.prototype.clampPositions=function(viewportSize)
+{var diameter=(new VertexModel()).diameter;for(i=0;i=2)
+{var curve=this.GetAvailableCurveValue(neighborEdges,edgeObject);if(edgeObject.model.default)
+{edgeObject.model.type=EdgeModels.curve;edgeObject.model.curveValue=curve;}}}
+Graph.prototype.GetAvailableCurveValue=function(neighborEdges,originalEdge)
+{var values=[];for(var i=0;i0.0)
+{context.globalAlpha=style.commonOpacity;context.fillStyle=style.commonColor;context.fillRect(-rect.minPoint.x,-rect.minPoint.y,rect.size().x+1,rect.size().y+1);this.DrawImage(style,width,height,position,scale);}
+context.globalAlpha=oldOpacity;}
+BaseBackgroundDrawer.prototype.DrawImage=function(style,width,height,position,scale)
+{if(style.image==null){return;}
+var context=this.context;context.clearRect(0,0,style.image.width,style.image.height);context.drawImage(style.image,0,0)}
+const lineDashTypes=[[],[4,4],[12,12],[16,4,4,4],];const WeightTextCenter=0,WeightTextUp=1;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;return this.FixNewFields(baseStyle);}
+BaseEdgeStyle.prototype.FixNewFields=function(style)
+{if(!style.hasOwnProperty('lineDash'))
+style.lineDash=0;if(!style.hasOwnProperty('weightPosition'))
+style.weightPosition=WeightTextCenter;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;}
+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+20,null);}}
+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+10,"16px");}
+if(baseEdge.GetUpText().length>0)
+{this.DrawUpText(positions[0],positions[1],baseEdge.GetUpText(),arcStyle,false,arcStyle.additionalTextColor,-baseEdge.model.width/2-15,null);}}}
+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 16px 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-8-arcStyle.textPadding/2,widthText+arcStyle.textPadding,16+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 12px sans-serif":"bold "+fontSize+" 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;const CommonTextCenter=0,CommonTextUp=1;const DefaultFont="px sans-serif",MainTextFontSize=16,TopTextFontSize=12.0;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,text)
+{var res=[];var width=diameter;var height=diameter;if(text)
+{var tempContext=document.createElement('canvas').getContext('2d');tempContext.font="bold "+MainTextFontSize+DefaultFont;width=tempContext.measureText(text).width+diameter/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));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,text=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,text);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;}}
+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;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;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;}
+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,MainTextFontSize);this.DrawCenterText(baseGraph.position.add(new Point(0,-shapeSize/2.0-9.0)),baseGraph.upText,graphStyle.upTextColor,graphStyle.strokeStyle,false,false,TopTextFontSize);}
+else if(graphStyle.commonTextPosition==CommonTextUp)
+{this.DrawCenterText(baseGraph.position.add(new Point(0,-shapeSize/2.0-7.0)),baseGraph.mainText,graphStyle.mainTextColor,graphStyle.fillStyle,true,false,MainTextFontSize);this.DrawCenterText(baseGraph.position.add(new Point(0,shapeSize/2.0+9.0)),baseGraph.upText,graphStyle.upTextColor,graphStyle.strokeStyle,false,false,TopTextFontSize);}}
+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,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);}
+{let modulDir="features/algorithms/";doInclude([include("model/Algorithms.js",modulDir),include("model/BaseTraversal.js",modulDir)])
+function loadAsyncAlgorithms(onFinish){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;iprocessData+=delimiter+param.name+delimiter+param.value);var res=this.app.processEmscripten(processData);processResult(res);}else{console.log("Use new CGI");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);});}
+return true;}
+BaseAlgorithmEx.prototype.GetNodesPath=function(array,start,count)
+{var res=[];for(var index=start;index";}
+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=""+g_DefaultWeightPreset+"";for(var i=0;i"+edgePreset+"";}
+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+" "+g_selectGroupText+""+" "+g_useContextMenuText+"";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;i0||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+" "+g_selectGroupText+""+" "+g_useContextMenuText+"";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
++""
++""
++""
++"
";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
++""
++" "+g_curveEdge+" "
++" "
++""
++""
++""
++"
";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+" "+g_selectGroupText+"";var hasVertices=false;var hasEdges=false;for(var i=0;i";this.message=this.message
++"    "
++""
+this.message=this.message
++"     "
++""
++"";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=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"+g_selectGroupText+"";});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"
++" "
++""
++" "+baseMessage;}
+ConnectionGraphHandler.checkUseDefaultEdge=function(elem,app)
+{app.setUseDefaultEdge(elem.checked);app.updateMessage();};ConnectionGraphHandler.prototype.GetUseDefaultEdgeCheckBox=function(){if(!this.app.hasDefaultEdge()){return"";}
+return" "+""+" "+"
";}
+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.graph=new Graph();this.app.savedGraphName="";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";var directedHeader="";var undirectedHeader="";var defaultWeight=1.0;var weightKeyId="\"d0\"";var weightNode=""+""+defaultWeight+""+"";var xmlBody="";for(var i=0;i";}
+var hasDirected=false;for(var i=0;i"+arc.weight+"";}
+xmlBody=xmlBody+""+weightData+"":"/>")}
+xml=mainHeader+weightNode+(hasDirected?directedHeader:undirectedHeader)+xmlBody+""
+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="Floyd–Warshall 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_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.";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_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;}
+var globalApplication=null;function Application(document,window)
+{this.document=document;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.userAction=function(){};this.undoStack=[];this.edgeCommonStyle=new CommonEdgeStyle();this.isEdgeCommonStyleCustom=false;this.edgeSelectedStyles=FullArrayCopy(DefaultSelectedEdgeStyles);this.isEdgeSelectedStylesCustom=false;this.edgePrintCommonStyle=new CommonPrintEdgeStyle();this.edgePrintSelectedStyles=FullArrayCopy(DefaultPrintSelectedEdgeStyles);this.vertexCommonStyle=new CommonVertexStyle();this.isVertexCommonStyleCustom=false;this.vertexSelectedVertexStyles=FullArrayCopy(DefaultSelectedGraphStyles);this.isVertexSelectedVertexStylesCustom=false;this.vertexPrintCommonStyle=new CommonPrintVertexStyle();this.vertexPrintSelectedVertexStyles=FullArrayCopy(DefaultPrintSelectedGraphStyles);this.backgroundCommonStyle=new CommonBackgroundStyle();this.backgroundPrintStyle=new PrintBackgroundStyle();this.isBackgroundCommonStyleCustom=false;this.renderPathWithEdges=false;this.edgePresets=[1,3,5,7,11,42];this.maxEdgePresets=6;this.selectionRect=null;this.defaultVertexSize=null;this.defaultEdgeWidth=null;this.processEmscriptenFunction=null;this.defaultEdge=null;this.useDefaultEdge=false;};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.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;ithis.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,this.canvasPosition,this.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,bbox.minPoint.inverse(),this.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,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,bbox.minPoint.inverse(),this.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;i0)
+{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.edgeCommonStyle:ForceCommonStyle;var selectedStyle=(ForceSelectedStyle===undefined)?this.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.edgeCommonStyle,this.edgeSelectedStyles);}
+Application.prototype.UpdateEdgesCurrentStyle=function(ForceCommonStyle,ForceSelectedStyle)
+{for(i=0;i0)
+{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.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.document.getElementById('message').innerHTML=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.SetHandlerMode=function(mode)
+{var manipulationHandlers=["default","addGraph","addArc","delete","findPath","connectedComponent","eulerianLoop"];if(this.handler&&(g_AlgorithmIds.indexOf(mode)>=0||manipulationHandlers.indexOf(mode)>=0))
+{this.handler.RestoreAll();}
+if(mode=="default")
+{this.handler=new DefaultHandler(this);}
+else if(mode=="addGraph")
+{this.handler=new AddGraphHandler(this);}
+else if(mode=="addArc")
+{this.handler=new ConnectionGraphHandler(this);}
+else if(mode=="delete")
+{this.handler=new DeleteGraphHandler(this);}
+else if(mode=="deleteAll")
+{var removeAll=new DeleteAllHandler(this);removeAll.clear();}
+else if(mode=="findPath")
+{this.handler=new FindPathGraphHandler(this);}
+else if(mode=="showAdjacencyMatrix")
+{var showAdjacencyMatrix=new ShowAdjacencyMatrix(this);showAdjacencyMatrix.show();}
+else if(mode=="showIncidenceMatrix")
+{var showIncidenceMatrix=new ShowIncidenceMatrix(this);showIncidenceMatrix.show();}
+else if(mode=="showDistanceMatrix")
+{var showDistanceMatrix=new ShowDistanceMatrix(this);showDistanceMatrix.show();}
+else if(mode=="connectedComponent")
+{this.handler=new ConnectedComponentGraphHandler(this);}
+else if(mode=="saveDialog")
+{var savedDialogGraphHandler=new SavedDialogGraphHandler(this);savedDialogGraphHandler.show();}
+else if(mode=="saveDialogImage")
+{var savedDialogGraphImageHandler=new SavedDialogGraphImageHandler(this);savedDialogGraphImageHandler.showWorkspace();}
+else if(mode=="saveDialogFullImage")
+{var savedDialogGraphImageHandler=new SavedDialogGraphImageHandler(this);savedDialogGraphImageHandler.showFullgraph();}
+else if(mode=="savePrintGraphImage")
+{var savedDialogGraphImageHandler=new SavedDialogGraphImageHandler(this);savedDialogGraphImageHandler.showPrint();}
+else if(mode=="saveSvgGraphImage")
+{var savedDialogGraphImageHandler=new SavedDialogGraphImageHandler(this);savedDialogGraphImageHandler.showSvg();}
+else if(mode=="eulerianLoop")
+{this.handler=new EulerianLoopGraphHandler(this);}
+else if(mode=="GroupRename")
+{var groupRenameVertices=new GroupRenameVertices(this);groupRenameVertices.show();}
+else if(mode=="setupVertexStyle")
+{var setupVertexStyle=new SetupVertexStyle(this);setupVertexStyle.show(0);}
+else if(mode=="setupVertexStyleSelected")
+{var setupVertexStyle=new SetupVertexStyle(this);setupVertexStyle.show(1);}
+else if(mode=="setupEdgeStyle")
+{var setupEdgeStyle=new SetupEdgeStyle(this);setupEdgeStyle.show(0);}
+else if(mode=="setupEdgeStyleSelected")
+{var setupEdgeStyle=new SetupEdgeStyle(this);setupEdgeStyle.show(1);}
+else if(mode=="setupBackgroundStyle")
+{var setupBackgroundStyle=new SetupBackgroundStyle(this);setupBackgroundStyle.show();}
+else if(mode=="graphUndo")
+{if(!this.IsUndoStackEmpty())
+this.Undo();}
+else if(g_AlgorithmIds.indexOf(mode)>=0)
+{this.handler=new AlgorithmGraphHandler(this,g_Algorithms[g_AlgorithmIds.indexOf(mode)](this.graph,this));}
+console.log(mode);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;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))
+{this.userAction("AdjacencyMatrix.Failed");this.ShowAdjacencyMatrixErrorDialog(matrix);}
+else
+{this.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))
+{this.userAction("IncidenceMatrix.Failed");this.ShowIncidenceMatrixErrorDialog(matrix);}
+else
+{this.userAction("IncidenceMatrix.Success");}
+this.updateMessage();this.redrawGraph();wasLoad=true;}
+var pairs=document.getElementById("inputPair").innerHTML;if(pairs.length>0)
+{pairs=pairs.replaceAll('>','>');pairs=pairs.replaceAll('<','<');if(!this.SetPairSmart(pairs))
+{this.userAction("Pair.Failed");this.ShowPairErrorDialog(pairs);}
+else
+{this.userAction("Pair.Success");}
+this.updateMessage();this.redrawGraph();wasLoad=true;}
+if(!wasLoad)
+{var graphName=this.getParameterByName("graph");if(graphName.length<=0)
+{graphName=document.cookie.replace(/(?:(?:^|.*;\s*)graphName\s*\=\s*([^;]*).*$)|^.*$/,"$1");}
+if(graphName.length>0)
+{this.userAction("LoadGraphFromDisk");this.LoadGraphFromDisk(graphName);}}
+if(this.IsUndoStackEmpty())
+document.getElementById('GraphUndo').style.display='none';this.updateMessage();this.redrawGraph();}
+Application.prototype.onLoad=function()
+{this.canvas=this.document.getElementById('canvas');this.SetDefaultHandler()
+this.updateMessage();this.redrawGraph();}
+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+"cgi-bin/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+"cgi-bin/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+"cgi-bin/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 styleSave=this.SaveUserSettings();if(this.savedGraphName.length<=0)
+{this.savedGraphName=this.GetNewGraphName();}
+var app=this;$.ajax({type:"POST",url:"/"+SiteDir+"cgi-bin/saveGraph.php?name="+this.savedGraphName,data:graphAsString,dataType:"text"}).done(function(msg)
+{document.cookie="graphName="+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();$.ajax({type:"POST",url:"/"+SiteDir+"cgi-bin/saveImage.php?name="+imageName+rectParams,data:{base64data:imageBase64Data},dataType:"text",success:function(data){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();$.ajax({type:"POST",url:"/"+SiteDir+"cgi-bin/saveImage.php?name="+imageName+rectParams,data:{base64data:imageBase64Data},dataType:"text",success:function(data){showDialogCallback();}});return imageName;}
+Application.prototype.SaveSVGGraphOnDisk=function(showDialogCallback)
+{var imageName=this.GetNewName();this.stopRenderTimer();var svgText=this._printToSVG();var bbox=this.graph.getGraphBBox();var imageBase64Data=canvas.toDataURL();$.ajax({type:"POST",url:"/"+SiteDir+"cgi-bin/saveSvg.php?name="+imageName,data:{svgdata:svgText},dataType:"text",success:function(data){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.LoadGraphFromDisk=function(graphName)
+{var app=this;$.ajax({type:"GET",url:"/"+SiteDir+"cgi-bin/loadGraph.php?name="+graphName}).done(function(msg)
+{app.LoadGraphFromString(msg);});}
+Application.prototype.GetNewGraphName=function()
+{var name=this.GetNewName();if(this.isVertexCommonStyleCustom||this.isVertexSelectedVertexStylesCustom||this.isBackgroundCommonStyleCustom||this.isEdgeCommonStyleCustom||this.isEdgeSelectedStylesCustom)
+{name=name+"ZZcst";}
+return name;}
+Application.prototype.GetNewName=function()
+{var name="";var possible="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";for(var i=0;i','>');pair=pair.replaceAll('<','<');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,});}
+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=Math.floor(graphBBox.maxPoint.x)&&Math.floor(canvasPositionInverse.y+canvasHeight)>=Math.floor(graphBBox.maxPoint.y));}
+Application.prototype.PushToStack=function(actionName)
+{var object={};object.actionName=actionName;object.graphSave=this.graph.SaveToXML(this.SaveUserSettings());this.undoStack.push(object);while(this.undoStack.length>this.maxUndoStackSize)
+{this.undoStack.shift();}
+document.getElementById('GraphUndo').style.display='inline-block';}
+Application.prototype.Undo=function()
+{if(this.IsUndoStackEmpty())
+return;var state=this.undoStack.pop();this.graph=new Graph();var userSettings={};this.graph.LoadFromXML(state.graphSave,userSettings);if(userSettings.hasOwnProperty("data")&&userSettings["data"].length>0)
+this.LoadUserSettings(userSettings["data"]);this.redrawGraph();if(this.IsUndoStackEmpty())
+document.getElementById('GraphUndo').style.display='none';}
+Application.prototype.ClearUndoStack=function()
+{this.undoStack=[];}
+Application.prototype.IsUndoStackEmpty=function()
+{return(this.undoStack.length<=0);}
+Application.prototype.SaveUserSettings=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 this.EncodeToHTML(res);}
+Application.prototype.LoadUserSettings=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:this.isBackgroundCommonStyleCustom,deep:false});var decoderStr=this.DecodeFromHTML(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(){app.redrawGraph()},1000);});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;entry.value[k].Clear();for(var deepK in parsedSave[entry.field][k])
+{if(k=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.vertexCommonStyle;}
+else if(styleName=="selected")
+{return object!==undefined&&object.hasOwnStyleFor(correctIndex+1)?object.getStyleFor(correctIndex+1):this.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.edgeCommonStyle;}
+else if(styleName=="selected")
+{return object!==undefined&&object.hasOwnStyleFor(correctIndex+1)?object.getStyleFor(correctIndex+1):this.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,backgroundPosition,backgroundStyle,bDrawSelectedRect,forceVertexCommon,forceVertexSelected,forceEdgeCommon,forceEdgeSelected)
+{var backgroundDrawer=new BaseBackgroundDrawer(context);backgroundDrawer.Draw(backgroundStyle,Math.max(this.canvas.width,this.GetRealWidth()),Math.max(this.canvas.height,this.GetRealHeight()),backgroundPosition,this.canvasScale);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;i0)
+{res.push(this.graph.vertices[i]);}}
+return res;}
+Application.prototype.GetSelectedEdges=function()
+{var res=[];for(i=0;i0)
+{res.push(this.graph.edges[i]);}}
+return res;}
+Application.prototype.SetDefaultVertexSize=function(diameter)
+{var oldDefaultDiameter=this.GetDefaultVertexSize();this.defaultVertexSize=diameter;for(i=0;i0)
+{application.multCanvasScale(1.3,e);}
+else
+{application.multCanvasScale(1.0/1.3,e);}}
+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,handlerName)
+{userAction(buttonName+"_shortcut");restButtons(buttonName);application.SetHandlerMode(handlerName);}
+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)
+{application.multCanvasScale(1.5);}
+else if(code==45)
+{application.multCanvasScale(1/1.5);}
+else if(key=='w'||key=='ц')
+{application.onCanvasMove(new Point(0,moveValue));}
+else if(key=='s'||key=='ы')
+{application.onCanvasMove(new Point(0,-moveValue));}
+else if(key=='a'||key=='ф')
+{application.onCanvasMove(new Point(moveValue,0));}
+else if(key=='d'||key=='в')
+{application.onCanvasMove(new Point(-moveValue,0));}
+else if(key=='v'||key=='м')
+{selectHandler('AddGraph','addGraph');}
+else if(key=='e'||key=='у')
+{selectHandler('ConnectGraphs','addArc');}
+else if(key=='r'||key=='к')
+{selectHandler('DeleteObject','delete');}
+else if(key=='m'||key=='ь')
+{selectHandler('Default','default');}
+else if(code==26&&isCtrl)
+{userAction("Key_GraphUndo");application.SetHandlerMode("graphUndo");}}
+$(document).keydown(function(event){if(event.which=="17"||event.which=="91")
+g_ctrlPressed=true;});$(document).keyup(function(){g_ctrlPressed=false;});document.getElementById('ShowAdjacencyMatrix').onclick=function()
+{userAction(this.id);application.SetHandlerMode("showAdjacencyMatrix");}
+document.getElementById('ShowIncidenceMatrix').onclick=function()
+{userAction(this.id);application.SetHandlerMode("showIncidenceMatrix");}
+document.getElementById('ShowDistanceMatrix').onclick=function()
+{userAction(this.id);application.SetHandlerMode("showDistanceMatrix");}
+document.getElementById('GroupRename').onclick=function()
+{userAction(this.id);application.SetHandlerMode("GroupRename");}
+document.getElementById('groupRenameButton').onclick=function()
+{userAction(this.id);application.SetHandlerMode("GroupRename");}
+document.getElementById('Default').onclick=function()
+{userAction(this.id);restButtons('Default');application.SetHandlerMode("default");document.getElementById('Default').className="btn btn-primary btn-sm";}
+document.getElementById('AddGraph').onclick=function()
+{userAction(this.id);restButtons('AddGraph');application.SetHandlerMode(document.getElementById('AddGraph').className!=""?"addGraph":"default");}
+document.getElementById('ConnectGraphs').onclick=function()
+{userAction(this.id);restButtons('ConnectGraphs');application.SetHandlerMode(document.getElementById('ConnectGraphs').className!=""?"addArc":"default");}
+document.getElementById('DeleteObject').onclick=function()
+{userAction(this.id);restButtons('DeleteObject');application.SetHandlerMode(document.getElementById('DeleteObject').className!=""?"delete":"default");}
+document.getElementById('DeleteAll').onclick=function()
+{userAction(this.id);application.SetHandlerMode("deleteAll");}
+document.getElementById('SaveGraph').onclick=function()
+{userAction(this.id);application.SetHandlerMode("saveDialog");}
+document.getElementById('NewGraph').onclick=function()
+{userAction(this.id);application.SetHandlerMode("deleteAll");application.SetDefaultTransformations();}
+document.getElementById('SaveGraphImage').onclick=function()
+{userAction(this.id);application.SetHandlerMode("saveDialogImage");}
+document.getElementById('SaveFullGraphImage').onclick=function()
+{userAction(this.id);application.SetHandlerMode("saveDialogFullImage");}
+document.getElementById('SavePrintGraphImage').onclick=function()
+{userAction(this.id);application.SetHandlerMode("savePrintGraphImage");}
+document.getElementById('SaveSvgGraphImage').onclick=function()
+{userAction(this.id);application.SetHandlerMode("saveSvgGraphImage");}
+document.getElementById('Zoom100').onclick=function()
+{userAction(this.id);application.setCanvasScale(1.0);}
+document.getElementById('Zoom50').onclick=function()
+{userAction(this.id);application.setCanvasScale(50/100);}
+document.getElementById('Zoom25').onclick=function()
+{userAction(this.id);application.setCanvasScale(25/100);}
+document.getElementById('ZoomFit').onclick=function()
+{userAction(this.id);application.OnAutoAdjustViewport();}
+document.getElementById('ZoomIn').onclick=function()
+{userAction(this.id);application.multCanvasScale(1.5);}
+document.getElementById('ZoomOut').onclick=function()
+{userAction(this.id);application.multCanvasScale(1.0/1.5);}
+document.getElementById('MoveWorspace').onclick=function()
+{userAction(this.id);restButtons('Default');application.SetHandlerMode("default");document.getElementById('Default').className="btn btn-primary btn-sm";}
+document.getElementById('SetupVertexStyle').onclick=function()
+{userAction(this.id);application.SetHandlerMode("setupVertexStyle");}
+document.getElementById('SetupVertexStyleSelected').onclick=function()
+{userAction(this.id);application.SetHandlerMode("setupVertexStyleSelected");}
+document.getElementById('SetupEdgeStyle').onclick=function()
+{userAction(this.id);application.SetHandlerMode("setupEdgeStyle");}
+document.getElementById('SetupEdgeStyleSelected').onclick=function()
+{userAction(this.id);application.SetHandlerMode("setupEdgeStyleSelected");}
+document.getElementById('SetupBackgroundStyle').onclick=function()
+{userAction(this.id);application.SetHandlerMode("setupBackgroundStyle");}
+document.getElementById('GraphUndo').onclick=function()
+{userAction(this.id);application.SetHandlerMode("graphUndo");}
+document.getElementById('runUserScript').onclick=function()
+{var el=document.getElementById('userScript');var oldScript=document.getElementById("userScriptSource");if(oldScript)
+{document.head.removeChild(oldScript);}
+var script=document.createElement('script');script.type="text/javascript";script.innerHTML=el.value;script.id="userScriptSource";document.head.appendChild(script);application.SetHandlerMode("user.algorithm");}
+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=application.graph.SaveToXML("");var savedGraphName=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()
+{setTimeout(function()
+{var button=document.getElementById('openAlgorithmList');var buttonRect=button.getBoundingClientRect();var algorithmList=document.getElementById('algorithmList');var delta=buttonRect.right-algorithmList.offsetWidth;if(delta<0)
+{var value=(delta-4)+"px";algorithmList.style.right=value;}
+else
+{algorithmList.style.right="0";}},1);}
+document.getElementById('Fullscreen').onclick=function()
+{var idList=["h1Header","h1Text","navigation","footerContent","bottom_adv"];fullscreen=!fullscreen
+userAction(fullscreen?"fullscreen_on":"fullscreen_off");for(var i=0;i{Module['onRuntimeInitialized']=onRuntimeInitialized;var process=Module.cwrap('ProcessAlgorithm','string',['string']);function onRuntimeInitialized(){application.setEmscripten(process);}})}});Array.prototype.swap=function(x,y){var b=this[x];this[x]=this[y];this[y]=b;return this;}
+moduleLoader.endCacheLoading();
\ No newline at end of file
diff --git a/script/Application.js b/script/pages/editor/model/Application.js
similarity index 100%
rename from script/Application.js
rename to script/pages/editor/model/Application.js
diff --git a/script/texts.js b/script/pages/editor/model/texts.js
similarity index 99%
rename from script/texts.js
rename to script/pages/editor/model/texts.js
index c0e6b1f..36ace26 100644
--- a/script/texts.js
+++ b/script/pages/editor/model/texts.js
@@ -420,10 +420,4 @@ function loadTexts()
g_wrongImageFormatPNGAndJPEG = document.getElementById("wrongImageFormatPNGAndJPEG").innerHTML;
g_wrongImageSizeP1 = document.getElementById("wrongImageSizeP1").innerHTML;
-}
-
-function formatString(string, params) {
- return string.replace(/{(\d+)}/g, (match, index) => {
- return typeof params[index] !== 'undefined' ? params[index] : match;
- });
- }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/script/main.js b/script/pages/editor/ui/main.js
similarity index 94%
rename from script/main.js
rename to script/pages/editor/ui/main.js
index fab0082..0bff681 100644
--- a/script/main.js
+++ b/script/pages/editor/ui/main.js
@@ -1,5 +1,4 @@
-var SiteDir = "";
var DisableEmscripten = false;
var algorithmsVersion = 2;
@@ -33,7 +32,7 @@ var g_ctrlPressed = false;
function restButtons (me)
{
var needSetDefault = false;
- for (var i = 0; i < buttonsList.length; i ++)
+ for (let i = 0; i < buttonsList.length; i ++)
{
if (buttonsList[i] != me)
{
@@ -49,7 +48,7 @@ function restButtons (me)
}
if (needSetDefault)
{
- document.getElementById(buttonsList[i]).className = "btn btn-primary btn-sm";
+ document.getElementById(me).className = "btn btn-primary btn-sm";
}
else
{
@@ -651,31 +650,7 @@ function postLoadPage()
}
// Get algorithms list and load it.
- $.get( "/" + SiteDir + "cgi-bin/getPluginsList.php",
- function( data )
- {
- var scriptList = JSON.parse(data);
-
- var loadOneScript = function()
- {
- if (scriptList.length == 0)
- {
- createAlgorithmMenu();
- }
- else
- {
- var script = document.createElement('script');
- script.src = "/" + SiteDir + "script/" + scriptList[0] + "?v=" + algorithmsVersion;
- scriptList.shift();
- script.onload = loadOneScript;
- script.onerror = loadOneScript;
- document.head.appendChild(script);
- }
- }
-
- loadOneScript();
-
- });
+ loadAsyncAlgorithms(createAlgorithmMenu);
var devTools = document.getElementById('developerTools');
devTools.style.left = 0;
@@ -743,16 +718,16 @@ $(document).ready(function ()
// Try load emscripten implementation
var isMobile = navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(android)|(webOS)/i);
if (!isMobile && !DisableEmscripten) {
- const jsScript = document.createElement('script');
- jsScript.src = '/script/Graphoffline.Emscripten.js?v=1';
- document.body.appendChild(jsScript);
- jsScript.addEventListener('load', () => {
+ let fullPathToGraphffoline = "features/graphoffline/Graphoffline.Emscripten.js";
+ doIncludeAsync ([
+ include (fullPathToGraphffoline),
+ ], () => {
Module['onRuntimeInitialized'] = onRuntimeInitialized;
var process = Module.cwrap('ProcessAlgorithm', 'string', ['string']);
function onRuntimeInitialized() {
application.setEmscripten(process);
}
- });
+ })
}
/*
$(document).ready(function(){
diff --git a/script/canvas2svg.js b/script/shared/canvas2svg.js
similarity index 100%
rename from script/canvas2svg.js
rename to script/shared/canvas2svg.js
diff --git a/script/shared/config.js b/script/shared/config.js
new file mode 100644
index 0000000..69e377a
--- /dev/null
+++ b/script/shared/config.js
@@ -0,0 +1,2 @@
+let SiteDir = ""; // Used for load from sub directory
+let UseCache = true;
\ No newline at end of file
diff --git a/script/shared/loader.js b/script/shared/loader.js
new file mode 100644
index 0000000..7671a38
--- /dev/null
+++ b/script/shared/loader.js
@@ -0,0 +1,199 @@
+var include = function(filename, localDir) {
+ return {filename: filename, localDir: localDir};
+};
+
+class ModuleLoader {
+ constructor(name) {
+ this.loadingStack = [];
+ this.startedLoading = new Set();
+ this.loaded = new Set();
+ this.isRunningSync = false;
+ this.syncLoaded = [];
+ this.cacheLoading = false;
+ this.callsAfterCacheResolve = [];
+ }
+
+ getFullname = function (filename, localDir)
+ {
+ let versionParam = "";
+ if (typeof globalVersion !== 'undefined') {
+ versionParam = "?v=" + globalVersion;
+ }
+ let localDirParam = "";
+ if (typeof localDir !== 'undefined') {
+ localDirParam = localDir;
+ }
+ return "/" + SiteDir + "script/" + localDirParam + filename + "?v=" + globalVersion;
+ }
+
+ isAllLoaded = function (includes)
+ {
+ self = this;
+ return includes.every((inc) => {
+ return self.loaded.has(inc);
+ });
+ }
+
+ load = function (fullFilename, checkQueue, sync) {
+ let self = this;
+
+ let loadError = function()
+ {
+ console.error("Cannot load " + fullFilename);
+ checkQueue();
+ }
+ let loadSuccess = function()
+ {
+ self.loaded.add(fullFilename);
+ console.log(self.loaded.size + ". " + fullFilename);
+ checkQueue();
+ }
+
+ if (this.loaded.has(fullFilename)) {
+ this.isRunning = true;
+ checkQueue();
+ return;
+ }
+
+ var script = document.createElement('script');
+ script.src = fullFilename;
+ script.onload = loadSuccess;
+ script.onerror = loadError;
+ document.head.appendChild(script);
+ this.isRunning = true;
+ if (sync) {
+ this.syncLoaded.push(fullFilename);
+ }
+ }
+
+ loadFromQueue = function (checkQueue) {
+ if (this.loadingStack.length == 0) {
+ return;
+ }
+
+ let fullFilename = this.loadingStack.pop();
+ this.load(fullFilename, checkQueue, true);
+ this.isRunning = true;
+ }
+
+ // Load modules one by one in sync mode.
+ // Call fullLoadedCallback when all modules loaded.
+ doInclude = function (includes, fullLoadedCallback) {
+ let self = this;
+
+ if (this.cacheLoading) {
+ this.callsAfterCacheResolve.push(
+ function() {
+ self.doInclude(includes, fullLoadedCallback);
+ }
+ );
+ return;
+ }
+
+ let checkQueue = function () {
+ if (self.loadingStack.length != 0) {
+ self.loadFromQueue(checkQueue);
+ return;
+ }
+
+ self.isRunning = false;
+ if (typeof fullLoadedCallback === 'undefined' || fullLoadedCallback === null) {
+ return;
+ }
+
+ fullLoadedCallback();
+ }
+
+ let pushToQueue = function (fullFilename) {
+ self.loadingStack.push(fullFilename)
+ self.startedLoading.add(fullFilename);
+ }
+
+ let reversedIncludes = includes.reverse();
+
+ reversedIncludes.forEach((inc) => {
+ let fullFilename = self.getFullname(inc.filename, inc.localDir);
+ if (self.startedLoading.has(fullFilename)) {
+ return;
+ }
+ pushToQueue(fullFilename)
+ });
+
+ if (!self.isRunning) {
+ checkQueue();
+ }
+ }
+
+ // Load modules async start load all modules.
+ // Call fullLoadedCallback when all includes loaded.
+ doIncludeAsync = function (includes, fullLoadedCallback) {
+ let self = this;
+ if (this.cacheLoading) {
+ this.callsAfterCacheResolve.push(
+ function() {
+ self.doIncludeAsync(includes, fullLoadedCallback);
+ }
+ );
+ return;
+ }
+
+ let includesFull = [];
+
+ let checkLoading = function () {
+ self.isRunning = false;
+ if (typeof fullLoadedCallback === 'undefined' || fullLoadedCallback === null) {
+ return;
+ }
+
+ if (!self.isAllLoaded(includesFull)) {
+ return;
+ }
+
+ fullLoadedCallback();
+ }
+
+ let pushToQueue = function (fullFilename) {
+ self.load(fullFilename, checkLoading, false);
+ self.startedLoading.add(fullFilename);
+ }
+
+ let reversedIncludes = includes.reverse();
+
+ reversedIncludes.forEach((inc) => {
+ let fullFilename = self.getFullname(inc.filename, inc.localDir);
+ includesFull.push(fullFilename);
+ if (self.startedLoading.has(fullFilename)) {
+ return;
+ }
+ pushToQueue(fullFilename)
+ });
+
+ checkLoading();
+ }
+
+ beginCacheLoading = function (cachedFiles) {
+ let self = this;
+ cachedFiles.forEach((file) => {
+ self.startedLoading.add(file);
+ self.loaded.add(file);
+ });
+ this.cacheLoading = true;
+ }
+
+ endCacheLoading = function () {
+ this.cacheLoading = false;
+ this.callsAfterCacheResolve.forEach((func) => {
+ func();
+ });
+ }
+}
+
+let moduleLoader = new ModuleLoader();
+
+function doInclude(includes, callback) {
+ moduleLoader.doInclude(includes, callback);
+}
+
+function doIncludeAsync(includes, callback) {
+ moduleLoader.doIncludeAsync(includes, callback);
+}
diff --git a/script/point.js b/script/shared/point.js
old mode 100755
new mode 100644
similarity index 100%
rename from script/point.js
rename to script/shared/point.js
diff --git a/script/utils.js b/script/shared/utils.js
similarity index 82%
rename from script/utils.js
rename to script/shared/utils.js
index 903a74b..a91b040 100644
--- a/script/utils.js
+++ b/script/shared/utils.js
@@ -41,4 +41,10 @@ function FullArrayCopy(arr)
});
return res;
-}
\ No newline at end of file
+}
+
+function formatString(string, params) {
+ return string.replace(/{(\d+)}/g, (match, index) => {
+ return typeof params[index] !== 'undefined' ? params[index] : match;
+ });
+ }
\ No newline at end of file
diff --git a/tpl/create_graph_by_edge_list.php b/tpl/create_graph_by_edge_list.php
index 483e3a5..5f93aba 100644
--- a/tpl/create_graph_by_edge_list.php
+++ b/tpl/create_graph_by_edge_list.php
@@ -1,11 +1,12 @@
-
+
+
+
+
+
+
-
+
+
+
-
-
-
= L('head_no_tags')?>
= L('text')?>
@@ -302,11 +25,11 @@ window.onload = function ()