@dualbox/editor 1.0.41 → 1.0.42

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.
@@ -45342,7 +45342,7 @@ var script = {
45342
45342
  //console.log('[UPDATING] ' + this.n.getUniqId());
45343
45343
  },
45344
45344
  destroyed: function() {
45345
- console.log('[DESTROYED] ' + this.n.getUniqId());
45345
+ //console.log('[DESTROYED] ' + this.n.getUniqId());
45346
45346
  },
45347
45347
  created: function() {
45348
45348
  this.initialized = false;
@@ -45358,7 +45358,7 @@ var script = {
45358
45358
  }
45359
45359
  },
45360
45360
  mounted: async function() {
45361
- console.log('[MOUNTED] ' + this.n.getUniqId());
45361
+ //console.log('[MOUNTED] ' + this.n.getUniqId());
45362
45362
  var div = $(this.$el);
45363
45363
  div.fixCardDisplay();
45364
45364
  div.ready(() => {
@@ -45373,7 +45373,7 @@ var script = {
45373
45373
  this.deactivateTooltip();
45374
45374
  },
45375
45375
  updated: async function() {
45376
- console.log('[UPDATED] ' + this.n.getUniqId());
45376
+ //console.log('[UPDATED] ' + this.n.getUniqId());
45377
45377
 
45378
45378
  // we reset jsPlumb before app update (in graph.vue)
45379
45379
  // so we need to initialize again
@@ -45445,7 +45445,7 @@ var script = {
45445
45445
 
45446
45446
  return new Promise(resolve => {
45447
45447
  div.ready(() => {
45448
- console.log('[INITIALIZED] ' + this.n.getUniqId());
45448
+ //console.log('[INITIALIZED] ' + this.n.getUniqId());
45449
45449
  this.initialized = true;
45450
45450
  resolve();
45451
45451
  });
@@ -46363,7 +46363,7 @@ __vue_render__._withStripped = true;
46363
46363
  /* style */
46364
46364
  const __vue_inject_styles__ = function (inject) {
46365
46365
  if (!inject) return
46366
- inject("data-v-51e7220d_0", { source: "\n.card-ui {\n background-color: #bff2ca!important;\n}\n.card-loop {\n /* background-color: #e5e8ea!important; */\n border: 5px double #dddddd;\n border-width: 4px;\n}\n.card-input {\n background-color: #f5d76e!important;\n}\n.card-output {\n background-color: #ffb3a7!important;\n}\n.box-inputs {\n float: left;\n padding-left: 2px;\n padding-right: 5px;\n vertical-align: top;\n text-align: left;\n}\n.box-outputs {\n float: right;\n padding-left: 5px;\n padding-right: 2px;\n vertical-align: top;\n text-align: right;\n}\n.dualbox-graph-canvas .card, .card-node {\n /*border: 1px solid #dddddd;*/\n box-shadow: 1px 1px 5px #716f6f;\n opacity: 1;\n cursor: pointer;\n z-index: 20;\n position: absolute;\n\n -webkit-transition: -webkit-box-shadow 0.15s ease-in;\n -moz-transition: -moz-box-shadow 0.15s ease-in;\n -o-transition: -o-box-shadow 0.15s ease-in;\n transition: box-shadow 0.15s ease-in;\n\n color: #4d4d4d;\n user-select: none;\n padding: 0px 8px 0px 8px;\n overflow:hidden;\n background-color: #fff;\n -moz-border-radius: 3px;\n border-radius:3px;\n font-size: 14px;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n}\n.card-node .card-top {\n padding-top: 2px;\n}\n.card-node .card-bottom {\n padding-bottom: 2px;\n text-align: center;\n line-height: 14px;\n white-space: nowrap;\n}\n.card-node hr {\n margin-top: 2px;\n margin-bottom: 2px;\n border-color: rgba(0,0,0,0.1);\n margin-left: -8px;\n margin-right: -8px;\n}\n.card-node:hover {\n border-color: #80b2fc;\n box-shadow: 1px 1px 10px #80b2fc;\n}\n.card-node.selected, .card-node.selected:hover {\n border-color: #0066ff;\n box-shadow: 1px 1px 10px #0066ff;\n}\n.card-node-incomplete {\n box-shadow: 1px 1px 5px #dd6666 !important;\n}\n.input-not-resolvable {\n color: #dd6666!important;\n}\n.card-node .title {\n vertical-align:top;\n font-weight: bold;\n}\n.card-node .subtitle {\n color:#929292;\n font-size: 11px;\n font-style: italic;\n vertical-align:center;\n font-family: tahoma, sans-serif;\n}\n.card-node .input {\n font-size: 13px;\n color: #8c8c8c;\n}\n.card-node .output {\n font-size: 13px;\n color: #8c8c8c;\n text-align:right;\n}\n.card-node .jtk-endpoint.active svg circle {\n /* fill: #99ff33 */\n stroke: #59b300;\n}\n.point {\n /* display: inline-block; */\n display: none;\n position: relative;\n top: 3px;\n margin-right: 5px;\n margin-left: 5px;\n}\n.dualbox-io {\n overflow: visible;\n margin-left: -8px;\n margin-right: -8px;\n}\n.box-inputs {\n display: flex;\n justify-content: space-between;\n position: relative;\n padding: 0;\n pointer-events: none;\n}\n.types {\n color: #6c757d!important;\n opacity: 0.7;\n pointer-events: none;\n}\n.box-inputs .types {\n display: inline-block;\n}\n.box-inputs .name {\n display: inline-block;\n}\n.box-inputs .type {\n display: block;\n text-align: right;\n}\n.box-inputs .point {\n display: block;\n}\n.box-inputs .name {\n display: block;\n}\n.box-outputs {\n display: flex;\n justify-content: center;\n position: relative;\n padding: 0;\n pointer-events: none;\n}\n.box-outputs .types {\n display: inline-block;\n}\n.box-outputs .point {\n display: inline-block;\n}\n.box-outputs .name {\n display: inline-block;\n}\n.box-outputs .type {\n display: block;\n text-align: left;\n}\n.box-outputs .point {\n display: block;\n}\n.box-outputs .name {\n display: block;\n}\nspan.feedback {\n font-weight: bold;\n}\n.event-dock {\n background-color: rgb(136, 137, 138);\n background-color: #a6a6a6;\n width: calc(100% + 18px);\n height: 12px;\n z-index: 3!important;\n}\n.event-dock-top {\n margin-left: -9px;\n margin-right: -9px;\n margin-top: -3px;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n margin-bottom: 4px;\n}\n.event-dock-bottom {\n margin-left: -9px;\n margin-right: -9px;\n margin-bottom: -3px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n margin-top: 4px;\n height: 11px; /* shorter because of box-shadow */\n}\n.event-label {\n z-index: 21;\n padding-left: 15px;\n transform: rotate(-90deg) translate(0%, -50%)!important;\n transform-origin: 0% 0%;\n color: #6c757d!important;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n font-size: 14px;\n opacity: 0.7;\n cursor: pointer;\n}\n.transparent {\n opacity: 0.3!important;\n}\n.card-node {\n position: relative;\n}\n.card-comment {\n position: absolute;\n top: 0;\n right: 0;\n margin-top: -22px;\n color: #f4ad42!important;\n}\n.card-problem {\n position: absolute;\n top: 0;\n left: 0;\n margin-top: -22px;\n color: red!important;\n}\n.card-snapshot {\n}\n.card-snapshot-idle {\n border: 2px solid gray!important;\n box-shadow: 1px 1px 5px gray!important;\n opacity: 0.7!important;\n}\n.card-snapshot-computing {\n border: 2px solid darkgreen!important;\n box-shadow: 1px 1px 5px darkgreen!important;\n opacity: 1!important;\n}\n.card-snapshot-awaiting-data {\n border: 2px solid blue!important;\n box-shadow: 1px 1px 5px blue!important;\n opacity: 0.7!important;\n}\n.card-snapshot-ready {\n border: 2px solid lightgreen!important;\n box-shadow: 1px 1px 5px lightgreen!important;\n opacity: 1!important;\n}\n.card-status {\n position: absolute;\n bottom: 0;\n right: 0;\n left: 0;\n margin-bottom: -26px;\n color: #f4ad42!important;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n font-weight: bold;\n text-align: center;\n}\n.card-status-idle {\n color: gray!important;\n min-width: 85px;\n}\n.card-status-computing {\n color: darkgreen!important;\n min-width: 110px;\n}\n.card-status-awaiting-data {\n color: blue!important;\n min-width: 85px;\n}\n.card-status-ready {\n color: lightgreen!important;\n min-width: 85px;\n}\n.btn-snapshot-details {\n position: relative;\n margin-top: -2px;\n color: inherit;\n}\nspan.name {\n overflow-wrap: normal;\n}\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/graphNode.vue"],"names":[],"mappings":";AACA;IACA,mCAAA;AACA;AAEA;IACA,yCAAA;IACA,0BAAA;IACA,iBAAA;AACA;AAEA;IACA,mCAAA;AACA;AAEA;IACA,mCAAA;AACA;AAEA;IACA,WAAA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,gBAAA;AACA;AAEA;IACA,YAAA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,iBAAA;AACA;AAEA;IACA,6BAAA;IACA,+BAAA;IACA,UAAA;IACA,eAAA;IACA,WAAA;IACA,kBAAA;;IAEA,oDAAA;IACA,8CAAA;IACA,0CAAA;IACA,oCAAA;;IAEA,cAAA;IACA,iBAAA;IACA,wBAAA;IACA,eAAA;IACA,sBAAA;IACA,uBAAA;IACA,iBAAA;IACA,eAAA;IACA,2DAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,mBAAA;IACA,kBAAA;IACA,iBAAA;IACA,mBAAA;AACA;AAEA;IACA,eAAA;IACA,kBAAA;IACA,6BAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,qBAAA;IACA,gCAAA;AACA;AAEA;IACA,qBAAA;IACA,gCAAA;AACA;AAEA;IACA,0CAAA;AACA;AAEA;IACA,wBAAA;AACA;AAEA;IACA,kBAAA;IACA,iBAAA;AACA;AAEA;IACA,aAAA;IACA,eAAA;IACA,kBAAA;IACA,qBAAA;IACA,+BAAA;AACA;AAEA;IACA,eAAA;IACA,cAAA;AACA;AAEA;IACA,eAAA;IACA,cAAA;IACA,gBAAA;AACA;AAEA;IACA,kBAAA;IACA,eAAA;AACA;AAEA;IACA,2BAAA;IACA,aAAA;IACA,kBAAA;IACA,QAAA;IACA,iBAAA;IACA,gBAAA;AACA;AAEA;IACA,iBAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,aAAA;IACA,8BAAA;IACA,kBAAA;IACA,UAAA;IACA,oBAAA;AACA;AAEA;IACA,wBAAA;IACA,YAAA;IACA,oBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,cAAA;IACA,iBAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,aAAA;IACA,uBAAA;IACA,kBAAA;IACA,UAAA;IACA,oBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,cAAA;IACA,gBAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,oCAAA;IACA,2BAAA;IACA,wBAAA;IACA,YAAA;IACA,oBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;IACA,2BAAA;IACA,4BAAA;IACA,kBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,8BAAA;IACA,+BAAA;IACA,eAAA;IACA,YAAA,EAAA,kCAAA;AACA;AAEA;IACA,WAAA;IACA,kBAAA;IACA,uDAAA;IACA,uBAAA;IACA,wBAAA;IACA,2DAAA;IACA,eAAA;IACA,YAAA;IACA,eAAA;AACA;AAEA;IACA,sBAAA;AACA;AAEA;IACA,kBAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,QAAA;IACA,iBAAA;IACA,wBAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,OAAA;IACA,iBAAA;IACA,oBAAA;AACA;AAEA;AAEA;AAEA;IACA,gCAAA;IACA,sCAAA;IACA,sBAAA;AACA;AAEA;IACA,qCAAA;IACA,2CAAA;IACA,oBAAA;AACA;AAEA;IACA,gCAAA;IACA,sCAAA;IACA,sBAAA;AACA;AAEA;IACA,sCAAA;IACA,4CAAA;IACA,oBAAA;AACA;AAEA;IACA,kBAAA;IACA,SAAA;IACA,QAAA;IACA,OAAA;IACA,oBAAA;IACA,wBAAA;IACA,2DAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,qBAAA;IACA,eAAA;AACA;AAEA;IACA,0BAAA;IACA,gBAAA;AACA;AAEA;IACA,qBAAA;IACA,eAAA;AACA;AAEA;IACA,2BAAA;IACA,eAAA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,cAAA;AACA;AAEA;IACA,qBAAA;AACA","file":"graphNode.vue","sourcesContent":["<style>\n.card-ui {\n background-color: #bff2ca!important;\n}\n\n.card-loop {\n /* background-color: #e5e8ea!important; */\n border: 5px double #dddddd;\n border-width: 4px;\n}\n\n.card-input {\n background-color: #f5d76e!important;\n}\n\n.card-output {\n background-color: #ffb3a7!important;\n}\n\n.box-inputs {\n float: left;\n padding-left: 2px;\n padding-right: 5px;\n vertical-align: top;\n text-align: left;\n}\n\n.box-outputs {\n float: right;\n padding-left: 5px;\n padding-right: 2px;\n vertical-align: top;\n text-align: right;\n}\n\n.dualbox-graph-canvas .card, .card-node {\n /*border: 1px solid #dddddd;*/\n box-shadow: 1px 1px 5px #716f6f;\n opacity: 1;\n cursor: pointer;\n z-index: 20;\n position: absolute;\n\n -webkit-transition: -webkit-box-shadow 0.15s ease-in;\n -moz-transition: -moz-box-shadow 0.15s ease-in;\n -o-transition: -o-box-shadow 0.15s ease-in;\n transition: box-shadow 0.15s ease-in;\n\n color: #4d4d4d;\n user-select: none;\n padding: 0px 8px 0px 8px;\n overflow:hidden;\n background-color: #fff;\n -moz-border-radius: 3px;\n border-radius:3px;\n font-size: 14px;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n}\n\n.card-node .card-top {\n padding-top: 2px;\n}\n\n.card-node .card-bottom {\n padding-bottom: 2px;\n text-align: center;\n line-height: 14px;\n white-space: nowrap;\n}\n\n.card-node hr {\n margin-top: 2px;\n margin-bottom: 2px;\n border-color: rgba(0,0,0,0.1);\n margin-left: -8px;\n margin-right: -8px;\n}\n\n.card-node:hover {\n border-color: #80b2fc;\n box-shadow: 1px 1px 10px #80b2fc;\n}\n\n.card-node.selected, .card-node.selected:hover {\n border-color: #0066ff;\n box-shadow: 1px 1px 10px #0066ff;\n}\n\n.card-node-incomplete {\n box-shadow: 1px 1px 5px #dd6666 !important;\n}\n\n.input-not-resolvable {\n color: #dd6666!important;\n}\n\n.card-node .title {\n vertical-align:top;\n font-weight: bold;\n}\n\n.card-node .subtitle {\n color:#929292;\n font-size: 11px;\n font-style: italic;\n vertical-align:center;\n font-family: tahoma, sans-serif;\n}\n\n.card-node .input {\n font-size: 13px;\n color: #8c8c8c;\n}\n\n.card-node .output {\n font-size: 13px;\n color: #8c8c8c;\n text-align:right;\n}\n\n.card-node .jtk-endpoint.active svg circle {\n /* fill: #99ff33 */\n stroke: #59b300;\n}\n\n.point {\n /* display: inline-block; */\n display: none;\n position: relative;\n top: 3px;\n margin-right: 5px;\n margin-left: 5px;\n}\n\n.dualbox-io {\n overflow: visible;\n margin-left: -8px;\n margin-right: -8px;\n}\n\n.box-inputs {\n display: flex;\n justify-content: space-between;\n position: relative;\n padding: 0;\n pointer-events: none;\n}\n\n.types {\n color: #6c757d!important;\n opacity: 0.7;\n pointer-events: none;\n}\n\n.box-inputs .types {\n display: inline-block;\n}\n\n.box-inputs .name {\n display: inline-block;\n}\n\n.box-inputs .type {\n display: block;\n text-align: right;\n}\n\n.box-inputs .point {\n display: block;\n}\n\n.box-inputs .name {\n display: block;\n}\n\n.box-outputs {\n display: flex;\n justify-content: center;\n position: relative;\n padding: 0;\n pointer-events: none;\n}\n\n.box-outputs .types {\n display: inline-block;\n}\n\n.box-outputs .point {\n display: inline-block;\n}\n\n.box-outputs .name {\n display: inline-block;\n}\n\n.box-outputs .type {\n display: block;\n text-align: left;\n}\n\n.box-outputs .point {\n display: block;\n}\n\n.box-outputs .name {\n display: block;\n}\n\nspan.feedback {\n font-weight: bold;\n}\n\n.event-dock {\n background-color: rgb(136, 137, 138);\n background-color: #a6a6a6;\n width: calc(100% + 18px);\n height: 12px;\n z-index: 3!important;\n}\n\n.event-dock-top {\n margin-left: -9px;\n margin-right: -9px;\n margin-top: -3px;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n margin-bottom: 4px;\n}\n\n.event-dock-bottom {\n margin-left: -9px;\n margin-right: -9px;\n margin-bottom: -3px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n margin-top: 4px;\n height: 11px; /* shorter because of box-shadow */\n}\n\n.event-label {\n z-index: 21;\n padding-left: 15px;\n transform: rotate(-90deg) translate(0%, -50%)!important;\n transform-origin: 0% 0%;\n color: #6c757d!important;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n font-size: 14px;\n opacity: 0.7;\n cursor: pointer;\n}\n\n.transparent {\n opacity: 0.3!important;\n}\n\n.card-node {\n position: relative;\n}\n\n.card-comment {\n position: absolute;\n top: 0;\n right: 0;\n margin-top: -22px;\n color: #f4ad42!important;\n}\n\n.card-problem {\n position: absolute;\n top: 0;\n left: 0;\n margin-top: -22px;\n color: red!important;\n}\n\n.card-snapshot {\n\n}\n\n.card-snapshot-idle {\n border: 2px solid gray!important;\n box-shadow: 1px 1px 5px gray!important;\n opacity: 0.7!important;\n}\n\n.card-snapshot-computing {\n border: 2px solid darkgreen!important;\n box-shadow: 1px 1px 5px darkgreen!important;\n opacity: 1!important;\n}\n\n.card-snapshot-awaiting-data {\n border: 2px solid blue!important;\n box-shadow: 1px 1px 5px blue!important;\n opacity: 0.7!important;\n}\n\n.card-snapshot-ready {\n border: 2px solid lightgreen!important;\n box-shadow: 1px 1px 5px lightgreen!important;\n opacity: 1!important;\n}\n\n.card-status {\n position: absolute;\n bottom: 0;\n right: 0;\n left: 0;\n margin-bottom: -26px;\n color: #f4ad42!important;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n font-weight: bold;\n text-align: center;\n}\n\n.card-status-idle {\n color: gray!important;\n min-width: 85px;\n}\n\n.card-status-computing {\n color: darkgreen!important;\n min-width: 110px;\n}\n\n.card-status-awaiting-data {\n color: blue!important;\n min-width: 85px;\n}\n\n.card-status-ready {\n color: lightgreen!important;\n min-width: 85px;\n}\n\n.btn-snapshot-details {\n position: relative;\n margin-top: -2px;\n color: inherit;\n}\n\nspan.name {\n overflow-wrap: normal;\n}\n</style>\n\n<template>\n <div class=\"jtk-node card card-node contextmenu\" v-bind:class=\"{ 'card-loop': n.hasLoop(), 'card-ui': n.isUI(), 'card-metanode': n.isMetanode(), 'card-input': n.isInput(), 'card-output': n.isOutput(), 'card-snapshot': n.hasSnapshot(), 'card-snapshot-idle': n.hasSnapshot() && n.isSnapshotStatus(0), 'card-snapshot-computing': n.hasSnapshot() && n.isSnapshotStatus(1), 'card-snapshot-awaiting-data': n.hasSnapshot() && n.isSnapshotStatus(2), 'card-snapshot-ready': n.hasSnapshot() && n.isSnapshotStatus(3) }\" v-bind:id=\"getId()\" v-bind:data-id=\"getId()\" v-bind:data-name=\"pkg.name\" style=\"overflow: visible;\">\n <div v-if=\"n.hasComment()\">\n <div class=\"card-comment\" data-toggle=\"tooltip\" data-placement=\"top\" :title=\"n.getComment()\">\n <i class=\"fas fa-comment-alt\" data-container=\"body\"></i>\n </div>\n </div>\n\n <div v-if=\"n.hasSnapshot()\">\n <div class=\"card-status\">\n <div v-if=\"n.isSnapshotStatus(0)\">\n <div class=\"card-status-idle\">\n <span>IDLE</span>\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\n </div>\n </div>\n\n <div v-if=\"n.isSnapshotStatus(1)\">\n <div class=\"card-status-computing\">\n <span>COMPUTING</span>\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\n </div>\n </div>\n\n <div v-if=\"n.isSnapshotStatus(2)\">\n <div class=\"card-status-awaiting-data\">\n <span>WAITING</span>\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\n </div>\n </div>\n\n <div v-if=\"n.isSnapshotStatus(3)\">\n <div class=\"card-status-ready\">\n <span>READY</span>\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\n </div>\n </div>\n </div>\n </div>\n\n <div v-if=\"!example && n.isUI() && !n.isOnAPanel()\">\n <div class=\"card-problem\">\n <i class=\"fas fa-exclamation-circle\" data-container=\"body\" data-toggle=\"popover\" data-placement=\"top\" data-content=\"This UI is not set in a panel. It won't have any effect. Go to the Interface tab to add it to a panel.\"></i>\n </div>\n </div>\n\n <div class=\"card-top\">\n <div class=\"d-flex\">\n <span class=\"title\" style=\"white-space: nowrap; margin-right: 5px;\">\n <span v-if=\"n.isMetanode()\" class=\"badge badge-secondary\"><b>META</b></span>\n {{n.graphId}}\n <i v-if=\"n.isParallel()\" class=\"fas fa-server\" style=\"color: orange;\" title=\"this module is computed in a web worker\"></i>\n </span>\n\n <div class=\"ml-auto\">\n <button class=\"btn btn-outline-secondary btn-outline-discrete btn-editor-xs btn-settings\" v-on:click=\"openNodeSettings\"><i class=\"fas fa-cog\"></i></button>\n </div>\n </div>\n </div>\n <div v-if=\"!n.isInput() && !n.isOutput()\" class=\"card-center\">\n <hr style=\"margin-bottom: 5px;\"/>\n <div class=\"dualbox-io\" style=\"overflow: visible;\">\n <div class=\"inputs\" style=\"display: inline-block; float: left;\">\n <div class=\"box-inputs\">\n <div class=\"types\">\n <span class=\"type\" v-for=\"key in getVisibleInputs()\" v-bind:data-key=\"key\">\n {{ n.getInputType(key) }}\n </span>\n </div>\n <div class=\"points\">\n <div class=\"point\" v-for=\"key in getVisibleInputs()\" v-bind:data-key=\"key\" v-bind:data-type=\"n.getInputDef(key).type\" v-html=\"point\"></div>\n </div>\n <div class=\"names\">\n <span class=\"name\" v-for=\"key in getVisibleInputs()\" :class=\"{'feedback': n.isFeedbackTarget(key), 'input-not-resolvable': !example && !n.isInputResolvable(key) }\" v-bind:data-input=\"key\">\n <span v-if=\"n.hasIterator(key)\">&lt;{{key}}&gt;</span>\n <span v-else>{{key}}</span>\n <small v-if=\"!n.isInputConst(key)\" data-toggle=\"tooltip\" data-trigger=\"hover\" title=\"this value will be cloned at execution time\"><i class=\"fas fa-clone transparent\"></i></small>\n </span>\n </div>\n </div>\n </div>\n <div class=\"outputs\" style=\"display: inline-block; float: right\">\n <div class=\"box-outputs\">\n <div class=\"names\">\n <span class=\"name\" v-for=\"key in getVisibleOutputs()\" v-bind:class=\"{feedback: n.isFeedbackTarget(key)}\" v-bind:data-output=\"key\">\n <span v-if=\"n.hasLoop() && n.hasFeedback(key)\">{{key}}</span>\n <span v-else-if=\"n.hasLoop() && !n.hasFeedback(key)\" v-html='\"&lt;\"+key+\"&gt;\"'></span>\n <span v-else>{{key}}</span>\n\n <span v-if=\"n.hasCacheActivated()\">\n &nbsp;<i class=\"fa fa-hdd\" title=\"This module has cache activated\"></i>\n </span>\n </span>\n </div>\n <div class=\"points\">\n <div class=\"point\" v-for=\"key in getVisibleOutputs()\" v-bind:data-key=\"key\" v-bind:data-type=\"n.getOutputDef(key).type\" v-html=\"point\"></div>\n </div>\n <div class=\"types\">\n <span class=\"type\" v-for=\"key in getVisibleOutputs()\" v-bind:data-key=\"key\">\n {{ n.getOutputType(key) }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <hr style=\"margin-top: 5px;\"/>\n <div class=\"card-bottom\">\n <span class=\"subtitle\">{{ shortName }}</span>\n\n <div v-if=\"n.isMetanode()\" class=\"d-inline-block\">\n <button class=\"btn btn-outline-secondary btn-outline-discrete btn-editor-xs btn-enter-metanode\" v-on:click=\"enterMetanode\"><i class=\"fas fa-sign-in-alt\"></i></button>\n </div>\n\n <!--\n <div v-if=\"n.isUI()\" class=\"event-dock event-dock-bottom\"></div>\n -->\n </div>\n </div>\n</template>\n\n<script>\nimport ContextMenu from '../ContextMenu';\nimport _ from 'lodash';\nimport dbutils from '../../m/DualboxUtils';\n\n// fix inputs types and output types position relatively to the div\n$.fn.fixCardDisplay = function() {\n var offsetPoint = 12;\n var offsetBorder = parseInt($(this).css(\"border-top-width\"));\n\n if( $(this).find('.box-inputs').height() === 0 && $(this).find('.box-outputs').height() === 0 ) {\n // if this card has no input/output, remove the card center\n $(this).find('.card-center').remove();\n }\n else {\n // else, adjust the input/output display for endpoints\n // 1) translate inputs by the right amount of pixels to have the circle on the line\n var boxInputs = $(this).find('.box-inputs');\n\n // fix css names width\n var namesDiv = boxInputs.find('.names');\n namesDiv.css('width', (namesDiv.width()+1) + 'px');\n\n // translate inputs to the left\n var translateLeft = boxInputs.find('.types').width() + offsetPoint + offsetBorder/2;\n $(this).find('.box-inputs').css('transform', 'translateX(-' + translateLeft + 'px)');\n\n // adjust inputs main div width\n $(this).find('.inputs').width( $(this).find('.inputs').width() - translateLeft + 10 /* margin */ );\n\n\n // 2) translate outputs by the right amount of pixels to have the circle on the line\n var boxOutputs = $(this).find('.box-outputs');\n\n // fix css names with\n var namesDiv = boxOutputs.find('.names');\n namesDiv.css('width', (namesDiv.width() + 1) + 'px');\n\n // translate inputs to the right\n var translateRight = boxOutputs.find('.types').width() + offsetPoint + offsetBorder/2;\n $(this).find('.box-outputs').css('transform', 'translateX(' + translateRight + 'px)');\n\n // adjust output main div width\n $(this).find('.outputs').width( $(this).find('.outputs').width() - translateRight + 10 /* margin */ );\n\n // fix io width\n //$('.dualbox-io').css('width', (($(this).find('.inputs').width() + $(this).find('.outputs').width()) + \"px\"));\n }\n}\n\n// take the current width and add it as a css property\n$.fn.fixWidth = function() {\n var width = $(this).width();\n width += parseInt($(this).css('padding-right'));\n width += parseInt($(this).css('padding-left'));\n width += parseInt($(this).css('border-left-width'));\n width += parseInt($(this).css('border-right-width'));\n $(this).css('width', width + 'px');\n}\n\n// find position of element relative to an ancestor matching selector\n$.fn.positionFrom = function( selector ) {\n var ancestor = $(this).closest(selector);\n var offset = $(this).offset();\n var ancestorOffset = ancestor.offset();\n return {\n top: offset.top - ancestorOffset.top,\n left: offset.left - ancestorOffset.left,\n }\n}\n\nexport default {\n props: [\n \"id\", // the module id\n \"pkg\", // the module package.json\n \"n\", // the GraphNode object (from model)\n \"example\", // true if this vue is used as an example display (no need to connect)\n ],\n data: function () {\n return {\n shortName: \"\",\n point: '<svg width=\"14\" height=\"14\" pointer-events=\"all\" position=\"absolute\" version=\"1.1\" xmlns=\"http://www.w3.org/1999/xhtml\"><circle cx=\"7\" cy=\"7\" r=\"5\" version=\"1.1\" xmlns=\"http://www.w3.org/1999/xhtml\" fill=\"#ffffff\" stroke=\"#727272\" style=\"\" stroke-width=\"2\"></circle></svg>',\n }\n },\n beforeUpdate: function() {\n //console.log('[UPDATING] ' + this.n.getUniqId());\n },\n destroyed: function() {\n console.log('[DESTROYED] ' + this.n.getUniqId());\n },\n created: function() {\n this.initialized = false;\n this.view = window.dualboxEditor.v;\n\n //console.log('[CREATED] ' + this.n.getUniqId());\n // We compute the shortname of our box\n if( this.n.isInput() || this.n.isOutput() ) {\n this.shortName = this.n.getType();\n }\n else {\n this.shortName = dbutils.shortName(this.pkg.name);\n }\n },\n mounted: async function() {\n console.log('[MOUNTED] ' + this.n.getUniqId());\n var div = $(this.$el);\n div.fixCardDisplay();\n div.ready(() => {\n //if( !this.example ) {\n div.fixWidth();\n //}\n });\n this.activateTooltip();\n return await this.initialize();\n },\n beforeUpdate: function() {\n this.deactivateTooltip();\n },\n updated: async function() {\n console.log('[UPDATED] ' + this.n.getUniqId());\n\n // we reset jsPlumb before app update (in graph.vue)\n // so we need to initialize again\n this.assignContextMenu();\n\n $(this.$el).fixCardDisplay();\n $(this.$el).ready(()=>{\n $(this.$el).fixWidth();\n this.activateTooltip();\n });\n return await this.initialize();\n },\n activate: function() {\n this.activateTooltip();\n },\n deactivate: function() {\n this.deactivateTooltip();\n },\n methods: {\n getId: function() {\n // if this is an example graphNode, change our \"id\" to \"id-junk\"\n // to avoid connection jsplumb conflicts with the real node\n return this.example ? this.id + '-junk' : this.id;\n },\n\n activateTooltip: function() {\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip();\n },\n\n deactivateTooltip: function() {\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip(\"dispose\");\n },\n\n initialize: async function() {\n var self = this;\n var div = $(this.$el);\n var id = this.getId();\n var view = this.view;\n\n this.initialized = false;\n\n if( !this.example ) {\n // if we have a position, set it\n var def = this.n.getDef();\n var position = _.get(def, [\"graph\", \"position\"]);\n if( position ) {\n var jsPlumbElement = self.$parent.jsPlumbInstance.getElement(id);\n self.$parent.jsPlumbInstance.setPosition(jsPlumbElement, position);\n }\n\n // This needs to be registered before draggable\n div.on('mousedown', function(e) {\n // if this div is not selected already, deselect the other divs\n if( !self.$parent.selector.isSelected(this) ) {\n self.$parent.selector.deselect();\n }\n });\n\n await this.initializeJsPlumb();\n\n div.click(function(e) {\n if( e.ctrlKey ) {\n view.selector.toggleSelection(this);\n }\n });\n\n this.assignContextMenu();\n }\n\n return new Promise(resolve => {\n div.ready(() => {\n console.log('[INITIALIZED] ' + this.n.getUniqId());\n this.initialized = true;\n resolve();\n });\n });\n },\n\n initializeJsPlumb: function() {\n var self = this;\n var div = $(this.$el);\n var id = this.getId();\n var view = this.view;\n\n if( !this.example ) {\n // If this node was never initialized in this jsplumb instance, do it\n if( !_.get(this.$parent.jsPlumbInstance, [\"initializedNodes\", id]) ) {\n _.set(this.$parent.jsPlumbInstance, [\"initializedNodes\", id], true); // initialized\n\n if( this.n.isInput() || this.n.isOutput() ) {\n var type = \"*\";\n var input = \"value\";\n var output = \"value\";\n var offsetTop = $(div).find('.card-top').height() + 12 /* hr size */ - 3;\n\n var uuid = [ id, \"input\", input].join('#');\n var ep = this.$parent.jsPlumbInstance.addEndpoint(id, {\n isSource : false,\n isTarget : true,\n uuid : uuid,\n anchor : [0,0,-1,0,0,offsetTop],\n maxConnections : 1,\n parameters : {\n type: \"data\",\n target : {\n id : id,\n input : output\n }\n }\n }, this.$parent.style.inputEndpoint);\n\n // add data to the endpoint div so we can identify it easier\n $(ep.canvas).attr('data-node', id);\n $(ep.canvas).attr('data-type', 'input');\n $(ep.canvas).attr('data-input', input);\n\n // bind tooltip\n $(ep.canvas).attr('data-toggle', \"tooltip\");\n $(ep.canvas).attr('data-trigger', \"hover\");\n $(ep.canvas).attr('data-placement', \"left\");\n $(ep.canvas).attr('data-html', \"true\");\n var inputType = view.m.getNode(id).getInputType(\"value\");\n $(ep.canvas).attr('title', \"Type: <b>\" + inputType + \"</b>\");\n $(ep.canvas).tooltip();\n\n // bind context menu to the endpoint\n $(ep.canvas).addClass('capture-right-click');\n $(ep.canvas).ready(function() {\n var menu = new ContextMenu(\".jtk-endpoint-anchor[data-node='\"+id.trim()+\"'][data-input='\" + input + \"']\", [\n {\n name: 'Create input for here',\n fn: () => {\n view.c.createInputFromConnection(id, input);\n }\n },\n ]);\n });\n\n var uuid = [ id, \"output\", output].join('#');\n var ep = this.$parent.jsPlumbInstance.addEndpoint(id, {\n isSource : true,\n isTarget : false,\n uuid : uuid,\n anchor : [1,0,1,0,0,offsetTop],\n parameters : {\n type: \"data\",\n source : {\n id : id,\n output : output\n }\n }\n }, this.$parent.style.outputEndpoint);\n\n // add data to the endpoint div so we can identify it easier\n $(ep.canvas).attr('data-node', id);\n $(ep.canvas).attr('data-type', \"output\");\n $(ep.canvas).attr('data-output', output);\n\n // bind tooltip\n $(ep.canvas).attr('data-toggle', \"tooltip\");\n $(ep.canvas).attr('data-trigger', \"hover\");\n $(ep.canvas).attr('data-placement', \"right\");\n $(ep.canvas).attr('data-html', \"true\");\n var outputType = view.m.getNode(id).getOutputType(\"value\");\n $(ep.canvas).attr('title', \"Type: <b>\" + outputType + \"</b>\");\n $(ep.canvas).tooltip();\n\n // bind context menu to the endpoint\n $(ep.canvas).addClass('capture-right-click');\n $(ep.canvas).ready(function() {\n var menu = new ContextMenu(\".jtk-endpoint-anchor[data-node='\"+id.trim()+\"'][data-output='\" + output.trim() + \"']\", [\n {\n name: 'Create output for here',\n fn: () => {\n view.c.createOutputFromConnection(id, output);\n }\n },\n ]);\n });\n }\n else {\n // add input endoints\n div.find('.box-inputs').find('.point').each( function(index) {\n $(this).css('visibility', 'hidden').css('opacity', '0'); // replaced by jsPlumb point\n\n var input = div.find('.box-inputs').find('.name').eq(index).attr('data-input').trim();\n var type = view.m.getNode(id).getInputType(input);\n\n var offsetTop = $(this).positionFrom('.card').top + $(this).height()/2 - 3;\n var uuid = [ id, \"input\", $(this).data('key')].join('#');\n var ep = self.$parent.jsPlumbInstance.addEndpoint(id, {\n isSource : false,\n isTarget : true,\n uuid : uuid,\n anchor : [0,0,-1,0,0,offsetTop],\n maxConnections : 1,\n parameters : {\n type: \"data\",\n target : {\n id : id,\n input : $(this).data('key')\n }\n }\n }, self.$parent.style.inputEndpoint);\n\n // add data to the endpoint div so we can identify it easier\n $(ep.canvas).attr('data-node', id);\n $(ep.canvas).attr('data-type', 'input');\n $(ep.canvas).attr('data-input', input);\n\n // bind tooltip\n $(ep.canvas).attr('data-toggle', \"tooltip\");\n $(ep.canvas).attr('data-trigger', \"hover\");\n $(ep.canvas).attr('data-placement', \"left\");\n $(ep.canvas).attr('data-html', \"true\");\n $(ep.canvas).attr('title', \"Type: <b>\" + type + \"</b>\");\n $(ep.canvas).tooltip();\n\n // bind context menu to the endpoint\n $(ep.canvas).addClass('capture-right-click');\n $(ep.canvas).ready(function() {\n var menu = new ContextMenu(\".jtk-endpoint-anchor[data-node='\"+id.trim()+\"'][data-input='\" + input.trim() + \"']\", [\n {\n name: 'Create input for here',\n fn: () => {\n view.c.createInputFromConnection(id, input);\n }\n },\n ]);\n });\n });\n\n // add output endpoints\n div.find('.box-outputs').find('.point').each( function(index) {\n $(this).css('visibility', 'hidden').css('opacity', '0'); // replaced by jsPlumb point\n\n var output = div.find('.box-outputs').find('.name').eq(index).attr('data-output').trim();\n var type = view.m.getNode(id).getOutputType(output);\n\n var offsetTop = $(this).positionFrom('.card').top + $(this).height()/2 - 3;\n var uuid = [ id, \"output\", $(this).data('key')].join('#');\n var ep = self.$parent.jsPlumbInstance.addEndpoint(id, {\n isSource : true,\n isTarget : false,\n uuid : uuid,\n anchor : [1,0,1,0,0,offsetTop],\n parameters : {\n type: \"data\",\n source : {\n id : id,\n output : $(this).data('key')\n }\n }\n }, self.$parent.style.outputEndpoint);\n\n // add data to the endpoint div so we can identify it easier\n $(ep.canvas).attr('data-node', id);\n $(ep.canvas).attr('data-type', \"output\");\n $(ep.canvas).attr('data-output', output);\n\n // bind tooltip\n $(ep.canvas).attr('data-toggle', \"tooltip\");\n $(ep.canvas).attr('data-trigger', \"hover\");\n $(ep.canvas).attr('data-placement', \"right\");\n $(ep.canvas).attr('data-html', \"true\");\n $(ep.canvas).attr('title', \"Type: <b>\" + type + \"</b>\");\n $(ep.canvas).tooltip();\n\n // bind context menu to the endpoint\n $(ep.canvas).addClass('capture-right-click');\n $(ep.canvas).ready(function() {\n var menu = new ContextMenu(\".jtk-endpoint-anchor[data-node='\"+id.trim()+\"'][data-output='\" + output.trim() + \"']\", [\n {\n name: 'Create output for here',\n fn: () => {\n view.c.createOutputFromConnection(id, output);\n }\n },\n ]);\n });\n });\n\n if( this.n.isUI() && view.showEvents ) {\n // Make this a target for events\n this.$parent.jsPlumbInstance.makeTarget(id, {\n isSource:false,\n isTarget:true,\n uniqueEndpoint: false,\n anchor:\"Continuous\",\n uuid: id + \"#event-in\",\n paintStyle:{ fill:\"green\" },\n parameters: {\n type: \"event\",\n target: { \"id\" : id }\n },\n }, self.$parent.style.eventEndpoint);\n\n // Create an enpoint to create a new event\n var ep = this.$parent.jsPlumbInstance.addEndpoint(id, {\n isSource : true,\n isTarget : false,\n uuid : id + \"#event-out\",\n anchor : [1, 1, 0, 1, 0, -10],\n parameters : {\n type: \"event\",\n source: { \"id\" : id }\n },\n }, this.$parent.style.eventEndpoint);\n\n // Add overlay here so we don't mess with splitConnection\n ep.addOverlay([\"PlainArrow\", { width:15, length:15, location:1, id:\"arrow\" }]);\n\n $(ep.canvas).attr('data-toggle', \"tooltip\");\n $(ep.canvas).attr('data-trigger', \"hover\");\n $(ep.canvas).attr('data-placement', \"bottom\");\n $(ep.canvas).attr('data-html', \"true\");\n $(ep.canvas).attr('title', \"Connect from here ito add an event that will be triggered when this box is done computing.\");\n $(ep.canvas).tooltip();\n }\n }\n\n // Make the div draggable\n this.$parent.jsPlumbInstance.draggable(div, {\n //containment:true, // not allowed outside of container div\n drag: function(e) {\n // TODO: bug. After a repaint(), jsPlumb seems to be broken (connections dont follow on div drag)\n // It doesn't occur on jsPlumb.reset() instead of creating another instance on beforeUpdate(),\n // (as it should be), but we can't do that, because JsPlumb is broken on zoom otherwise...\n // One of thoses problem may be fixed later by updating jsPlumb...\n // Note: this \"fix\" may affect performances on drag, maybe a setTimeout will do\n //self.$parent.jsPlumbInstance.repaintEverything();\n self.$parent.jsPlumbInstance.repaint(id);\n },\n stop: function(e) {\n // resize the canvas if necessary\n self.$parent.canvasSizeHandler.debouncedResize();\n\n if( self.$parent.selector.isMultipleSelectionActive() ) {\n // We just dropped a bunch of divs, ajust all their positions\n self.view.m.history.batch(() => {\n self.$parent.selector.each(div => {\n var pos = self.$parent.jsPlumbInstance.getPosition(div);\n view.m.getNode($(div).attr('id')).setPosition(pos);\n });\n });\n }\n else {\n // We just dropped this one, set the new position in the graph model\n var el = self.$parent.jsPlumbInstance.getElement(id);\n $(el).ready(function() {\n var pos = self.$parent.jsPlumbInstance.getPosition(el);\n view.m.getNode(id).setPosition(pos);\n });\n }\n }\n });\n }\n }\n\n return new Promise((resolve) => this.$parent.jsPlumbInstance.ready(resolve));\n },\n\n assignContextMenu: function() {\n var id = this.getId();\n\n // Create a contextmenu for the div\n var contextOptions = [\n {\n name: 'Remove this box',\n fn: () => {\n this.view.c.removeBox(id);\n }\n }\n ];\n if( this.n.isModule() || this.n.isUI() ) {\n contextOptions.push({\n name: 'Duplicate this box',\n fn: () => {\n this.view.c.duplicateBox(id);\n }\n });\n }\n var nodeMenu = new ContextMenu(\"#\" + id, contextOptions);\n },\n\n htmlentities: function( s ) {\n return this.view.utils.htmlentities(s);\n },\n\n getVisibleInputs: function() {\n return this.n.getInputsNames().filter((inputName) => {\n return this.n.isInputVisible(inputName);\n })\n },\n\n getVisibleOutputs: function() {\n return this.n.getOutputsNames().filter((outputName) => {\n return this.n.isOutputVisible(outputName);\n })\n },\n\n enterMetanode: function(e) {\n e.preventDefault();\n e.stopPropagation();\n\n this.view.c.enterMetanode(this.id);\n },\n\n openNodeSettings: function(e) {\n e.preventDefault();\n e.stopPropagation();\n this.view.openBoxSettings(this.id);\n },\n\n openSnapshotDetails: function(e) {\n e.preventDefault();\n e.stopPropagation();\n this.view.openDebug(this.id);\n }\n },\n watch: {\n 'app': {\n handler: () => {\n console.log('graphVue.app changed');\n },\n deep: true\n }\n }\n}\n\n</script>\n"]}, media: undefined });
46366
+ inject("data-v-054e64e6_0", { source: "\n.card-ui {\n background-color: #bff2ca!important;\n}\n.card-loop {\n /* background-color: #e5e8ea!important; */\n border: 5px double #dddddd;\n border-width: 4px;\n}\n.card-input {\n background-color: #f5d76e!important;\n}\n.card-output {\n background-color: #ffb3a7!important;\n}\n.box-inputs {\n float: left;\n padding-left: 2px;\n padding-right: 5px;\n vertical-align: top;\n text-align: left;\n}\n.box-outputs {\n float: right;\n padding-left: 5px;\n padding-right: 2px;\n vertical-align: top;\n text-align: right;\n}\n.dualbox-graph-canvas .card, .card-node {\n /*border: 1px solid #dddddd;*/\n box-shadow: 1px 1px 5px #716f6f;\n opacity: 1;\n cursor: pointer;\n z-index: 20;\n position: absolute;\n\n -webkit-transition: -webkit-box-shadow 0.15s ease-in;\n -moz-transition: -moz-box-shadow 0.15s ease-in;\n -o-transition: -o-box-shadow 0.15s ease-in;\n transition: box-shadow 0.15s ease-in;\n\n color: #4d4d4d;\n user-select: none;\n padding: 0px 8px 0px 8px;\n overflow:hidden;\n background-color: #fff;\n -moz-border-radius: 3px;\n border-radius:3px;\n font-size: 14px;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n}\n.card-node .card-top {\n padding-top: 2px;\n}\n.card-node .card-bottom {\n padding-bottom: 2px;\n text-align: center;\n line-height: 14px;\n white-space: nowrap;\n}\n.card-node hr {\n margin-top: 2px;\n margin-bottom: 2px;\n border-color: rgba(0,0,0,0.1);\n margin-left: -8px;\n margin-right: -8px;\n}\n.card-node:hover {\n border-color: #80b2fc;\n box-shadow: 1px 1px 10px #80b2fc;\n}\n.card-node.selected, .card-node.selected:hover {\n border-color: #0066ff;\n box-shadow: 1px 1px 10px #0066ff;\n}\n.card-node-incomplete {\n box-shadow: 1px 1px 5px #dd6666 !important;\n}\n.input-not-resolvable {\n color: #dd6666!important;\n}\n.card-node .title {\n vertical-align:top;\n font-weight: bold;\n}\n.card-node .subtitle {\n color:#929292;\n font-size: 11px;\n font-style: italic;\n vertical-align:center;\n font-family: tahoma, sans-serif;\n}\n.card-node .input {\n font-size: 13px;\n color: #8c8c8c;\n}\n.card-node .output {\n font-size: 13px;\n color: #8c8c8c;\n text-align:right;\n}\n.card-node .jtk-endpoint.active svg circle {\n /* fill: #99ff33 */\n stroke: #59b300;\n}\n.point {\n /* display: inline-block; */\n display: none;\n position: relative;\n top: 3px;\n margin-right: 5px;\n margin-left: 5px;\n}\n.dualbox-io {\n overflow: visible;\n margin-left: -8px;\n margin-right: -8px;\n}\n.box-inputs {\n display: flex;\n justify-content: space-between;\n position: relative;\n padding: 0;\n pointer-events: none;\n}\n.types {\n color: #6c757d!important;\n opacity: 0.7;\n pointer-events: none;\n}\n.box-inputs .types {\n display: inline-block;\n}\n.box-inputs .name {\n display: inline-block;\n}\n.box-inputs .type {\n display: block;\n text-align: right;\n}\n.box-inputs .point {\n display: block;\n}\n.box-inputs .name {\n display: block;\n}\n.box-outputs {\n display: flex;\n justify-content: center;\n position: relative;\n padding: 0;\n pointer-events: none;\n}\n.box-outputs .types {\n display: inline-block;\n}\n.box-outputs .point {\n display: inline-block;\n}\n.box-outputs .name {\n display: inline-block;\n}\n.box-outputs .type {\n display: block;\n text-align: left;\n}\n.box-outputs .point {\n display: block;\n}\n.box-outputs .name {\n display: block;\n}\nspan.feedback {\n font-weight: bold;\n}\n.event-dock {\n background-color: rgb(136, 137, 138);\n background-color: #a6a6a6;\n width: calc(100% + 18px);\n height: 12px;\n z-index: 3!important;\n}\n.event-dock-top {\n margin-left: -9px;\n margin-right: -9px;\n margin-top: -3px;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n margin-bottom: 4px;\n}\n.event-dock-bottom {\n margin-left: -9px;\n margin-right: -9px;\n margin-bottom: -3px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n margin-top: 4px;\n height: 11px; /* shorter because of box-shadow */\n}\n.event-label {\n z-index: 21;\n padding-left: 15px;\n transform: rotate(-90deg) translate(0%, -50%)!important;\n transform-origin: 0% 0%;\n color: #6c757d!important;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n font-size: 14px;\n opacity: 0.7;\n cursor: pointer;\n}\n.transparent {\n opacity: 0.3!important;\n}\n.card-node {\n position: relative;\n}\n.card-comment {\n position: absolute;\n top: 0;\n right: 0;\n margin-top: -22px;\n color: #f4ad42!important;\n}\n.card-problem {\n position: absolute;\n top: 0;\n left: 0;\n margin-top: -22px;\n color: red!important;\n}\n.card-snapshot {\n}\n.card-snapshot-idle {\n border: 2px solid gray!important;\n box-shadow: 1px 1px 5px gray!important;\n opacity: 0.7!important;\n}\n.card-snapshot-computing {\n border: 2px solid darkgreen!important;\n box-shadow: 1px 1px 5px darkgreen!important;\n opacity: 1!important;\n}\n.card-snapshot-awaiting-data {\n border: 2px solid blue!important;\n box-shadow: 1px 1px 5px blue!important;\n opacity: 0.7!important;\n}\n.card-snapshot-ready {\n border: 2px solid lightgreen!important;\n box-shadow: 1px 1px 5px lightgreen!important;\n opacity: 1!important;\n}\n.card-status {\n position: absolute;\n bottom: 0;\n right: 0;\n left: 0;\n margin-bottom: -26px;\n color: #f4ad42!important;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n font-weight: bold;\n text-align: center;\n}\n.card-status-idle {\n color: gray!important;\n min-width: 85px;\n}\n.card-status-computing {\n color: darkgreen!important;\n min-width: 110px;\n}\n.card-status-awaiting-data {\n color: blue!important;\n min-width: 85px;\n}\n.card-status-ready {\n color: lightgreen!important;\n min-width: 85px;\n}\n.btn-snapshot-details {\n position: relative;\n margin-top: -2px;\n color: inherit;\n}\nspan.name {\n overflow-wrap: normal;\n}\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/graphNode.vue"],"names":[],"mappings":";AACA;IACA,mCAAA;AACA;AAEA;IACA,yCAAA;IACA,0BAAA;IACA,iBAAA;AACA;AAEA;IACA,mCAAA;AACA;AAEA;IACA,mCAAA;AACA;AAEA;IACA,WAAA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,gBAAA;AACA;AAEA;IACA,YAAA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,iBAAA;AACA;AAEA;IACA,6BAAA;IACA,+BAAA;IACA,UAAA;IACA,eAAA;IACA,WAAA;IACA,kBAAA;;IAEA,oDAAA;IACA,8CAAA;IACA,0CAAA;IACA,oCAAA;;IAEA,cAAA;IACA,iBAAA;IACA,wBAAA;IACA,eAAA;IACA,sBAAA;IACA,uBAAA;IACA,iBAAA;IACA,eAAA;IACA,2DAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,mBAAA;IACA,kBAAA;IACA,iBAAA;IACA,mBAAA;AACA;AAEA;IACA,eAAA;IACA,kBAAA;IACA,6BAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,qBAAA;IACA,gCAAA;AACA;AAEA;IACA,qBAAA;IACA,gCAAA;AACA;AAEA;IACA,0CAAA;AACA;AAEA;IACA,wBAAA;AACA;AAEA;IACA,kBAAA;IACA,iBAAA;AACA;AAEA;IACA,aAAA;IACA,eAAA;IACA,kBAAA;IACA,qBAAA;IACA,+BAAA;AACA;AAEA;IACA,eAAA;IACA,cAAA;AACA;AAEA;IACA,eAAA;IACA,cAAA;IACA,gBAAA;AACA;AAEA;IACA,kBAAA;IACA,eAAA;AACA;AAEA;IACA,2BAAA;IACA,aAAA;IACA,kBAAA;IACA,QAAA;IACA,iBAAA;IACA,gBAAA;AACA;AAEA;IACA,iBAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,aAAA;IACA,8BAAA;IACA,kBAAA;IACA,UAAA;IACA,oBAAA;AACA;AAEA;IACA,wBAAA;IACA,YAAA;IACA,oBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,cAAA;IACA,iBAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,aAAA;IACA,uBAAA;IACA,kBAAA;IACA,UAAA;IACA,oBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,qBAAA;AACA;AAEA;IACA,cAAA;IACA,gBAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,iBAAA;AACA;AAEA;IACA,oCAAA;IACA,2BAAA;IACA,wBAAA;IACA,YAAA;IACA,oBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;IACA,gBAAA;IACA,2BAAA;IACA,4BAAA;IACA,kBAAA;AACA;AAEA;IACA,iBAAA;IACA,kBAAA;IACA,mBAAA;IACA,8BAAA;IACA,+BAAA;IACA,eAAA;IACA,YAAA,EAAA,kCAAA;AACA;AAEA;IACA,WAAA;IACA,kBAAA;IACA,uDAAA;IACA,uBAAA;IACA,wBAAA;IACA,2DAAA;IACA,eAAA;IACA,YAAA;IACA,eAAA;AACA;AAEA;IACA,sBAAA;AACA;AAEA;IACA,kBAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,QAAA;IACA,iBAAA;IACA,wBAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,OAAA;IACA,iBAAA;IACA,oBAAA;AACA;AAEA;AAEA;AAEA;IACA,gCAAA;IACA,sCAAA;IACA,sBAAA;AACA;AAEA;IACA,qCAAA;IACA,2CAAA;IACA,oBAAA;AACA;AAEA;IACA,gCAAA;IACA,sCAAA;IACA,sBAAA;AACA;AAEA;IACA,sCAAA;IACA,4CAAA;IACA,oBAAA;AACA;AAEA;IACA,kBAAA;IACA,SAAA;IACA,QAAA;IACA,OAAA;IACA,oBAAA;IACA,wBAAA;IACA,2DAAA;IACA,iBAAA;IACA,kBAAA;AACA;AAEA;IACA,qBAAA;IACA,eAAA;AACA;AAEA;IACA,0BAAA;IACA,gBAAA;AACA;AAEA;IACA,qBAAA;IACA,eAAA;AACA;AAEA;IACA,2BAAA;IACA,eAAA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,cAAA;AACA;AAEA;IACA,qBAAA;AACA","file":"graphNode.vue","sourcesContent":["<style>\n.card-ui {\n background-color: #bff2ca!important;\n}\n\n.card-loop {\n /* background-color: #e5e8ea!important; */\n border: 5px double #dddddd;\n border-width: 4px;\n}\n\n.card-input {\n background-color: #f5d76e!important;\n}\n\n.card-output {\n background-color: #ffb3a7!important;\n}\n\n.box-inputs {\n float: left;\n padding-left: 2px;\n padding-right: 5px;\n vertical-align: top;\n text-align: left;\n}\n\n.box-outputs {\n float: right;\n padding-left: 5px;\n padding-right: 2px;\n vertical-align: top;\n text-align: right;\n}\n\n.dualbox-graph-canvas .card, .card-node {\n /*border: 1px solid #dddddd;*/\n box-shadow: 1px 1px 5px #716f6f;\n opacity: 1;\n cursor: pointer;\n z-index: 20;\n position: absolute;\n\n -webkit-transition: -webkit-box-shadow 0.15s ease-in;\n -moz-transition: -moz-box-shadow 0.15s ease-in;\n -o-transition: -o-box-shadow 0.15s ease-in;\n transition: box-shadow 0.15s ease-in;\n\n color: #4d4d4d;\n user-select: none;\n padding: 0px 8px 0px 8px;\n overflow:hidden;\n background-color: #fff;\n -moz-border-radius: 3px;\n border-radius:3px;\n font-size: 14px;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n}\n\n.card-node .card-top {\n padding-top: 2px;\n}\n\n.card-node .card-bottom {\n padding-bottom: 2px;\n text-align: center;\n line-height: 14px;\n white-space: nowrap;\n}\n\n.card-node hr {\n margin-top: 2px;\n margin-bottom: 2px;\n border-color: rgba(0,0,0,0.1);\n margin-left: -8px;\n margin-right: -8px;\n}\n\n.card-node:hover {\n border-color: #80b2fc;\n box-shadow: 1px 1px 10px #80b2fc;\n}\n\n.card-node.selected, .card-node.selected:hover {\n border-color: #0066ff;\n box-shadow: 1px 1px 10px #0066ff;\n}\n\n.card-node-incomplete {\n box-shadow: 1px 1px 5px #dd6666 !important;\n}\n\n.input-not-resolvable {\n color: #dd6666!important;\n}\n\n.card-node .title {\n vertical-align:top;\n font-weight: bold;\n}\n\n.card-node .subtitle {\n color:#929292;\n font-size: 11px;\n font-style: italic;\n vertical-align:center;\n font-family: tahoma, sans-serif;\n}\n\n.card-node .input {\n font-size: 13px;\n color: #8c8c8c;\n}\n\n.card-node .output {\n font-size: 13px;\n color: #8c8c8c;\n text-align:right;\n}\n\n.card-node .jtk-endpoint.active svg circle {\n /* fill: #99ff33 */\n stroke: #59b300;\n}\n\n.point {\n /* display: inline-block; */\n display: none;\n position: relative;\n top: 3px;\n margin-right: 5px;\n margin-left: 5px;\n}\n\n.dualbox-io {\n overflow: visible;\n margin-left: -8px;\n margin-right: -8px;\n}\n\n.box-inputs {\n display: flex;\n justify-content: space-between;\n position: relative;\n padding: 0;\n pointer-events: none;\n}\n\n.types {\n color: #6c757d!important;\n opacity: 0.7;\n pointer-events: none;\n}\n\n.box-inputs .types {\n display: inline-block;\n}\n\n.box-inputs .name {\n display: inline-block;\n}\n\n.box-inputs .type {\n display: block;\n text-align: right;\n}\n\n.box-inputs .point {\n display: block;\n}\n\n.box-inputs .name {\n display: block;\n}\n\n.box-outputs {\n display: flex;\n justify-content: center;\n position: relative;\n padding: 0;\n pointer-events: none;\n}\n\n.box-outputs .types {\n display: inline-block;\n}\n\n.box-outputs .point {\n display: inline-block;\n}\n\n.box-outputs .name {\n display: inline-block;\n}\n\n.box-outputs .type {\n display: block;\n text-align: left;\n}\n\n.box-outputs .point {\n display: block;\n}\n\n.box-outputs .name {\n display: block;\n}\n\nspan.feedback {\n font-weight: bold;\n}\n\n.event-dock {\n background-color: rgb(136, 137, 138);\n background-color: #a6a6a6;\n width: calc(100% + 18px);\n height: 12px;\n z-index: 3!important;\n}\n\n.event-dock-top {\n margin-left: -9px;\n margin-right: -9px;\n margin-top: -3px;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n margin-bottom: 4px;\n}\n\n.event-dock-bottom {\n margin-left: -9px;\n margin-right: -9px;\n margin-bottom: -3px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n margin-top: 4px;\n height: 11px; /* shorter because of box-shadow */\n}\n\n.event-label {\n z-index: 21;\n padding-left: 15px;\n transform: rotate(-90deg) translate(0%, -50%)!important;\n transform-origin: 0% 0%;\n color: #6c757d!important;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n font-size: 14px;\n opacity: 0.7;\n cursor: pointer;\n}\n\n.transparent {\n opacity: 0.3!important;\n}\n\n.card-node {\n position: relative;\n}\n\n.card-comment {\n position: absolute;\n top: 0;\n right: 0;\n margin-top: -22px;\n color: #f4ad42!important;\n}\n\n.card-problem {\n position: absolute;\n top: 0;\n left: 0;\n margin-top: -22px;\n color: red!important;\n}\n\n.card-snapshot {\n\n}\n\n.card-snapshot-idle {\n border: 2px solid gray!important;\n box-shadow: 1px 1px 5px gray!important;\n opacity: 0.7!important;\n}\n\n.card-snapshot-computing {\n border: 2px solid darkgreen!important;\n box-shadow: 1px 1px 5px darkgreen!important;\n opacity: 1!important;\n}\n\n.card-snapshot-awaiting-data {\n border: 2px solid blue!important;\n box-shadow: 1px 1px 5px blue!important;\n opacity: 0.7!important;\n}\n\n.card-snapshot-ready {\n border: 2px solid lightgreen!important;\n box-shadow: 1px 1px 5px lightgreen!important;\n opacity: 1!important;\n}\n\n.card-status {\n position: absolute;\n bottom: 0;\n right: 0;\n left: 0;\n margin-bottom: -26px;\n color: #f4ad42!important;\n font-family: \"Helvetica Neue\", Arial, Helvetica, sans-serif;\n font-weight: bold;\n text-align: center;\n}\n\n.card-status-idle {\n color: gray!important;\n min-width: 85px;\n}\n\n.card-status-computing {\n color: darkgreen!important;\n min-width: 110px;\n}\n\n.card-status-awaiting-data {\n color: blue!important;\n min-width: 85px;\n}\n\n.card-status-ready {\n color: lightgreen!important;\n min-width: 85px;\n}\n\n.btn-snapshot-details {\n position: relative;\n margin-top: -2px;\n color: inherit;\n}\n\nspan.name {\n overflow-wrap: normal;\n}\n</style>\n\n<template>\n <div class=\"jtk-node card card-node contextmenu\" v-bind:class=\"{ 'card-loop': n.hasLoop(), 'card-ui': n.isUI(), 'card-metanode': n.isMetanode(), 'card-input': n.isInput(), 'card-output': n.isOutput(), 'card-snapshot': n.hasSnapshot(), 'card-snapshot-idle': n.hasSnapshot() && n.isSnapshotStatus(0), 'card-snapshot-computing': n.hasSnapshot() && n.isSnapshotStatus(1), 'card-snapshot-awaiting-data': n.hasSnapshot() && n.isSnapshotStatus(2), 'card-snapshot-ready': n.hasSnapshot() && n.isSnapshotStatus(3) }\" v-bind:id=\"getId()\" v-bind:data-id=\"getId()\" v-bind:data-name=\"pkg.name\" style=\"overflow: visible;\">\n <div v-if=\"n.hasComment()\">\n <div class=\"card-comment\" data-toggle=\"tooltip\" data-placement=\"top\" :title=\"n.getComment()\">\n <i class=\"fas fa-comment-alt\" data-container=\"body\"></i>\n </div>\n </div>\n\n <div v-if=\"n.hasSnapshot()\">\n <div class=\"card-status\">\n <div v-if=\"n.isSnapshotStatus(0)\">\n <div class=\"card-status-idle\">\n <span>IDLE</span>\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\n </div>\n </div>\n\n <div v-if=\"n.isSnapshotStatus(1)\">\n <div class=\"card-status-computing\">\n <span>COMPUTING</span>\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\n </div>\n </div>\n\n <div v-if=\"n.isSnapshotStatus(2)\">\n <div class=\"card-status-awaiting-data\">\n <span>WAITING</span>\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\n </div>\n </div>\n\n <div v-if=\"n.isSnapshotStatus(3)\">\n <div class=\"card-status-ready\">\n <span>READY</span>\n <button class=\"btn btn-editor-xs btn-outline-secondary btn-outline-discrete btn-snapshot-details d-inline-block\" data-id=\"getId()\" v-on:click=\"openSnapshotDetails\"><i class=\"fas fa-info-circle\"></i></button>\n </div>\n </div>\n </div>\n </div>\n\n <div v-if=\"!example && n.isUI() && !n.isOnAPanel()\">\n <div class=\"card-problem\">\n <i class=\"fas fa-exclamation-circle\" data-container=\"body\" data-toggle=\"popover\" data-placement=\"top\" data-content=\"This UI is not set in a panel. It won't have any effect. Go to the Interface tab to add it to a panel.\"></i>\n </div>\n </div>\n\n <div class=\"card-top\">\n <div class=\"d-flex\">\n <span class=\"title\" style=\"white-space: nowrap; margin-right: 5px;\">\n <span v-if=\"n.isMetanode()\" class=\"badge badge-secondary\"><b>META</b></span>\n {{n.graphId}}\n <i v-if=\"n.isParallel()\" class=\"fas fa-server\" style=\"color: orange;\" title=\"this module is computed in a web worker\"></i>\n </span>\n\n <div class=\"ml-auto\">\n <button class=\"btn btn-outline-secondary btn-outline-discrete btn-editor-xs btn-settings\" v-on:click=\"openNodeSettings\"><i class=\"fas fa-cog\"></i></button>\n </div>\n </div>\n </div>\n <div v-if=\"!n.isInput() && !n.isOutput()\" class=\"card-center\">\n <hr style=\"margin-bottom: 5px;\"/>\n <div class=\"dualbox-io\" style=\"overflow: visible;\">\n <div class=\"inputs\" style=\"display: inline-block; float: left;\">\n <div class=\"box-inputs\">\n <div class=\"types\">\n <span class=\"type\" v-for=\"key in getVisibleInputs()\" v-bind:data-key=\"key\">\n {{ n.getInputType(key) }}\n </span>\n </div>\n <div class=\"points\">\n <div class=\"point\" v-for=\"key in getVisibleInputs()\" v-bind:data-key=\"key\" v-bind:data-type=\"n.getInputDef(key).type\" v-html=\"point\"></div>\n </div>\n <div class=\"names\">\n <span class=\"name\" v-for=\"key in getVisibleInputs()\" :class=\"{'feedback': n.isFeedbackTarget(key), 'input-not-resolvable': !example && !n.isInputResolvable(key) }\" v-bind:data-input=\"key\">\n <span v-if=\"n.hasIterator(key)\">&lt;{{key}}&gt;</span>\n <span v-else>{{key}}</span>\n <small v-if=\"!n.isInputConst(key)\" data-toggle=\"tooltip\" data-trigger=\"hover\" title=\"this value will be cloned at execution time\"><i class=\"fas fa-clone transparent\"></i></small>\n </span>\n </div>\n </div>\n </div>\n <div class=\"outputs\" style=\"display: inline-block; float: right\">\n <div class=\"box-outputs\">\n <div class=\"names\">\n <span class=\"name\" v-for=\"key in getVisibleOutputs()\" v-bind:class=\"{feedback: n.isFeedbackTarget(key)}\" v-bind:data-output=\"key\">\n <span v-if=\"n.hasLoop() && n.hasFeedback(key)\">{{key}}</span>\n <span v-else-if=\"n.hasLoop() && !n.hasFeedback(key)\" v-html='\"&lt;\"+key+\"&gt;\"'></span>\n <span v-else>{{key}}</span>\n\n <span v-if=\"n.hasCacheActivated()\">\n &nbsp;<i class=\"fa fa-hdd\" title=\"This module has cache activated\"></i>\n </span>\n </span>\n </div>\n <div class=\"points\">\n <div class=\"point\" v-for=\"key in getVisibleOutputs()\" v-bind:data-key=\"key\" v-bind:data-type=\"n.getOutputDef(key).type\" v-html=\"point\"></div>\n </div>\n <div class=\"types\">\n <span class=\"type\" v-for=\"key in getVisibleOutputs()\" v-bind:data-key=\"key\">\n {{ n.getOutputType(key) }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <hr style=\"margin-top: 5px;\"/>\n <div class=\"card-bottom\">\n <span class=\"subtitle\">{{ shortName }}</span>\n\n <div v-if=\"n.isMetanode()\" class=\"d-inline-block\">\n <button class=\"btn btn-outline-secondary btn-outline-discrete btn-editor-xs btn-enter-metanode\" v-on:click=\"enterMetanode\"><i class=\"fas fa-sign-in-alt\"></i></button>\n </div>\n\n <!--\n <div v-if=\"n.isUI()\" class=\"event-dock event-dock-bottom\"></div>\n -->\n </div>\n </div>\n</template>\n\n<script>\nimport ContextMenu from '../ContextMenu';\nimport _ from 'lodash';\nimport dbutils from '../../m/DualboxUtils';\n\n// fix inputs types and output types position relatively to the div\n$.fn.fixCardDisplay = function() {\n var offsetPoint = 12;\n var offsetBorder = parseInt($(this).css(\"border-top-width\"));\n\n if( $(this).find('.box-inputs').height() === 0 && $(this).find('.box-outputs').height() === 0 ) {\n // if this card has no input/output, remove the card center\n $(this).find('.card-center').remove();\n }\n else {\n // else, adjust the input/output display for endpoints\n // 1) translate inputs by the right amount of pixels to have the circle on the line\n var boxInputs = $(this).find('.box-inputs');\n\n // fix css names width\n var namesDiv = boxInputs.find('.names');\n namesDiv.css('width', (namesDiv.width()+1) + 'px');\n\n // translate inputs to the left\n var translateLeft = boxInputs.find('.types').width() + offsetPoint + offsetBorder/2;\n $(this).find('.box-inputs').css('transform', 'translateX(-' + translateLeft + 'px)');\n\n // adjust inputs main div width\n $(this).find('.inputs').width( $(this).find('.inputs').width() - translateLeft + 10 /* margin */ );\n\n\n // 2) translate outputs by the right amount of pixels to have the circle on the line\n var boxOutputs = $(this).find('.box-outputs');\n\n // fix css names with\n var namesDiv = boxOutputs.find('.names');\n namesDiv.css('width', (namesDiv.width() + 1) + 'px');\n\n // translate inputs to the right\n var translateRight = boxOutputs.find('.types').width() + offsetPoint + offsetBorder/2;\n $(this).find('.box-outputs').css('transform', 'translateX(' + translateRight + 'px)');\n\n // adjust output main div width\n $(this).find('.outputs').width( $(this).find('.outputs').width() - translateRight + 10 /* margin */ );\n\n // fix io width\n //$('.dualbox-io').css('width', (($(this).find('.inputs').width() + $(this).find('.outputs').width()) + \"px\"));\n }\n}\n\n// take the current width and add it as a css property\n$.fn.fixWidth = function() {\n var width = $(this).width();\n width += parseInt($(this).css('padding-right'));\n width += parseInt($(this).css('padding-left'));\n width += parseInt($(this).css('border-left-width'));\n width += parseInt($(this).css('border-right-width'));\n $(this).css('width', width + 'px');\n}\n\n// find position of element relative to an ancestor matching selector\n$.fn.positionFrom = function( selector ) {\n var ancestor = $(this).closest(selector);\n var offset = $(this).offset();\n var ancestorOffset = ancestor.offset();\n return {\n top: offset.top - ancestorOffset.top,\n left: offset.left - ancestorOffset.left,\n }\n}\n\nexport default {\n props: [\n \"id\", // the module id\n \"pkg\", // the module package.json\n \"n\", // the GraphNode object (from model)\n \"example\", // true if this vue is used as an example display (no need to connect)\n ],\n data: function () {\n return {\n shortName: \"\",\n point: '<svg width=\"14\" height=\"14\" pointer-events=\"all\" position=\"absolute\" version=\"1.1\" xmlns=\"http://www.w3.org/1999/xhtml\"><circle cx=\"7\" cy=\"7\" r=\"5\" version=\"1.1\" xmlns=\"http://www.w3.org/1999/xhtml\" fill=\"#ffffff\" stroke=\"#727272\" style=\"\" stroke-width=\"2\"></circle></svg>',\n }\n },\n beforeUpdate: function() {\n //console.log('[UPDATING] ' + this.n.getUniqId());\n },\n destroyed: function() {\n //console.log('[DESTROYED] ' + this.n.getUniqId());\n },\n created: function() {\n this.initialized = false;\n this.view = window.dualboxEditor.v;\n\n //console.log('[CREATED] ' + this.n.getUniqId());\n // We compute the shortname of our box\n if( this.n.isInput() || this.n.isOutput() ) {\n this.shortName = this.n.getType();\n }\n else {\n this.shortName = dbutils.shortName(this.pkg.name);\n }\n },\n mounted: async function() {\n //console.log('[MOUNTED] ' + this.n.getUniqId());\n var div = $(this.$el);\n div.fixCardDisplay();\n div.ready(() => {\n //if( !this.example ) {\n div.fixWidth();\n //}\n });\n this.activateTooltip();\n return await this.initialize();\n },\n beforeUpdate: function() {\n this.deactivateTooltip();\n },\n updated: async function() {\n //console.log('[UPDATED] ' + this.n.getUniqId());\n\n // we reset jsPlumb before app update (in graph.vue)\n // so we need to initialize again\n this.assignContextMenu();\n\n $(this.$el).fixCardDisplay();\n $(this.$el).ready(()=>{\n $(this.$el).fixWidth();\n this.activateTooltip();\n });\n return await this.initialize();\n },\n activate: function() {\n this.activateTooltip();\n },\n deactivate: function() {\n this.deactivateTooltip();\n },\n methods: {\n getId: function() {\n // if this is an example graphNode, change our \"id\" to \"id-junk\"\n // to avoid connection jsplumb conflicts with the real node\n return this.example ? this.id + '-junk' : this.id;\n },\n\n activateTooltip: function() {\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip();\n },\n\n deactivateTooltip: function() {\n $(this.$el).find('[data-toggle=\"tooltip\"]').tooltip(\"dispose\");\n },\n\n initialize: async function() {\n var self = this;\n var div = $(this.$el);\n var id = this.getId();\n var view = this.view;\n\n this.initialized = false;\n\n if( !this.example ) {\n // if we have a position, set it\n var def = this.n.getDef();\n var position = _.get(def, [\"graph\", \"position\"]);\n if( position ) {\n var jsPlumbElement = self.$parent.jsPlumbInstance.getElement(id);\n self.$parent.jsPlumbInstance.setPosition(jsPlumbElement, position);\n }\n\n // This needs to be registered before draggable\n div.on('mousedown', function(e) {\n // if this div is not selected already, deselect the other divs\n if( !self.$parent.selector.isSelected(this) ) {\n self.$parent.selector.deselect();\n }\n });\n\n await this.initializeJsPlumb();\n\n div.click(function(e) {\n if( e.ctrlKey ) {\n view.selector.toggleSelection(this);\n }\n });\n\n this.assignContextMenu();\n }\n\n return new Promise(resolve => {\n div.ready(() => {\n //console.log('[INITIALIZED] ' + this.n.getUniqId());\n this.initialized = true;\n resolve();\n });\n });\n },\n\n initializeJsPlumb: function() {\n var self = this;\n var div = $(this.$el);\n var id = this.getId();\n var view = this.view;\n\n if( !this.example ) {\n // If this node was never initialized in this jsplumb instance, do it\n if( !_.get(this.$parent.jsPlumbInstance, [\"initializedNodes\", id]) ) {\n _.set(this.$parent.jsPlumbInstance, [\"initializedNodes\", id], true); // initialized\n\n if( this.n.isInput() || this.n.isOutput() ) {\n var type = \"*\";\n var input = \"value\";\n var output = \"value\";\n var offsetTop = $(div).find('.card-top').height() + 12 /* hr size */ - 3;\n\n var uuid = [ id, \"input\", input].join('#');\n var ep = this.$parent.jsPlumbInstance.addEndpoint(id, {\n isSource : false,\n isTarget : true,\n uuid : uuid,\n anchor : [0,0,-1,0,0,offsetTop],\n maxConnections : 1,\n parameters : {\n type: \"data\",\n target : {\n id : id,\n input : output\n }\n }\n }, this.$parent.style.inputEndpoint);\n\n // add data to the endpoint div so we can identify it easier\n $(ep.canvas).attr('data-node', id);\n $(ep.canvas).attr('data-type', 'input');\n $(ep.canvas).attr('data-input', input);\n\n // bind tooltip\n $(ep.canvas).attr('data-toggle', \"tooltip\");\n $(ep.canvas).attr('data-trigger', \"hover\");\n $(ep.canvas).attr('data-placement', \"left\");\n $(ep.canvas).attr('data-html', \"true\");\n var inputType = view.m.getNode(id).getInputType(\"value\");\n $(ep.canvas).attr('title', \"Type: <b>\" + inputType + \"</b>\");\n $(ep.canvas).tooltip();\n\n // bind context menu to the endpoint\n $(ep.canvas).addClass('capture-right-click');\n $(ep.canvas).ready(function() {\n var menu = new ContextMenu(\".jtk-endpoint-anchor[data-node='\"+id.trim()+\"'][data-input='\" + input + \"']\", [\n {\n name: 'Create input for here',\n fn: () => {\n view.c.createInputFromConnection(id, input);\n }\n },\n ]);\n });\n\n var uuid = [ id, \"output\", output].join('#');\n var ep = this.$parent.jsPlumbInstance.addEndpoint(id, {\n isSource : true,\n isTarget : false,\n uuid : uuid,\n anchor : [1,0,1,0,0,offsetTop],\n parameters : {\n type: \"data\",\n source : {\n id : id,\n output : output\n }\n }\n }, this.$parent.style.outputEndpoint);\n\n // add data to the endpoint div so we can identify it easier\n $(ep.canvas).attr('data-node', id);\n $(ep.canvas).attr('data-type', \"output\");\n $(ep.canvas).attr('data-output', output);\n\n // bind tooltip\n $(ep.canvas).attr('data-toggle', \"tooltip\");\n $(ep.canvas).attr('data-trigger', \"hover\");\n $(ep.canvas).attr('data-placement', \"right\");\n $(ep.canvas).attr('data-html', \"true\");\n var outputType = view.m.getNode(id).getOutputType(\"value\");\n $(ep.canvas).attr('title', \"Type: <b>\" + outputType + \"</b>\");\n $(ep.canvas).tooltip();\n\n // bind context menu to the endpoint\n $(ep.canvas).addClass('capture-right-click');\n $(ep.canvas).ready(function() {\n var menu = new ContextMenu(\".jtk-endpoint-anchor[data-node='\"+id.trim()+\"'][data-output='\" + output.trim() + \"']\", [\n {\n name: 'Create output for here',\n fn: () => {\n view.c.createOutputFromConnection(id, output);\n }\n },\n ]);\n });\n }\n else {\n // add input endoints\n div.find('.box-inputs').find('.point').each( function(index) {\n $(this).css('visibility', 'hidden').css('opacity', '0'); // replaced by jsPlumb point\n\n var input = div.find('.box-inputs').find('.name').eq(index).attr('data-input').trim();\n var type = view.m.getNode(id).getInputType(input);\n\n var offsetTop = $(this).positionFrom('.card').top + $(this).height()/2 - 3;\n var uuid = [ id, \"input\", $(this).data('key')].join('#');\n var ep = self.$parent.jsPlumbInstance.addEndpoint(id, {\n isSource : false,\n isTarget : true,\n uuid : uuid,\n anchor : [0,0,-1,0,0,offsetTop],\n maxConnections : 1,\n parameters : {\n type: \"data\",\n target : {\n id : id,\n input : $(this).data('key')\n }\n }\n }, self.$parent.style.inputEndpoint);\n\n // add data to the endpoint div so we can identify it easier\n $(ep.canvas).attr('data-node', id);\n $(ep.canvas).attr('data-type', 'input');\n $(ep.canvas).attr('data-input', input);\n\n // bind tooltip\n $(ep.canvas).attr('data-toggle', \"tooltip\");\n $(ep.canvas).attr('data-trigger', \"hover\");\n $(ep.canvas).attr('data-placement', \"left\");\n $(ep.canvas).attr('data-html', \"true\");\n $(ep.canvas).attr('title', \"Type: <b>\" + type + \"</b>\");\n $(ep.canvas).tooltip();\n\n // bind context menu to the endpoint\n $(ep.canvas).addClass('capture-right-click');\n $(ep.canvas).ready(function() {\n var menu = new ContextMenu(\".jtk-endpoint-anchor[data-node='\"+id.trim()+\"'][data-input='\" + input.trim() + \"']\", [\n {\n name: 'Create input for here',\n fn: () => {\n view.c.createInputFromConnection(id, input);\n }\n },\n ]);\n });\n });\n\n // add output endpoints\n div.find('.box-outputs').find('.point').each( function(index) {\n $(this).css('visibility', 'hidden').css('opacity', '0'); // replaced by jsPlumb point\n\n var output = div.find('.box-outputs').find('.name').eq(index).attr('data-output').trim();\n var type = view.m.getNode(id).getOutputType(output);\n\n var offsetTop = $(this).positionFrom('.card').top + $(this).height()/2 - 3;\n var uuid = [ id, \"output\", $(this).data('key')].join('#');\n var ep = self.$parent.jsPlumbInstance.addEndpoint(id, {\n isSource : true,\n isTarget : false,\n uuid : uuid,\n anchor : [1,0,1,0,0,offsetTop],\n parameters : {\n type: \"data\",\n source : {\n id : id,\n output : $(this).data('key')\n }\n }\n }, self.$parent.style.outputEndpoint);\n\n // add data to the endpoint div so we can identify it easier\n $(ep.canvas).attr('data-node', id);\n $(ep.canvas).attr('data-type', \"output\");\n $(ep.canvas).attr('data-output', output);\n\n // bind tooltip\n $(ep.canvas).attr('data-toggle', \"tooltip\");\n $(ep.canvas).attr('data-trigger', \"hover\");\n $(ep.canvas).attr('data-placement', \"right\");\n $(ep.canvas).attr('data-html', \"true\");\n $(ep.canvas).attr('title', \"Type: <b>\" + type + \"</b>\");\n $(ep.canvas).tooltip();\n\n // bind context menu to the endpoint\n $(ep.canvas).addClass('capture-right-click');\n $(ep.canvas).ready(function() {\n var menu = new ContextMenu(\".jtk-endpoint-anchor[data-node='\"+id.trim()+\"'][data-output='\" + output.trim() + \"']\", [\n {\n name: 'Create output for here',\n fn: () => {\n view.c.createOutputFromConnection(id, output);\n }\n },\n ]);\n });\n });\n\n if( this.n.isUI() && view.showEvents ) {\n // Make this a target for events\n this.$parent.jsPlumbInstance.makeTarget(id, {\n isSource:false,\n isTarget:true,\n uniqueEndpoint: false,\n anchor:\"Continuous\",\n uuid: id + \"#event-in\",\n paintStyle:{ fill:\"green\" },\n parameters: {\n type: \"event\",\n target: { \"id\" : id }\n },\n }, self.$parent.style.eventEndpoint);\n\n // Create an enpoint to create a new event\n var ep = this.$parent.jsPlumbInstance.addEndpoint(id, {\n isSource : true,\n isTarget : false,\n uuid : id + \"#event-out\",\n anchor : [1, 1, 0, 1, 0, -10],\n parameters : {\n type: \"event\",\n source: { \"id\" : id }\n },\n }, this.$parent.style.eventEndpoint);\n\n // Add overlay here so we don't mess with splitConnection\n ep.addOverlay([\"PlainArrow\", { width:15, length:15, location:1, id:\"arrow\" }]);\n\n $(ep.canvas).attr('data-toggle', \"tooltip\");\n $(ep.canvas).attr('data-trigger', \"hover\");\n $(ep.canvas).attr('data-placement', \"bottom\");\n $(ep.canvas).attr('data-html', \"true\");\n $(ep.canvas).attr('title', \"Connect from here ito add an event that will be triggered when this box is done computing.\");\n $(ep.canvas).tooltip();\n }\n }\n\n // Make the div draggable\n this.$parent.jsPlumbInstance.draggable(div, {\n //containment:true, // not allowed outside of container div\n drag: function(e) {\n // TODO: bug. After a repaint(), jsPlumb seems to be broken (connections dont follow on div drag)\n // It doesn't occur on jsPlumb.reset() instead of creating another instance on beforeUpdate(),\n // (as it should be), but we can't do that, because JsPlumb is broken on zoom otherwise...\n // One of thoses problem may be fixed later by updating jsPlumb...\n // Note: this \"fix\" may affect performances on drag, maybe a setTimeout will do\n //self.$parent.jsPlumbInstance.repaintEverything();\n self.$parent.jsPlumbInstance.repaint(id);\n },\n stop: function(e) {\n // resize the canvas if necessary\n self.$parent.canvasSizeHandler.debouncedResize();\n\n if( self.$parent.selector.isMultipleSelectionActive() ) {\n // We just dropped a bunch of divs, ajust all their positions\n self.view.m.history.batch(() => {\n self.$parent.selector.each(div => {\n var pos = self.$parent.jsPlumbInstance.getPosition(div);\n view.m.getNode($(div).attr('id')).setPosition(pos);\n });\n });\n }\n else {\n // We just dropped this one, set the new position in the graph model\n var el = self.$parent.jsPlumbInstance.getElement(id);\n $(el).ready(function() {\n var pos = self.$parent.jsPlumbInstance.getPosition(el);\n view.m.getNode(id).setPosition(pos);\n });\n }\n }\n });\n }\n }\n\n return new Promise((resolve) => this.$parent.jsPlumbInstance.ready(resolve));\n },\n\n assignContextMenu: function() {\n var id = this.getId();\n\n // Create a contextmenu for the div\n var contextOptions = [\n {\n name: 'Remove this box',\n fn: () => {\n this.view.c.removeBox(id);\n }\n }\n ];\n if( this.n.isModule() || this.n.isUI() ) {\n contextOptions.push({\n name: 'Duplicate this box',\n fn: () => {\n this.view.c.duplicateBox(id);\n }\n });\n }\n var nodeMenu = new ContextMenu(\"#\" + id, contextOptions);\n },\n\n htmlentities: function( s ) {\n return this.view.utils.htmlentities(s);\n },\n\n getVisibleInputs: function() {\n return this.n.getInputsNames().filter((inputName) => {\n return this.n.isInputVisible(inputName);\n })\n },\n\n getVisibleOutputs: function() {\n return this.n.getOutputsNames().filter((outputName) => {\n return this.n.isOutputVisible(outputName);\n })\n },\n\n enterMetanode: function(e) {\n e.preventDefault();\n e.stopPropagation();\n\n this.view.c.enterMetanode(this.id);\n },\n\n openNodeSettings: function(e) {\n e.preventDefault();\n e.stopPropagation();\n this.view.openBoxSettings(this.id);\n },\n\n openSnapshotDetails: function(e) {\n e.preventDefault();\n e.stopPropagation();\n this.view.openDebug(this.id);\n }\n },\n watch: {\n 'app': {\n handler: () => {\n console.log('graphVue.app changed');\n },\n deep: true\n }\n }\n}\n\n</script>\n"]}, media: undefined });
46367
46367
 
46368
46368
  };
46369
46369
  /* scoped */
@@ -104035,7 +104035,23 @@ class DualboxEditor {
104035
104035
 
104036
104036
  this.loadCorePackages();
104037
104037
 
104038
+ // if defined, call progress callback when needed
104039
+ // signature: onLoadProgress(stepName, percentage);
104040
+ this.onLoadProgress = attrs.onLoadProgress || function (stepName, numberDone, numberTotal) {
104041
+ if (numberDone && numberTotal) {
104042
+ console.log(`[LOAD] ${stepName}: ${numberDone}/${numberTotal}`);
104043
+ } else {
104044
+ console.log(`[LOAD] ${stepName}`);
104045
+ }
104046
+ };
104047
+
104038
104048
  if (attrs.json) {
104049
+ this.onLoadProgress((step, nbDone, nbTotal) => {
104050
+ if (attrs.onLoadProgress) {
104051
+ p.onLoadProgress(step, nbDone, nbTotal);
104052
+ }
104053
+ });
104054
+
104039
104055
  this.onReady(() => {
104040
104056
  var p = this.setApp(attrs.json);
104041
104057
  if (attrs.onLoaded) {
@@ -104076,11 +104092,18 @@ class DualboxEditor {
104076
104092
  // return a Promise
104077
104093
  loadPackages(json) {
104078
104094
  var promises = []; // array of promises
104079
- this.promises = promises;
104095
+ this.promises = [];
104096
+
104097
+ var nbPackages = 0;
104098
+ var nbLoaded = 0;
104080
104099
 
104081
104100
  var parser = new AppParser_1(json);
104082
104101
  parser.eachComponent((name, version) => {
104083
- promises.push(this.loadPackage(name, version));
104102
+ nbPackages++;
104103
+ promises.push(this.loadPackage(name, version).then(() => {
104104
+ nbLoaded++;
104105
+ this.onLoadProgress("Loading application", nbLoaded, nbPackages);
104106
+ }));
104084
104107
  });
104085
104108
 
104086
104109
  return Promise.all(promises);
@@ -206,7 +206,23 @@ class DualboxEditor {
206
206
 
207
207
  this.loadCorePackages();
208
208
 
209
+ // if defined, call progress callback when needed
210
+ // signature: onLoadProgress(stepName, percentage);
211
+ this.onLoadProgress = attrs.onLoadProgress || function (stepName, numberDone, numberTotal) {
212
+ if (numberDone && numberTotal) {
213
+ console.log(`[LOAD] ${stepName}: ${numberDone}/${numberTotal}`);
214
+ } else {
215
+ console.log(`[LOAD] ${stepName}`);
216
+ }
217
+ };
218
+
209
219
  if (attrs.json) {
220
+ this.onLoadProgress((step, nbDone, nbTotal) => {
221
+ if (attrs.onLoadProgress) {
222
+ p.onLoadProgress(step, nbDone, nbTotal);
223
+ }
224
+ });
225
+
210
226
  this.onReady(() => {
211
227
  var p = this.setApp(attrs.json);
212
228
  if (attrs.onLoaded) {
@@ -250,11 +266,18 @@ class DualboxEditor {
250
266
  // return a Promise
251
267
  loadPackages(json) {
252
268
  var promises = []; // array of promises
253
- this.promises = promises;
269
+ this.promises = [];
270
+
271
+ var nbPackages = 0;
272
+ var nbLoaded = 0;
254
273
 
255
274
  var parser = new AppParser(json);
256
275
  parser.eachComponent((name, version) => {
257
- promises.push(this.loadPackage(name, version));
276
+ nbPackages++;
277
+ promises.push(this.loadPackage(name, version).then(() => {
278
+ nbLoaded++;
279
+ this.onLoadProgress("Loading application", nbLoaded, nbPackages);
280
+ }));
258
281
  });
259
282
 
260
283
  return Promise.all(promises);
@@ -554,7 +554,7 @@ export default {
554
554
  //console.log('[UPDATING] ' + this.n.getUniqId());
555
555
  },
556
556
  destroyed: function() {
557
- console.log('[DESTROYED] ' + this.n.getUniqId());
557
+ //console.log('[DESTROYED] ' + this.n.getUniqId());
558
558
  },
559
559
  created: function() {
560
560
  this.initialized = false;
@@ -570,7 +570,7 @@ export default {
570
570
  }
571
571
  },
572
572
  mounted: async function() {
573
- console.log('[MOUNTED] ' + this.n.getUniqId());
573
+ //console.log('[MOUNTED] ' + this.n.getUniqId());
574
574
  var div = $(this.$el);
575
575
  div.fixCardDisplay();
576
576
  div.ready(() => {
@@ -585,7 +585,7 @@ export default {
585
585
  this.deactivateTooltip();
586
586
  },
587
587
  updated: async function() {
588
- console.log('[UPDATED] ' + this.n.getUniqId());
588
+ //console.log('[UPDATED] ' + this.n.getUniqId());
589
589
 
590
590
  // we reset jsPlumb before app update (in graph.vue)
591
591
  // so we need to initialize again
@@ -657,7 +657,7 @@ export default {
657
657
 
658
658
  return new Promise(resolve => {
659
659
  div.ready(() => {
660
- console.log('[INITIALIZED] ' + this.n.getUniqId());
660
+ //console.log('[INITIALIZED] ' + this.n.getUniqId());
661
661
  this.initialized = true;
662
662
  resolve();
663
663
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dualbox/editor",
3
- "version": "1.0.41",
3
+ "version": "1.0.42",
4
4
  "description": "Editor of Dualbox apps",
5
5
  "browser": "js/dist/GraphEditor.js",
6
6
  "main": "js/dist/GraphEditor.js",