cpee 2.1.135 → 2.1.136

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/cockpit/compliance-view.html +12 -13
  4. data/cockpit/compliance.html +12 -13
  5. data/cockpit/css/llm.css +3 -3
  6. data/cockpit/css/llmmodel.css +140 -0
  7. data/cockpit/css/model.css +0 -1
  8. data/cockpit/css/ui.css +13 -7
  9. data/cockpit/css/wfadaptor.css +15 -10
  10. data/cockpit/edit.html +12 -13
  11. data/cockpit/graph.html +8 -8
  12. data/cockpit/index.html +12 -13
  13. data/cockpit/js/build-bpmn2.js +302 -0
  14. data/cockpit/js/details.js +27 -10
  15. data/cockpit/js/instance.js +193 -203
  16. data/cockpit/js/llm-ui-bubble.js +36 -0
  17. data/cockpit/js/llm-ui-status.js +34 -0
  18. data/cockpit/js/llm-ui.js +87 -0
  19. data/cockpit/js/llm.js +463 -118
  20. data/cockpit/js/parameters.js +45 -14
  21. data/cockpit/js/wfadaptor.js +394 -75
  22. data/cockpit/llm.html +17 -15
  23. data/cockpit/llmmodel.html +18 -17
  24. data/cockpit/model.html +9 -9
  25. data/cockpit/only_llm.html +15 -13
  26. data/cockpit/themes/base.js +1 -1
  27. data/cockpit/themes/packed/theme.js +3 -0
  28. data/cockpit/themes/presetlr/rngs/alternative.rng +28 -0
  29. data/cockpit/themes/presetlr/rngs/call.rng +249 -0
  30. data/cockpit/themes/presetlr/rngs/callmanipulate.rng +281 -0
  31. data/cockpit/themes/presetlr/rngs/choose.rng +27 -0
  32. data/cockpit/themes/presetlr/rngs/closed_loop.rng +62 -0
  33. data/cockpit/themes/presetlr/rngs/closed_loop_cancel.rng +5 -0
  34. data/cockpit/themes/presetlr/rngs/closed_loop_control.rng +31 -0
  35. data/cockpit/themes/presetlr/rngs/closed_loop_measuring.rng +12 -0
  36. data/cockpit/themes/presetlr/rngs/critical.rng +8 -0
  37. data/cockpit/themes/presetlr/rngs/escape.rng +5 -0
  38. data/cockpit/themes/presetlr/rngs/group.rng +3 -0
  39. data/cockpit/themes/presetlr/rngs/loop.rng +40 -0
  40. data/cockpit/themes/presetlr/rngs/manipulate.rng +76 -0
  41. data/cockpit/themes/presetlr/rngs/otherwise.rng +25 -0
  42. data/cockpit/themes/presetlr/rngs/parallel.rng +24 -0
  43. data/cockpit/themes/presetlr/rngs/parallel_branch.rng +5 -0
  44. data/cockpit/themes/presetlr/rngs/scripts.rng +23 -0
  45. data/cockpit/themes/presetlr/rngs/start.rng +143 -0
  46. data/cockpit/themes/presetlr/rngs/stop.rng +5 -0
  47. data/cockpit/themes/presetlr/rngs/terminate.rng +8 -0
  48. data/cockpit/themes/presetlr/rngs/wait_for_signal.rng +8 -0
  49. data/cockpit/themes/presetlr/symbols/alternative.svg +19 -0
  50. data/cockpit/themes/presetlr/symbols/arrow.svg +1 -0
  51. data/cockpit/themes/presetlr/symbols/call.svg +1 -0
  52. data/cockpit/themes/presetlr/symbols/call_sensor.svg +1 -0
  53. data/cockpit/themes/presetlr/symbols/callmanipulate.svg +1 -0
  54. data/cockpit/themes/presetlr/symbols/callmanipulate_sensor.svg +1 -0
  55. data/cockpit/themes/presetlr/symbols/callmanipulate_sensor_signal.svg +1 -0
  56. data/cockpit/themes/presetlr/symbols/callmanipulate_signal.svg +1 -0
  57. data/cockpit/themes/presetlr/symbols/choose.svg +15 -0
  58. data/cockpit/themes/presetlr/symbols/choose_exclusive.svg +15 -0
  59. data/cockpit/themes/presetlr/symbols/choose_exclusive_finish.svg +1 -0
  60. data/cockpit/themes/presetlr/symbols/choose_inclusive.svg +13 -0
  61. data/cockpit/themes/presetlr/symbols/choose_inclusive_finish.svg +1 -0
  62. data/cockpit/themes/presetlr/symbols/closed_loop.svg +1 -0
  63. data/cockpit/themes/presetlr/symbols/closed_loop_cancel.svg +1 -0
  64. data/cockpit/themes/presetlr/symbols/closed_loop_control.svg +1 -0
  65. data/cockpit/themes/presetlr/symbols/closed_loop_measuring.svg +1 -0
  66. data/cockpit/themes/presetlr/symbols/complex.svg +1 -0
  67. data/cockpit/themes/presetlr/symbols/critical.svg +1 -0
  68. data/cockpit/themes/presetlr/symbols/delete.svg +1 -0
  69. data/cockpit/themes/presetlr/symbols/end.svg +1 -0
  70. data/cockpit/themes/presetlr/symbols/escape.svg +1 -0
  71. data/cockpit/themes/presetlr/symbols/event_end.svg +1 -0
  72. data/cockpit/themes/presetlr/symbols/event_start.svg +1 -0
  73. data/cockpit/themes/presetlr/symbols/loop.svg +15 -0
  74. data/cockpit/themes/presetlr/symbols/loop_end.svg +15 -0
  75. data/cockpit/themes/presetlr/symbols/loop_end_pre.svg +15 -0
  76. data/cockpit/themes/presetlr/symbols/manipulate.svg +1 -0
  77. data/cockpit/themes/presetlr/symbols/mark.svg +1 -0
  78. data/cockpit/themes/presetlr/symbols/otherwise.svg +7 -0
  79. data/cockpit/themes/presetlr/symbols/parallel.svg +1 -0
  80. data/cockpit/themes/presetlr/symbols/parallel_branch.svg +7 -0
  81. data/cockpit/themes/presetlr/symbols/parallel_branch_event.svg +14 -0
  82. data/cockpit/themes/presetlr/symbols/parallel_branch_event_rev.svg +11 -0
  83. data/cockpit/themes/presetlr/symbols/parallel_branch_normal.svg +7 -0
  84. data/cockpit/themes/presetlr/symbols/parallel_eventbased_exclusive.svg +1 -0
  85. data/cockpit/themes/presetlr/symbols/parallel_eventbased_parallel.svg +1 -0
  86. data/cockpit/themes/presetlr/symbols/scripts.svg +1 -0
  87. data/cockpit/themes/presetlr/symbols/start.svg +1 -0
  88. data/cockpit/themes/presetlr/symbols/start_event.svg +1 -0
  89. data/cockpit/themes/presetlr/symbols/stop.svg +1 -0
  90. data/cockpit/themes/presetlr/symbols/terminate.svg +1 -0
  91. data/cockpit/themes/presetlr/symbols/wait_for_signal.svg +1 -0
  92. data/cockpit/themes/presetlr/theme.js +54 -0
  93. data/cockpit/themes/wellformed/rngs/alternative.rng +28 -0
  94. data/cockpit/themes/wellformed/rngs/call.rng +249 -0
  95. data/cockpit/themes/wellformed/rngs/callmanipulate.rng +281 -0
  96. data/cockpit/themes/wellformed/rngs/choose.rng +27 -0
  97. data/cockpit/themes/wellformed/rngs/closed_loop.rng +62 -0
  98. data/cockpit/themes/wellformed/rngs/closed_loop_cancel.rng +5 -0
  99. data/cockpit/themes/wellformed/rngs/closed_loop_control.rng +31 -0
  100. data/cockpit/themes/wellformed/rngs/closed_loop_measuring.rng +12 -0
  101. data/cockpit/themes/wellformed/rngs/critical.rng +8 -0
  102. data/cockpit/themes/wellformed/rngs/escape.rng +5 -0
  103. data/cockpit/themes/wellformed/rngs/group.rng +3 -0
  104. data/cockpit/themes/wellformed/rngs/loop.rng +40 -0
  105. data/cockpit/themes/wellformed/rngs/manipulate.rng +76 -0
  106. data/cockpit/themes/wellformed/rngs/otherwise.rng +25 -0
  107. data/cockpit/themes/wellformed/rngs/parallel.rng +24 -0
  108. data/cockpit/themes/wellformed/rngs/parallel_branch.rng +5 -0
  109. data/cockpit/themes/wellformed/rngs/scripts.rng +23 -0
  110. data/cockpit/themes/wellformed/rngs/start.rng +143 -0
  111. data/cockpit/themes/wellformed/rngs/stop.rng +5 -0
  112. data/cockpit/themes/wellformed/rngs/terminate.rng +8 -0
  113. data/cockpit/themes/wellformed/rngs/wait_for_signal.rng +8 -0
  114. data/cockpit/themes/wellformed/symbols/alternative.svg +1 -0
  115. data/cockpit/themes/wellformed/symbols/arrow.svg +1 -0
  116. data/cockpit/themes/wellformed/symbols/call.svg +1 -0
  117. data/cockpit/themes/wellformed/symbols/call_sensor.svg +1 -0
  118. data/cockpit/themes/wellformed/symbols/callmanipulate.svg +1 -0
  119. data/cockpit/themes/wellformed/symbols/callmanipulate_sensor.svg +1 -0
  120. data/cockpit/themes/wellformed/symbols/callmanipulate_sensor_signal.svg +1 -0
  121. data/cockpit/themes/wellformed/symbols/callmanipulate_signal.svg +1 -0
  122. data/cockpit/themes/wellformed/symbols/choose.svg +1 -0
  123. data/cockpit/themes/wellformed/symbols/choose_exclusive.svg +1 -0
  124. data/cockpit/themes/wellformed/symbols/choose_exclusive_finish.svg +1 -0
  125. data/cockpit/themes/wellformed/symbols/choose_inclusive.svg +1 -0
  126. data/cockpit/themes/wellformed/symbols/choose_inclusive_finish.svg +1 -0
  127. data/cockpit/themes/wellformed/symbols/closed_loop.svg +1 -0
  128. data/cockpit/themes/wellformed/symbols/closed_loop_cancel.svg +1 -0
  129. data/cockpit/themes/wellformed/symbols/closed_loop_control.svg +1 -0
  130. data/cockpit/themes/wellformed/symbols/closed_loop_measuring.svg +1 -0
  131. data/cockpit/themes/wellformed/symbols/complex.svg +1 -0
  132. data/cockpit/themes/wellformed/symbols/critical.svg +1 -0
  133. data/cockpit/themes/wellformed/symbols/delete.svg +1 -0
  134. data/cockpit/themes/wellformed/symbols/end.svg +1 -0
  135. data/cockpit/themes/wellformed/symbols/escape.svg +1 -0
  136. data/cockpit/themes/wellformed/symbols/event_end.svg +1 -0
  137. data/cockpit/themes/wellformed/symbols/event_start.svg +6 -0
  138. data/cockpit/themes/wellformed/symbols/loop.svg +1 -0
  139. data/cockpit/themes/wellformed/symbols/loop_end.svg +1 -0
  140. data/cockpit/themes/wellformed/symbols/manipulate.svg +1 -0
  141. data/cockpit/themes/wellformed/symbols/mark.svg +1 -0
  142. data/cockpit/themes/wellformed/symbols/otherwise.svg +1 -0
  143. data/cockpit/themes/wellformed/symbols/parallel.svg +1 -0
  144. data/cockpit/themes/wellformed/symbols/parallel_branch.svg +1 -0
  145. data/cockpit/themes/wellformed/symbols/parallel_branch_event.svg +1 -0
  146. data/cockpit/themes/wellformed/symbols/parallel_branch_event_rev.svg +11 -0
  147. data/cockpit/themes/wellformed/symbols/parallel_branch_normal.svg +1 -0
  148. data/cockpit/themes/wellformed/symbols/parallel_eventbased_exclusive.svg +1 -0
  149. data/cockpit/themes/wellformed/symbols/parallel_eventbased_parallel.svg +1 -0
  150. data/cockpit/themes/wellformed/symbols/scripts.svg +1 -0
  151. data/cockpit/themes/wellformed/symbols/start.svg +1 -0
  152. data/cockpit/themes/wellformed/symbols/start_event.svg +1 -0
  153. data/cockpit/themes/wellformed/symbols/stop.svg +1 -0
  154. data/cockpit/themes/wellformed/symbols/terminate.svg +1 -0
  155. data/cockpit/themes/wellformed/symbols/wait_for_signal.svg +1 -0
  156. data/cockpit/themes/wellformed/theme.js +32 -0
  157. data/cockpit/track.html +8 -8
  158. data/cpee.gemspec +2 -2
  159. data/lib/callbacks/callbacks.rng +4 -4
  160. data/lib/callbacks.xml +4 -4
  161. data/lib/cpee/constants.rb +4 -4
  162. data/lib/cpee/fail.rb +4 -4
  163. data/lib/cpee/implementation.rb +5 -4
  164. data/lib/cpee/implementation_callbacks.rb +4 -4
  165. data/lib/cpee/implementation_notifications.rb +4 -4
  166. data/lib/cpee/implementation_properties.rb +108 -12
  167. data/lib/cpee/message.rb +4 -4
  168. data/lib/cpee/persistence.rb +6 -4
  169. data/lib/cpee/redis.rb +4 -4
  170. data/lib/cpee/statemachine.rb +4 -4
  171. data/lib/cpee/value_helper.rb +4 -4
  172. data/lib/cpee.xml +4 -4
  173. data/lib/engine/executionhandler-list.rng +4 -4
  174. data/lib/engine/instance-info.rng +4 -4
  175. data/lib/engine/instances.rng +4 -4
  176. data/lib/engine.xml +4 -4
  177. data/lib/properties/t_dslx.rng +346 -0
  178. data/lib/properties/transformation.rng +14 -0
  179. data/lib/properties.xml +5 -4
  180. data/server/executionhandlers/eval/backend/opts.yaml +1 -1
  181. data/server/executionhandlers/eval/connection.rb +4 -4
  182. data/server/executionhandlers/eval/execution.rb +4 -4
  183. data/server/executionhandlers/ruby/backend/opts.yaml +1 -1
  184. data/server/executionhandlers/ruby/connection.rb +5 -6
  185. data/server/executionhandlers/ruby/controller.rb +4 -4
  186. data/server/executionhandlers/ruby/dsl_to_dslx.xsl +6 -2
  187. data/server/executionhandlers/ruby/execution.rb +4 -4
  188. data/server/resources/properties.empty +5 -4
  189. data/server/resources/properties.init +5 -4
  190. data/server/resources/topics.xml +4 -4
  191. data/server/routing/end.pid +1 -1
  192. data/server/routing/end.rb +4 -4
  193. data/server/routing/forward-events-00.pid +1 -1
  194. data/server/routing/forward-events.rb +4 -4
  195. data/server/routing/forward-votes.pid +1 -1
  196. data/server/routing/forward-votes.rb +4 -4
  197. data/server/routing/persist.pid +1 -1
  198. data/server/routing/persist.rb +6 -4
  199. data/tools/server/cpee +1 -1
  200. data/tools/server/resources/properties.init +4 -4
  201. metadata +136 -5
  202. data/cockpit/CPEE.xml +0 -8
  203. data/cockpit/Signavio.xml +0 -8
  204. data/cockpit/transformations.xml +0 -4
  205. /data/{COPYING → LICENSE} +0 -0
@@ -1,4 +1,5 @@
1
1
  var es;
2
+ var es_reconnect;
2
3
  var suspended_redrawing = false;
3
4
  var skip_location = false;
4
5
  var myid = ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
@@ -20,8 +21,16 @@ var save = {};
20
21
  save['attributes'] = undefined;
21
22
  save['attributes_raw'] = {};
22
23
  var node_state = {};
24
+ var tracking_memory = 10000; // ms finished uuids are remembered, to drop late events
23
25
  var debug = false;
24
26
 
27
+ var cpee= {
28
+ 'instance': undefined,
29
+ 'base': undefined,
30
+ 'attributes': {},
31
+ 'url': undefined
32
+ }
33
+
25
34
  function global_init() {
26
35
  suspended_redrawing = false;
27
36
  loading = false;
@@ -39,7 +48,8 @@ function global_init() {
39
48
  save['details'] = undefined;
40
49
  save['details_target'] = {};
41
50
  save['instance_pos'] = [];
42
- save['modeltype'] = 'CPEE';
51
+ save['instance_pos_anon'] = {};
52
+ save['position_states'] = {};
43
53
  save['modifiers'] = {};
44
54
  save['modifiers_active'] = {};
45
55
  save['modifiers_additional'] = {};
@@ -147,9 +157,8 @@ function cockpit() { //{{{
147
157
  $("button[name=loadtestset]").click(function(e){new CustomMenu(e).menu($('#templates'),function(){ load_testset(false) } ); });
148
158
  $("button[name=loadtestsetfile]").click(load_testsetfile);
149
159
  $("button[name=loadmodelfile]").click(load_modelfile);
150
- $("button[name=loadmodeltype]").click(function(e){new CustomMenu(e).menu($('#modeltypes'),load_modeltype, $("button[name=loadmodeltype]")); });
151
160
  $("button[name=savetestsetfile]").click(function(){ save_testsetfile(); });
152
- $("button[name=savebpmnfile]").click(function(){ save_bpmnfile(); });
161
+ $("button[name=savemodelfile]").click(function(){ save_modelfile(); });
153
162
  $("button[name=savesvgfile]").click(function(){ save_svgfile(); });
154
163
  $("button[name=state_start]").click(function(){ $(this).parent().find('button').attr("disabled","disabled");start_instance(); });
155
164
  $("button[name=state_stop]").click(function(){ $(this).parent().find('button').attr("disabled","disabled");stop_instance(); });
@@ -163,6 +172,7 @@ function cockpit() { //{{{
163
172
  save['graph_adaptor'].illustrator.get_elements().removeClass('marked');
164
173
  localStorage.removeItem('marked');
165
174
  localStorage.removeItem('marked_from');
175
+ details_leave(true);
166
176
  $('#dat_details').empty();
167
177
  e.stopImmediatePropagation();
168
178
  });
@@ -263,16 +273,6 @@ function cockpit() { //{{{
263
273
  }
264
274
  }
265
275
  });
266
- $.ajax({
267
- url: "transformations.xml",
268
- dataType: 'xml',
269
- success: function(res){
270
- $('transformation',res).each(function(){
271
- var ts = $(this).text();
272
- $('#modeltypes').append($("<div class='menuitem'></div>").text(ts));
273
- });
274
- }
275
- });
276
276
  } //}}}
277
277
 
278
278
  function check_subscription() { // {{{
@@ -348,6 +348,31 @@ function create_instance(base,name,load,exec) {// {{{
348
348
  }
349
349
  }// }}}
350
350
 
351
+ function subscribe(url,retry,success) { //{{{
352
+ es_reconnect = undefined;
353
+ if ($('body').attr('current-instance') != url) { return; } // instance switched while waiting for reconnect
354
+ $.ajax({
355
+ type: "POST",
356
+ url: url + "/notifications/subscriptions/",
357
+ data: subscription_state == 'more' ? sub_more : sub_less,
358
+ success: function(res){
359
+ subscription = res;
360
+ append_to_log("monitoring", "id", subscription);
361
+ sse(); // also (re)loads everything, so a reconnect catches up on what was missed
362
+ if (success) { success(); }
363
+ },
364
+ error: function(xhr) {
365
+ if (retry && (xhr.status == 0 || xhr.status >= 500)) {
366
+ append_to_log("monitoring", "closed", "server not reachable, reconnecting in 5 seconds.");
367
+ es_reconnect = setTimeout(() => subscribe(url,true), 5000);
368
+ } else {
369
+ subscription = undefined;
370
+ append_to_log("monitoring", "closed", "For Good.");
371
+ sse();
372
+ }
373
+ }
374
+ });
375
+ } //}}}
351
376
  async function sse() { //{{{
352
377
  var url = $('body').attr('current-instance');
353
378
  if (subscription) {
@@ -408,20 +433,29 @@ async function sse() { //{{{
408
433
  append_to_log(data['type'], data['topic'] + '/' + data['name'], JSON.stringify(data['content']));
409
434
  };
410
435
  es.onerror = function() {
411
- append_to_log("monitoring", "closed", "finished or abandoned or not existing or server down. one of these, i assume.");
412
- // setTimeout(sse,10000);
436
+ // the server deletes the subscription when the connection closes, so the
437
+ // native EventSource retry can never succeed. resubscribe instead.
438
+ this.close();
439
+ if (save['state'] == 'finished' || save['state'] == 'abandoned') {
440
+ append_to_log("monitoring", "closed", "instance " + save['state'] + ".");
441
+ return;
442
+ }
443
+ append_to_log("monitoring", "closed", "connection lost, reconnecting in 5 seconds.");
444
+ es_reconnect = setTimeout(() => subscribe(url,true), 5000);
413
445
  };
414
446
  }
415
- await monitor_instance_values("endpoints"); // we cant render before we know specialized endpoint symbols
416
- await monitor_instance_values("attributes"); // attributes first, to catch the <resources> attribute which overrides current-resources
417
- monitor_instance_values("dataelements");
418
- monitor_instance_values("documents");
447
+ await monitor_instance_values("endpoints",undefined,true); // we cant render before we know specialized endpoint symbols
448
+ await monitor_instance_values("attributes",undefined,true); // attributes first, to catch the <resources> attribute which overrides current-resources
449
+ monitor_instance_values("documents",undefined,true);
450
+ monitor_instance_values("dataelements",undefined,true);
419
451
  monitor_instance_dsl();
420
452
  monitor_graph_change(false);
421
453
  monitor_instance_state();
422
454
  } //}}}
423
455
 
424
456
  function monitor_instance(cin,rep,load,exec) {// {{{
457
+ if (es) { es.close(); }
458
+ clearTimeout(es_reconnect);
425
459
  global_init();
426
460
  format_visual_clear();
427
461
  format_visual_vote_clear();
@@ -429,16 +463,21 @@ function monitor_instance(cin,rep,load,exec) {// {{{
429
463
  $("body").attr('current-instance',sanitize_url(cin));
430
464
  $("body").attr('current-resources',sanitize_url(rep));
431
465
 
466
+ url = $("body").attr('current-instance');
467
+
468
+ cpee.url = $("body").attr('current-instance');
469
+ cpee.base = $("body").attr('current-base');
470
+ cpee.instance = url.match(/(\d+)\/?$/)[1];
471
+
432
472
  $("input[name=instance-url]").val($("body").attr('current-instance'));
433
473
  $("input[name=res-url]").val($("body").attr('current-resources'));
434
474
 
435
475
  $('#parameters ui-content ui-area > button, ui-tabbed.parameters ui-content ui-area > button').attr('disabled','disabled');
476
+ details_leave(false);
436
477
  $('#dat_details').empty();
437
478
 
438
479
  $('#modifiers > div').remove();
439
480
 
440
- url = $("body").attr('current-instance');
441
-
442
481
  $.ajax({
443
482
  type: "GET",
444
483
  url: url,
@@ -472,22 +511,9 @@ function monitor_instance(cin,rep,load,exec) {// {{{
472
511
  // Change url to return to current instance when reloading (because new subscription is made)
473
512
  $("input[name=votecontinue]").prop( "checked", false );
474
513
 
475
- $.ajax({
476
- type: "POST",
477
- url: url + "/notifications/subscriptions/",
478
- data: sub_less,
479
- success: function(res){
480
- subscription = res;
481
- append_to_log("monitoring", "id", subscription);
482
- sse();
483
- if (load || exec) {
484
- load_testset(exec);
485
- }
486
- },
487
- error: function() {
488
- subscription = undefined;
489
- append_to_log("monitoring", "closed", "For Good.");
490
- sse();
514
+ subscribe(url,false,function(){
515
+ if (load || exec) {
516
+ load_testset(exec);
491
517
  }
492
518
  });
493
519
  },
@@ -498,7 +524,7 @@ function monitor_instance(cin,rep,load,exec) {// {{{
498
524
  });
499
525
  }// }}}
500
526
 
501
- function monitor_instance_values(type,vals) {// {{{
527
+ function monitor_instance_values(type,vals,first=false) {// {{{
502
528
  if (type == "dataelements" && save['state'] == "running") {
503
529
  let de = save[type].save();
504
530
  Object.entries(vals).forEach(([key,value]) => {
@@ -527,6 +553,9 @@ function monitor_instance_values(type,vals) {// {{{
527
553
  url: url + "/properties/" + type + "/",
528
554
  success: function(res){
529
555
  save[type].content(res);
556
+ if (first) {
557
+ document.dispatchEvent(eval(type + '_loaded'));
558
+ }
530
559
  if (type == "endpoints") {
531
560
  save['endpoints_list'] = {};
532
561
  var tmp = {};
@@ -545,6 +574,7 @@ function monitor_instance_values(type,vals) {// {{{
545
574
  save['endpoints_cache'] = tmp;
546
575
  def.resolve();
547
576
  // when updating attributes clear the attributes, because they might change as well. New arguments are possible.
577
+ details_leave(true);
548
578
  $('#dat_details').empty();
549
579
  });
550
580
  },
@@ -562,6 +592,7 @@ function monitor_instance_values(type,vals) {// {{{
562
592
  save['endpoints_cache'] = tmp;
563
593
  def.resolve();
564
594
  // when updating attributes clear the attributes, because they might change as well. New arguments are possible.
595
+ details_leave(true);
565
596
  $('#dat_details').empty();
566
597
  });
567
598
  },
@@ -577,6 +608,7 @@ function monitor_instance_values(type,vals) {// {{{
577
608
  } else if(type == "attributes") {
578
609
  $(" > attributes > *",res).each((k,v)=>{
579
610
  save['attributes_raw'][v.nodeName] = v.textContent;
611
+ cpee.attributes[v.nodeName] = v.textContent;
580
612
  });
581
613
  document.dispatchEvent(eval(type + '_changed'));
582
614
  if ($(" > attributes > resources",res).length > 0) {
@@ -584,11 +616,6 @@ function monitor_instance_values(type,vals) {// {{{
584
616
  } else {
585
617
  save['resources'] = undefined;
586
618
  }
587
- if ($(" > attributes > modeltype",res).length > 0) {
588
- save['modeltype'] = $(" > attributes > modeltype",res).text();
589
- } else {
590
- save['modeltype'] = undefined;
591
- }
592
619
  if ($('#modifiers').length > 0) {
593
620
  if ($('#modifiers > div').length == 0) {
594
621
  modifiers_display().then(function(){ modifiers_select(); });
@@ -679,58 +706,27 @@ function adaptor_init(url,theme,dslx) { //{{{
679
706
  save['graph'].removeAttr('svg-subtype');
680
707
  save['graph'].removeAttr('svg-label');
681
708
  document.dispatchEvent(graph_changed);
682
- if (save['modeltype'] != 'CPEE') {
683
- $.ajax({
684
- type: "PUT",
685
- url: url + "/properties/attributes/modeltype/",
686
- data: {'value': 'CPEE'},
687
- error: report_failure
688
- });
689
- $.ajax({
690
- type: "PUT",
691
- url: url + "/properties/transformation/",
692
- contentType: 'text/xml',
693
- headers: {
694
- 'Content-ID': 'transformation',
695
- 'CPEE-Event-Source': myid
696
- },
697
- data: '<transformation xmlns="http://cpee.org/ns/properties/2.0"><description type="copy"/><dataelements type="none"/><endpoints type="none"/></transformation>',
698
- success: function() {
699
- $.ajax({
700
- type: "PUT",
701
- url: url + "/properties/description/",
702
- contentType: 'text/xml',
703
- headers: {
704
- 'Content-ID': 'description',
705
- 'CPEE-Event-Source': myid
706
- },
707
- data: g,
708
- error: report_failure
709
- });
710
- },
711
- error: report_failure
712
- });
713
- } else {
714
- $.ajax({
715
- type: "PUT",
716
- url: url + "/properties/description/",
717
- contentType: 'text/xml',
718
- headers: {
719
- 'Content-ID': 'description',
720
- 'CPEE-Event-Source': myid
721
- },
722
- data: g,
723
- error: report_failure
724
- });
725
- }
709
+ $.ajax({
710
+ type: "PUT",
711
+ url: url + "/properties/dslx/",
712
+ contentType: 'text/xml',
713
+ headers: {
714
+ 'Content-ID': 'dslx',
715
+ 'CPEE-Event-Source': myid
716
+ },
717
+ data: g,
718
+ error: report_model_failure
719
+ });
726
720
  manifestation.events.click(svgid);
727
721
  format_instance_pos();
728
722
  if (manifestation.selected() == "unknown") { // nothing selected
723
+ details_leave(false);
729
724
  $('#dat_details').empty();
730
725
  }
731
726
  };
732
727
 
733
728
  monitor_instance_pos();
729
+ details_leave(false);
734
730
  $('#dat_details').empty();
735
731
 
736
732
  // while inside and svgs are reloaded, do nothing here
@@ -805,7 +801,7 @@ function monitor_instance_pos() {// {{{
805
801
  if (graph_position && graph_position == 'false') {
806
802
  save['instance_pos'] = [];
807
803
  format_visual_clear();
808
- format_instance_pos();
804
+ format_instance_pos_load();
809
805
  return;
810
806
  };
811
807
  var url = $('body').attr('current-instance');
@@ -815,42 +811,84 @@ function monitor_instance_pos() {// {{{
815
811
  success: function(res){
816
812
  save['instance_pos'] = $("positions > *",res);
817
813
  format_visual_clear();
818
- format_instance_pos();
814
+ format_instance_pos_load();
819
815
  }
820
816
  });
821
817
  }// }}}
822
818
 
819
+ function track_start(states,uuid,what,cls) {// {{{
820
+ if (states[uuid]) { return; } // already running, or a late start after the end
821
+ states[uuid] = { position: what, state: 'running' };
822
+ let anon = save['instance_pos_anon'][what];
823
+ if (anon && anon[cls] > 0) {
824
+ anon[cls] -= 1; // most likely the snapshot entry itself, so it is already counted
825
+ return;
826
+ }
827
+ format_visual_add(what,cls);
828
+ } // }}}
829
+ function track_end(states,uuid,what,cls) {// {{{
830
+ let cur = states[uuid];
831
+ if (cur && cur.state == 'done') { return; }
832
+ states[uuid] = { position: what, state: 'done' };
833
+ setTimeout(() => {delete states[uuid]},tracking_memory);
834
+ let anon = save['instance_pos_anon'][what];
835
+ if (!cur) { // start never seen, so it belongs to a snapshot entry, if any
836
+ if (!anon || !(anon[cls] > 0)) { return; }
837
+ anon[cls] -= 1;
838
+ }
839
+ format_visual_remove(what,cls);
840
+ } // }}}
841
+ function track_forget_running(states,what) {// {{{
842
+ // counts were reset, so running uuids are no longer counted. ends of them
843
+ // consume snapshot entries instead.
844
+ for (const [uuid, ele] of Object.entries(states)) {
845
+ if (ele.state == 'running' && (what == undefined || ele.position == what)) { delete states[uuid]; }
846
+ }
847
+ } // }}}
848
+
823
849
  function monitor_instance_running(content,event) {// {{{
824
- let uuid = content['activity-uuid'];
825
- let cur = save['activity_red_states'][uuid];
826
850
  if (event == "calling" || event == "manipulating") {
827
- if (!cur && save['instance_pos'].filter( (_,e) => { return e.nodeName == content.activity }).length == 0) {
828
- save['activity_red_states'][uuid] = { position: content.activity, state: 'active' };
829
- format_visual_add(content.activity,"active");
830
- }
851
+ track_start(save['activity_red_states'],content['activity-uuid'],content.activity,"active");
831
852
  } else if (event == "done") {
832
- if ((cur && cur.state == 'active') || save['instance_pos'].filter( (_,e) => { return e.nodeName == content.activity }).length > 0) {
833
- format_visual_remove(content.activity,"active");
834
- }
835
- save['activity_red_states'][uuid] = { position: content.activity, state: 'done' };
836
- setTimeout(() => {delete save['activity_red_states'][uuid]},1000);
853
+ track_end(save['activity_red_states'],content['activity-uuid'],content.activity,"active");
854
+ }
855
+ } // }}}
856
+ function monitor_instance_pos_mark(b) {// {{{
857
+ if (b.uuid) {
858
+ track_start(save['position_states'],b.uuid,b.position,"passive");
859
+ } else { // set by user, behaves like a snapshot entry
860
+ let anon = save['instance_pos_anon'][b.position] ??= {};
861
+ if (anon['passive'] > 0) { return; }
862
+ anon['passive'] = 1;
863
+ format_visual_add(b.position,"passive");
864
+ }
865
+ } // }}}
866
+ function monitor_instance_pos_unmark(b) {// {{{
867
+ if (b.uuid) {
868
+ track_end(save['position_states'],b.uuid,b.position,"passive");
869
+ } else { // set by user, clears the node
870
+ track_forget_running(save['position_states'],b.position);
871
+ if (save['instance_pos_anon'][b.position]) { save['instance_pos_anon'][b.position]['passive'] = 0; }
872
+ if (node_state[b.position]) { node_state[b.position]['passive'] = 0; }
873
+ format_visual_set(b.position);
837
874
  }
838
875
  } // }}}
839
876
  function monitor_instance_pos_change(content) {// {{{
840
877
  if (graph_position && graph_position == 'false') { return; }
878
+ // unmark first, a single change may unmark and mark the same node (e.g. loops)
879
+ if (content['unmark']) {
880
+ $.each(content['unmark'],function(a,b){
881
+ monitor_instance_pos_unmark(b);
882
+ });
883
+ }
841
884
  if (content['at']) {
842
885
  $.each(content['at'],function(a,b){
843
- format_visual_add(b.position,"passive",false);
886
+ monitor_instance_pos_mark(b);
844
887
  });
845
888
  }
846
889
  if (content['after']) {
847
890
  $.each(content['after'],function(a,b){
848
- format_visual_add(b.position,"passive",false);
849
- });
850
- }
851
- if (content['unmark']) {
852
- $.each(content['unmark'],function(a,b){
853
- format_visual_remove(b.position,"passive",false)
891
+ monitor_instance_pos_mark(b);
854
892
  });
855
893
  }
856
894
  if (!content['at'] && !content['unmark'] && !content['after'] && !content['wait']) {
@@ -882,6 +920,8 @@ function monitor_instance_state_change(notification) { //{{{
882
920
  monitor_instance_pos();
883
921
  }
884
922
  if (notification == "running") {
923
+ track_forget_running(save['position_states']);
924
+ for (const [key, ele] of Object.entries(save['instance_pos_anon'])) { ele['passive'] = 0; }
885
925
  for (const [key, ele] of Object.entries(node_state)) {
886
926
  for (i=0; i<ele.passive; i++) {
887
927
  format_visual_remove(key,'passive');
@@ -1050,56 +1090,9 @@ function get_testset(deferred) {// {{{
1050
1090
  }// }}}
1051
1091
  function save_svgfile() {// {{{
1052
1092
  var url = $('body').attr('current-instance');
1093
+ if (!save['graph_adaptor']) { return; } // no instance loaded
1053
1094
 
1054
- var gc = $('#graphcanvas').clone();
1055
- var start = parseInt(gc.attr('width'));
1056
- $('#graphgrid > svg:not(#graphcanvas)').each( (i,ele) => {
1057
- const gr = $X('<g transform="translate(' + start + ')" xmlns="http://www.w3.org/2000/svg"></g>');
1058
- start = start + parseInt(ele.getAttribute('width'));
1059
- $('g',ele).each((j,g) => {
1060
- gr.append($(g).clone());
1061
- });
1062
- gc.append(gr);
1063
- });
1064
- gc.find('.selected').removeClass('selected');
1065
- var varreps = {};
1066
- var ffamily = '';
1067
- $(window.document.styleSheets).each(function(i,x){
1068
- if (x && x.href && x.ownerNode.attributes.getNamedItem('data-include-export')) {
1069
- $(x.cssRules).each(function(j,y){
1070
- if (y.selectorText == ":root") {
1071
- $(y.style).each(function(k,z) {
1072
- varreps['var\\(' + z + '\\)'] = getComputedStyle(document.documentElement).getPropertyValue(z).toString();
1073
- });
1074
- }
1075
- if (y.selectorText == "svg") {
1076
- $(y.style).each(function(k,z) {
1077
- if (z == 'font-family') {
1078
- ffamily = getComputedStyle($('#graphgrid > svg')[0]).getPropertyValue(z).toString();
1079
- }
1080
- });
1081
- }
1082
- var loc = $(gc).find(y.selectorText.replace(/svg /g,''));
1083
- var cst = y.style.cssText;
1084
- for (k in varreps) {
1085
- cst = cst.replace(new RegExp(k,'g'),varreps[k]);
1086
- }
1087
- loc.each(function(k,loco) {
1088
- var sty = $(loco).attr('style') == undefined ? '' : $(loco).attr('style');
1089
- $(loco).attr('style',cst + sty);
1090
- });
1091
- });
1092
- $(gc).find('text.super,g.hoverstyle,g.markstyle').each(function(k,loco){
1093
- $(loco).attr('style',$(loco).attr('style') + ' display: none; ');
1094
- });
1095
- ffamily = ffamily.replace(/-/,' ').split(' ').map(function(word) { return word[0].toUpperCase() + word.substr(1); }).join(' ');
1096
- $(gc).find('text').each(function(k,loco){
1097
- $(loco).attr('style',$(loco).attr('style') + ' font-family: \'' + ffamily + '\'; ');
1098
- });
1099
- }
1100
- });
1101
- gc.attr('width',start+1);
1102
- gc.find('.duration').remove();
1095
+ var gc = $(save['graph_adaptor'].get_svg());
1103
1096
  $.ajax({
1104
1097
  type: "GET",
1105
1098
  url: url + "/properties/attributes/info/",
@@ -1112,23 +1105,21 @@ function save_svgfile() {// {{{
1112
1105
  });
1113
1106
  } // }}}
1114
1107
 
1115
- function save_bpmnfile() {// {{{
1108
+ function save_modelfile() {// {{{
1116
1109
  var url = $('body').attr('current-instance');
1117
-
1118
- let dpm = JSON.parse($('svg[data-pos-matrix]').attr('data-pos-matrix'));
1119
- let dcl = JSON.parse($('svg[data-con-list]').attr('data-con-list'));
1120
-
1121
- let david = david_bpmn_convert(dpm,dcl);
1122
-
1123
- $.ajax({
1124
- type: "GET",
1125
- url: url + "/properties/attributes/info/",
1126
- success: function(res){
1127
- $('#savebpmnfile').attr('download',res + '.bpmn');
1128
- $('#savebpmnfile').attr('href','data:application/xml;charset=utf-8;base64,' + $B64(david.serializePrettyXML()));
1129
- document.getElementById('savebpmnfile').click();
1130
- },
1131
- error: report_failure
1110
+ if (!save['graph_adaptor']) { return; } // no instance loaded
1111
+
1112
+ let extensions = { 'Signavio': 'bpmn', 'ChatGPT_Mermaid': 'mmd', 'ChatGPT_Graphviz': 'dot' };
1113
+ Promise.all([
1114
+ $.ajax({ type: "GET", url: url + "/properties/description/", dataType: 'text' }),
1115
+ $.ajax({ type: "GET", url: url + "/properties/attributes/info/" }),
1116
+ $.ajax({ type: "GET", url: url + "/properties/attributes/modeltype/" }).catch(() => 'CPEE') // instances without modeltype
1117
+ ]).then(function([desc,info,modeltype]){
1118
+ $('#savemodelfile').attr('download',info + '.' + (extensions[modeltype] || 'xml'));
1119
+ $('#savemodelfile').attr('href','data:application/xml;charset=utf-8;base64,' + $B64(desc));
1120
+ document.getElementById('savemodelfile').click();
1121
+ },function(xhr){
1122
+ append_to_log("failure", 'GET ' + url + '/properties/description/', xhr.status + ' ' + xhr.statusText);
1132
1123
  });
1133
1124
  }// }}}
1134
1125
  async function set_testset(testset,exec) {// {{{
@@ -1140,8 +1131,10 @@ async function set_testset(testset,exec) {// {{{
1140
1131
  // load old testsets. remove 12/2026
1141
1132
  $("testset > description manipulate",testset).each((_,t) => {
1142
1133
  if ($('code',t).length == 0) {
1143
- let st = $(t).text();
1144
- $(t).text();
1134
+ // only direct text nodes, children (if any) stay untouched
1135
+ let txt = $(t).contents().filter((_,n) => n.nodeType == Node.TEXT_NODE);
1136
+ let st = txt.text();
1137
+ txt.remove();
1145
1138
  let c = $X('<code xmlns="http://cpee.org/ns/description/1.0"/>');
1146
1139
  c.text(st);
1147
1140
  $(t).append(c);
@@ -1267,6 +1260,7 @@ function load_testset(exec) {// {{{
1267
1260
  url: url,
1268
1261
  success: function(res){
1269
1262
  save['dsl'] = null; // reload dsl and position under all circumstances
1263
+ details_leave(false);
1270
1264
  $('#dat_details').empty();
1271
1265
 
1272
1266
  document.title = "Untitled";
@@ -1278,32 +1272,6 @@ function load_testset(exec) {// {{{
1278
1272
  });
1279
1273
  }
1280
1274
  }// }}}
1281
- function load_modeltype() {// {{{
1282
- if (loading) return;
1283
- var url = $('body').attr('current-instance');
1284
- loading = true;
1285
-
1286
- var name = $("#modeltypes div.menuitem[data-selected=selected]").text();
1287
- $.ajax({
1288
- cache: false,
1289
- dataType: 'xml',
1290
- url: name + ".xml",
1291
- success: function(res){
1292
- $.ajax({
1293
- type: "PUT",
1294
- url: url + "/properties/attributes/modeltype/",
1295
- data: ({value: name}),
1296
- success: function(){
1297
- set_testset(res,false);
1298
- },
1299
- error: report_failure
1300
- });
1301
- },
1302
- complete: function() {
1303
- loading = false;
1304
- }
1305
- });
1306
- }// }}}
1307
1275
 
1308
1276
  async function load_des(url,model) { //{{{
1309
1277
  return $.ajax({
@@ -1510,13 +1478,27 @@ function format_visual_vote_clear() {//{{{
1510
1478
  $("#votes").empty();
1511
1479
  }//}}}
1512
1480
 
1513
- function format_instance_pos() { //{{{
1481
+ function format_instance_pos_load() { //{{{
1482
+ // counts were just cleared, they are rebuilt from the snapshot
1483
+ save['instance_pos_anon'] = {};
1484
+ track_forget_running(save['activity_red_states']);
1485
+ track_forget_running(save['position_states']);
1514
1486
  $(save['instance_pos']).each(function(){
1515
1487
  var taskname = this.nodeName;
1516
1488
  var taskstate = this.textContent;
1517
- format_visual_add(taskname,save['state'] == 'running' ? (taskstate == 'at' ? 'active' : 'passive') : 'passive');
1489
+ var anon = save['instance_pos_anon'][taskname] ??= {};
1490
+ var clss = ['passive']; // like position events, at and after are passive
1491
+ if (save['state'] == 'running' && taskstate == 'at') { clss.push('active'); }
1492
+ clss.forEach((cls) => {
1493
+ anon[cls] = (anon[cls] ?? 0) + 1;
1494
+ format_visual_add(taskname,cls);
1495
+ });
1518
1496
  });
1519
1497
  } //}}}
1498
+ function format_instance_pos() { //{{{
1499
+ // graph was redrawn, so only render the current state again
1500
+ Object.keys(node_state).forEach((what) => { format_visual_set(what); });
1501
+ } //}}}
1520
1502
 
1521
1503
  function format_visual_forms() { //{{{
1522
1504
  if (save['state'] != "ready" && save['state'] != "stopped") {
@@ -1651,4 +1633,12 @@ function add_ui_pos(e) { //{{{
1651
1633
  });
1652
1634
  } //}}}
1653
1635
 
1654
- function report_failure(){}
1636
+ function report_failure(xhr,status,error){ //{{{
1637
+ // used as ajax error callback, this is the request
1638
+ append_to_log("failure", this.type + ' ' + this.url, xhr.status + ' ' + (error || status));
1639
+ } //}}}
1640
+ function report_model_failure(xhr,status,error){ //{{{
1641
+ // if the server sends a real error, dont reload, we handle in sse, only if
1642
+ // the server is down or we fail on riddl facade, reload
1643
+ if (xhr.status == 0 || xhr.status >= 500) { monitor_graph_change(true); }
1644
+ } //}}}
@@ -0,0 +1,36 @@
1
+ function clean_bubble_ui_type(type) { //{{{
2
+ let status = $('#' + ui.current_bubble);
3
+ if (type == 'loading') {
4
+ status.removeClass('success');
5
+ status.removeClass('error');
6
+ } else if (type == 'success') {
7
+ status.removeClass('loading');
8
+ status.removeClass('error');
9
+ } else if (type == 'error') {
10
+ status.removeClass('success');
11
+ status.removeClass('loading');
12
+ } else {
13
+ status.removeClass('success');
14
+ status.removeClass('error');
15
+ status.removeClass('loading');
16
+ }
17
+ } //}}}
18
+ function set_bubble_ui(llms,what,type='') { //{{{
19
+ if (!what) { what = 'Unknown Error'; }
20
+ let status = $('#' + ui.current_bubble);
21
+ clean_bubble_ui_type(type);
22
+ status.addClass(type);
23
+ if (what.match(/Agent/)) {
24
+ let myllm = llms.find(":selected").val();
25
+ if (myllm === undefined){ myllm = default_llm; }
26
+ what += ' (' + myllm + ')';
27
+ }
28
+ status.text(what);
29
+ status[0].parentElement.scrollTo({ top: status[0].parentElement.scrollHeight, behavior: 'smooth' });
30
+ } //}}}
31
+ function add_bubble_ui(type) { //{{{
32
+ let id = Math.random().toString(36).substring(2, 10);
33
+ $('<div></div>').attr('id',id).addClass(type).appendTo('#status');
34
+ ui.current_bubble = id;
35
+ return id;
36
+ } //}}}