Browse Source

Fix merge.

Bentley James Oakes 7 years ago
parent
commit
e76becddab
100 changed files with 532 additions and 2180 deletions
  1. BIN
      .etc/tcorepaper.pdf
  2. 1 0
      .gitignore
  3. BIN
      .manual/figures/atompm.pdf
  4. BIN
      .manual/figures/forestCSMM1.pdf
  5. BIN
      .manual/figures/forestCSMM2.pdf
  6. BIN
      .manual/figures/forestMM.pdf
  7. BIN
      .manual/figures/geomctrl_ok.pdf
  8. BIN
      .manual/figures/geomctrl_resize.pdf
  9. BIN
      .manual/figures/geomctrl_resizeH.pdf
  10. BIN
      .manual/figures/geomctrl_resizeW.pdf
  11. BIN
      .manual/figures/geomctrl_rotate.pdf
  12. BIN
      .manual/figures/icon_cloudmgmt.pdf
  13. 0 148
      .manual/figures/icon_compileToASMM.pdf
  14. 0 150
      .manual/figures/icon_compileToCSMM.pdf
  15. BIN
      .manual/figures/icon_compileToPatternMM.pdf
  16. BIN
      .manual/figures/icon_copy.pdf
  17. BIN
      .manual/figures/icon_download.pdf
  18. BIN
      .manual/figures/icon_dropToolbar.pdf
  19. BIN
      .manual/figures/icon_editprefs.pdf
  20. BIN
      .manual/figures/icon_exportSVG.pdf
  21. BIN
      .manual/figures/icon_insertModel.pdf
  22. BIN
      .manual/figures/icon_load.pdf
  23. 0 150
      .manual/figures/icon_loadModel.pdf
  24. BIN
      .manual/figures/icon_loadToolbar.pdf
  25. BIN
      .manual/figures/icon_newTab.pdf
  26. BIN
      .manual/figures/icon_paste.pdf
  27. BIN
      .manual/figures/icon_pause.pdf
  28. BIN
      .manual/figures/icon_play.pdf
  29. 0 149
      .manual/figures/icon_redo.pdf
  30. BIN
      .manual/figures/icon_saveModel.pdf
  31. 0 152
      .manual/figures/icon_saveModelAs.pdf
  32. BIN
      .manual/figures/icon_step.pdf
  33. BIN
      .manual/figures/icon_stop.pdf
  34. BIN
      .manual/figures/icon_toggleVisibleContainmentLinks.pdf
  35. BIN
      .manual/figures/icon_toggledebug.pdf
  36. BIN
      .manual/figures/icon_togglemm.pdf
  37. BIN
      .manual/figures/icon_undo.pdf
  38. BIN
      .manual/figures/icon_validateM.pdf
  39. BIN
      .manual/figures/mainmenum.pdf
  40. BIN
      .manual/manual.pdf
  41. 0 938
      .manual/manual.tex
  42. 24 0
      CHANGES.md
  43. 8 3
      README.md
  44. 0 0
      REFS
  45. 13 13
      client/behavioursc_canvas.js
  46. 6 5
      client/client.js
  47. 3 1
      client/constants.js
  48. 129 42
      client/geometry_utils.js
  49. 70 26
      client/gui_utils.js
  50. 11 7
      client/http_utils.js
  51. 72 11
      client/window_management.js
  52. 185 166
      csworker.js
  53. 10 215
      doc/Makefile
  54. BIN
      doc/_build/doctrees/environment.pickle
  55. BIN
      doc/_build/doctrees/executing_transformation.doctree
  56. BIN
      doc/_build/doctrees/index.doctree
  57. BIN
      doc/_build/doctrees/installation.doctree
  58. BIN
      doc/_build/doctrees/modelling_transformation.doctree
  59. BIN
      doc/_build/doctrees/new_language.doctree
  60. BIN
      doc/_build/doctrees/overview.doctree
  61. BIN
      doc/_build/doctrees/troubleshooting.doctree
  62. BIN
      doc/_build/doctrees/using_language.doctree
  63. BIN
      doc/_build/doctrees/workflows.doctree
  64. 0 4
      doc/_build/html/.buildinfo
  65. BIN
      doc/_build/html/_images/association_option.png
  66. BIN
      doc/_build/html/_images/compilation_toolbar.png
  67. BIN
      doc/_build/html/_images/compile_as.png
  68. BIN
      doc/_build/html/_images/compile_cs.png
  69. BIN
      doc/_build/html/_images/compile_pattern.png
  70. BIN
      doc/_build/html/_images/complex_mapper_example.png
  71. BIN
      doc/_build/html/_images/console.png
  72. BIN
      doc/_build/html/_images/create_new_account.png
  73. BIN
      doc/_build/html/_images/cs_toolbar.png
  74. BIN
      doc/_build/html/_images/debugging_transformation.png
  75. BIN
      doc/_build/html/_images/dragging_selection.png
  76. BIN
      doc/_build/html/_images/drawing_edge.png
  77. BIN
      doc/_build/html/_images/edge_editing.png
  78. BIN
      doc/_build/html/_images/example_rules.png
  79. BIN
      doc/_build/html/_images/example_schedule.png
  80. BIN
      doc/_build/html/_images/first_login_screen.png
  81. BIN
      doc/_build/html/_images/geometry_editing.png
  82. BIN
      doc/_build/html/_images/global_action.png
  83. BIN
      doc/_build/html/_images/global_constraint.png
  84. BIN
      doc/_build/html/_images/instance_tilted_environment.png
  85. BIN
      doc/_build/html/_images/interrupt_pattern.png
  86. BIN
      doc/_build/html/_images/load_pattern_metamodel.png
  87. BIN
      doc/_build/html/_images/load_trafficlights.png
  88. BIN
      doc/_build/html/_images/local_action.png
  89. BIN
      doc/_build/html/_images/local_constraint.png
  90. BIN
      doc/_build/html/_images/main_toolbar.png
  91. BIN
      doc/_build/html/_images/mapper_example.png
  92. BIN
      doc/_build/html/_images/new_formalism.png
  93. BIN
      doc/_build/html/_images/rule_init.png
  94. BIN
      doc/_build/html/_images/something_selected.png
  95. BIN
      doc/_build/html/_images/state.png
  96. BIN
      doc/_build/html/_images/timed_transition.png
  97. BIN
      doc/_build/html/_images/trafficlight_toolbar.png
  98. BIN
      doc/_build/html/_images/trafficlights_as.png
  99. BIN
      doc/_build/html/_images/trafficlights_cs.png
  100. 0 0
      doc/_build/html/_images/transformation_controller.png

BIN
.etc/tcorepaper.pdf


+ 1 - 0
.gitignore

@@ -61,6 +61,7 @@ coverage.xml
 
 
 # Sphinx documentation
 # Sphinx documentation
 docs/_build/
 docs/_build/
+doc/_build/
 
 
 # PyBuilder
 # PyBuilder
 target/
 target/

BIN
.manual/figures/atompm.pdf


BIN
.manual/figures/forestCSMM1.pdf


BIN
.manual/figures/forestCSMM2.pdf


BIN
.manual/figures/forestMM.pdf


BIN
.manual/figures/geomctrl_ok.pdf


BIN
.manual/figures/geomctrl_resize.pdf


BIN
.manual/figures/geomctrl_resizeH.pdf


BIN
.manual/figures/geomctrl_resizeW.pdf


BIN
.manual/figures/geomctrl_rotate.pdf


BIN
.manual/figures/icon_cloudmgmt.pdf


+ 0 - 148
.manual/figures/icon_compileToASMM.pdf

@@ -1,148 +0,0 @@
-%PDF-1.4 
-1 0 obj
-<<
-/Pages 2 0 R
-/Type /Catalog
->>
-endobj
-2 0 obj
-<<
-/Type /Pages
-/Kids [ 3 0 R ]
-/Count 1
->>
-endobj
-3 0 obj
-<<
-/Type /Page
-/Parent 2 0 R
-/Resources <<
-/XObject << /Im0 8 0 R >>
-/ProcSet 6 0 R >>
-/MediaBox [0 0 32 32]
-/CropBox [0 0 32 32]
-/Contents 4 0 R
-/Thumb 11 0 R
->>
-endobj
-4 0 obj
-<<
-/Length 5 0 R
->>
-stream
-q
-32 0 0 32 0 0 cm
-/Im0 Do
-Q
-endstream
-endobj
-5 0 obj
-29
-endobj
-6 0 obj
-[ /PDF /Text /ImageC ]
-endobj
-7 0 obj
-<<
->>
-endobj
-8 0 obj
-<<
-/Type /XObject
-/Subtype /Image
-/Name /Im0
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace 10 0 R
-/BitsPerComponent 8
-/SMask 15 0 R
-/Length 9 0 R
->>
-stream
-xÚ…Ï‹‚0ЊF|‹ŠDå55ÆWÄÿÿ7×n#q]Ø	in¹d@Ó|;4ÍÇãíñòx¸<Q¼»P
oªÊWÝ拃é1×̹ªu�[ÅœªJÕ´-€CÈVÚKD�Di+�~_QäyaÉ$ó½�fL*™úpH™½Ôö{n'µçï¸é:Ù&LŒ¨¥´�-›kÀ©Ž£+ÈK¡5²-—‘îi]psó;¸ÌL�yÊML�ËØEÕGaÈ�yè1ðè{½NÁÖ–W
-endstream
-endobj
-9 0 obj
-206
-endobj
-10 0 obj
-/DeviceGray
-endobj
-11 0 obj
-<<
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace 10 0 R
-/BitsPerComponent 8
-/Length 12 0 R
->>
-stream
-xÚ…Ï‹‚0ЊF|‹ŠDå55ÆWÄÿÿ7×n#q]Ø	in¹d@Ó|;4ÍÇãíñòx¸<Q¼»P
oªÊWÝ拃é1×̹ªu�[ÅœªJÕ´-€CÈVÚKD�Di+�~_QäyaÉ$ó½�fL*™úpH™½Ôö{n'µçï¸é:Ù&LŒ¨¥´�-›kÀ©Ž£+ÈK¡5²-—‘îi]psó;¸ÌL�yÊML�ËØEÕGaÈ�yè1ðè{½NÁÖ–W
-endstream
-endobj
-12 0 obj
-206
-endobj
-13 0 obj
-endobj
-14 0 obj
-206
-endobj
-15 0 obj
-<<
-/Type /XObject
-/Subtype /Image
-/Name /Ma0
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace /DeviceGray
-/BitsPerComponent 8
-/Length 16 0 R
->>
-stream
-xÚµ“QÄ0D‘€„H@B$TB¥œƒ“€„J‰„HˆJÚ´w7ä£sû—<†,³„ªªb-�?hCèb�§Cvp91 ÃyppFJ!/˜SÀ7\%ûþÞÚ¢`æÏåaWÏ+ZC�~P,Ö›—_ ßœš<â^ÁÌß÷|¶Ã[¯žúˆí^Ü ÊŸq‰ó/ç¯bÞ&\(ÞOÍ?ýäÿDu‚ã\iX(¡
-endstream
-endobj
-16 0 obj
-167
-endobj
-17 0 obj
-<<
-/Title (compileToASMM.icon.png.pdf)
-/CreationDate (D:20120323152053)
-/ModDate (D:20120323152053)
-/Producer (ImageMagick 6.6.0-4 2011-06-15 Q16 http://www.imagemagick.org)
->>
-endobj
-xref
-0 18
-0000000000 65535 f 
-0000000010 00000 n 
-0000000059 00000 n 
-0000000118 00000 n 
-0000000296 00000 n 
-0000000377 00000 n 
-0000000395 00000 n 
-0000000433 00000 n 
-0000000454 00000 n 
-0000000854 00000 n 
-0000000873 00000 n 
-0000000901 00000 n 
-0000001247 00000 n 
-0000001267 00000 n 
-0000001283 00000 n 
-0000001303 00000 n 
-0000001657 00000 n 
-0000001677 00000 n 
-trailer
-<<
-/Size 18
-/Info 17 0 R
-/Root 1 0 R
->>
-startxref
-1870
-%%EOF

+ 0 - 150
.manual/figures/icon_compileToCSMM.pdf

@@ -1,150 +0,0 @@
-%PDF-1.4 
-1 0 obj
-<<
-/Pages 2 0 R
-/Type /Catalog
->>
-endobj
-2 0 obj
-<<
-/Type /Pages
-/Kids [ 3 0 R ]
-/Count 1
->>
-endobj
-3 0 obj
-<<
-/Type /Page
-/Parent 2 0 R
-/Resources <<
-/XObject << /Im0 8 0 R >>
-/ProcSet 6 0 R >>
-/MediaBox [0 0 32 32]
-/CropBox [0 0 32 32]
-/Contents 4 0 R
-/Thumb 11 0 R
->>
-endobj
-4 0 obj
-<<
-/Length 5 0 R
->>
-stream
-q
-32 0 0 32 0 0 cm
-/Im0 Do
-Q
-endstream
-endobj
-5 0 obj
-29
-endobj
-6 0 obj
-[ /PDF /Text /ImageC ]
-endobj
-7 0 obj
-<<
->>
-endobj
-8 0 obj
-<<
-/Type /XObject
-/Subtype /Image
-/Name /Im0
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace 10 0 R
-/BitsPerComponent 8
-/SMask 15 0 R
-/Length 9 0 R
->>
-stream
-xÚmÒÛ‚0EÑ#ŠÑhŒä&¢hŒF#þÿ¿	b;-œõ2�ìÇNó!hoJú‹’þ¤¤?(éwJú�’~¥¤_É8Ûê¶“
UUu³}?šPš[Ùõƒ(Íå§í…@^ä@¦å�TC’Ž$Ø+ò²Ä
-¢˜ˆB!((_�OyÊΣä'¶”ô
%}MI_QÆ),	óT„uKó‘Á±¹3‹‹¡©„3ùsúý+ÛNÞ
-endstream
-endobj
-9 0 obj
-173
-endobj
-10 0 obj
-/DeviceGray
-endobj
-11 0 obj
-<<
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace 10 0 R
-/BitsPerComponent 8
-/Length 12 0 R
->>
-stream
-xÚmÒÛ‚0EÑ#ŠÑhŒä&¢hŒF#þÿ¿	b;-œõ2�ìÇNó!hoJú‹’þ¤¤?(éwJú�’~¥¤_É8Ûê¶“
UUu³}?šPš[Ùõƒ(Íå§í…@^ä@¦å�TC’Ž$Ø+ò²Ä
-¢˜ˆB!((_�OyÊΣä'¶”ô
%}MI_QÆ),	óT„uKó‘Á±¹3‹‹¡©„3ùsúý+ÛNÞ
-endstream
-endobj
-12 0 obj
-173
-endobj
-13 0 obj
-endobj
-14 0 obj
-173
-endobj
-15 0 obj
-<<
-/Type /XObject
-/Subtype /Image
-/Name /Ma0
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace /DeviceGray
-/BitsPerComponent 8
-/Length 16 0 R
->>
-stream
-xÚÕ’A
D!DG�€$ )8©¤ ¡øÉÏ(Ù½î»ÑGHi§tBÁ SþÜëÝ«äqó-;XŒ‡ í½(áô¾ÎSõ›ÏHjZIÆÒÞlZ|s^w¯ËëµÔá�MjÂü(f4æG1^6õÍ—O{Îsÿ{xÓóÿMÏç³D�Îw�îg…í×^8óa9óµ³çóv~Éô
-endstream
-endobj
-16 0 obj
-157
-endobj
-17 0 obj
-<<
-/Title (compileToCSMM.icon.png.pdf)
-/CreationDate (D:20120323152053)
-/ModDate (D:20120323152053)
-/Producer (ImageMagick 6.6.0-4 2011-06-15 Q16 http://www.imagemagick.org)
->>
-endobj
-xref
-0 18
-0000000000 65535 f 
-0000000010 00000 n 
-0000000059 00000 n 
-0000000118 00000 n 
-0000000296 00000 n 
-0000000377 00000 n 
-0000000395 00000 n 
-0000000433 00000 n 
-0000000454 00000 n 
-0000000821 00000 n 
-0000000840 00000 n 
-0000000868 00000 n 
-0000001181 00000 n 
-0000001201 00000 n 
-0000001217 00000 n 
-0000001237 00000 n 
-0000001581 00000 n 
-0000001601 00000 n 
-trailer
-<<
-/Size 18
-/Info 17 0 R
-/Root 1 0 R
->>
-startxref
-1794
-%%EOF

BIN
.manual/figures/icon_compileToPatternMM.pdf


BIN
.manual/figures/icon_copy.pdf


BIN
.manual/figures/icon_download.pdf


BIN
.manual/figures/icon_dropToolbar.pdf


BIN
.manual/figures/icon_editprefs.pdf


BIN
.manual/figures/icon_exportSVG.pdf


BIN
.manual/figures/icon_insertModel.pdf


BIN
.manual/figures/icon_load.pdf


+ 0 - 150
.manual/figures/icon_loadModel.pdf

@@ -1,150 +0,0 @@
-%PDF-1.4 
-1 0 obj
-<<
-/Pages 2 0 R
-/Type /Catalog
->>
-endobj
-2 0 obj
-<<
-/Type /Pages
-/Kids [ 3 0 R ]
-/Count 1
->>
-endobj
-3 0 obj
-<<
-/Type /Page
-/Parent 2 0 R
-/Resources <<
-/XObject << /Im0 8 0 R >>
-/ProcSet 6 0 R >>
-/MediaBox [0 0 32 32]
-/CropBox [0 0 32 32]
-/Contents 4 0 R
-/Thumb 11 0 R
->>
-endobj
-4 0 obj
-<<
-/Length 5 0 R
->>
-stream
-q
-32 0 0 32 0 0 cm
-/Im0 Do
-Q
-endstream
-endobj
-5 0 obj
-29
-endobj
-6 0 obj
-[ /PDF /Text /ImageC ]
-endobj
-7 0 obj
-<<
->>
-endobj
-8 0 obj
-<<
-/Type /XObject
-/Subtype /Image
-/Name /Im0
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace 10 0 R
-/BitsPerComponent 8
-/SMask 15 0 R
-/Length 9 0 R
->>
-stream
-xÚ­ÏÍ
-‚`…á‰~Ȥ¢Å4-Š>-³û¿·<cA¡gV=‹Ù¼ÌÀˆ4Ï·FÕ��z(ß¿Üú¹úÕë®dœC¿Ð/ô³ýÔCQ­,ynfÉ2»§i7™äÐæ„‹±¾�©=âBô�Cè;NÜrÚ7òjÍ¡/9=ïsÈÞ‚CŸsz~ÆiŸL)ícNûˆ’?xÝc;0
-endstream
-endobj
-9 0 obj
-151
-endobj
-10 0 obj
-/DeviceGray
-endobj
-11 0 obj
-<<
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace 10 0 R
-/BitsPerComponent 8
-/Length 12 0 R
->>
-stream
-xÚ­ÏÍ
-‚`…á‰~Ȥ¢Å4-Š>-³û¿·<cA¡gV=‹Ù¼ÌÀˆ4Ï·FÕ��z(ß¿Üú¹úÕë®dœC¿Ð/ô³ýÔCQ­,ynfÉ2»§i7™äÐæ„‹±¾�©=âBô�Cè;NÜrÚ7òjÍ¡/9=ïsÈÞ‚CŸsz~ÆiŸL)ícNûˆ’?xÝc;0
-endstream
-endobj
-12 0 obj
-151
-endobj
-13 0 obj
-endobj
-14 0 obj
-151
-endobj
-15 0 obj
-<<
-/Type /XObject
-/Subtype /Image
-/Name /Ma0
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace /DeviceGray
-/BitsPerComponent 8
-/Length 16 0 R
->>
-stream
-xÚ­ÓA„0Ð/¡�P	H¨”JÀA%T�P	•€„0awg™ÒŸràzyC“f䛌nêÏ%öx‘ü�Ý~ñênž…eŸÔ…gyÇó#"&C*lÏzÖc™ç�(úy¤\“úJ={H'ÏÜ]»�î°QOxP>p?Ë'ÊÌá~6ÀñëçAùÁ¯ÍÿÓ&^ïíö^È!¨{3
-endstream
-endobj
-16 0 obj
-159
-endobj
-17 0 obj
-<<
-/Title (loadModel.icon.png.pdf)
-/CreationDate (D:20120322115414)
-/ModDate (D:20120322115414)
-/Producer (ImageMagick 6.6.0-4 2011-06-15 Q16 http://www.imagemagick.org)
->>
-endobj
-xref
-0 18
-0000000000 65535 f 
-0000000010 00000 n 
-0000000059 00000 n 
-0000000118 00000 n 
-0000000296 00000 n 
-0000000377 00000 n 
-0000000395 00000 n 
-0000000433 00000 n 
-0000000454 00000 n 
-0000000799 00000 n 
-0000000818 00000 n 
-0000000846 00000 n 
-0000001137 00000 n 
-0000001157 00000 n 
-0000001173 00000 n 
-0000001193 00000 n 
-0000001539 00000 n 
-0000001559 00000 n 
-trailer
-<<
-/Size 18
-/Info 17 0 R
-/Root 1 0 R
->>
-startxref
-1748
-%%EOF

BIN
.manual/figures/icon_loadToolbar.pdf


BIN
.manual/figures/icon_newTab.pdf


BIN
.manual/figures/icon_paste.pdf


BIN
.manual/figures/icon_pause.pdf


BIN
.manual/figures/icon_play.pdf


+ 0 - 149
.manual/figures/icon_redo.pdf

@@ -1,149 +0,0 @@
-%PDF-1.4 
-1 0 obj
-<<
-/Pages 2 0 R
-/Type /Catalog
->>
-endobj
-2 0 obj
-<<
-/Type /Pages
-/Kids [ 3 0 R ]
-/Count 1
->>
-endobj
-3 0 obj
-<<
-/Type /Page
-/Parent 2 0 R
-/Resources <<
-/XObject << /Im0 8 0 R >>
-/ProcSet 6 0 R >>
-/MediaBox [0 0 32 32]
-/CropBox [0 0 32 32]
-/Contents 4 0 R
-/Thumb 11 0 R
->>
-endobj
-4 0 obj
-<<
-/Length 5 0 R
->>
-stream
-q
-32 0 0 32 0 0 cm
-/Im0 Do
-Q
-endstream
-endobj
-5 0 obj
-29
-endobj
-6 0 obj
-[ /PDF /Text /ImageC ]
-endobj
-7 0 obj
-<<
->>
-endobj
-8 0 obj
-<<
-/Type /XObject
-/Subtype /Image
-/Name /Im0
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace 10 0 R
-/BitsPerComponent 8
-/SMask 15 0 R
-/Length 9 0 R
->>
-stream
-xÚÝÒQ‚0Àñ“$R33L͈[¶¾ÿ‡ëvÓÙFÛkÐïepÿ=mð/8Mø—:>?�r6ªÌ:ÆhƦ<ÜMÂCæÞŠòÍŽúÕNäîbÕ‰Þ*çÖ„¹ž4�¸ÜÔ:€J:ÍOQi <Jê©Êy"”P�ƒÊûB9Qy—ë –Ê)YzjˆQb~v"Äd‹"ËÆDhƒ\[µCçÖAà쾿rvσŸzи14
-endstream
-endobj
-9 0 obj
-173
-endobj
-10 0 obj
-/DeviceGray
-endobj
-11 0 obj
-<<
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace 10 0 R
-/BitsPerComponent 8
-/Length 12 0 R
->>
-stream
-xÚÝÒQ‚0Àñ“$R33L͈[¶¾ÿ‡ëvÓÙFÛkÐïepÿ=mð/8Mø—:>?�r6ªÌ:ÆhƦ<ÜMÂCæÞŠòÍŽúÕNäîbÕ‰Þ*çÖ„¹ž4�¸ÜÔ:€J:ÍOQi <Jê©Êy"”P�ƒÊûB9Qy—ë –Ê)YzjˆQb~v"Äd‹"ËÆDhƒ\[µCçÖAà쾿rvσŸzи14
-endstream
-endobj
-12 0 obj
-173
-endobj
-13 0 obj
-endobj
-14 0 obj
-173
-endobj
-15 0 obj
-<<
-/Type /XObject
-/Subtype /Image
-/Name /Ma0
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace /DeviceGray
-/BitsPerComponent 8
-/Length 16 0 R
->>
-stream
-xÚÝ’QÄ D‘€$ 	•P	HˆƒJ@B% 	H@B.4@¡wðÛ™ÛOÞ&d3â_¤¬Ç¬è¶T:¼w~Ó
›„ƒ¼"P¼ãSIFÃxÃo%Â<YÂ‰Ž‹ûF?ë^ƒdë�\xºr�WÐñ3
-xr±©«èEU‰{o²Oc…-¾†‡€ÛÃSÀ“uŽóS¦¬Ò‡�½ÁÝ«É@µQš('C¶|3ûêªïxª¼‚%OrÉ=ˆWõ‘µdÞ
-endstream
-endobj
-16 0 obj
-194
-endobj
-17 0 obj
-<<
-/Title (redo.icon.png.pdf)
-/CreationDate (D:20120322115414)
-/ModDate (D:20120322115414)
-/Producer (ImageMagick 6.6.0-4 2011-06-15 Q16 http://www.imagemagick.org)
->>
-endobj
-xref
-0 18
-0000000000 65535 f 
-0000000010 00000 n 
-0000000059 00000 n 
-0000000118 00000 n 
-0000000296 00000 n 
-0000000377 00000 n 
-0000000395 00000 n 
-0000000433 00000 n 
-0000000454 00000 n 
-0000000821 00000 n 
-0000000840 00000 n 
-0000000868 00000 n 
-0000001181 00000 n 
-0000001201 00000 n 
-0000001217 00000 n 
-0000001237 00000 n 
-0000001618 00000 n 
-0000001638 00000 n 
-trailer
-<<
-/Size 18
-/Info 17 0 R
-/Root 1 0 R
->>
-startxref
-1822
-%%EOF

BIN
.manual/figures/icon_saveModel.pdf


+ 0 - 152
.manual/figures/icon_saveModelAs.pdf

@@ -1,152 +0,0 @@
-%PDF-1.4 
-1 0 obj
-<<
-/Pages 2 0 R
-/Type /Catalog
->>
-endobj
-2 0 obj
-<<
-/Type /Pages
-/Kids [ 3 0 R ]
-/Count 1
->>
-endobj
-3 0 obj
-<<
-/Type /Page
-/Parent 2 0 R
-/Resources <<
-/XObject << /Im0 8 0 R >>
-/ProcSet 6 0 R >>
-/MediaBox [0 0 31.996 31.996]
-/CropBox [0 0 31.996 31.996]
-/Contents 4 0 R
-/Thumb 11 0 R
->>
-endobj
-4 0 obj
-<<
-/Length 5 0 R
->>
-stream
-q
-31.996 0 0 31.996 0 0 cm
-/Im0 Do
-Q
-endstream
-endobj
-5 0 obj
-37
-endobj
-6 0 obj
-[ /PDF /Text /ImageC ]
-endobj
-7 0 obj
-<<
->>
-endobj
-8 0 obj
-<<
-/Type /XObject
-/Subtype /Image
-/Name /Im0
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace 10 0 R
-/BitsPerComponent 8
-/SMask 15 0 R
-/Length 9 0 R
->>
-stream
-xÚ…Ñ‹r‚0„áíÝ­T[´Vð"¢8¥ïÿnÝ%N&´|c<˜P�ú÷¶º~þ‡s‡ªÃ‘N8Z'à¤yÇ’€Ò̧Ë(
-KÝ�9¹¥}wîØYÚwgJ@jiß�[¶–öݹ&`m­€•Ù3»K–-êš	I‹ºæ‚pƒÚ7µKݼ«}Q+WçJCmF^+@ó|¥ZD^/öû|߬Bíƒü/ϲ4Õ+ƒÚ„ü¾¹üS¨½“OqÌ»O’8^¨…ääyssð†oäžÏKžòŠ£h:›©äÿþxbŒ¡6$¿�Bcµ>yy¯A³šÖ£·÷\:g Ô{¾êÉ=^uo�:ÜuøMN³
-endstream
-endobj
-9 0 obj
-271
-endobj
-10 0 obj
-/DeviceGray
-endobj
-11 0 obj
-<<
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace 10 0 R
-/BitsPerComponent 8
-/Length 12 0 R
->>
-stream
-xÚ…Ñ‹r‚0„áíÝ­T[´Vð"¢8¥ïÿnÝ%N&´|c<˜P�ú÷¶º~þ‡s‡ªÃ‘N8Z'à¤yÇ’€Ò̧Ë(
-KÝ�9¹¥}wîØYÚwgJ@jiß�[¶–öݹ&`m­€•Ù3»K–-êš	I‹ºæ‚pƒÚ7µKݼ«}Q+WçJCmF^+@ó|¥ZD^/öû|߬Bíƒü/ϲ4Õ+ƒÚ„ü¾¹üS¨½“OqÌ»O’8^¨…ääyssð†oäžÏKžòŠ£h:›©äÿþxbŒ¡6$¿�Bcµ>yy¯A³šÖ£·÷\:g Ô{¾êÉ=^uo�:ÜuøMN³
-endstream
-endobj
-12 0 obj
-271
-endobj
-13 0 obj
-endobj
-14 0 obj
-271
-endobj
-15 0 obj
-<<
-/Type /XObject
-/Subtype /Image
-/Name /Ma0
-/Filter [ /FlateDecode ]
-/Width 32
-/Height 32
-/ColorSpace /DeviceGray
-/BitsPerComponent 8
-/Length 16 0 R
->>
-stream
-xÚÍ‘Û
à E=‚GÉ�<Š7@ê"ŒÀŒÐá–EIZÚŸ*	ƒ�ð‹Š±êB„Ké„Cñ…Â!JK¹¬–(<7ß±
-¢~k†'œîÈ÷þ|þ§ŸëÇל¹¯1·kÎà!W!¬›º\�Ø`œ ~ü„Ò ?ä¶
-»œÅbVÒÍ‹oÝ‘Oýáý4ÿ´~§ÿàÏï�?¨Nð‚á�ó
-endstream
-endobj
-16 0 obj
-159
-endobj
-17 0 obj
-<<
-/Title (saveModelAs.icon.png.pdf)
-/CreationDate (D:20120322115414)
-/ModDate (D:20120322115414)
-/Producer (ImageMagick 6.6.0-4 2011-06-15 Q16 http://www.imagemagick.org)
->>
-endobj
-xref
-0 18
-0000000000 65535 f 
-0000000010 00000 n 
-0000000059 00000 n 
-0000000118 00000 n 
-0000000312 00000 n 
-0000000401 00000 n 
-0000000419 00000 n 
-0000000457 00000 n 
-0000000478 00000 n 
-0000000943 00000 n 
-0000000962 00000 n 
-0000000990 00000 n 
-0000001401 00000 n 
-0000001421 00000 n 
-0000001437 00000 n 
-0000001457 00000 n 
-0000001803 00000 n 
-0000001823 00000 n 
-trailer
-<<
-/Size 18
-/Info 17 0 R
-/Root 1 0 R
->>
-startxref
-2014
-%%EOF

BIN
.manual/figures/icon_step.pdf


BIN
.manual/figures/icon_stop.pdf


BIN
.manual/figures/icon_toggleVisibleContainmentLinks.pdf


BIN
.manual/figures/icon_toggledebug.pdf


BIN
.manual/figures/icon_togglemm.pdf


BIN
.manual/figures/icon_undo.pdf


BIN
.manual/figures/icon_validateM.pdf


BIN
.manual/figures/mainmenum.pdf


BIN
.manual/manual.pdf


File diff suppressed because it is too large
+ 0 - 938
.manual/manual.tex


+ 24 - 0
CHANGES.md

@@ -4,6 +4,30 @@ All notable changes to AToMPM will be documented in this file.
 
 
 ## [Unreleased]
 ## [Unreleased]
 
 
+## [0.8.0] - 2018-06-21
+
+### Added
+- Replace Documentation button with About button in main toolbar. About dialog provides information on current and newest versions of AToMPM, and links to website and documentation
+- Add explicit 'verify' event for constraints/actions, triggered when the user presses the 'verify model' button
+- Add additional information when errors occur during abstract syntax or concrete syntax compilation
+- Add a plugin for producing Ecore models from metamodels
+- Add tabbing through attributes in editing dialog, as well as in workflow parameter dialog.
+- Sort toolbars by name for consistency
+- A default icon is loaded for toolbar buttons if the button icon could not be found
+
+### Fixed
+- Correctly open toolbars in the CreateDSL Workflow
+- Add Firefox detection of mouse wheel, so that geometry controls work
+- Reset key state when window gains focus, to avoid input issues
+- Fix crash where alternate concrete syntax for an abstract syntax would not be loaded 
+
+### Removed
+- Merged information in manual into the AToMPM documentation
+
+## Other
+- Extended tests to load all toolbars, and to programmatically create a domain-specific language
+
+
 ## [0.7.0] - 2018-05-16
 ## [0.7.0] - 2018-05-16
 
 
 ### Added
 ### Added

+ 8 - 3
README.md

@@ -10,7 +10,9 @@ To install AToMPM, follow these steps:
     * Or visit http://python.org/download/
     * Or visit http://python.org/download/
 * Download and install python-igraph
 * Download and install python-igraph
     * Use the pip package manager (comes with Python)
     * Use the pip package manager (comes with Python)
-    * `pip install python-igraph`
+        * `pip install python-igraph`
+    * For Windows, you may need to install the compiled igraph core
+        * `http://www.lfd.uci.edu/~gohlke/pythonlibs/#python-igraph`
 * Download and install node.js
 * Download and install node.js
     * Use a package manager on Linux
     * Use a package manager on Linux
     * Or visit https://nodejs.org/en/download/
     * Or visit https://nodejs.org/en/download/
@@ -20,11 +22,14 @@ To install AToMPM, follow these steps:
 
 
 ## Usage
 ## Usage
 
 
+The commands below are for starting the ATOMPM server. Note that the default port is 8124.
+
+Once started, the server can be connected to by accessing http://localhost:8124/atompm in either the Firefox or Chrome browsers.
+
 ### Windows
 ### Windows
 To run AToMPM on Windows, execute the `run.bat` script inside of the main AToMPM folder.
 To run AToMPM on Windows, execute the `run.bat` script inside of the main AToMPM folder.
 
 
 ### Mac or Linux
 ### Mac or Linux
-
 * Execute commands in different terminals
 * Execute commands in different terminals
     1. Execute `node httpwsd.js` in the main AToMPM folder
     1. Execute `node httpwsd.js` in the main AToMPM folder
     2. Execute `python2 mt\main.py` in the main AToMPM folder
     2. Execute `python2 mt\main.py` in the main AToMPM folder
@@ -37,7 +42,7 @@ To run AToMPM on Windows, execute the `run.bat` script inside of the main AToMPM
 
 
 
 
 ## Documentation
 ## Documentation
-Documentation can be found here: https://msdl.uantwerpen.be/documentation/AToMPM/index.html
+Documentation can be found here: https://atompm.readthedocs.io
 
 
 ## Testing
 ## Testing
 To run tests on AToMPM, run `npm test'
 To run tests on AToMPM, run `npm test'

.etc/REFS → REFS


+ 13 - 13
client/behavioursc_canvas.js

@@ -18,19 +18,19 @@ __canvasBehaviourStatechart = {
 			function(event)
 			function(event)
 			{
 			{
 				GUIUtils.disableDock();
 				GUIUtils.disableDock();
-				__initCanvasSelectionOverlay(GUIUtils.convertToCanvasX(event.pageX), GUIUtils.convertToCanvasY(event.pageY));
+				__initCanvasSelectionOverlay(GUIUtils.convertToCanvasX(event), GUIUtils.convertToCanvasY(event));
 			},
 			},
 		3:
 		3:
 			function(event)	
 			function(event)	
 			{
 			{
 				GUIUtils.disableDock();
 				GUIUtils.disableDock();
-				GeometryUtils.initSelectionTransformationPreviewOverlay(GUIUtils.convertToCanvasX(event.pageX), GUIUtils.convertToCanvasY(event.pageY));
+				GeometryUtils.initSelectionTransformationPreviewOverlay(GUIUtils.convertToCanvasX(event), GUIUtils.convertToCanvasY(event));
 			},
 			},
 		4:
 		4:
 			function(event)	
 			function(event)	
 			{
 			{
 				GUIUtils.disableDock();
 				GUIUtils.disableDock();
-				ConnectionUtils.initConnectionPath(GUIUtils.convertToCanvasX(event.pageX), GUIUtils.convertToCanvasY(event.pageY),event.target);
+				ConnectionUtils.initConnectionPath(GUIUtils.convertToCanvasX(event), GUIUtils.convertToCanvasY(event),event.target);
 			},
 			},
 		6:
 		6:
 			function(event)	
 			function(event)	
@@ -92,7 +92,7 @@ __canvasBehaviourStatechart = {
 			if( this.__currentState == this.__STATE_IDLE )
 			if( this.__currentState == this.__STATE_IDLE )
 			{
 			{
 				if( name == __EVENT_RIGHT_RELEASE_CANVAS )
 				if( name == __EVENT_RIGHT_RELEASE_CANVAS )
-					DataUtils.create(GUIUtils.convertToCanvasX(event.pageX), GUIUtils.convertToCanvasY(event.pageY));
+					DataUtils.create(GUIUtils.convertToCanvasX(event), GUIUtils.convertToCanvasY(event));
 			
 			
 				else if( name == __EVENT_LEFT_PRESS_CANVAS )
 				else if( name == __EVENT_LEFT_PRESS_CANVAS )
 					this.__T(this.__STATE_CANVAS_SELECTING,event);
 					this.__T(this.__STATE_CANVAS_SELECTING,event);
@@ -151,7 +151,7 @@ __canvasBehaviourStatechart = {
 			else if( this.__currentState == this.__STATE_CANVAS_SELECTING )
 			else if( this.__currentState == this.__STATE_CANVAS_SELECTING )
 			{
 			{
 				if( name == __EVENT_MOUSE_MOVE ){
 				if( name == __EVENT_MOUSE_MOVE ){
-					__updateCanvasSelectionOverlay(GUIUtils.convertToCanvasX(event.pageX), GUIUtils.convertToCanvasY(event.pageY));
+					__updateCanvasSelectionOverlay(GUIUtils.convertToCanvasX(event), GUIUtils.convertToCanvasY(event));
 				}
 				}
 				
 				
 				else if( name == __EVENT_LEFT_RELEASE_CANVAS ||
 				else if( name == __EVENT_LEFT_RELEASE_CANVAS ||
@@ -266,7 +266,7 @@ __canvasBehaviourStatechart = {
 			else if( this.__currentState == this.__STATE_DRAGGING_SELECTION )
 			else if( this.__currentState == this.__STATE_DRAGGING_SELECTION )
 			{
 			{
 				if( name == __EVENT_MOUSE_MOVE )
 				if( name == __EVENT_MOUSE_MOVE )
-					GeometryUtils.previewSelectionTranslation(GUIUtils.convertToCanvasX(event.pageX), GUIUtils.convertToCanvasY(event.pageY));
+					GeometryUtils.previewSelectionTranslation(GUIUtils.convertToCanvasX(event), GUIUtils.convertToCanvasY(event));
 				
 				
 				else if( name == __EVENT_KEYUP_ESC )
 				else if( name == __EVENT_KEYUP_ESC )
 				{
 				{
@@ -315,7 +315,7 @@ __canvasBehaviourStatechart = {
 			else if( this.__currentState == this.__STATE_DRAWING_EDGE )
 			else if( this.__currentState == this.__STATE_DRAWING_EDGE )
 			{
 			{
 				if( name == __EVENT_MOUSE_MOVE ){
 				if( name == __EVENT_MOUSE_MOVE ){
-					ConnectionUtils.updateConnectionSegment(GUIUtils.convertToCanvasX(event.pageX), GUIUtils.convertToCanvasY(event.pageY));
+					ConnectionUtils.updateConnectionSegment(GUIUtils.convertToCanvasX(event), GUIUtils.convertToCanvasY(event));
 				}
 				}
 				else if( name == __EVENT_KEYUP_ESC ||
 				else if( name == __EVENT_KEYUP_ESC ||
 							name == __EVENT_RIGHT_RELEASE_CANVAS )
 							name == __EVENT_RIGHT_RELEASE_CANVAS )
@@ -378,9 +378,9 @@ __canvasBehaviourStatechart = {
 				else if( name == __EVENT_MIDDLE_RELEASE_CTRL_POINT )
 				else if( name == __EVENT_MIDDLE_RELEASE_CTRL_POINT )
 					ConnectionUtils.deleteControlPoint(event.target);
 					ConnectionUtils.deleteControlPoint(event.target);
 		
 		
-				else if( name == __EVENT_RIGHT_RELEASE_CTRL_POINT )
-					ConnectionUtils.addControlPoint(GUIUtils.convertToCanvasX(event.pageX), GUIUtils.convertToCanvasY(event.pageY),event.target);
-						
+				else if( name == __EVENT_RIGHT_RELEASE_CTRL_POINT ) {
+                    ConnectionUtils.addControlPoint(GUIUtils.convertToCanvasX(event), GUIUtils.convertToCanvasY(event), event.target);
+				}
 				else if( name == __EVENT_KEYUP_TAB )
 				else if( name == __EVENT_KEYUP_TAB )
 					ConnectionUtils.snapControlPoint();
 					ConnectionUtils.snapControlPoint();
 		
 		
@@ -404,9 +404,9 @@ __canvasBehaviourStatechart = {
 
 
 			else if( this.__currentState == this.__STATE_DRAGGING_CONNECTION_PATH_CTRL_POINT )
 			else if( this.__currentState == this.__STATE_DRAGGING_CONNECTION_PATH_CTRL_POINT )
 			{
 			{
-				if( name == __EVENT_MOUSE_MOVE )
-					ConnectionUtils.previewControlPointTranslation(GUIUtils.convertToCanvasX(event.pageX), GUIUtils.convertToCanvasY(event.pageY));
-		
+				if( name == __EVENT_MOUSE_MOVE ) {
+                    ConnectionUtils.previewControlPointTranslation(GUIUtils.convertToCanvasX(event), GUIUtils.convertToCanvasY(event));
+				}
 				else if( name == __EVENT_LEFT_RELEASE_CTRL_POINT )
 				else if( name == __EVENT_LEFT_RELEASE_CTRL_POINT )
 				{
 				{
 					ConnectionUtils.updateConnectionPath();
 					ConnectionUtils.updateConnectionPath();

+ 6 - 5
client/client.js

@@ -1022,11 +1022,12 @@ function __relativizeURL(url)
 
 
 
 
 /* returns the csuri of the icon that contains the specified VisualObject */
 /* returns the csuri of the icon that contains the specified VisualObject */
-function __vobj2uri(vobj)
-{
-	if( vobj != document.body )
-		return vobj.parentNode.getAttribute('__csuri') ||
-				 __vobj2uri(vobj.parentNode);
+function __vobj2uri(vobj) {
+    if (vobj != document.body) {
+        return vobj.parentNode.getAttribute('__csuri') ||
+            vobj.parentNode.getAttribute('__linkuri') ||
+            __vobj2uri(vobj.parentNode);
+    }
 }
 }
 
 
 function __getRecentDir(name) {
 function __getRecentDir(name) {

+ 3 - 1
client/constants.js

@@ -5,7 +5,9 @@
 
 
 /****************************** GLOBAL CONSTANTS ******************************/
 /****************************** GLOBAL CONSTANTS ******************************/
 var __WEBPAGE__ = 'https://atompm.github.io/',
 var __WEBPAGE__ = 'https://atompm.github.io/',
-    __VERSION__ = '0.7.0',
+	__RELEASE_LOC__ = "https://api.github.com/repos/AToMPM/atompm/releases/latest",
+	__DOC_WEBPAGE__ = "https://atompm.readthedocs.io",
+    __VERSION__ = '0.8.0',
     __DEFAULT_SAVEAS		 	= '.autosave.model',
     __DEFAULT_SAVEAS		 	= '.autosave.model',
 	 __TITLE						= 'AToMPM',
 	 __TITLE						= 'AToMPM',
 	 __EXITWARNING				= 'There are unsaved changes. Proceeding will cause'+
 	 __EXITWARNING				= 'There are unsaved changes. Proceeding will cause'+

+ 129 - 42
client/geometry_utils.js

@@ -509,48 +509,61 @@ GeometryUtils = function(){
 		  						 offsetTy + parseFloat(icon.getAttr('__y'))];
 		  						 offsetTy + parseFloat(icon.getAttr('__y'))];
 					}
 					}
 	 				uris2changes[it] = changes;
 	 				uris2changes[it] = changes;
-	
-	
-					if( ! __isConnectionType(it) )
-					{
-						/* have edge ends out follow */
-						__icons[it]['edgesOut'].forEach(
-							function(edgeId)
-							{
-								var linkuri = __edgeId2linkuri(edgeId);
-								if( __isSelected(linkuri) )
-									return;
-					
-								var segments = __edges[edgeId]['segments'],
-									 points	 = segments.match(/([\d\.]*,[\d\.]*)/g),
-									 xy 		 = utils.head(points).split(','),
-									 newXY 	 = GeometryUtils.transformPoint(xy[0],xy[1],T);
-										 
-								connectedEdgesChanges[linkuri] = 
-									(connectedEdgesChanges[linkuri] || {});
-								points.splice(0,1,newXY.join(','));
-								connectedEdgesChanges[linkuri][edgeId] = 
-									'M'+points.join('L');
-							});
-	
-						/* have edge ends in follow */
-						__icons[it]['edgesIn'].forEach(
-							function(edgeId)
-							{
-								var linkuri = __edgeId2linkuri(edgeId);
-								if( __isSelected(linkuri) )
-									return;
-				
-								var segments = __edges[edgeId]['segments'],
-									 points	 = segments.match(/([\d\.]*,[\d\.]*)/g),
-									 xy 		 = utils.tail(points).split(','),
-									 newXY 	 = GeometryUtils.transformPoint(xy[0],xy[1],T);
-								connectedEdgesChanges[linkuri] = 
-									(connectedEdgesChanges[linkuri] || {});
-								points.splice(points.length-1,1,newXY.join(','));
-								connectedEdgesChanges[linkuri][edgeId] = 
-									'M'+points.join('L');
-							});
+
+
+                    if (!__isConnectionType(it)) {
+                        let inLinkUris = __icons[it]['edgesIn'].map(__edgeId2linkuri);
+                        let outLinkUris = __icons[it]['edgesOut'].map(__edgeId2linkuri);
+                        /* have edge ends out follow */
+                        __icons[it]['edgesOut'].forEach(
+                            function (edgeId) {
+                                let linkuri = __edgeId2linkuri(edgeId);
+                                if (__isSelected(linkuri))
+                                    return;
+
+                                let isLooping = inLinkUris.includes(linkuri);
+                                let changes = moveEdges(edgeId, T, true, isLooping);
+                                let newEdgeChanges = changes[0];
+                                let centrePoint = changes[1];
+
+                                connectedEdgesChanges[linkuri] =
+                                    (connectedEdgesChanges[linkuri] || {});
+                                connectedEdgesChanges[linkuri] = utils.mergeDicts([connectedEdgesChanges[linkuri], newEdgeChanges]);
+
+                                //move the assoc text if the central point changed
+                                if (centrePoint != null) {
+                                    if (uris2changes[__edgeId2linkuri(edgeId)] == null) {
+                                        uris2changes[__edgeId2linkuri(edgeId)] = {};
+                                    }
+                                    uris2changes[__edgeId2linkuri(edgeId)]['position'] = centrePoint;
+                                }
+
+                            });
+
+                        /* have edge ends in follow */
+                        __icons[it]['edgesIn'].forEach(
+                            function (edgeId) {
+                                let linkuri = __edgeId2linkuri(edgeId);
+                                if (__isSelected(linkuri))
+                                    return;
+
+                                let isLooping = outLinkUris.includes(linkuri);
+                                let changes = moveEdges(edgeId, T, false, isLooping);
+                                let newEdgeChanges = changes[0];
+                                let centrePoint = changes[1];
+
+                                connectedEdgesChanges[linkuri] =
+                                    (connectedEdgesChanges[linkuri] || {});
+                                connectedEdgesChanges[linkuri] = utils.mergeDicts([connectedEdgesChanges[linkuri], newEdgeChanges]);
+
+                                //move the assoc text if the central point changed
+                                if (centrePoint != null) {
+                                    if (uris2changes[__edgeId2linkuri(edgeId)] == null) {
+                                        uris2changes[__edgeId2linkuri(edgeId)] = {};
+                                    }
+                                    uris2changes[__edgeId2linkuri(edgeId)]['position'] = centrePoint;
+                                }
+                            });
 					}
 					}
 					else
 					else
 					{
 					{
@@ -632,6 +645,80 @@ GeometryUtils = function(){
 					insertRequests));
 					insertRequests));
 		}
 		}
 	};
 	};
+
+    /**
+     * Moves the points for this edge using the transformation T
+     * If the edge is only comprised of three points
+     * (the point on the icon, the central point, and the connected node's point)
+     * then move the central point
+	 * Returns the changes to be made to the edges, and the central point if calculated
+     */
+    this.moveEdges = function (edgeId, T, isOutDir, isLooping) {
+
+        let segments = __edges[edgeId]['segments'];
+        let points = segments.match(/([\d\.]*,[\d\.]*)/g);
+
+        let xy = null;
+        let newXY = null;
+
+        //update the point connected to the icon
+        if (isOutDir) {
+            xy = utils.head(points).split(',');
+            newXY = GeometryUtils.transformPoint(xy[0], xy[1], T);
+            points.splice(0, 1, newXY.join(','));
+        } else {
+            xy = utils.tail(points).split(',');
+            newXY = GeometryUtils.transformPoint(xy[0], xy[1], T);
+            points.splice(points.length - 1, 1, newXY.join(','));
+        }
+
+        //dict to hold edge updates
+        let edgeDict = {};
+
+        // the centre point if the association text should be moved
+        let centrePoint = null;
+
+        // if there are exactly two points in this edge,
+        // move the middle control point as well
+        // by updating the other edge in the association
+        //
+        //don't do this if it's a looping edge
+        //as it will overwrite the changes
+        if (points.length == 2 && !isLooping) {
+            let connectionPartici = __getConnectionParticipants(edgeId);
+            let otherEdge = isOutDir ? connectionPartici[2] : connectionPartici[1];
+
+            let otherSegments = __edges[otherEdge]['segments'];
+            let otherPoints = otherSegments.match(/([\d\.]*,[\d\.]*)/g);
+
+            //get the other edge's point which is not the center point
+            let otherxy = isOutDir ? otherPoints[1] : otherPoints[otherPoints.length - 2];
+            otherxy = otherxy.split(",");
+
+            let xCentrePoint = (parseFloat(newXY[0]) + parseFloat(otherxy[0])) / 2;
+            let yCentrePoint = (parseFloat(newXY[1]) + parseFloat(otherxy[1])) / 2;
+
+            let centrePointStr = xCentrePoint + "," + yCentrePoint;
+
+            if (isOutDir) {
+                points.splice(points.length - 1, 1, centrePointStr);
+                otherPoints.splice(0, 1, centrePointStr);
+            } else {
+                points.splice(0, 1, centrePointStr);
+                otherPoints.splice(otherPoints.length - 1, 1, centrePointStr);
+            }
+
+            let newOtherEdge = 'M' + otherPoints.join('L');
+            edgeDict[otherEdge] = newOtherEdge;
+
+            centrePoint = [xCentrePoint, yCentrePoint];
+        }
+
+        let newEdge = 'M' + points.join('L');
+        edgeDict[edgeId] = newEdge;
+
+        return [edgeDict, centrePoint];
+    };
 	
 	
 	/**
 	/**
 	 * Apply the specified transformation to the given point and return
 	 * Apply the specified transformation to the given point and return

+ 70 - 26
client/gui_utils.js

@@ -15,15 +15,25 @@ GUIUtils = function(){
 	/**
 	/**
 	 * Converts from page centric X coordinates to canvas centric X coordinates
 	 * Converts from page centric X coordinates to canvas centric X coordinates
 	 */
 	 */
-	this.convertToCanvasX = function(pageX){
-		return pageX + $('#div_container').scrollLeft() - $('#contentDiv').offset().left;
+	this.convertToCanvasX = function(event){
+
+		//experimental property
+		return event.offsetX;
+
+		//breaks when page is scrolled
+		//return event.pageX + $('#div_container').scrollLeft() - $('#contentDiv').offset().left;
 	};
 	};
 
 
 	/**
 	/**
 	 * Converts from page centric Y coordinates to canvas centric Y coordinates
 	 * Converts from page centric Y coordinates to canvas centric Y coordinates
-	 */	
-	this.convertToCanvasY = function(pageY){
-		return pageY + $('#div_container').scrollTop() - $('#contentDiv').offset().top;
+	 */
+	this.convertToCanvasY = function(event){
+
+		//experimental property
+		return event.offsetY;
+
+		//breaks when page is scrolled
+		//return event.pageY + $('#div_container').scrollTop() - $('#contentDiv').offset().top;
 	};
 	};
 	
 	
 	/**
 	/**
@@ -309,27 +319,21 @@ GUIUtils = function(){
 				
 				
 				return true;
 				return true;
 			}
 			}
-            // https://media.giphy.com/media/12XMGIWtrHBl5e/giphy.gif
-			else if( event.keyCode == KEY_ENTER )
-			{
-                if (rows > 1) {
-                    // only for multi-line input fields
-                    var cursorPos = event.target.selectionStart;
-                    input.val( 
-                            input.val().substring(0,cursorPos)+'\r\n'+
-                            input.val().substring(cursorPos));
-                    input.get(0).setSelectionRange(cursorPos+1,cursorPos+1);
+
+            else if (event.keyCode == KEY_ENTER) {
+                //for single row fields, don't create a new line
+                if (rows == 1) {
+                    event.preventDefault();
                 }
                 }
-				event.stopPropagation();
-                event.preventDefault();
-				return true;
-			}
+            }
 		});
 		});
-        input.keyup( function (event) {
-			if( event.keyCode == KEY_ENTER )
-			{
-				event.stopPropagation();
-                event.preventDefault();
+        input.keyup(function (event) {
+            if (event.keyCode == KEY_ENTER) {
+                //don't send the enter key for multi-line fields
+                //this closes the window
+                if (rows > 1) {
+                    event.stopPropagation();
+                }
             }
             }
         });
         });
 		return input;
 		return input;
@@ -462,8 +466,48 @@ GUIUtils = function(){
 			dialog.append(cancel);
 			dialog.append(cancel);
 		}
 		}
 
 
-		BehaviorManager.setActiveBehaviourStatechart(__SC_DIALOG);
-		BehaviorManager.handleUserEvent(__EVENT_SHOW_DIALOG);
+        dialog.keydown(function (event) {
+
+            //tab through the fields
+            if (event.key == "Tab") {
+
+                try {
+                    if (title.startsWith("edit")) {
+                        let table_row = event.target.parentElement.parentElement;
+                        let nextEle = table_row.nextElementSibling;
+
+                        // at end, so select first element
+                        if (nextEle == null) {
+                            nextEle = table_row.parentElement.firstElementChild;
+                        }
+
+                        //get the actual text field
+                        let nextField = nextEle.children[1].children[0];
+                        nextField.focus();
+                    } else if (title.startsWith("Parameters")) { //try to tab through workflow parameters
+                        let element = event.target;
+
+                        //get the next element
+                        //skips the <br>s and labels
+                        let nextEle = element.nextElementSibling.nextElementSibling
+                            .nextElementSibling.nextElementSibling;
+
+                        //cycle back around to the top
+                        if (nextEle.nodeName == "BUTTON") {
+                            nextEle = nextEle.parentElement.children[3];
+                        }
+                        nextEle.focus();
+                    }
+
+                } catch (err) { //catch errors if something was unexpected
+                    console.debug("Tab event failed: " + err);
+                }
+
+            }
+        });
+
+        BehaviorManager.setActiveBehaviourStatechart(__SC_DIALOG);
+        BehaviorManager.handleUserEvent(__EVENT_SHOW_DIALOG);
 	};
 	};
 	
 	
 	/* 
 	/* 

+ 11 - 7
client/http_utils.js

@@ -28,13 +28,17 @@ HttpUtils = function(){
 		var onreadystatechange = function(ev) {
 		var onreadystatechange = function(ev) {
 			 if( req.readyState == 4 )
 			 if( req.readyState == 4 )
 			 {
 			 {
-	 			 console.debug(method+' '+url+' >> '+req.status);
-				 if( req.status == 0 )
-	 				 WindowManagement.openDialog(__FATAL_ERROR,'lost connection to back-end');
-				 else if( onresponse )
-					 onresponse(req.status,req.responseText);
-				 else if( ! utils.isHttpSuccessCode(req.status) )
-	 				 WindowManagement.openDialog(_ERROR,req.responseText);
+                 console.debug(method + ' ' + url + ' >> ' + req.status);
+                 //ignore calls made to other addresses
+                 if (url.startsWith("http://") || url.startsWith("https://")) {
+                     onresponse(req.status, req.responseText);
+                 }
+                 else if (req.status == 0)
+                     WindowManagement.openDialog(__FATAL_ERROR, 'lost connection to back-end');
+                 else if (onresponse)
+                     onresponse(req.status, req.responseText);
+                 else if (!utils.isHttpSuccessCode(req.status))
+                     WindowManagement.openDialog(_ERROR, req.responseText);
 			 }
 			 }
  		 };
  		 };
 	
 	

+ 72 - 11
client/window_management.js

@@ -58,6 +58,55 @@ WindowManagement = function(){
 		__setCanvasScrolling(false);
 		__setCanvasScrolling(false);
 	};
 	};
 	
 	
+	this.showAboutDialog = function () {
+
+        let create_about = function (status, text) {
+
+            let version = null;
+            let time_at = null;
+
+            if (utils.isHttpSuccessCode(status)) {
+                let resp = JSON.parse(text);
+                version = resp['tag_name'];
+
+                time_at = resp['published_at'];
+                time_at = time_at.split("T")[0];
+            }
+
+            let title = "About AToMPM";
+            let elements = [];
+
+            let website = "<a href= '" + __WEBPAGE__ + "' target='_blank'>Website and Tutorials</a>";
+            elements.push(GUIUtils.getTextSpan(website));
+
+            let doc_website = "<a href= '" + __DOC_WEBPAGE__ + "' target='_blank'>Documentation</a>";
+            elements.push(GUIUtils.getTextSpan(doc_website));
+
+            let curr_version_str = "Current Version: " + __VERSION__;
+            elements.push(GUIUtils.getTextSpan(curr_version_str));
+
+            elements.push(GUIUtils.getTextSpan("\n"));
+
+            if (version != null) {
+                let new_version_str = "Newest Version: " + version;
+                elements.push(GUIUtils.getTextSpan(new_version_str));
+
+                let time_at_str = "Released on: " + time_at;
+                elements.push(GUIUtils.getTextSpan(time_at_str));
+
+            }
+
+            GUIUtils.setupAndShowDialog(
+                elements,
+                null,
+                __ONE_BUTTON,
+                title,
+                null);
+        };
+
+        HttpUtils.httpReq("GET", "https://api.github.com/repos/AToMPM/atompm/releases/latest", null, create_about);
+	};
+	
 	//Todo: Shred this function into smaller functions, as this should
 	//Todo: Shred this function into smaller functions, as this should
 	// really just amount to a switch statement
 	// really just amount to a switch statement
 	//TBI: complete comments about each dialog (copy from user's manual)
 	//TBI: complete comments about each dialog (copy from user's manual)
@@ -554,8 +603,13 @@ WindowManagement = function(){
 			 completion */
 			 completion */
 	this.spawnClient = function (fname,callbackURL)
 	this.spawnClient = function (fname,callbackURL)
 	{
 	{
-		var c 		= window.open(window.location.href, '_blank'),
-		onspawn = 
+		let c 		= window.open(window.location.href, '_blank');
+
+		if (c == undefined){
+			WindowManagement.openDialog(_ERROR, "Failed to open new window. Are pop-ups blocked?");
+			return;
+		}
+			let onspawn =
 			 function()
 			 function()
 			 {
 			 {
 				 if( (fname || callbackURL)	 &&
 				 if( (fname || callbackURL)	 &&
@@ -589,8 +643,15 @@ WindowManagement = function(){
 		the instance*/	
 		the instance*/	
 	this.spawnClientOption = function (fname,tbname,option,trafo,msg)
 	this.spawnClientOption = function (fname,tbname,option,trafo,msg)
 	{
 	{
-		var c 		= window.open(window.location.href, '_blank'),
-		onspawn = 
+        let c = window.open(window.location.href, '_blank');
+
+        if (c == undefined) {
+            WindowManagement.openDialog(_ERROR, "Failed to open new window. Are pop-ups blocked?\n" +
+                "Please reload the workflow model after allowing pop-ups.");
+            return;
+        }
+
+		let onspawn =
 			 function()
 			 function()
 			 {
 			 {
 				if( (fname|| tbname)	 &&
 				if( (fname|| tbname)	 &&
@@ -607,13 +668,13 @@ WindowManagement = function(){
 				if (trafo == undefined){
 				if (trafo == undefined){
 					trafo = option;
 					trafo = option;
 				}
 				}
-				if( tbname ){
-						toolbars = tbname.split(",");
-						for ( var n in toolbars){
-							c._loadToolbar(toolbars[n]);
-						}						
-				}				
-				if( fname ){
+                 if (tbname) {
+                     let toolbars = tbname.split(",");
+                     for (let toolbar of toolbars) {
+                         c._loadToolbar(toolbar);
+                     }
+                 }
+                 if( fname ){
 						c.__saveas = fname;
 						c.__saveas = fname;
 						if( option.length > 2 ){
 						if( option.length > 2 ){
 							c._loadModel(fname);
 							c._loadModel(fname);

+ 185 - 166
csworker.js

@@ -318,76 +318,73 @@ module.exports = {
 										[{'op':step['op'],'id1':csid1,'id2':csid2}]);
 										[{'op':step['op'],'id1':csid1,'id2':csid2}]);
 									return __successContinuable();
 									return __successContinuable();
 								});
 								});
-		
-						/* create appropriate CS instance and associate it with new AS
-							instance (remember the association in __asid2csid to 
-							optimize future operations) */
-						else if( step['op'] == 'MKNODE' )
-							actions.push(
-								function()
-								{
-									manageHitchhiker(step['id']);
-	
-									var asid 	  	= step['id'],
-	  									 node   		= _utils.jsonp(step['node']),
-										 isLink		= ('segments' in hitchhiker),
-										 fullastype	= node['$type'],
-										 fullcstype = self.__astype_to_cstype(
-											 							fullastype,
-																		isLink),				
-										 asuri 		= fullastype+'/'+asid+'.instance';
-										 attrs		= {'$asuri':asuri};
-
-									if( 'pos' in hitchhiker )
-										attrs['position'] = hitchhiker['pos'];
-									else if( 'neighborhood' in hitchhiker )
-									{
-										var nc = self.__nodesCenter(
-															hitchhiker['neighborhood']);
-										attrs['position'] = 
-											[(nc[0] || 200), (nc[1] || 200)];
-									}
-									else if( 'clone' in hitchhiker )
-										attrs = _utils.mergeDicts(
-														[attrs,hitchhiker['clone']]);
-									else
-										attrs['position'] = [200,200];
-
-									var res  = _mmmk.create(fullcstype,attrs),
-										 csid	= res['id'];
-				 					self.__asid2csid[asid] = csid;
-				 					cschangelogs.push(res['changelog']);
-	
-									if( isLink )
-									{
-										var s 		 = {},
-											 src		 = 
-												 hitchhiker['src'] ||
-												 self.__asuri_to_csuri(hitchhiker['asSrc']),
-											 dest		 = 
-												 hitchhiker['dest'] ||
-												 self.__asuri_to_csuri(hitchhiker['asDest']),
-											 segments = 
-												 hitchhiker['segments'] ||
-												 self.__defaultSegments(src,dest);
-										s[ src+'--'+__id_to_uri(csid) ]  = segments[0];
-										s[ __id_to_uri(csid)+'--'+dest ] = segments[1];
-	
-										cschangelogs.push( 
-											_mmmk.update(
-												csid,
-												{'$segments':s})['changelog'],
-										  	self.__positionLinkDecorators(csid));
-									}
-	
-									return self.__regenIcon(csid);
-								},
-								function(riChangelog)
-								{
-									cschangelogs.push(riChangelog);
-									return __successContinuable();
-								});
-	
+
+                        /* create appropriate CS instance and associate it with new AS
+                            instance (remember the association in __asid2csid to
+                            optimize future operations) */
+                        else if (step['op'] == 'MKNODE') {
+                            actions.push(
+                                function () {
+                                    manageHitchhiker(step['id']);
+
+                                    let asid = step['id'],
+                                        node = _utils.jsonp(step['node']),
+                                        isLink = ('segments' in hitchhiker),
+                                        fullastype = node['$type'],
+                                        fullcstype = self.__astype_to_cstype(
+                                            fullastype,
+                                            isLink),
+                                        asuri = fullastype + '/' + asid + '.instance',
+                                        attrs = {'$asuri': asuri};
+
+                                    if ('pos' in hitchhiker)
+                                        attrs['position'] = hitchhiker['pos'];
+                                    else if ('neighborhood' in hitchhiker) {
+                                        let nc = self.__nodesCenter(
+                                            hitchhiker['neighborhood']);
+                                        attrs['position'] =
+                                            [(nc[0] || 200), (nc[1] || 200)];
+                                    }
+                                    else if ('clone' in hitchhiker)
+                                        attrs = _utils.mergeDicts(
+                                            [attrs, hitchhiker['clone']]);
+                                    else
+                                        attrs['position'] = [200, 200];
+
+                                    let res = _mmmk.create(fullcstype, attrs),
+                                        csid = res['id'];
+
+                                    self.__asid2csid[asid] = csid;
+                                    cschangelogs.push(res['changelog']);
+
+                                    if (isLink) {
+                                        let s = {},
+                                            src =
+                                                hitchhiker['src'] ||
+                                                self.__asuri_to_csuri(hitchhiker['asSrc']),
+                                            dest =
+                                                hitchhiker['dest'] ||
+                                                self.__asuri_to_csuri(hitchhiker['asDest']),
+                                            segments =
+                                                hitchhiker['segments'] ||
+                                                self.__defaultSegments(src, dest);
+                                        s[src + '--' + __id_to_uri(csid)] = segments[0];
+                                        s[__id_to_uri(csid) + '--' + dest] = segments[1];
+
+                                        cschangelogs.push(
+                                            _mmmk.update(
+                                                csid,
+                                                {'$segments': s})['changelog'],
+                                            self.__positionLinkDecorators(csid));
+                                    }
+
+                                    return self.__regenIcon(csid);
+                                },
+                                function (riChangelog) {
+                                    cschangelogs.push(riChangelog);
+                                    return __successContinuable();
+                                });
+                        }
 						/* remove appropriate CS instance... update __asid2csid for it
 						/* remove appropriate CS instance... update __asid2csid for it
 						  	to remain consistent */				
 						  	to remain consistent */				
 						else if( step['op'] == 'RMNODE' )
 						else if( step['op'] == 'RMNODE' )
@@ -1376,107 +1373,129 @@ module.exports = {
                 );
                 );
             }
             }
 		},
 		},
-	
 
 
-	/* INTENT :
- 			create a new instance of specified type (if reqData has 'segments', 
-			'src' and 'dest' fields, type is a connector)
-		IN PRACTICE: 
-			adjust uri (and reqData) and forward to asworker
 
 
-		1. parse + validate parameters
-		2. setup sync/async action chaining
-			a) construct reqData for asworker.POST *.type
-				i.   handle connector ends if applicable
-				ii.  handle 'pos'... pass as hitchhiker and evaluate the to-be
-					  *Icon's parser within a dummy context where 'position' is set
-					  to 'pos'... see NOTES above for more details on this
-		   b) ask asworker to create an instance of appropriate AS type
-		3. launch chain... return success code or error */
-	'POST *.type' :
-		function(resp,uri,reqData/*pos|clone,[segments,src,dest]*/)
-		{
-			var matches = 
-					uri.match(/((.*)\..*Icons)(\.pattern){0,1}\/((.*)Icon)\.type/) ||
-					uri.match(/((.*)\..*Icons)(\.pattern){0,1}\/((.*)Link)\.type/);
-			if( ! matches )
-				return __postBadReqErrorMsg(
-								resp,
-								'bad uri for Icon/Link type :: '+uri);
-
-			var asuri   = matches[2]+(matches[3] || '')+'/'+matches[5]+'.type',
-				 csmm		= matches[1]+(matches[3] || ''),
-				 cstype	= matches[4],
-                 types = _utils.jsonp(_mmmk.readMetamodels(csmm))['types'];
-            if (cstype in types) {
-				 var parser	= 
-					 types[cstype].
-					 	filter( 
-							function(attr) 
-							{
-								return attr['name']=='parser';
-							})[0]['default'],
-				 self = this,
-				 actions  = 
-					[__successContinuable(),
-					 function()
-					 {
-						 if( reqData == undefined || 
-							  (pos = reqData['pos']) == undefined )
-							 return __errorContinuable('missing creation parameters');
-
-						 var hitchhiker = {},
-						 	  reqParams	 = {};
-						 if( (segments = reqData['segments']) != undefined &&
-							  (src = reqData['src']) != undefined 				&&
-							  (dest = reqData['dest']) != undefined )
-						 {
-							 if( (src_asuri = self.__csuri_to_asuri(src))['$err'] )
-								 return __errorContinuable(src_asuri['$err']);
-							 if( (dest_asuri = self.__csuri_to_asuri(dest))['$err'] )
-								 return __errorContinuable(dest_asuri['$err']);
-
-							 hitchhiker = {'segments':segments,
-												'src':src,
-												'dest':dest};
-							 reqParams	= {'src':src_asuri,
-												'dest':dest_asuri};
-						 }
-
-						 hitchhiker['pos'] = pos;
-						 reqParams['attrs'] = 
-								 self.__runParser(
-										 parser,
-										 {'position':pos,
-  										  'orientation':0,
-										  'scale':[1,1]},
-	 									 {});
-
-						 return __successContinuable(
-									 	_utils.mergeDicts(
-											[{'hitchhiker':hitchhiker}, reqParams]) );
-					 },
-					 function(asreqData)
-					 {
-	 					 return __wHttpReq(
-									 'POST',
-									 asuri+'?wid='+self.__aswid,
-									 asreqData);
-					 }];
+    /* INTENT :
+             create a new instance of specified type (if reqData has
+             'src' and 'dest' fields, type is a connector)
+        IN PRACTICE:
+            adjust uri (and reqData) and forward to asworker
+
+        1. parse + validate parameters
+        2. setup sync/async action chaining
+            a) construct reqData for asworker.POST *.type
+                i.   handle connector ends if applicable
+                ii.  handle 'pos'... pass as hitchhiker and evaluate the to-be
+                      *Icon's parser within a dummy context where 'position' is set
+                      to 'pos'... see NOTES above for more details on this
+           b) ask asworker to create an instance of appropriate AS type
+        3. launch chain... return success code or error */
+    'POST *.type':
+        function (resp, uri, reqData/*pos|clone,[segments,src,dest]*/) {
+            let matches =
+                uri.match(/((.*)\..*Icons)(\.pattern){0,1}\/((.*)Icon)\.type/) ||
+                uri.match(/((.*)\..*Icons)(\.pattern){0,1}\/((.*)Link)\.type/);
+            if (!matches)
+                return __postBadReqErrorMsg(
+                    resp,
+                    'bad uri for Icon/Link type :: ' + uri);
 
 
-                 _do.chain(actions)(
-                        function(res) 	
-                        {
-                            __postMessage({'statusCode':202, 'respIndex':resp});
-                        },
-                        function(err) 	{__postInternalErrorMsg(resp,err);}
-                 );
-            } else {
+            let asuri = matches[2] + (matches[3] || '') + '/' + matches[5] + '.type',
+                csmm = matches[1] + (matches[3] || ''),
+                cstype = matches[4],
+                types = _utils.jsonp(_mmmk.readMetamodels(csmm))['types'];
+
+            if (!(cstype in types)) {
                 return __postBadReqErrorMsg(
                 return __postBadReqErrorMsg(
-								resp,
-								'no concrete syntax definition found for '+cstype);
+                    resp, 'no concrete syntax definition found for ' + cstype);
             }
             }
-		},
+
+            let parser =
+                    types[cstype].filter(
+                        function (attr) {
+                            return attr['name'] == 'parser';
+                        })[0]['default'],
+                self = this,
+                actions =
+                    [__successContinuable(),
+                        function () {
+                            if (reqData == undefined)
+                                return __errorContinuable('missing creation parameters');
+
+                            let hitchhiker = {},
+                                reqParams = {},
+                                segments = reqData['segments'],
+                                src = reqData['src'],
+                                dest = reqData['dest'],
+                                pos = reqData['pos'];
+
+                            if (src != undefined &&
+                                dest != undefined) {
+
+                                let src_asuri = self.__csuri_to_asuri(src);
+                                if (src_asuri['$err'])
+                                    return __errorContinuable(src_asuri['$err']);
+
+                                let dest_asuri = self.__csuri_to_asuri(dest);
+                                if (dest_asuri['$err'])
+                                    return __errorContinuable(dest_asuri['$err']);
+
+                                if (segments == undefined) {
+                                    segments = self.__defaultSegments(src, dest);
+                                }
+
+                                if (pos == undefined) {
+                                    pos = self.__nodesCenter([src_asuri, dest_asuri]);
+                                }
+
+                                hitchhiker = {
+                                    'segments': segments,
+                                    'src': src,
+                                    'dest': dest
+                                };
+                                reqParams = {
+                                    'src': src_asuri,
+                                    'dest': dest_asuri
+                                };
+
+
+                            }
+
+                            if (pos == undefined)
+                                return __errorContinuable('missing position');
+
+                            hitchhiker['pos'] = pos;
+                            reqParams['attrs'] =
+                                self.__runParser(
+                                    parser,
+                                    {
+                                        'position': pos,
+                                        'orientation': 0,
+                                        'scale': [1, 1]
+                                    },
+                                    {});
+
+                            return __successContinuable(
+                                _utils.mergeDicts(
+                                    [{'hitchhiker': hitchhiker}, reqParams]));
+                        },
+                        function (asreqData) {
+                            return __wHttpReq(
+                                'POST',
+                                asuri + '?wid=' + self.__aswid,
+                                asreqData);
+                        }];
+
+            _do.chain(actions)(
+                function (res) {
+                    __postMessage({'statusCode': 202, 'respIndex': resp, 'reason': res});
+                },
+                function (err) {
+                    __postInternalErrorMsg(resp, err);
+                }
+            );
+
+        },
 
 
 
 
 	/* return an AS instance, and optionally also the associated CS instance
 	/* return an AS instance, and optionally also the associated CS instance

+ 10 - 215
doc/Makefile

@@ -1,225 +1,20 @@
-# Makefile for Sphinx documentation
+# Minimal makefile for Sphinx documentation
 #
 #
 
 
 # You can set these variables from the command line.
 # You can set these variables from the command line.
 SPHINXOPTS    =
 SPHINXOPTS    =
 SPHINXBUILD   = sphinx-build
 SPHINXBUILD   = sphinx-build
-PAPER         =
+SPHINXPROJ    = AToMPM
+SOURCEDIR     = .
 BUILDDIR      = _build
 BUILDDIR      = _build
 
 
-# Internal variables.
-PAPEROPT_a4     = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help
+# Put it first so that "make" without argument is like "make help".
 help:
 help:
-	@echo "Please use \`make <target>' where <target> is one of"
-	@echo "  html       to make standalone HTML files"
-	@echo "  dirhtml    to make HTML files named index.html in directories"
-	@echo "  singlehtml to make a single large HTML file"
-	@echo "  pickle     to make pickle files"
-	@echo "  json       to make JSON files"
-	@echo "  htmlhelp   to make HTML files and a HTML help project"
-	@echo "  qthelp     to make HTML files and a qthelp project"
-	@echo "  applehelp  to make an Apple Help Book"
-	@echo "  devhelp    to make HTML files and a Devhelp project"
-	@echo "  epub       to make an epub"
-	@echo "  epub3      to make an epub3"
-	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
-	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
-	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
-	@echo "  text       to make text files"
-	@echo "  man        to make manual pages"
-	@echo "  texinfo    to make Texinfo files"
-	@echo "  info       to make Texinfo files and run them through makeinfo"
-	@echo "  gettext    to make PO message catalogs"
-	@echo "  changes    to make an overview of all changed/added/deprecated items"
-	@echo "  xml        to make Docutils-native XML files"
-	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes"
-	@echo "  linkcheck  to check all external links for integrity"
-	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
-	@echo "  coverage   to run coverage check of the documentation (if enabled)"
-	@echo "  dummy      to check syntax errors of document sources"
-
-.PHONY: clean
-clean:
-	rm -rf $(BUILDDIR)/*
-
-.PHONY: html
-html:
-	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
-	@echo
-	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-.PHONY: dirhtml
-dirhtml:
-	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
-	@echo
-	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-.PHONY: singlehtml
-singlehtml:
-	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
-	@echo
-	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-.PHONY: pickle
-pickle:
-	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
-	@echo
-	@echo "Build finished; now you can process the pickle files."
-
-.PHONY: json
-json:
-	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
-	@echo
-	@echo "Build finished; now you can process the JSON files."
-
-.PHONY: htmlhelp
-htmlhelp:
-	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
-	@echo
-	@echo "Build finished; now you can run HTML Help Workshop with the" \
-	      ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-.PHONY: qthelp
-qthelp:
-	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
-	@echo
-	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
-	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
-	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/AToMPM.qhcp"
-	@echo "To view the help file:"
-	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/AToMPM.qhc"
-
-.PHONY: applehelp
-applehelp:
-	$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
-	@echo
-	@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
-	@echo "N.B. You won't be able to view it unless you put it in" \
-	      "~/Library/Documentation/Help or install it in your application" \
-	      "bundle."
-
-.PHONY: devhelp
-devhelp:
-	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
-	@echo
-	@echo "Build finished."
-	@echo "To view the help file:"
-	@echo "# mkdir -p $$HOME/.local/share/devhelp/AToMPM"
-	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/AToMPM"
-	@echo "# devhelp"
-
-.PHONY: epub
-epub:
-	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
-	@echo
-	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-.PHONY: epub3
-epub3:
-	$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
-	@echo
-	@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
-
-.PHONY: latex
-latex:
-	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-	@echo
-	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
-	@echo "Run \`make' in that directory to run these through (pdf)latex" \
-	      "(use \`make latexpdf' here to do that automatically)."
-
-.PHONY: latexpdf
-latexpdf:
-	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-	@echo "Running LaTeX files through pdflatex..."
-	$(MAKE) -C $(BUILDDIR)/latex all-pdf
-	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-.PHONY: latexpdfja
-latexpdfja:
-	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-	@echo "Running LaTeX files through platex and dvipdfmx..."
-	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
-	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-.PHONY: text
-text:
-	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
-	@echo
-	@echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-.PHONY: man
-man:
-	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
-	@echo
-	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-.PHONY: texinfo
-texinfo:
-	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-	@echo
-	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
-	@echo "Run \`make' in that directory to run these through makeinfo" \
-	      "(use \`make info' here to do that automatically)."
-
-.PHONY: info
-info:
-	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-	@echo "Running Texinfo files through makeinfo..."
-	make -C $(BUILDDIR)/texinfo info
-	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-.PHONY: gettext
-gettext:
-	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
-	@echo
-	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-.PHONY: changes
-changes:
-	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
-	@echo
-	@echo "The overview file is in $(BUILDDIR)/changes."
-
-.PHONY: linkcheck
-linkcheck:
-	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
-	@echo
-	@echo "Link check complete; look for any errors in the above output " \
-	      "or in $(BUILDDIR)/linkcheck/output.txt."
-
-.PHONY: doctest
-doctest:
-	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
-	@echo "Testing of doctests in the sources finished, look at the " \
-	      "results in $(BUILDDIR)/doctest/output.txt."
-
-.PHONY: coverage
-coverage:
-	$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
-	@echo "Testing of coverage in the sources finished, look at the " \
-	      "results in $(BUILDDIR)/coverage/python.txt."
-
-.PHONY: xml
-xml:
-	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
-	@echo
-	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
 
 
-.PHONY: pseudoxml
-pseudoxml:
-	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
-	@echo
-	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
+.PHONY: help Makefile
 
 
-.PHONY: dummy
-dummy:
-	$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
-	@echo
-	@echo "Build finished. Dummy builder generates no files."
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

BIN
doc/_build/doctrees/environment.pickle


BIN
doc/_build/doctrees/executing_transformation.doctree


BIN
doc/_build/doctrees/index.doctree


BIN
doc/_build/doctrees/installation.doctree


BIN
doc/_build/doctrees/modelling_transformation.doctree


BIN
doc/_build/doctrees/new_language.doctree


BIN
doc/_build/doctrees/overview.doctree


BIN
doc/_build/doctrees/troubleshooting.doctree


BIN
doc/_build/doctrees/using_language.doctree


BIN
doc/_build/doctrees/workflows.doctree


+ 0 - 4
doc/_build/html/.buildinfo

@@ -1,4 +0,0 @@
-# Sphinx build info version 1
-# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: 01e5a55cdede7aef24476a99d779e227
-tags: 645f666f9bcd5a90fca523b33c5a78b7

BIN
doc/_build/html/_images/association_option.png


BIN
doc/_build/html/_images/compilation_toolbar.png


BIN
doc/_build/html/_images/compile_as.png


BIN
doc/_build/html/_images/compile_cs.png


BIN
doc/_build/html/_images/compile_pattern.png


BIN
doc/_build/html/_images/complex_mapper_example.png


BIN
doc/_build/html/_images/console.png


BIN
doc/_build/html/_images/create_new_account.png


BIN
doc/_build/html/_images/cs_toolbar.png


BIN
doc/_build/html/_images/debugging_transformation.png


BIN
doc/_build/html/_images/dragging_selection.png


BIN
doc/_build/html/_images/drawing_edge.png


BIN
doc/_build/html/_images/edge_editing.png


BIN
doc/_build/html/_images/example_rules.png


BIN
doc/_build/html/_images/example_schedule.png


BIN
doc/_build/html/_images/first_login_screen.png


BIN
doc/_build/html/_images/geometry_editing.png


BIN
doc/_build/html/_images/global_action.png


BIN
doc/_build/html/_images/global_constraint.png


BIN
doc/_build/html/_images/instance_tilted_environment.png


BIN
doc/_build/html/_images/interrupt_pattern.png


BIN
doc/_build/html/_images/load_pattern_metamodel.png


BIN
doc/_build/html/_images/load_trafficlights.png


BIN
doc/_build/html/_images/local_action.png


BIN
doc/_build/html/_images/local_constraint.png


BIN
doc/_build/html/_images/main_toolbar.png


BIN
doc/_build/html/_images/mapper_example.png


BIN
doc/_build/html/_images/new_formalism.png


BIN
doc/_build/html/_images/rule_init.png


BIN
doc/_build/html/_images/something_selected.png


BIN
doc/_build/html/_images/state.png


BIN
doc/_build/html/_images/timed_transition.png


BIN
doc/_build/html/_images/trafficlight_toolbar.png


BIN
doc/_build/html/_images/trafficlights_as.png


BIN
doc/_build/html/_images/trafficlights_cs.png


+ 0 - 0
doc/_build/html/_images/transformation_controller.png


Some files were not shown because too many files changed in this diff