Name: cockpit/js/instance.js 
1:
var ws;
2:
var running = false;
3:
var graphrealization;
4:
var subscription;
5:
var subscription_state = 'less';
6:
var save = {};
7:
    save['state']= undefined;
8:
    save['dsl'] = undefined;
9:
    save['endpoints'] = undefined;
10:
    save['dataelements'] = undefined;
11:
    save['details'] = undefined;
12:
var node_state = {};
13:
var sub_more = 'topic'  + '=' + 'running' + '&' +// {{{
14:
               'events' + '=' + 'activity_calling,activity_receiving,activity_manipulating,activity_failed,activity_done' + '&' +
15:
               'topic'  + '=' + 'running' + '&' +
16:
               'votes'  + '=' + 'syncing_after' + '&' +
17:
               'topic'  + '=' + 'properties/description' + '&' +
18:
               'events' + '=' + 'change,error' + '&' +
19:
               'topic'  + '=' + 'properties/position' + '&' +
20:
               'events' + '=' + 'change' + '&' +
21:
               'topic'  + '=' + 'properties/state' + '&' +
22:
               'events' + '=' + 'change' + '&' +
23:
               'topic'  + '=' + 'properties/dataelements' + '&' +
24:
               'events' + '=' + 'change' + '&' +
25:
               'topic'  + '=' + 'properties/endpoints' + '&' +
26:
               'events' + '=' + 'change' + '&' +
27:
               'topic'  + '=' + 'properties/handlerwrapper' + '&' +
28:
               'events' + '=' + 'result' + '&' +
29:
               'topic'  + '=' + 'properties/handlers' + '&' +
30:
               'events' + '=' + 'change';// }}}
31:
var sub_less = 'topic'  + '=' + 'running' + '&' +// {{{
32:
               'events' + '=' + 'activity_calling,activity_manipulating,activity_failed,activity_done' + '&' +
33:
               'topic'  + '=' + 'properties/position' + '&' +
34:
               'events' + '=' + 'change' + '&' +
35:
               'topic'  + '=' + 'properties/description' + '&' +
36:
               'events' + '=' + 'change,error' + '&' +
37:
               'topic'  + '=' + 'properties/state' + '&' +
38:
               'events' + '=' + 'change' + '&' +
39:
               'topic'  + '=' + 'properties/dataelements' + '&' +
40:
               'events' + '=' + 'change' + '&' +
41:
               'topic'  + '=' + 'properties/endpoints' + '&' +
42:
               'events' + '=' + 'change' + '&' +
43:
               'topic'  + '=' + 'properties/handlerwrapper' + '&' +
44:
               'events' + '=' + 'result' + '&' +
45:
               'topic'  + '=' + 'properties/handlers' + '&' +
46:
               'events' + '=' + 'change';// }}}
47:
 
48:
$(document).ready(function() {// {{{
49:
  $("input[name=base-url]").val(location.protocol + "//" + location.host + ":" + $('body').data('defaultport'));
50:
  $("button[name=base]").click(function(){ create_instance(null); });
51:
  $("button[name=instance]").click(function(){ ui_tab_click("#tabinstance"); monitor_instance(false); });
52:
  $("button[name=loadtestset]").click(load_testset);
53:
  $("button[name=loadtestsetfile]").click(load_testsetfile);
54:
  $("button[name=loadmodelfile]").click(load_modelfile);
55:
  $("button[name=savetestset]").click(function(){ save_testset(); });
56:
  $("button[name=savesvg]").click(function(){ save_svg(); });
57:
  $("input[name=votecontinue]").click(check_subscription);
58:
 
59:
 
60:
  $.ajax({
61:
    url: "testsets/index.xml",
62:
    dataType: 'xml',
63:
    success: function(res){
64:
      $('testset',res).each(function(){
65:
        var ts = $(this).text();
66:
        $('select[name=testset-names]').append(
67:
          $("<option></option>").attr("value",ts).text(ts)
68:
        );
69:
      });
70:
      var q = $.parseQuery();
71:
      if (q.monitor && q.load) {
72:
        $("input[name=instance-url]").val(q.monitor);
73:
        $("select[name=testset-names]").val(q.load)
74:
        ui_tab_click("#tabexecution");
75:
        monitor_instance(true);
76:
      } else if (q.load) {
77:
        $("select[name=testset-names]").val(q.load)
78:
        ui_tab_click("#tabexecution");
79:
        create_instance(q.load);
80:
      } else if (q.monitor) {
81:
        $("input[name=instance-url]").val(q.monitor);
82:
        ui_tab_click("#tabexecution");
83:
        // ui_toggle_vis_tab($("#instance td.switch"));
84:
        monitor_instance(false);
85:
      }  
86:
    }
87:
  });
88:
});// }}}
89:
 
90:
function check_subscription() { // {{{
91:
  var url = $("input[name=current-instance]").val();
92:
  var num = 0;
93:
  if ($("input[name=votecontinue]").is(':checked')) num += 1;
94:
  if (num > 0 && subscription_state == 'less') {
95:
    $.ajax({
96:
      type: "PUT",
97:
      url: url + "/notifications/subscriptions/" + subscription,
98:
      data: (
99:
        'message-uid' + '=' + 'xxx' + '&' +
100:
        sub_more + '&' +
101:
        'fingerprint-with-producer-secret' + '=' + 'xxx'
102:
      )
103:
    });
104:
    subscription_state = 'more';
105:
  }  
106:
  if (num == 0 && subscription_state == 'more') {
107:
    $.ajax({
108:
      type: "PUT",
109:
      url: url + "/notifications/subscriptions/" + subscription,
110:
      data: (
111:
        'message-uid' + '=' + 'xxx' + '&' +
112:
        sub_less + '&' +
113:
        'fingerprint-with-producer-secret' + '=' + 'xxx'
114:
      )
115:
    });  
116:
    subscription_state = 'less';
117:
    format_visual_vote_clear();
118:
  }  
119:
}// }}}
120:
 
121:
function create_instance(ask) {// {{{
122:
  var info = ask ? ask: prompt("Instance info?", "Enter info here");
123:
  if (info != null) {
124:
    if (info.match(/\S/)) {
125:
      var base = $("input[name=base-url]").val();
126:
      $.ajax({
127:
        type: "POST",
128:
        url: base,
129:
        dataType: "text",
130:
        data: "info=" + info,
131:
        success: function(res){
132:
          $("input[name=instance-url]").val((base + "//" + res + "/").replace(/\/+/g,"/").replace(/:\//,"://"));
133:
          if (ask) monitor_instance(true);
134:
        },  
135:
        error: function(a,b,c) {
136:
          alert("No CPEE running.");
137:
        }
138:
      });
139:
    } else {
140:
      alert("An instance info is necessary!");
141:
    }
142:
  }  
143:
}// }}}
144:
  
145:
function monitor_instance(load) {// {{{
146:
  var url = $("input[name=instance-url]").val();
147:
 
148:
  $('.tabbehind button').hide();
149:
  $('#dat_details').empty();
150:
 
151:
  $.ajax({
152:
    type: "GET",
153:
    url: url + "/properties/schema/",
154:
    success: function(res){
155:
      $(".tabbed.hidden").removeClass("hidden");
156:
      $(".tabbed .tab.hidden").removeClass("hidden");
157:
 
158:
      // Change url to return to current instance when reloading
159:
      $("input[name=current-instance]").val(url);
160:
      $("#current-instance").text(url);
161:
      $("#current-instance").attr('href',url);
162:
      history.replaceState({}, '', '?monitor='+url);
163:
 
164:
      // Change url to return to current instance when reloading (because new subscription is made)
165:
      $("input[name=votecontinue]").removeAttr('checked');
166:
      subscription_state = 'less';
167:
 
168:
      $.ajax({
169:
        type: "POST",
170:
        url: url + "/notifications/subscriptions/",
171:
        data: sub_less,
172:
        success: function(res){
173:
          res = res.unserialize();
174:
          $.each(res,function(a,b){
175:
            if (b[0] == 'key') {
176:
              subscription = b[1];
177:
            }  
178:
          });
179:
          append_to_log("monitoring", "id", subscription);
180:
          var Socket = "MozWebSocket" in window ? MozWebSocket : WebSocket;
181:
          if (ws) ws.close();
182:
          ws = new Socket(url.replace(/http/,'ws') + "/notifications/subscriptions/" + subscription + "/ws/");
183:
          ws.onopen = function() {
184:
            append_to_log("monitoring", "opened", "");
185:
          };
186:
          ws.onmessage = function(e) {
187:
            data = e.data.parseXML();
188:
            if ($('event > topic',data).length > 0) {
189:
              switch($('event > topic',data).text()) {
190:
                case 'properties/dataelements':
191:
                  monitor_instance_dataelements();
192:
                  break;
193:
                case 'properties/description':
194:
                  monitor_instance_dsl();
195:
                  break;
196:
                case 'properties/endpoints':
197:
                  monitor_instance_endpoints();
198:
                  break;
199:
                case 'properties/state':
200:
                  monitor_instance_state_change(JSON.parse($('event > notification',data).text()).state);
201:
                  break;
202:
                case 'properties/position':
203:
                  monitor_instance_pos_change($('event > notification',data).text());
204:
                  break;
205:
                case 'running':
206:
                  monitor_instance_running($('event > notification',data).text(),$('event > event',data).text());
207:
                  break;
208:
              }
209:
              append_to_log("event", $('event > topic',data).text() + "/" + $('event > event',data).text(), $('event > notification',data).text());
210:
            }
211:
            if ($('vote > topic',data).length > 0) {
212:
              var notification = $('vote > notification',data).text();
213:
              append_to_log("vote", $('vote > topic',data).text() + "/" + $('vote > vote',data).text(), notification);
214:
              monitor_instance_vote_add(notification);
215:
            }  
216:
          };
217:
          ws.onclose = function() {
218:
            append_to_log("monitoring", "closed", "server down i assume.");
219:
          };
220:
          if (load) load_testset();
221:
        }
222:
      });
223:
 
224:
      monitor_instance_dataelements();
225:
      monitor_instance_endpoints();
226:
      monitor_instance_dsl();
227:
      monitor_instance_state();
228:
    },
229:
    error: function(a,b,c) {
230:
      alert("This ain't no CPEE instance");
231:
      ui_tab_click("#tabnew");
232:
    }
233:
  });      
234:
}// }}}
235:
 
236:
function monitor_instance_dataelements() {// {{{
237:
  var url = $("input[name=current-instance]").val();
238:
  $.ajax({
239:
    type: "GET",
240:
    url: url + "/properties/values/dataelements/",
241:
    success: function(res){
242:
      var values = $("value > *",res);
243:
      var temp = {};
244:
      values.each(function() {
245:
        temp[this.nodeName] = format_text($(this).text());
246:
      });
247:
      var temp_xml = serialize_hash(temp);
248:
 
249:
      if (temp_xml != save['dataelements']) {
250:
        save['dataelements'] = temp_xml;
251:
        var ctv = $("#dat_dataelements");
252:
        ctv.empty();
253:
        $.each(temp,function(a,b){
254:
          var node = $("#dat_template_pair tr").clone(true);
255:
          $('.pair_name',node).val(a);
256:
          $('.pair_value',node).val(b);
257:
          ctv.append(node);
258:
        });
259:
      }  
260:
    }
261:
  });      
262:
} // }}}
263:
 
264:
function monitor_instance_endpoints() {// {{{
265:
  var url = $("input[name=current-instance]").val();
266:
  $.ajax({
267:
    type: "GET",
268:
    url: url + "/properties/values/endpoints/",
269:
    success: function(res){
270:
      var values = $("value > *",res);
271:
      var temp = {}
272:
      values.each(function(){
273:
        temp[this.nodeName] = $(this).text();
274:
      });
275:
      var temp_xml = serialize_hash(temp);
276:
 
277:
      if (temp_xml != save['endpoints']) {
278:
        save['endpoints'] = temp_xml;
279:
        var ctv = $("#dat_endpoints");
280:
        ctv.empty();
281:
        $.each(temp,function(a,b){
282:
          var node = $("#dat_template_pair tr").clone(true);
283:
          $('.pair_name',node).val(a);
284:
          $('.pair_value',node).val(b);
285:
          ctv.append(node);
286:
        });
287:
        ctv.append(temp);
288:
      }  
289:
    }
290:
  });
291:
}// }}}
292:
 
293:
function monitor_instance_dsl() {// {{{
294:
  var url = $("input[name=current-instance]").val();
295:
  $.ajax({
296:
    type: "GET",
297:
    dataType: "text",
298:
    url: url + "/properties/values/dsl/",
299:
    success: function(res){
300:
      if (res != save['dsl']) {
301:
        save['dsl'] = res;
302:
        var ctv = $("#areadsl");
303:
        ctv.empty();
304:
 
305:
        res = format_code(res,false,true);
306:
        res = res.replace(/activity\s+:([A-Za-z][a-zA-Z0-9_]+)/g,"<span class='activities' id=\"activity-$1\">activity :$1</span>");
307:
        res = res.replace(/activity\s+\[:([A-Za-z][a-zA-Z0-9_]+)([^\]]*\])/g,"<span class='activities' id=\"activity-$1\">activity [:$1$2</span>");
308:
 
309:
        ctv.append(res);
310:
 
311:
        $.ajax({
312:
          type: "GET",
313:
          url: url + "/properties/values/dslx/",
314:
          success: function(res){
315:
            graphrealization = new WfAdaptor(CPEE);
316:
            graphrealization.set_svg_container($('#graphcanvas'));
317:
            graphrealization.set_description($(res), true);
318:
            graphrealization.notify = function(svgid) {
319:
              save_description();
320:
              manifestation.events.click(svgid,undefined);
321:
            };
322:
            $('#graphcanvas').redraw();
323:
            $('#graphcolumn div').redraw();
324:
 
325:
            monitor_instance_pos();
326:
          }
327:
        });
328:
      }
329:
    }
330:
  });
331:
}// }}}
332:
 
333:
function monitor_instance_state() {// {{{
334:
  var url = $("input[name=current-instance]").val();
335:
  $.ajax({
336:
    type: "GET",
337:
    url: url + "/properties/values/state/",
338:
    dataType: "text",
339:
    success: function(res){
340:
      monitor_instance_state_change(res);
341:
    }
342:
  });
343:
}// }}}
344:
 
345:
function monitor_instance_pos() {// {{{
346:
  var url = $("input[name=current-instance]").val();
347:
  $.ajax({
348:
    type: "GET",
349:
    url: url + "/properties/values/positions/",
350:
    success: function(res){
351:
      var values = $("value > *",res);
352:
      format_visual_clear();
353:
      values.each(function(){
354:
        var what = this.nodeName;
355:
        format_visual_add(what,"passive");
356:
      });
357:
    }
358:
  });
359:
}// }}}
360:
 
361:
function monitor_instance_running(notification,event) {// {{{
362:
  if (save['state'] == "stopping") return;
363:
  var parts = JSON.parse(notification);
364:
  if (event == "activity_calling")
365:
    format_visual_add(parts.activity,"active")
366:
  if (event == "activity_done")
367:
    format_visual_remove(parts.activity,"active")
368:
} // }}}
369:
function monitor_instance_state_change(notification) { //{{{
370:
  if (notification == "ready" || notification == "stopped" || notification == "running") {
371:
    $("#state button").removeAttr('disabled');
372:
  }  
373:
  if (notification != save['state']) {
374:
    save['state'] = notification;
375:
 
376:
    var ctv = $("#state");
377:
    ctv.empty();
378:
 
379:
    if (notification == "stopped") {
380:
      monitor_instance_pos();
381:
    }  
382:
    if (notification == "running") {
383:
      format_visual_clear();
384:
    }  
385:
 
386:
    var but = "";
387:
    if (notification == "ready" || notification == "stopped") {
388:
      but = " ⇒ <button onclick='$(this).attr(\"disabled\",\"disabled\");start_instance();'>start</button> / <button onclick='$(this).attr(\"disabled\",\"disabled\");sim_instance();'>simulate</button>";
389:
    }
390:
    if (notification == "running") {
391:
      but = " ⇒ <button onclick='$(this).attr(\"disabled\",\"disabled\");stop_instance();'>stop</button>";
392:
    }
393:
 
394:
    if (notification == "finished") {
395:
      $('.tabbehind button').hide();
396:
    } else {
397:
      $('#parameters .tabbehind button').show();
398:
    }  
399:
 
400:
    ctv.append(notification + but);
401:
  }
402:
}   //}}}
403:
function monitor_instance_pos_change(notification) {// {{{
404:
  var parts = JSON.parse(notification);
405:
  if (parts['unmark']) {
406:
    $.each(parts['unmark'],function(a,b){
407:
      format_visual_remove(b,"passive")
408:
    });
409:
  }
410:
  if (parts['at']) {
411:
    $.each(parts['at'],function(a,b){
412:
      format_visual_add(b,"passive")
413:
    });
414:
  }
415:
} // }}}
416:
 
417:
function monitor_instance_vote_add(notification) {// {{{
418:
  var parts = JSON.parse(notification);
419:
  var ctv = $("#votes");
420:
 
421:
  astr = '';
422:
  if ($("input[name=votecontinue]").is(':checked'))
423:
    astr += "<button id='vote_to_continue-" + parts.activity + "-" + parts.callback + "' onclick='$(this).attr(\"disabled\",\"disabled\");monitor_instance_vote_remove(\"" + parts.activity + "\",\"" + parts.callback + "\",\"true\");'>" + parts.activity + "</button>";
424:
  ctv.append(astr);
425:
  format_visual_add(parts.activity,"vote")
426:
}// }}}
427:
function monitor_instance_vote_remove(activity,callback,value) {//{{{
428:
  var url = $("input[name=current-instance]").val();
429:
  $.ajax({
430:
    type: "PUT",
431:
    url: url + "/callbacks/" + callback,
432:
    data: ({'continue': value}),
433:
    error: report_failure
434:
  });
435:
  format_visual_remove(activity,"vote");
436:
  $('#vote_to_continue-' + activity + '-' + callback).remove();
437:
}//}}}
438:
 
439:
function start_instance() {// {{{
440:
  var url = $("input[name=current-instance]").val();
441:
  $.ajax({
442:
    type: "PUT",
443:
    url: url + "/properties/values/state",
444:
    data: ({value: "running"}),
445:
    error: report_failure
446:
  });
447:
}// }}}
448:
function sim_instance() {// {{{
449:
  var url = $("input[name=current-instance]").val();
450:
  $.ajax({
451:
    type: "PUT",
452:
    url: url + "/properties/values/state",
453:
    data: ({value: "simulating"}),
454:
    error: report_failure
455:
  });
456:
}// }}}
457:
function stop_instance() {// {{{
458:
  var url = $("input[name=current-instance]").val();
459:
  $.ajax({
460:
    type: "PUT",
461:
    url: url + "/properties/values/state",
462:
    data: ({value: "stopping"}),
463:
    error: report_failure
464:
  });
465:
}// }}}
466:
 
467:
function save_testset() {// {{{
468:
  var base = $("input[name=current-instance]").val();
469:
  var testset = $X('<testset/>');
470:
 
471:
  $.ajax({
472:
    type: "GET",
473:
    url: base + "/properties/values/dataelements/",
474:
    success: function(res){
475:
      var pars = $X('<dataelements/>');
476:
      pars.append($(res.documentElement).children());
477:
      testset.append(pars);
478:
      $.ajax({
479:
        type: "GET",
480:
        url: base + "/properties/values/handlerwrapper/",
481:
        success: function(res){
482:
          var pars = $X('<handlerwrapper>' + res + '</handlerwrapper>');
483:
          testset.append(pars);
484:
          $.ajax({
485:
            type: "GET",
486:
            url: base + "/properties/values/endpoints/",
487:
            success: function(res){
488:
              var pars = $X('<endpoints/>');
489:
              pars.append($(res.documentElement).children());
490:
              testset.append(pars);
491:
              $.ajax({
492:
                type: "GET",
493:
                url: base + "/properties/values/positions/",
494:
                success: function(res){
495:
                  var pars = $X('<positions/>');
496:
                  pars.append($(res.documentElement).children());
497:
                  testset.append(pars);
498:
                  $.ajax({
499:
                    type: "GET",
500:
                    url: base + "/properties/values/description/",
501:
                    success: function(res){
502:
                      var pars = $X('<description/>');
503:
                      pars.append($(res.documentElement));
504:
                      testset.append(pars);
505:
                      $.ajax({
506:
                        type: "GET",
507:
                        url: base + "/properties/values/transformation/",
508:
                        success: function(res){
509:
                          var pars = $X('<transformation/>');
510:
                          pars.append($(res.documentElement).children());
511:
                          testset.append(pars);
512:
                          $.ajax({
513:
                            type: "GET",
514:
                            url: base + "/properties/values/info/",
515:
                            success: function(res){
516:
                              var name = res;
517:
 
518:
                              $('#savetestset').attr('download',name + '.xml');
519:
                              $('#savetestset').attr('href','data:application/xml;charset=utf-8;base64,' + window.btoa(testset.serializeXML()));
520:
                              document.getElementById('savetestset').click();
521:
                            },  
522:
                            error: report_failure
523:
                          });
524:
                        },  
525:
                        error: report_failure
526:
                      });
527:
                    },  
528:
                    error: report_failure
529:
                  });
530:
                },
531:
                error: report_failure
532:
              });
533:
            },
534:
            error: report_failure
535:
          });
536:
        },
537:
        error: report_failure
538:
      });
539:
    },
540:
    error: report_failure
541:
  });  
542:
}// }}}
543:
function save_svg() {// {{{
544:
  var base = $("input[name=current-instance]").val();
545:
  var params = { mimetype: 'image/svg+xml' };
546:
 
547:
  var gc = $('#graphcanvas').clone();
548:
  $.ajax({
549:
    type: "GET",
550:
    url: "lib/wfadaptor.css",
551:
    success: function(res){
552:
      gc.prepend($X('<style xmlns="http://www.w3.org/2000/svg" type="text/css"><![CDATA[' + res + ']]></style>'));
553:
      $.ajax({
554:
        type: "GET",
555:
        url: base + "/properties/values/info/",
556:
        success: function(res){
557:
          var name = res;
558:
 
559:
          $('#savesvg').attr('download',name + '.svg');
560:
          $('#savesvg').attr('href','data:application/xml;charset=utf-8;base64,' + window.btoa(gc.serializeXML()));
561:
          document.getElementById('savesvg').click();
562:
        },  
563:
        error: report_failure
564:
      });
565:
    }  
566:
  });
567:
}// }}}
568:
function set_testset(testset) {// {{{
569:
  var url = $("input[name=current-instance]").val();
570:
 
571:
  $.ajax({
572:
    type: "GET",
573:
    url: url + "/notifications/subscriptions/",
574:
    success: function(res){
575:
      var rcount = 0;
576:
      var values = $("subscriptions > subscription[url]",res);
577:
      var vals = [];
578:
      values.each(function(){
579:
        vals.push($(this).attr('url'));
580:
      });
581:
      load_testset_handlers(url,testset,vals);
582:
    },
583:
    error: report_failure
584:
  });  
585:
 
586:
  load_testset_dataelements(url,testset);
587:
  load_testset_endpoints(url,testset);
588:
  load_testset_pos(url,testset);
589:
 
590:
  if ($("testset > transformation",testset).length > 0) {
591:
    var ser = '';
592:
    $("testset > transformation > *",testset).each(function(){
593:
      ser += $(this).serializeXML() + "\n";
594:
    });
595:
    var val = "<content>" + ser + "</content>";
596:
    $.ajax({
597:
      type: "PUT",
598:
      url: url + "/properties/values/transformation",
599:
      data: ({content: val}),
600:
      success: function() {
601:
        load_testset_des(url,testset);
602:
      },
603:
      error: report_failure
604:
    });
605:
  }  
606:
  
607:
  load_testset_hw(url,testset);
608:
  $.ajax({
609:
    type: "GET",
610:
    url: url + "/properties/values/state/",
611:
    dataType: "text",
612:
    success: function(res){
613:
      $.ajax({
614:
        type: "PUT",
615:
        url: url + "/properties/values/state",
616:
        data: ({value: res}),
617:
        error: report_failure
618:
      });
619:
    }
620:
  });
621:
 }// }}}
622:
function load_testsetfile() { //{{{
623:
  if (running) return;
624:
  if (typeof window.FileReader !== 'function') {
625:
    alert('FileReader not yet supportet');
626:
    return;
627:
  }  
628:
  var files = $('#testsetfile').get(0).files;
629:
  var reader = new FileReader();
630:
  reader.onload = function(){
631:
    set_testset(reader.result.parseXML());
632:
    running  = false;
633:
  }  
634:
  reader.onerror = function(){ running  = false; }  
635:
  reader.onabort = function(){ running  = false; }  
636:
  reader.readAsText(files[0]);
637:
} //}}}
638:
function load_modelfile() { //{{{
639:
  if (running) return;
640:
  if (typeof window.FileReader !== 'function') {
641:
    alert('FileReader not yet supportet');
642:
    return;
643:
  }  
644:
  var files = $('#modelfile').get(0).files;
645:
  var reader = new FileReader();
646:
  reader.onload = function(){
647:
    var url = $("input[name=current-instance]").val();
648:
    load_des(url,reader.result);
649:
    running  = false;
650:
  }  
651:
  reader.onerror = function(){ running  = false; }  
652:
  reader.onabort = function(){ running  = false; }  
653:
  reader.readAsText(files[0]);
654:
} //}}}
655:
function load_testset() {// {{{
656:
  if (running) return;
657:
  running  = true;
658:
  save['dsl'] = null; // reload dsl and position under all circumstances
659:
  
660:
  $('#main .tabbehind button').hide();
661:
  $('#dat_details').empty();
662:
 
663:
  var name = $("select[name=testset-names]").val();
664:
 
665:
  $.ajax({
666:
    cache: false,
667:
    dataType: 'xml',
668:
    url: "testsets/" + name + ".xml",
669:
    success: function(res){
670:
      document.title = name;
671:
      set_testset(res);
672:
    }
673:
  });
674:
  running  = false;
675:
}// }}}
676:
 
677:
function load_des(url,model) { //{{{
678:
  model = model.replace(/<\?[^\?]+\?>/,'');
679:
  var val = "<content>" + model + "</content>";
680:
  $.ajax({
681:
    type: "PUT",
682:
    url: url + "/properties/values/description",
683:
    data: ({content: val}),
684:
    error: report_failure
685:
  });
686:
}   //}}}
687:
 
688:
function load_testset_des(url,testset) {// {{{
689:
  if ($("testset > description",testset).length == 0) { return; }
690:
  var ser = '';
691:
  $("testset > description > *",testset).each(function(){
692:
    ser += $(this).serializeXML() + "\n";
693:
  });
694:
  load_des(url,ser);
695:
} // }}}
696:
function load_testset_hw(url,testset) {// {{{
697:
  $("testset > handlerwrapper",testset).each(function(){
698:
    var val = $(this).text();
699:
    $.ajax({
700:
      type: "PUT",
701:
      url: url + "/properties/values/handlerwrapper",
702:
      data: ({value: val}),
703:
      error: report_failure
704:
    });
705:
  });
706:
} // }}}
707:
function load_testset_dataelements(url,testset) {// {{{
708:
  if ($("testset > dataelements",testset).length == 0) { return; }
709:
  var ser = '';
710:
  $("testset > dataelements > *",testset).each(function(){
711:
    ser += $(this).serializeXML() + "\n";
712:
  });
713:
  var val = "<content>" + ser + "</content>";
714:
  $.ajax({
715:
    type: "PUT",
716:
    url: url + "/properties/values/dataelements",
717:
    data: ({content: val}),
718:
    error: report_failure
719:
  });
720:
}// }}}
721:
function load_testset_endpoints(url,testset) {// {{{
722:
  if ($("testset > endpoints",testset).length == 0) { return; }
723:
  var ser = '';
724:
  $("testset > endpoints > *",testset).each(function(){
725:
    ser += $(this).serializeXML() + "\n";
726:
  });
727:
  var val = "<content>" + ser + "</content>";
728:
  $.ajax({
729:
    type: "PUT",
730:
    url: url + "/properties/values/endpoints/",
731:
    data: ({content: val}),
732:
    error: report_failure
733:
  });  
734:
}// }}}
735:
function load_testset_pos(url,testset) {// {{{
736:
  if ($("testset > positions",testset).length == 0) { return; }
737:
  var ser = '';
738:
  $("testset > positions > *",testset).each(function(){
739:
    ser += $(this).serializeXML() + "\n";
740:
  });
741:
  var val = "<content>" + ser + "</content>";
742:
  $.ajax({
743:
    type: "PUT",
744:
    url: url + "/properties/values/positions/",
745:
    data: ({content: val}),
746:
    success: monitor_instance_pos,
747:
    error: report_failure
748:
  });  
749:
}// }}}
750:
function load_testset_handlers(url,testset,vals) {// {{{
751:
  $("testset > handlers > *",testset).each(function(){
752:
    var han = this;
753:
    var suburl = $(han).attr('url');
754:
    if ($.inArray(suburl,vals) == -1) {
755:
      var inp = "url="+encodeURIComponent(suburl);
756:
      $("*",han).each(function(){
757:
        inp += "&topic=" + $(this).attr('topic');
758:
        inp += "&" + this.nodeName + "=" + $(this).text();
759:
      });
760:
      $.ajax({
761:
        type: "POST",
762:
        url: url + "/notifications/subscriptions/",
763:
        data: inp
764:
      });
765:
    }
766:
  });
767:
}// }}}
768:
 
769:
function format_visual_add(what,cls) {//{{{
770:
  if (node_state[what] == undefined)
771:
    node_state[what] = {};
772:
  if (node_state[what][cls] == undefined)
773:
    node_state[what][cls] = 0;
774:
  node_state[what][cls] += 1;
775:
  format_visual_set(what);
776:
}//}}}
777:
function format_visual_remove(what,cls) {//{{{
778:
  if (node_state[what] == undefined)
779:
    node_state[what] = {};
780:
  if (node_state[what][cls] == undefined)
781:
    node_state[what][cls] = 0;
782:
  node_state[what][cls] -= 1;
783:
  format_visual_set(what);
784:
}//}}}
785:
function format_visual_set(what) {//{{{
786:
  if (node_state[what] != undefined) {
787:
    if (node_state[what]['vote'] == undefined) node_state[what]['vote'] = 0;
788:
    if (node_state[what]['active'] == undefined) node_state[what]['active'] = 0;
789:
    if (node_state[what]['passive'] == undefined) node_state[what]['passive'] = 0;
790:
 
791:
    var votes = node_state[what]['vote'];
792:
    var actives = node_state[what]['active'];
793:
    var passives = node_state[what]['passive'];
794:
 
795:
    if (actives > 0 && votes > 0)
796:
      $('g[element-id="' + what + '"] .super .colon').each(function(a,b){
797:
        b.setAttribute('class','colon necessary');
798:
      });
799:
    else  
800:
      $('g[element-id="' + what + '"] .super .colon').each(function(a,b){
801:
        b.setAttribute('class','colon');
802:
      });
803:
    if (actives > 0)
804:
      $('g[element-id="' + what + '"] .super .active').each(function(a,b){
805:
        b.setAttribute('class','active necessary');
806:
        var txt = b.childNodes[0];
807:
        txt.nodeValue = actives;
808:
      });
809:
    else  
810:
      $('g[element-id="' + what + '"] .super .active').each(function(a,b){
811:
        b.setAttribute('class','active');
812:
      });
813:
    if (votes > 0)
814:
      $('g[element-id="' + what + '"] .super .vote').each(function(a,b){
815:
        b.setAttribute('class','vote necessary');
816:
        var txt = b.childNodes[0];
817:
        txt.nodeValue = votes;
818:
      });
819:
    else  
820:
      $('g[element-id="' + what + '"] .super .vote').each(function(a,b){
821:
        b.setAttribute('class','vote');
822:
      });
823:
 
824:
    $.each(['#activity-' + what, 'g[element-id="' + what + '"] g'],function(i,t){
825:
      $(t).each(function(a,b){
826:
        if      (actives > 0)  vs = 'active';
827:
        else if (votes > 0)    vs = 'vote';
828:
        else if (passives > 0) vs = 'passive';
829:
        else                   vs = '';
830:
        b.setAttribute("class",'activities ' + vs);
831:
      });
832:
    });
833:
  }  
834:
 
835:
}//}}}
836:
function format_visual_clear() {//{{{
837:
  node_state = {};
838:
  $('.super .active').each(function(a,b){b.setAttribute("class","active");});
839:
  $('.super .passive').each(function(a,b){b.setAttribute("class","passive");});
840:
  $('.super .vote').each(function(a,b){b.setAttribute("class","vote");});
841:
  $('.super .colon').each(function(a,b){b.setAttribute("class","colon");});
842:
  $('.activities').each(function(a,b){b.setAttribute("class","activities");});
843:
  $("#votes").empty();
844:
}//}}}
845:
function format_visual_vote_clear() {//{{{
846:
  node_state = {};
847:
  $('.super .vote').each(function(a,b){b.setAttribute("class","vote");});
848:
  $("#votes").empty();
849:
}//}}}
850:
 
851:
function format_code(res,skim,lnums) {// {{{
852:
 try {
853:
  res = res.replace(/&/g,'&');
854:
  res = res.replace(/</g,'<');
855:
  res = res.replace(/>/g,'>');
856:
  res = res.replace(/\t/g,'  ');
857:
  res = res.replace(/\t/g,'  ');
858:
  res = res.replace(/\r/g,'');
859:
  res = res.replace(/\s*$/gm,'');
860:
  res = res.replace(/^(\s*\n)*/m,'');
861:
 
862:
  if (res.match(/\S/)) {
863:
    if (skim) format_text_skim(res);
864:
 
865:
    var m;
866:
    var l = 1;
867:
    while (m = res.match(/^ +|^(?!<div style=)|^$/m)) {
868:
      m = m[0];
869:
      var tm = (m.length + 2) * 0.6 + 2 * 0.6 + 4 * 0.6;
870:
      var ln = (lnums ? $.sprintf("%03d",l) + ':&#160;' : '');
871:
      res = res.replace(/^ +|^(?!<div style=)|^$/m,"<div style='text-indent:-" + tm + "em;margin-left:" + tm + "em'>" + ln + "&#160;".repeat(m.length));
872:
      l++;
873:
    }
874:
    res = res.replace(/  /g," &#160;");
875:
    res = res.replace(/\n$/g,"\n<div>&#160;");
876:
    res = res.replace(/\n|$/g,"</div>\n");
877:
  }  
878:
  } catch(e) {
879:
    alert(e.toString());
880:
  }  
881:
  return res;
882:
}// }}}
883:
function format_text(res) {// {{{
884:
  res = res.replace(/&/g,'&');
885:
  res = res.replace(/</g,'<');
886:
  res = res.replace(/>/g,'>');
887:
  return res;
888:
}// }}}
889:
function format_text_skim(res) {// {{{
890:
  var l = res.match(/^ */);
891:
  l = l[0].length;
892:
  res = res.replace(new RegExp("^ {" + l + "}",'mg'),'');
893:
  return res;
894:
}// }}}
895:
 
896:
function serialize_hash(ary) { //{{{
897:
  var xml = $X('<content/>');
898:
  $.each(ary,function(k,v) {
899:
    if (k.match(/^[a-zA-Z][a-zA-Z0-9_]*$/)) {
900:
      xml.append($X('<' + k + '>' + v + '</' + k + '>'));
901:
    }
902:
  });
903:
  return xml.serializeXML();
904:
} //}}}
905:
 
906:
function append_to_log(what,type,message) {//{{{
907:
  var d = new Date();
908:
  message = message.replace(/,\"/g,', "');
909:
  message = message.replace(/,\{/g,', {');
910:
  message = message.replace(/,\[/g,', [');
911:
  message = message.replace(/:\"/g,': "');
912:
  message = message.replace(/:\{/g,': {');
913:
  message = message.replace(/:\[/g,': [');
914:
  $("#dat_log").append("<tr><td class='fixed'><a title=\"" + d.strftime("[%d/%b/%Y %H:%M:%S]") + "\">D</a></td><td class='fixed'>&#160;-&#160;</td><td class='fixed'><a title=\"" + what + "\">T</a></td><td class='fixed'>&#160;-&#160;</td><td class='fixed'>" +  type + "</td><td class='fixed'>&#160;-&#160;</td><td class='long'>" +  message + "</td></tr>");
915:
}//}}}
916:
 
917:
function report_failure(){}