@dualbox/editor 1.0.70 → 1.0.72

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.
@@ -18017,6 +18017,7 @@ class History {
18017
18017
  save() {
18018
18018
  if (!this._holdSaving) {
18019
18019
  var currentAppClone = this.clone(this.m.data);
18020
+ currentAppClone.root = this.m.getCleanJson(); // if it's a snapshot, remove the extra infos
18020
18021
  var previousHash = hash(this.lastState.root);
18021
18022
  var diff = patcher.diff(this.lastState, currentAppClone);
18022
18023
  if (diff) {
@@ -45956,6 +45957,7 @@ class AppManager {
45956
45957
  options.options.debug.makeSynchrone = options.options.debug.makeSynchrone || false;
45957
45958
  options.options.debug.removeTryCatch = options.options.debug.removeTryCatch || false;
45958
45959
  options.options.debug.record = options.options.debug.record || false;
45960
+ options.options.debug.ressourceCaching = options.options.debug.ressourceCaching || false;
45959
45961
  options.ressources = window.DualBoxRessources || {};
45960
45962
 
45961
45963
  this.app = window.app = window.DualBox.start(options);
@@ -47358,16 +47360,20 @@ __vue_render__._withStripped = true;
47358
47360
  const __vue_is_functional_template__ = false;
47359
47361
  /* style inject SSR */
47360
47362
 
47363
+ /* style inject shadow dom */
47364
+
47361
47365
 
47362
47366
 
47363
- var GraphNodeVue = normalizeComponent_1(
47367
+ const __vue_component__ = normalizeComponent_1(
47364
47368
  { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
47365
47369
  __vue_inject_styles__,
47366
47370
  __vue_script__,
47367
47371
  __vue_scope_id__,
47368
47372
  __vue_is_functional_template__,
47369
47373
  __vue_module_identifier__,
47374
+ false,
47370
47375
  browser,
47376
+ undefined,
47371
47377
  undefined
47372
47378
  );
47373
47379
 
@@ -48423,7 +48429,7 @@ var script$1 = {
48423
48429
  "displayEvents" // display events or not
48424
48430
  ],
48425
48431
  components: {
48426
- 'graph-node' : GraphNodeVue,
48432
+ 'graph-node' : __vue_component__,
48427
48433
  },
48428
48434
  data: function () {
48429
48435
  return {
@@ -49376,16 +49382,20 @@ __vue_render__$1._withStripped = true;
49376
49382
  const __vue_is_functional_template__$1 = false;
49377
49383
  /* style inject SSR */
49378
49384
 
49385
+ /* style inject shadow dom */
49386
+
49379
49387
 
49380
49388
 
49381
- var graphVue = normalizeComponent_1(
49389
+ const __vue_component__$1 = normalizeComponent_1(
49382
49390
  { render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 },
49383
49391
  __vue_inject_styles__$1,
49384
49392
  __vue_script__$1,
49385
49393
  __vue_scope_id__$1,
49386
49394
  __vue_is_functional_template__$1,
49387
49395
  __vue_module_identifier__$1,
49396
+ false,
49388
49397
  browser,
49398
+ undefined,
49389
49399
  undefined
49390
49400
  );
49391
49401
 
@@ -49510,16 +49520,20 @@ __vue_render__$2._withStripped = true;
49510
49520
  const __vue_is_functional_template__$2 = false;
49511
49521
  /* style inject SSR */
49512
49522
 
49523
+ /* style inject shadow dom */
49524
+
49513
49525
 
49514
49526
 
49515
- var SearchResultsVue = normalizeComponent_1(
49527
+ const __vue_component__$2 = normalizeComponent_1(
49516
49528
  { render: __vue_render__$2, staticRenderFns: __vue_staticRenderFns__$2 },
49517
49529
  __vue_inject_styles__$2,
49518
49530
  __vue_script__$2,
49519
49531
  __vue_scope_id__$2,
49520
49532
  __vue_is_functional_template__$2,
49521
49533
  __vue_module_identifier__$2,
49534
+ false,
49522
49535
  browser,
49536
+ undefined,
49523
49537
  undefined
49524
49538
  );
49525
49539
 
@@ -49530,7 +49544,7 @@ var script$3 = {
49530
49544
  "result",
49531
49545
  ],
49532
49546
  components: {
49533
- 'graph-node' : GraphNodeVue
49547
+ 'graph-node' : __vue_component__
49534
49548
  },
49535
49549
  created: function() {
49536
49550
  this.view = window.dualboxEditor.v;
@@ -49868,16 +49882,20 @@ __vue_render__$3._withStripped = true;
49868
49882
  const __vue_is_functional_template__$3 = false;
49869
49883
  /* style inject SSR */
49870
49884
 
49885
+ /* style inject shadow dom */
49886
+
49871
49887
 
49872
49888
 
49873
- var DisplayResultVue = normalizeComponent_1(
49889
+ const __vue_component__$3 = normalizeComponent_1(
49874
49890
  { render: __vue_render__$3, staticRenderFns: __vue_staticRenderFns__$3 },
49875
49891
  __vue_inject_styles__$3,
49876
49892
  __vue_script__$3,
49877
49893
  __vue_scope_id__$3,
49878
49894
  __vue_is_functional_template__$3,
49879
49895
  __vue_module_identifier__$3,
49896
+ false,
49880
49897
  browser,
49898
+ undefined,
49881
49899
  undefined
49882
49900
  );
49883
49901
 
@@ -63065,16 +63083,20 @@ __vue_render__$4._withStripped = true;
63065
63083
  const __vue_is_functional_template__$4 = false;
63066
63084
  /* style inject SSR */
63067
63085
 
63086
+ /* style inject shadow dom */
63087
+
63068
63088
 
63069
63089
 
63070
- var EditTypeVue = normalizeComponent_1(
63090
+ const __vue_component__$4 = normalizeComponent_1(
63071
63091
  { render: __vue_render__$4, staticRenderFns: __vue_staticRenderFns__$4 },
63072
63092
  __vue_inject_styles__$4,
63073
63093
  __vue_script__$4,
63074
63094
  __vue_scope_id__$4,
63075
63095
  __vue_is_functional_template__$4,
63076
63096
  __vue_module_identifier__$4,
63097
+ false,
63077
63098
  browser,
63099
+ undefined,
63078
63100
  undefined
63079
63101
  );
63080
63102
 
@@ -63086,9 +63108,9 @@ var script$5 = {
63086
63108
  "mousePosition" // mouse position when this panel was opened
63087
63109
  ],
63088
63110
  components: {
63089
- 'search-results' : SearchResultsVue,
63090
- 'display-result' : DisplayResultVue,
63091
- 'edit-type' : EditTypeVue
63111
+ 'search-results' : __vue_component__$2,
63112
+ 'display-result' : __vue_component__$3,
63113
+ 'edit-type' : __vue_component__$4
63092
63114
  },
63093
63115
  data: function () {
63094
63116
  return {
@@ -63954,16 +63976,20 @@ __vue_render__$5._withStripped = true;
63954
63976
  const __vue_is_functional_template__$5 = false;
63955
63977
  /* style inject SSR */
63956
63978
 
63979
+ /* style inject shadow dom */
63980
+
63957
63981
 
63958
63982
 
63959
- var addNodeVue = normalizeComponent_1(
63983
+ const __vue_component__$5 = normalizeComponent_1(
63960
63984
  { render: __vue_render__$5, staticRenderFns: __vue_staticRenderFns__$5 },
63961
63985
  __vue_inject_styles__$5,
63962
63986
  __vue_script__$5,
63963
63987
  __vue_scope_id__$5,
63964
63988
  __vue_is_functional_template__$5,
63965
63989
  __vue_module_identifier__$5,
63990
+ false,
63966
63991
  browser,
63992
+ undefined,
63967
63993
  undefined
63968
63994
  );
63969
63995
 
@@ -64122,15 +64148,19 @@ __vue_render__$6._withStripped = true;
64122
64148
 
64123
64149
  /* style inject SSR */
64124
64150
 
64151
+ /* style inject shadow dom */
64152
+
64125
64153
 
64126
64154
 
64127
- var ModalVue = normalizeComponent_1(
64155
+ const __vue_component__$6 = normalizeComponent_1(
64128
64156
  { render: __vue_render__$6, staticRenderFns: __vue_staticRenderFns__$6 },
64129
64157
  __vue_inject_styles__$6,
64130
64158
  __vue_script__$6,
64131
64159
  __vue_scope_id__$6,
64132
64160
  __vue_is_functional_template__$6,
64133
64161
  __vue_module_identifier__$6,
64162
+ false,
64163
+ undefined,
64134
64164
  undefined,
64135
64165
  undefined
64136
64166
  );
@@ -64143,8 +64173,8 @@ var script$7 = {
64143
64173
  "readonly",
64144
64174
  ],
64145
64175
  components : {
64146
- 'modal' : ModalVue,
64147
- 'edit-type' : EditTypeVue
64176
+ 'modal' : __vue_component__$6,
64177
+ 'edit-type' : __vue_component__$4
64148
64178
  },
64149
64179
  data: function () {
64150
64180
  return {
@@ -64286,16 +64316,20 @@ __vue_render__$7._withStripped = true;
64286
64316
  const __vue_is_functional_template__$7 = false;
64287
64317
  /* style inject SSR */
64288
64318
 
64319
+ /* style inject shadow dom */
64320
+
64289
64321
 
64290
64322
 
64291
- var DisplayTypeVue = normalizeComponent_1(
64323
+ const __vue_component__$7 = normalizeComponent_1(
64292
64324
  { render: __vue_render__$7, staticRenderFns: __vue_staticRenderFns__$7 },
64293
64325
  __vue_inject_styles__$7,
64294
64326
  __vue_script__$7,
64295
64327
  __vue_scope_id__$7,
64296
64328
  __vue_is_functional_template__$7,
64297
64329
  __vue_module_identifier__$7,
64330
+ false,
64298
64331
  browser,
64332
+ undefined,
64299
64333
  undefined
64300
64334
  );
64301
64335
 
@@ -64513,8 +64547,7 @@ var script$8 = {
64513
64547
  if( ["string", "number", "boolean", "array", "map"].indexOf(this.dataType) == -1 ) {
64514
64548
  this.dataType = "object";
64515
64549
  }
64516
-
64517
- console.log(`Type: ${this.type}, Datatype: ${this.dataType}, embeddedType: ${this.embeddedType}`);
64550
+ //console.log(`Type: ${this.type}, Datatype: ${this.dataType}, embeddedType: ${this.embeddedType}`);
64518
64551
  },
64519
64552
 
64520
64553
  initData: function() {
@@ -65007,27 +65040,31 @@ __vue_render__$8._withStripped = true;
65007
65040
  /* style */
65008
65041
  const __vue_inject_styles__$8 = function (inject) {
65009
65042
  if (!inject) return
65010
- inject("data-v-33721d92_0", { source: "\n.template-value-container[data-v-33721d92], .field-editor[data-v-33721d92] {\n margin-bottom: 10px;\n}\n.template-value-message[data-v-33721d92] {\n text-align: center;\n margin-top: 30px;\n margin-bottom: 30px;\n width: 100%;\n opacity: 0.5;\n}\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/editValue.vue"],"names":[],"mappings":";AACA;IACA,mBAAA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;IACA,WAAA;IACA,YAAA;AACA","file":"editValue.vue","sourcesContent":["<style scoped>\n .template-value-container, .field-editor {\n margin-bottom: 10px;\n }\n\n .template-value-message {\n text-align: center;\n margin-top: 30px;\n margin-bottom: 30px;\n width: 100%;\n opacity: 0.5;\n }\n</style>\n\n<template>\n <div class=\"w-100\">\n <p style=\"display: none;\">{{cIndex}}</p>\n <template v-if=\"isBasicDataType()\">\n <template v-if=\"dataType === 'string'\">\n <input class=\"edit-value-input\" type=\"text\" @keyup.enter=\"setStringValue\" @keyup.esc=\"setStringValue\" :value=\"v\" @focus=\"$event.target.select()\"></input>\n </template>\n <template v-else-if=\"dataType === 'boolean'\">\n <select class=\"edit-value-input\" @change=\"setBoolValue\">\n <option value=\"true\" :selected=\"v == true\">True</option>\n <option value=\"false\" :selected=\"v == false\">False</option>\n </select>\n </template>\n <template v-else-if=\"dataType === 'number'\">\n <input class=\"edit-value-input\" type=\"number\" @keyup.enter=\"setNumberValue\" @blur=\"setNumberValue\" :value=\"v\" @focus=\"$event.target.select()\" style=\"width: 40px;\"></input>\n </template>\n </template>\n <template v-else>\n <!-- we already are in a modal, don't instanciate another one -->\n <template v-if=\"isTemplateType()\">\n <div class=\"container template-value-container\" style=\"border: 1px solid rgba(0, 0, 0, 0.125);\">\n <div v-if=\"isArrayType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Array Editor</div>\n <div v-else-if=\"isMapType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Map Editor</div>\n <div class=\"row\" style=\"1px solid rgba(0,0,0,.125);\">\n <div class=\"col list-group-flush\" :class=\"{ 'col-1' : isArrayType(), 'col-2' : isMapType()}\" style=\"padding: 0; background-color: white; overflow-y: auto; border-right: 1px solid rgba(0, 0, 0, 0.125);\">\n <button v-for=\"index in deserializedValue.keys()\" :key=\"index\" :data-key=\"index\" type=\"button\" class=\"list-group-item list-group-item-action\" :class=\"{ active: isSelectedIndex(index) }\" style=\"text-align: center;\" @click=\"selectIndex(index)\">{{index}}</button>\n <button type=\"button\" @click=\"addItem\" class=\"list-group-item list-group-item-action add-item\" style=\"text-align: center;\"><i class=\"fas fa-plus-circle\"></i></button>\n </div>\n <div class=\"col\" style=\"padding: 10px\">\n <edit-value v-if=\"selectedIndex !== undefined && selectedIndex !== null\" :cIndex=\"selectedIndex\" :type=\"embeddedType\" :v=\"getElement(selectedIndex)\" @edited=\"onSubValueEdited(selectedIndex, $event)\"></edit-value>\n <p v-else class=\"template-value-message\">Select an element to edit.</p>\n </div>\n </div>\n </div>\n </template>\n <template v-else>\n <div class=\"field-editor\" :data-value=\"hash()\"></div>\n </template>\n </template>\n\n <!-- set null and delete buttons -->\n <div class=\"d-inline-block float-right\">\n <button class=\"btn btn-secondary btn-sm btn-xs\" title=\"set Null\" @click=\"setNullValue\">null</button>\n <button class=\"btn btn-danger btn-sm btn-xs\" title=\"delete value\" @click=\"deleteValue\" style=\"margin-left: 0px;\"><i class=\"fas fa-trash\"></i></button>\n </div>\n </div>\n\n</template>\n\n<script>\nimport _ from 'lodash-es';\nimport swal from 'sweetalert2';\nimport JSONEditor from '@dualbox/dualbox-lib-jsoneditor';\n\nString.prototype.hashCode = function() {\n var hash = 0, i, chr;\n if (this.length === 0) return hash;\n for (i = 0; i < this.length; i++) {\n chr = this.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n};\n\nexport default {\n name : \"edit-value\",\n props: [\n // required\n \"v\", // the value\n \"type\", // the dualbox type of the value\n\n // specific properties (for recursivity)\n \"cIndex\" // index for reference when in an array\n ],\n data: function () {\n return {\n \"dataType\": null, // the real javascript dataType of this.v\n \"deserializedValue\": null,\n\n // if type is a collection (dataType==\"map\" or dataType==\"array\")\n \"embeddedType\": null, // the embedded type of this templated collection\n \"selectedIndex\": null, // the current index of the element we are editing\n };\n },\n created: function() {\n this.view = window.dualboxEditor.v;\n this.editor = null;\n this.edited = false;\n this.initData();\n },\n mounted: function() {\n var self = this;\n\n this.updateEditor();\n\n $(this.$el).find('.edit-value-input').focus(); // focus on the edit element\n },\n beforeUpdate: function() {\n this.updateData();\n },\n updated: function() {\n if( this.autochange ) {\n // change triggered by ourself, skip\n this.autochange = false;\n }\n else {\n this.updateEditor();\n }\n },\n beforeDestroy: function() {\n // make sure the value was set\n if( !this.emitted ) {\n if( this.isBasicDataType()) {\n var elt = $(this.$el).find('.edit-value-input');\n var val = elt.val();\n this.$emit(\"edited\", val);\n }\n else {\n this.saveChanges();\n }\n }\n },\n methods: {\n hash: function() {\n var str = new String(this.v).toString();\n return str.split('').reduce((prevHash, currVal) => (((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0);\n },\n\n updateEditor: function() {\n if( this.dataType === \"object\" ) {\n if( !this.editor && $(this.$el).find('.field-editor')[0] !== undefined ) {\n // bind the json editor\n this.editor = new JSONEditor(\n $(this.$el).find('.field-editor')[0], {\n modes: ['tree', 'code', 'text' ],\n onChange: () => {\n try {\n var json = this.editor.get();\n this.autochange = true;\n this.$emit('edited', json);\n }\n catch(e) {}\n }\n });\n }\n\n if( this.editor ) {\n this.editor.set(this.v || {});\n }\n }\n },\n resolveDatatype() {\n // determine datatype of the value\n var resolvedType = this.type ? this.type.toLowerCase() : typeof this.v;\n\n // If \"*\", resolve the type by detecting it dynamically from value\n if( resolvedType.indexOf(\"*\") !== -1 ) {\n resolvedType = window.DualBox.Type.detectType(this.v).toLowerCase();\n }\n\n // Check if we have a template type. If so, determine current index and embedded type\n var templateType = null;\n if( resolvedType.startsWith(\"array\") ) {\n templateType = \"array\";\n this.deserializedValue = this.v || [];\n }\n else if( resolvedType.startsWith(\"map\") ) {\n templateType = \"map\";\n this.deserializedValue = window.DualBox.Type.deserialize(this.v || {\n \"metadata\":{\n \"type\":\"Map<String,\"+ this.firstLetterUppercase( this.getEmbeddedType(resolvedType) )+\">\"\n },\n \"data\": {}\n });\n }\n\n if( templateType ) {\n this.dataType = templateType;\n this.embeddedType = this.getEmbeddedType(resolvedType);\n if( this.selectedIndex == null ) {\n var firstKey = this.deserializedValue.keys().next();\n if( firstKey && firstKey.value ) {\n this.selectedIndex = firstKey.value;\n }\n }\n }\n else {\n this.dataType = resolvedType;\n }\n\n // Finally, transform to object if not a basic value\n if( [\"string\", \"number\", \"boolean\", \"array\", \"map\"].indexOf(this.dataType) == -1 ) {\n this.dataType = \"object\";\n }\n\n console.log(`Type: ${this.type}, Datatype: ${this.dataType}, embeddedType: ${this.embeddedType}`);\n },\n\n initData: function() {\n this.v = this.v;\n this.resolveDatatype();\n this.selectNextIndex();\n },\n\n updateData: function() {\n this.resolveDatatype();\n },\n\n isBasicDataType() {\n return this.dataType == \"string\" ||\n this.dataType == \"number\" ||\n this.dataType == \"boolean\";\n },\n\n serialize( value ) {\n if( this.isTemplateType() ) {\n if( this.isArrayType() ) {\n return value; // we store arrays as is\n }\n else if( this.isMapType() ) {\n return window.DualBox.Type.serialize(value);\n }\n }\n else {\n return value;\n }\n },\n\n saveChanges: function() {\n this.$forceUpdate();\n\n if( this.isTemplateType() ) {\n this.$emit(\"edited\", this.serialize(this.deserializedValue));\n this.emitted = true;\n }\n else if( this.isObjectType() ) {\n // emit the result to the parent Vue\n this.$emit(\"edited\", this.editor.get());\n this.emitted = true;\n }\n },\n\n setStringValue: function(e) {\n var val = $(e.target).val();\n this.$emit(\"edited\", val);\n this.emitted = true;\n },\n\n setBoolValue: function(e) {\n var val = $(e.target).val() == \"true\";\n this.$emit(\"edited\", val);\n this.emitted = true;\n },\n\n setNumberValue: function(e) {\n var val = parseFloat($(e.target).val());\n this.$emit(\"edited\", val);\n this.emitted = true;\n },\n\n setNullValue: function() {\n this.$forceUpdate();\n\n // emit the result to the parent Vue\n this.$emit(\"edited\", null);\n },\n\n selectNextIndex: function() {\n if( this.isArrayType() ) {\n this.selectedIndex = this.deserializedValue.length > 0 ? 0 : null;\n }\n else if( this.isMapType() ) {\n var keys = this.deserializedValue.keys();\n var next = keys.next();\n this.selectedIndex = next ? next.value : null;\n }\n },\n\n deleteValue: function(e) {\n this.selectNextIndex();\n this.$forceUpdate();\n\n // emit the result to the parent Vue\n this.$emit(\"edited\", undefined);\n },\n\n isArrayType: function() {\n return this.dataType == \"array\";\n },\n\n isMapType: function() {\n return this.dataType == \"map\";\n },\n\n isObjectType: function() {\n return this.dataType == \"object\";\n },\n\n isTemplateType: function() {\n return this.isArrayType() || this.isMapType();\n },\n\n getEmbeddedType: function(type) {\n var start = type.indexOf('<') + 1;\n var end = type.lastIndexOf('>');\n if( type.toLowerCase().startsWith('array') ) {\n return type.substr(start, end - start).trim().toLowerCase();\n }\n else if( type.toLowerCase().startsWith('map') ) {\n var sub = type.substr(start, end - start);\n return sub.substr(sub.indexOf(',') + 1).trim().toLowerCase();\n }\n },\n\n firstLetterUppercase: function(s) {\n return s.charAt(0).toUpperCase() + s.slice(1)\n },\n\n selectIndex: function(index) {\n if( this.selectedIndex !== index ) {\n this.selectedIndex = index;\n this.$forceUpdate();\n }\n },\n\n isSelectedIndex: function(index) {\n return index == this.selectedIndex;\n },\n\n getElement: function(i) {\n if( Array.isArray(this.v) ) {\n return this.deserializedValue[i];\n }\n else {\n return this.deserializedValue.get(i);\n }\n },\n\n onSubValueEdited: function(index, newValue) {\n console.log(`Edited at index ${index}: ${JSON.stringify(newValue)}`);\n if( this.isArrayType() ) {\n if( newValue === undefined ) {\n // we just remove this value\n this.deserializedValue.splice(index, 1);\n }\n else {\n this.deserializedValue[index] = newValue;\n }\n }\n else if ( this.isMapType() ) {\n if( newValue === undefined ) {\n this.deserializedValue.delete(index);\n }\n else {\n this.deserializedValue.set(index, newValue);\n }\n }\n this.saveChanges();\n this.$forceUpdate();\n },\n\n addItem: function() {\n if( this.isArrayType() ) {\n this.deserializedValue[ this.deserializedValue.length ] = null;\n this.selectedIndex = this.deserializedValue.length - 1;\n this.saveChanges();\n this.$forceUpdate();\n }\n else if( this.isMapType() ) {\n this.swalFixBootstrapModal();\n swal({\n input: 'text',\n title: 'Enter map key',\n }).then((result) => {\n this.swalRestoreBootstrapModal();\n if( result && result.value ) {\n this.selectedIndex = result.value;\n this.deserializedValue.set(result.value, null);\n this.saveChanges();\n this.$forceUpdate();\n }\n });\n }\n },\n\n // call this before showing SweetAlert:\n swalFixBootstrapModal() {\n var modal = $(\"body\").find('.modal[tabindex=\"-1\"]');\n if (!modal) return;\n modal.removeAttr('tabindex');\n modal.addClass('js-swal-fixed');\n },\n\n // call this before hiding SweetAlert (inside done callback):\n swalRestoreBootstrapModal() {\n var modal = $(\"body\").find('.modal.js-swal-fixed');\n if (!modal) return;\n modal.attr('tabindex', '-1');\n modal.removeClass('js-swal-fixed');\n }\n }\n}\n</script>\n"]}, media: undefined });
65043
+ inject("data-v-b2b26ee0_0", { source: "\n.template-value-container[data-v-b2b26ee0], .field-editor[data-v-b2b26ee0] {\n margin-bottom: 10px;\n}\n.template-value-message[data-v-b2b26ee0] {\n text-align: center;\n margin-top: 30px;\n margin-bottom: 30px;\n width: 100%;\n opacity: 0.5;\n}\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/editValue.vue"],"names":[],"mappings":";AACA;IACA,mBAAA;AACA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;IACA,WAAA;IACA,YAAA;AACA","file":"editValue.vue","sourcesContent":["<style scoped>\n .template-value-container, .field-editor {\n margin-bottom: 10px;\n }\n\n .template-value-message {\n text-align: center;\n margin-top: 30px;\n margin-bottom: 30px;\n width: 100%;\n opacity: 0.5;\n }\n</style>\n\n<template>\n <div class=\"w-100\">\n <p style=\"display: none;\">{{cIndex}}</p>\n <template v-if=\"isBasicDataType()\">\n <template v-if=\"dataType === 'string'\">\n <input class=\"edit-value-input\" type=\"text\" @keyup.enter=\"setStringValue\" @keyup.esc=\"setStringValue\" :value=\"v\" @focus=\"$event.target.select()\"></input>\n </template>\n <template v-else-if=\"dataType === 'boolean'\">\n <select class=\"edit-value-input\" @change=\"setBoolValue\">\n <option value=\"true\" :selected=\"v == true\">True</option>\n <option value=\"false\" :selected=\"v == false\">False</option>\n </select>\n </template>\n <template v-else-if=\"dataType === 'number'\">\n <input class=\"edit-value-input\" type=\"number\" @keyup.enter=\"setNumberValue\" @blur=\"setNumberValue\" :value=\"v\" @focus=\"$event.target.select()\" style=\"width: 40px;\"></input>\n </template>\n </template>\n <template v-else>\n <!-- we already are in a modal, don't instanciate another one -->\n <template v-if=\"isTemplateType()\">\n <div class=\"container template-value-container\" style=\"border: 1px solid rgba(0, 0, 0, 0.125);\">\n <div v-if=\"isArrayType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Array Editor</div>\n <div v-else-if=\"isMapType()\" class=\"row\" style=\"background-color: rgba(0,0,0,.125);\">Map Editor</div>\n <div class=\"row\" style=\"1px solid rgba(0,0,0,.125);\">\n <div class=\"col list-group-flush\" :class=\"{ 'col-1' : isArrayType(), 'col-2' : isMapType()}\" style=\"padding: 0; background-color: white; overflow-y: auto; border-right: 1px solid rgba(0, 0, 0, 0.125);\">\n <button v-for=\"index in deserializedValue.keys()\" :key=\"index\" :data-key=\"index\" type=\"button\" class=\"list-group-item list-group-item-action\" :class=\"{ active: isSelectedIndex(index) }\" style=\"text-align: center;\" @click=\"selectIndex(index)\">{{index}}</button>\n <button type=\"button\" @click=\"addItem\" class=\"list-group-item list-group-item-action add-item\" style=\"text-align: center;\"><i class=\"fas fa-plus-circle\"></i></button>\n </div>\n <div class=\"col\" style=\"padding: 10px\">\n <edit-value v-if=\"selectedIndex !== undefined && selectedIndex !== null\" :cIndex=\"selectedIndex\" :type=\"embeddedType\" :v=\"getElement(selectedIndex)\" @edited=\"onSubValueEdited(selectedIndex, $event)\"></edit-value>\n <p v-else class=\"template-value-message\">Select an element to edit.</p>\n </div>\n </div>\n </div>\n </template>\n <template v-else>\n <div class=\"field-editor\" :data-value=\"hash()\"></div>\n </template>\n </template>\n\n <!-- set null and delete buttons -->\n <div class=\"d-inline-block float-right\">\n <button class=\"btn btn-secondary btn-sm btn-xs\" title=\"set Null\" @click=\"setNullValue\">null</button>\n <button class=\"btn btn-danger btn-sm btn-xs\" title=\"delete value\" @click=\"deleteValue\" style=\"margin-left: 0px;\"><i class=\"fas fa-trash\"></i></button>\n </div>\n </div>\n\n</template>\n\n<script>\nimport _ from 'lodash-es';\nimport swal from 'sweetalert2';\nimport JSONEditor from '@dualbox/dualbox-lib-jsoneditor';\n\nString.prototype.hashCode = function() {\n var hash = 0, i, chr;\n if (this.length === 0) return hash;\n for (i = 0; i < this.length; i++) {\n chr = this.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n};\n\nexport default {\n name : \"edit-value\",\n props: [\n // required\n \"v\", // the value\n \"type\", // the dualbox type of the value\n\n // specific properties (for recursivity)\n \"cIndex\" // index for reference when in an array\n ],\n data: function () {\n return {\n \"dataType\": null, // the real javascript dataType of this.v\n \"deserializedValue\": null,\n\n // if type is a collection (dataType==\"map\" or dataType==\"array\")\n \"embeddedType\": null, // the embedded type of this templated collection\n \"selectedIndex\": null, // the current index of the element we are editing\n };\n },\n created: function() {\n this.view = window.dualboxEditor.v;\n this.editor = null;\n this.edited = false;\n this.initData();\n },\n mounted: function() {\n var self = this;\n\n this.updateEditor();\n\n $(this.$el).find('.edit-value-input').focus(); // focus on the edit element\n },\n beforeUpdate: function() {\n this.updateData();\n },\n updated: function() {\n if( this.autochange ) {\n // change triggered by ourself, skip\n this.autochange = false;\n }\n else {\n this.updateEditor();\n }\n },\n beforeDestroy: function() {\n // make sure the value was set\n if( !this.emitted ) {\n if( this.isBasicDataType()) {\n var elt = $(this.$el).find('.edit-value-input');\n var val = elt.val();\n this.$emit(\"edited\", val);\n }\n else {\n this.saveChanges();\n }\n }\n },\n methods: {\n hash: function() {\n var str = new String(this.v).toString();\n return str.split('').reduce((prevHash, currVal) => (((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0);\n },\n\n updateEditor: function() {\n if( this.dataType === \"object\" ) {\n if( !this.editor && $(this.$el).find('.field-editor')[0] !== undefined ) {\n // bind the json editor\n this.editor = new JSONEditor(\n $(this.$el).find('.field-editor')[0], {\n modes: ['tree', 'code', 'text' ],\n onChange: () => {\n try {\n var json = this.editor.get();\n this.autochange = true;\n this.$emit('edited', json);\n }\n catch(e) {}\n }\n });\n }\n\n if( this.editor ) {\n this.editor.set(this.v || {});\n }\n }\n },\n resolveDatatype() {\n // determine datatype of the value\n var resolvedType = this.type ? this.type.toLowerCase() : typeof this.v;\n\n // If \"*\", resolve the type by detecting it dynamically from value\n if( resolvedType.indexOf(\"*\") !== -1 ) {\n resolvedType = window.DualBox.Type.detectType(this.v).toLowerCase();\n }\n\n // Check if we have a template type. If so, determine current index and embedded type\n var templateType = null;\n if( resolvedType.startsWith(\"array\") ) {\n templateType = \"array\";\n this.deserializedValue = this.v || [];\n }\n else if( resolvedType.startsWith(\"map\") ) {\n templateType = \"map\";\n this.deserializedValue = window.DualBox.Type.deserialize(this.v || {\n \"metadata\":{\n \"type\":\"Map<String,\"+ this.firstLetterUppercase( this.getEmbeddedType(resolvedType) )+\">\"\n },\n \"data\": {}\n });\n }\n\n if( templateType ) {\n this.dataType = templateType;\n this.embeddedType = this.getEmbeddedType(resolvedType);\n if( this.selectedIndex == null ) {\n var firstKey = this.deserializedValue.keys().next();\n if( firstKey && firstKey.value ) {\n this.selectedIndex = firstKey.value;\n }\n }\n }\n else {\n this.dataType = resolvedType;\n }\n\n // Finally, transform to object if not a basic value\n if( [\"string\", \"number\", \"boolean\", \"array\", \"map\"].indexOf(this.dataType) == -1 ) {\n this.dataType = \"object\";\n }\n //console.log(`Type: ${this.type}, Datatype: ${this.dataType}, embeddedType: ${this.embeddedType}`);\n },\n\n initData: function() {\n this.v = this.v;\n this.resolveDatatype();\n this.selectNextIndex();\n },\n\n updateData: function() {\n this.resolveDatatype();\n },\n\n isBasicDataType() {\n return this.dataType == \"string\" ||\n this.dataType == \"number\" ||\n this.dataType == \"boolean\";\n },\n\n serialize( value ) {\n if( this.isTemplateType() ) {\n if( this.isArrayType() ) {\n return value; // we store arrays as is\n }\n else if( this.isMapType() ) {\n return window.DualBox.Type.serialize(value);\n }\n }\n else {\n return value;\n }\n },\n\n saveChanges: function() {\n this.$forceUpdate();\n\n if( this.isTemplateType() ) {\n this.$emit(\"edited\", this.serialize(this.deserializedValue));\n this.emitted = true;\n }\n else if( this.isObjectType() ) {\n // emit the result to the parent Vue\n this.$emit(\"edited\", this.editor.get());\n this.emitted = true;\n }\n },\n\n setStringValue: function(e) {\n var val = $(e.target).val();\n this.$emit(\"edited\", val);\n this.emitted = true;\n },\n\n setBoolValue: function(e) {\n var val = $(e.target).val() == \"true\";\n this.$emit(\"edited\", val);\n this.emitted = true;\n },\n\n setNumberValue: function(e) {\n var val = parseFloat($(e.target).val());\n this.$emit(\"edited\", val);\n this.emitted = true;\n },\n\n setNullValue: function() {\n this.$forceUpdate();\n\n // emit the result to the parent Vue\n this.$emit(\"edited\", null);\n },\n\n selectNextIndex: function() {\n if( this.isArrayType() ) {\n this.selectedIndex = this.deserializedValue.length > 0 ? 0 : null;\n }\n else if( this.isMapType() ) {\n var keys = this.deserializedValue.keys();\n var next = keys.next();\n this.selectedIndex = next ? next.value : null;\n }\n },\n\n deleteValue: function(e) {\n this.selectNextIndex();\n this.$forceUpdate();\n\n // emit the result to the parent Vue\n this.$emit(\"edited\", undefined);\n },\n\n isArrayType: function() {\n return this.dataType == \"array\";\n },\n\n isMapType: function() {\n return this.dataType == \"map\";\n },\n\n isObjectType: function() {\n return this.dataType == \"object\";\n },\n\n isTemplateType: function() {\n return this.isArrayType() || this.isMapType();\n },\n\n getEmbeddedType: function(type) {\n var start = type.indexOf('<') + 1;\n var end = type.lastIndexOf('>');\n if( type.toLowerCase().startsWith('array') ) {\n return type.substr(start, end - start).trim().toLowerCase();\n }\n else if( type.toLowerCase().startsWith('map') ) {\n var sub = type.substr(start, end - start);\n return sub.substr(sub.indexOf(',') + 1).trim().toLowerCase();\n }\n },\n\n firstLetterUppercase: function(s) {\n return s.charAt(0).toUpperCase() + s.slice(1)\n },\n\n selectIndex: function(index) {\n if( this.selectedIndex !== index ) {\n this.selectedIndex = index;\n this.$forceUpdate();\n }\n },\n\n isSelectedIndex: function(index) {\n return index == this.selectedIndex;\n },\n\n getElement: function(i) {\n if( Array.isArray(this.v) ) {\n return this.deserializedValue[i];\n }\n else {\n return this.deserializedValue.get(i);\n }\n },\n\n onSubValueEdited: function(index, newValue) {\n console.log(`Edited at index ${index}: ${JSON.stringify(newValue)}`);\n if( this.isArrayType() ) {\n if( newValue === undefined ) {\n // we just remove this value\n this.deserializedValue.splice(index, 1);\n }\n else {\n this.deserializedValue[index] = newValue;\n }\n }\n else if ( this.isMapType() ) {\n if( newValue === undefined ) {\n this.deserializedValue.delete(index);\n }\n else {\n this.deserializedValue.set(index, newValue);\n }\n }\n this.saveChanges();\n this.$forceUpdate();\n },\n\n addItem: function() {\n if( this.isArrayType() ) {\n this.deserializedValue[ this.deserializedValue.length ] = null;\n this.selectedIndex = this.deserializedValue.length - 1;\n this.saveChanges();\n this.$forceUpdate();\n }\n else if( this.isMapType() ) {\n this.swalFixBootstrapModal();\n swal({\n input: 'text',\n title: 'Enter map key',\n }).then((result) => {\n this.swalRestoreBootstrapModal();\n if( result && result.value ) {\n this.selectedIndex = result.value;\n this.deserializedValue.set(result.value, null);\n this.saveChanges();\n this.$forceUpdate();\n }\n });\n }\n },\n\n // call this before showing SweetAlert:\n swalFixBootstrapModal() {\n var modal = $(\"body\").find('.modal[tabindex=\"-1\"]');\n if (!modal) return;\n modal.removeAttr('tabindex');\n modal.addClass('js-swal-fixed');\n },\n\n // call this before hiding SweetAlert (inside done callback):\n swalRestoreBootstrapModal() {\n var modal = $(\"body\").find('.modal.js-swal-fixed');\n if (!modal) return;\n modal.attr('tabindex', '-1');\n modal.removeClass('js-swal-fixed');\n }\n }\n}\n</script>\n"]}, media: undefined });
65011
65044
 
65012
65045
  };
65013
65046
  /* scoped */
65014
- const __vue_scope_id__$8 = "data-v-33721d92";
65047
+ const __vue_scope_id__$8 = "data-v-b2b26ee0";
65015
65048
  /* module identifier */
65016
65049
  const __vue_module_identifier__$8 = undefined;
65017
65050
  /* functional template */
65018
65051
  const __vue_is_functional_template__$8 = false;
65019
65052
  /* style inject SSR */
65020
65053
 
65054
+ /* style inject shadow dom */
65055
+
65021
65056
 
65022
65057
 
65023
- var EditValueVue = normalizeComponent_1(
65058
+ const __vue_component__$8 = normalizeComponent_1(
65024
65059
  { render: __vue_render__$8, staticRenderFns: __vue_staticRenderFns__$8 },
65025
65060
  __vue_inject_styles__$8,
65026
65061
  __vue_script__$8,
65027
65062
  __vue_scope_id__$8,
65028
65063
  __vue_is_functional_template__$8,
65029
65064
  __vue_module_identifier__$8,
65065
+ false,
65030
65066
  browser,
65067
+ undefined,
65031
65068
  undefined
65032
65069
  );
65033
65070
 
@@ -65041,8 +65078,8 @@ var script$9 = {
65041
65078
  "readonlyReason"
65042
65079
  ],
65043
65080
  components : {
65044
- 'modal' : ModalVue,
65045
- 'edit-value' : EditValueVue,
65081
+ 'modal' : __vue_component__$6,
65082
+ 'edit-value' : __vue_component__$8,
65046
65083
  },
65047
65084
  data: function () {
65048
65085
  return {
@@ -65255,16 +65292,20 @@ __vue_render__$9._withStripped = true;
65255
65292
  const __vue_is_functional_template__$9 = false;
65256
65293
  /* style inject SSR */
65257
65294
 
65295
+ /* style inject shadow dom */
65296
+
65258
65297
 
65259
65298
 
65260
- var DisplayValueVue = normalizeComponent_1(
65299
+ const __vue_component__$9 = normalizeComponent_1(
65261
65300
  { render: __vue_render__$9, staticRenderFns: __vue_staticRenderFns__$9 },
65262
65301
  __vue_inject_styles__$9,
65263
65302
  __vue_script__$9,
65264
65303
  __vue_scope_id__$9,
65265
65304
  __vue_is_functional_template__$9,
65266
65305
  __vue_module_identifier__$9,
65306
+ false,
65267
65307
  browser,
65308
+ undefined,
65268
65309
  undefined
65269
65310
  );
65270
65311
 
@@ -65275,8 +65316,8 @@ var script$a = {
65275
65316
  "app"
65276
65317
  ],
65277
65318
  components: {
65278
- "display-type" : DisplayTypeVue,
65279
- "display-value" : DisplayValueVue,
65319
+ "display-type" : __vue_component__$7,
65320
+ "display-value" : __vue_component__$9,
65280
65321
  },
65281
65322
  data: function () {
65282
65323
  return {
@@ -66719,16 +66760,20 @@ __vue_render__$a._withStripped = true;
66719
66760
  const __vue_is_functional_template__$a = false;
66720
66761
  /* style inject SSR */
66721
66762
 
66763
+ /* style inject shadow dom */
66764
+
66722
66765
 
66723
66766
 
66724
- var editMainSettingsVue = normalizeComponent_1(
66767
+ const __vue_component__$a = normalizeComponent_1(
66725
66768
  { render: __vue_render__$a, staticRenderFns: __vue_staticRenderFns__$a },
66726
66769
  __vue_inject_styles__$a,
66727
66770
  __vue_script__$a,
66728
66771
  __vue_scope_id__$a,
66729
66772
  __vue_is_functional_template__$a,
66730
66773
  __vue_module_identifier__$a,
66774
+ false,
66731
66775
  browser,
66776
+ undefined,
66732
66777
  undefined
66733
66778
  );
66734
66779
 
@@ -66739,9 +66784,9 @@ var script$b = {
66739
66784
  "id", // the GraphNode object
66740
66785
  ],
66741
66786
  components: {
66742
- "display-type" : DisplayTypeVue,
66743
- "display-value" : DisplayValueVue,
66744
- "graph-node" : GraphNodeVue
66787
+ "display-type" : __vue_component__$7,
66788
+ "display-value" : __vue_component__$9,
66789
+ "graph-node" : __vue_component__
66745
66790
  },
66746
66791
  data: function () {
66747
66792
  return {
@@ -69030,16 +69075,20 @@ __vue_render__$b._withStripped = true;
69030
69075
  const __vue_is_functional_template__$b = false;
69031
69076
  /* style inject SSR */
69032
69077
 
69078
+ /* style inject shadow dom */
69079
+
69033
69080
 
69034
69081
 
69035
- var editNodeSettingsVue = normalizeComponent_1(
69082
+ const __vue_component__$b = normalizeComponent_1(
69036
69083
  { render: __vue_render__$b, staticRenderFns: __vue_staticRenderFns__$b },
69037
69084
  __vue_inject_styles__$b,
69038
69085
  __vue_script__$b,
69039
69086
  __vue_scope_id__$b,
69040
69087
  __vue_is_functional_template__$b,
69041
69088
  __vue_module_identifier__$b,
69089
+ false,
69042
69090
  browser,
69091
+ undefined,
69043
69092
  undefined
69044
69093
  );
69045
69094
 
@@ -73650,7 +73699,7 @@ var script$c = {
73650
73699
  "id"
73651
73700
  ],
73652
73701
  components: {
73653
- "display-value" : DisplayValueVue,
73702
+ "display-value" : __vue_component__$9,
73654
73703
  },
73655
73704
  data: function () {
73656
73705
  return {
@@ -73666,7 +73715,6 @@ var script$c = {
73666
73715
  beforeUpdate: function() {
73667
73716
  this.n = this.view.m.getNode(this.id); // it breaks updating node name
73668
73717
  this.debug = this.n.getSnapshot(); // shortcut
73669
- this.$forceupdate();
73670
73718
  },
73671
73719
  mounted: function() {
73672
73720
 
@@ -73887,7 +73935,7 @@ var __vue_render__$c = function() {
73887
73935
  attrs: {
73888
73936
  id: "debug-node-inputs-collapse",
73889
73937
  "aria-labelledby": "debug-node-inputs",
73890
- "data-parent": "#card-debug"
73938
+ "data-parent": "#debug-node"
73891
73939
  }
73892
73940
  },
73893
73941
  [
@@ -73971,8 +74019,7 @@ var __vue_render__$c = function() {
73971
74019
  attrs: {
73972
74020
  v: _vm.n.m.getSnapshotValue(
73973
74021
  _vm.getInputData(key).value
73974
- ),
73975
- readonly: "true"
74022
+ )
73976
74023
  }
73977
74024
  })
73978
74025
  ]
@@ -73990,8 +74037,7 @@ var __vue_render__$c = function() {
73990
74037
  attrs: {
73991
74038
  v: _vm.n.m.getSnapshotValue(
73992
74039
  _vm.getInputData(key).default
73993
- ),
73994
- readonly: "true"
74040
+ )
73995
74041
  }
73996
74042
  })
73997
74043
  ]
@@ -74021,7 +74067,7 @@ var __vue_render__$c = function() {
74021
74067
  attrs: {
74022
74068
  id: "debug-node-cache-collapse",
74023
74069
  "aria-labelledby": "debug-node-cache",
74024
- "data-parent": "#card-debug"
74070
+ "data-parent": "#debug-node"
74025
74071
  }
74026
74072
  },
74027
74073
  [
@@ -74053,8 +74099,7 @@ var __vue_render__$c = function() {
74053
74099
  attrs: {
74054
74100
  v: _vm.n.m.getSnapshotValue(
74055
74101
  _vm.debug.cache[_vm.key]
74056
- ),
74057
- readonly: "true"
74102
+ )
74058
74103
  }
74059
74104
  })
74060
74105
  ],
@@ -74090,7 +74135,7 @@ var __vue_render__$c = function() {
74090
74135
  attrs: {
74091
74136
  id: "debug-node-events-collapse",
74092
74137
  "aria-labelledby": "debug-node-events",
74093
- "data-parent": "#card-debug"
74138
+ "data-parent": "#debug-node"
74094
74139
  }
74095
74140
  },
74096
74141
  [
@@ -74242,8 +74287,7 @@ var __vue_render__$c = function() {
74242
74287
  v: _vm.n.m.getSnapshotValue(
74243
74288
  _vm.debug.times.emissions
74244
74289
  .lastData.data[key]
74245
- ),
74246
- readonly: "true"
74290
+ )
74247
74291
  }
74248
74292
  })
74249
74293
  ],
@@ -74281,7 +74325,7 @@ var __vue_render__$c = function() {
74281
74325
  attrs: {
74282
74326
  id: "debug-node-evaluations-collapse",
74283
74327
  "aria-labelledby": "debug-node-evaluations",
74284
- "data-parent": "#card-debug"
74328
+ "data-parent": "#debug-node"
74285
74329
  }
74286
74330
  },
74287
74331
  [
@@ -74696,7 +74740,7 @@ __vue_render__$c._withStripped = true;
74696
74740
  /* style */
74697
74741
  const __vue_inject_styles__$c = function (inject) {
74698
74742
  if (!inject) return
74699
- inject("data-v-27e694bc_0", { source: "\n.card-debug .card-body {\n font-size: 12px;\n padding-left: 5px;\n padding-right: 5px;\n}\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/debugNodeInfos.vue"],"names":[],"mappings":";AACA;IACA,eAAA;IACA,iBAAA;IACA,kBAAA;AACA","file":"debugNodeInfos.vue","sourcesContent":["<style>\n .card-debug .card-body {\n font-size: 12px;\n padding-left: 5px;\n padding-right: 5px;\n }\n</style>\n\n<template>\n<div class=\"card-debug h100\" id=\"debug-node\">\n <div style=\"padding-left: 10px; padding-top: 10px; padding-right: 10px;\">\n <h2 class=\"edit-dualbox-node-id\">\n <div class=\"dualbox-node-name\">\n <span class=\"text-truncate d-inline-block\" style=\"width: 290px\" :data-id=\"id\">{{n.graphId}}</span>\n </div>\n <div class=\"dualbox-node-name-edit\" style=\"display: none;\">\n <input type=\"text\" class=\"form-control dualbox-node-name-input\" style=\"display: inline-block;\" :value=\"n.graphId\" :data-type=\"n.type\" autofocus/>\n <button class=\"btn btn-primary btn-save-node-name-change\" :data-id=\"n.graphId\" :data-type=\"n.type\" style=\"display: inline-block;\">Save</button>\n </div>\n </h2>\n <p><small class=\"edit-dualbox-node-package-name\">{{n.getPackageName()}}</small></p>\n </div>\n\n <div class=\"edit-body\">\n <div class=\"card card-state\">\n <div class=\"card-header\" id=\"debug-node-state\" data-toggle=\"collapse\" data-target=\"#debug-node-state-collapse\" aria-expanded=\"true\" aria-controls=\"debug-node-state-collapse\">\n <h5 class=\"mb-0 btn-link\">State</h5>\n </div>\n\n <div id=\"debug-node-state-collapse\" class=\"collapse show\" aria-labelledby=\"debug-node-state\" data-parent=\"#debug-node\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Key</th>\n <th>Value</th>\n </thead>\n <tbody>\n <tr>\n <td>status</td>\n <td><span :class=\"{'card-status-idle':n.isSnapshotStatus(0),'card-status-computing':n.isSnapshotStatus(1),'card-status-awaiting-data':n.isSnapshotStatus(2), 'card-status-ready':n.isSnapshotStatus(3)}\">{{ getSnapshotStatus(n) }}</span></td>\n </tr>\n <tr><td>invalidateSent</td><td>{{debug.state.invalidateSent}}</td></tr>\n <tr><td>readSent</td><td>{{debug.state.readSent}}</td></tr>\n <tr><td>allowedToRestart</td><td>{{debug.state.allowedToRestart}}</td></tr>\n <tr><td>evaluating</td><td>{{debug.state.evaluating}}</td></tr>\n <tr><td>initialized</td><td>{{debug.state.initialized}}</td></tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n\n <div v-if=\"n.hasInputs()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"debug-node-inputs\" data-toggle=\"collapse\" data-target=\"#debug-node-inputs-collapse\" aria-expanded=\"false\" aria-controls=\"debug-node-inputs-collapse\">\n <h5 class=\"mb-0 btn-link\">Data <small><span class=\"badge badge-secondary\">{{ n.getInputsNames().length }}</span></small></h5>\n </div>\n <div id=\"debug-node-inputs-collapse\" class=\"collapse\" aria-labelledby=\"debug-node-inputs\" data-parent=\"#card-debug\">\n <div class=\"card-body\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Input</th>\n <th>Valid</th>\n <th>Type</th>\n <th>Value</th>\n <th>Default</th>\n </thead>\n <tbody>\n <tr v-for=\"key in n.getInputsNames()\" :key=\"n.id + '-input-' + key\">\n <td>\n {{key}}\n <button v-if=\"n.hasInputDesc(key)\" type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" :title=\"n.getInputDesc(key)\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </td>\n <td>{{ getInputData(key).valid }}</td>\n <td>\n <template v-if=\"getInputData(key).value\">\n <template v-if=\"getInputData(key).value.metadata && getInputData(key).value.metadata.type\">{{getInputData(key).value.metadata}}</template>\n <template v-else>{{typeof n.m.getSnapshotValue(getInputData(key).value) }}</template>\n </template>\n </td>\n <td>\n <template v-if=\"getInputData(key).value\">\n <display-value :v=\"n.m.getSnapshotValue(getInputData(key).value)\" readonly=true></display-value>\n </template>\n </td>\n <td>\n <template v-if=\"getInputData(key).default\">\n <display-value :v=\"n.m.getSnapshotValue(getInputData(key).default)\" readonly=true></display-value>\n </template>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <div v-if=\"debug.cache\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"debug-node-cache\" data-toggle=\"collapse\" data-target=\"#debug-node-cache-collapse\" aria-expanded=\"false\" aria-controls=\"debug-node-cache-collapse\">\n <h5 class=\"mb-0 btn-link\">Cache</h5>\n </div>\n <div id=\"debug-node-cache-collapse\" class=\"collapse\" aria-labelledby=\"debug-node-cache\" data-parent=\"#card-debug\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Output</th>\n <th>Value</th>\n </thead>\n <tbody>\n <tr v-for=\"key in Object.keys(debug.cache)\" :key=\"n.id + '-cache-' + key\">\n <tr>\n <td>{{key}}</td>\n <td><display-value :v=\"n.m.getSnapshotValue(debug.cache[key])\" readonly=true></display-value></td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <div v-if=\"debug.times && debug.times.emissions && (debug.times.emissions.lastRead || debug.times.emissions.lastInvalidate || debug.times.emissions.lastData )\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"debug-node-events\" data-toggle=\"collapse\" data-target=\"#debug-node-events-collapse\" aria-expanded=\"false\" aria-controls=\"debug-node-events-collapse\">\n <h5 class=\"mb-0 btn-link\">Last events</h5>\n </div>\n <div id=\"debug-node-events-collapse\" class=\"collapse\" aria-labelledby=\"debug-node-events\" data-parent=\"#card-debug\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n\n <div v-if=\"debug.times.emissions.lastRead\" class=\"mb-3\">\n <p><b><u>Last read {{showNumber(debug.times.emissions.nbRead)}}</u> <span class=\"float-right\">{{ showTime(debug.times.emissions.lastRead.date) }}</span></b></p>\n <span>Missing: <b>{{ debug.times.emissions.lastRead.data.join(', ') }}</b></span><br/>\n </div>\n\n <div v-if=\"debug.times.emissions.lastInvalidate\" class=\"mb-3\">\n <p><b><u>Last Invalidate {{showNumber(debug.times.emissions.nbInvalidate)}}</u> <span class=\"float-right\">{{ showTime(debug.times.emissions.lastInvalidate.date) }}</span></b></p>\n <span>Invalidated keys: <b>{{ debug.times.emissions.lastInvalidate.data.join(', ') }}</b></span><br/>\n </div>\n\n <div v-if=\"debug.times.emissions.lastData\" class=\"mb-3\">\n <p><b><u>Last Data {{ showNumber(debug.times.emissions.nbData) }}</u> <span class=\"float-right\">{{ showTime(debug.times.emissions.lastData.date) }}</span></b></p>\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Output</th>\n <th>Value</th>\n </thead>\n <tbody>\n <tr v-for=\"key in Object.keys(debug.times.emissions.lastData.data)\" :key=\"n.id + '-cache-' + key\">\n <td>{{key}}</td>\n <td><display-value :v=\"n.m.getSnapshotValue(debug.times.emissions.lastData.data[key])\" readonly=true></display-value></td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n\n <div v-if=\"debug.times && debug.times.evaluations && (debug.times.evaluations.lastStart || debug.times.evaluations.lastEnd || debug.times.evaluations.lastCancel )\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"debug-node-evaluations\" data-toggle=\"collapse\" data-target=\"#debug-node-evaluations-collapse\" aria-expanded=\"false\" aria-controls=\"debug-node-evaluations-collapse\">\n <h5 class=\"mb-0 btn-link\">Last evaluations</h5>\n </div>\n <div id=\"debug-node-evaluations-collapse\" class=\"collapse\" aria-labelledby=\"debug-node-evaluations\" data-parent=\"#card-debug\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n\n <div v-if=\"debug.times.evaluations.lastStart\" class=\"mb-3\">\n <p><b><u>Last start</u> <span class=\"float-right\">{{ showTime(debug.times.evaluations.lastStart.date) }}</span></b></p>\n </div>\n\n <div v-if=\"debug.times.evaluations.lastEnd\" class=\"mb-3\">\n <p><b><u>Last end</u> <span class=\"float-right\">{{ showTime(debug.times.evaluations.lastEnd.date) }}</span></b></p>\n </div>\n\n <div v-if=\"debug.times.evaluations.lastCancel\" class=\"mb-3\">\n <p><b><u>Last Cancel</u> <span class=\"float-right\">{{ showTime(debug.times.evaluations.lastCancel.date) }}</span></b></p>\n <span>reason: <b>{{ debug.times.evaluations.lastCancel.reason }}</b></span><br/>\n </div>\n </div>\n </div>\n </div>\n\n\n <div v-if=\"debug.performances\" class=\"card card-performances\">\n <div class=\"card-header\" id=\"debug-node-performances\" data-toggle=\"collapse\" data-target=\"#debug-node-performances-collapse\" aria-expanded=\"false\" aria-controls=\"debug-node-performances-collapse\">\n <h5 class=\"mb-0 btn-link\">Performances</h5>\n </div>\n\n <div id=\"debug-node-performances-collapse\" class=\"collapse\" aria-labelledby=\"debug-node-performances\" data-parent=\"#debug-node\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Stat</th>\n <th>Value</th>\n </thead>\n <tbody>\n <tr><td>min</td><td>{{debug.performances.min && debug.performances.min.toFixed(0)}}ms</td></tr>\n <tr><td>max</td><td>{{debug.performances.max && debug.performances.max.toFixed(0)}}ms</td></tr>\n <tr><td>avg</td><td>{{debug.performances.avg && debug.performances.avg.toFixed(0)}}ms</td></tr>\n <tr><td>total</td><td>{{debug.performances.total && debug.performances.total.toFixed(0)}}ms</td></tr>\n <tr><td>Nb of runs</td><td>{{debug.performances.nbRuns}}</td></tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"modal debug-json-modal\" tabindex=\"-1\" role=\"dialog\">\n <div class=\"modal-dialog\" role=\"document\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Value debugger</h5>\n <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"json-editor\" style=\"height: 400px;\"></div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary btn-save\">Save changes</button>\n <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n</template>\n\n<script>\nimport _ from 'lodash-es';\nimport moment from 'moment';\n\nimport DisplayValueVue from './displayValue.vue';\n\nexport default {\n props: [\n \"id\"\n ],\n components: {\n \"display-value\" : DisplayValueVue,\n },\n data: function () {\n return {\n \"n\" : null,\n \"debug\": null\n };\n },\n created: function() {\n this.view = window.dualboxEditor.v;\n this.n = this.view.m.getNode(this.id);\n this.debug = this.n.getSnapshot(); // shortcut\n },\n beforeUpdate: function() {\n this.n = this.view.m.getNode(this.id); // it breaks updating node name\n this.debug = this.n.getSnapshot(); // shortcut\n this.$forceupdate();\n },\n mounted: function() {\n\n },\n methods: {\n getSnapshotStatus : function(n) {\n if( this.n.isSnapshotStatus(0) ) return \"IDLE\";\n else if( this.n.isSnapshotStatus(1) ) return \"COMPUTING\";\n else if( this.n.isSnapshotStatus(2) ) return \"WAITING\";\n else if( this.n.isSnapshotStatus(3) ) return \"READY\";\n else throw \"Error: unknown status\";\n },\n\n getInputData: function(key) {\n return this.debug.data[key];\n },\n\n // show number if not null, undefined or 0\n showNumber: function(n) {\n return n? n: \"\";\n },\n\n showTime: function(d) {\n return moment(d).format('HH:mm:ss.SSS');\n }\n }\n}\n</script>\n"]}, media: undefined });
74743
+ inject("data-v-25f2255a_0", { source: "\n.card-debug .card-body {\n font-size: 12px;\n padding-left: 5px;\n padding-right: 5px;\n}\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/debugNodeInfos.vue"],"names":[],"mappings":";AACA;IACA,eAAA;IACA,iBAAA;IACA,kBAAA;AACA","file":"debugNodeInfos.vue","sourcesContent":["<style>\n .card-debug .card-body {\n font-size: 12px;\n padding-left: 5px;\n padding-right: 5px;\n }\n</style>\n\n<template>\n<div class=\"card-debug h100\" id=\"debug-node\">\n <div style=\"padding-left: 10px; padding-top: 10px; padding-right: 10px;\">\n <h2 class=\"edit-dualbox-node-id\">\n <div class=\"dualbox-node-name\">\n <span class=\"text-truncate d-inline-block\" style=\"width: 290px\" :data-id=\"id\">{{n.graphId}}</span>\n </div>\n <div class=\"dualbox-node-name-edit\" style=\"display: none;\">\n <input type=\"text\" class=\"form-control dualbox-node-name-input\" style=\"display: inline-block;\" :value=\"n.graphId\" :data-type=\"n.type\" autofocus/>\n <button class=\"btn btn-primary btn-save-node-name-change\" :data-id=\"n.graphId\" :data-type=\"n.type\" style=\"display: inline-block;\">Save</button>\n </div>\n </h2>\n <p><small class=\"edit-dualbox-node-package-name\">{{n.getPackageName()}}</small></p>\n </div>\n\n <div class=\"edit-body\">\n <div class=\"card card-state\">\n <div class=\"card-header\" id=\"debug-node-state\" data-toggle=\"collapse\" data-target=\"#debug-node-state-collapse\" aria-expanded=\"true\" aria-controls=\"debug-node-state-collapse\">\n <h5 class=\"mb-0 btn-link\">State</h5>\n </div>\n\n <div id=\"debug-node-state-collapse\" class=\"collapse show\" aria-labelledby=\"debug-node-state\" data-parent=\"#debug-node\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Key</th>\n <th>Value</th>\n </thead>\n <tbody>\n <tr>\n <td>status</td>\n <td><span :class=\"{'card-status-idle':n.isSnapshotStatus(0),'card-status-computing':n.isSnapshotStatus(1),'card-status-awaiting-data':n.isSnapshotStatus(2), 'card-status-ready':n.isSnapshotStatus(3)}\">{{ getSnapshotStatus(n) }}</span></td>\n </tr>\n <tr><td>invalidateSent</td><td>{{debug.state.invalidateSent}}</td></tr>\n <tr><td>readSent</td><td>{{debug.state.readSent}}</td></tr>\n <tr><td>allowedToRestart</td><td>{{debug.state.allowedToRestart}}</td></tr>\n <tr><td>evaluating</td><td>{{debug.state.evaluating}}</td></tr>\n <tr><td>initialized</td><td>{{debug.state.initialized}}</td></tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n\n <div v-if=\"n.hasInputs()\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"debug-node-inputs\" data-toggle=\"collapse\" data-target=\"#debug-node-inputs-collapse\" aria-expanded=\"false\" aria-controls=\"debug-node-inputs-collapse\">\n <h5 class=\"mb-0 btn-link\">Data <small><span class=\"badge badge-secondary\">{{ n.getInputsNames().length }}</span></small></h5>\n </div>\n <div id=\"debug-node-inputs-collapse\" class=\"collapse\" aria-labelledby=\"debug-node-inputs\" data-parent=\"#debug-node\">\n <div class=\"card-body\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Input</th>\n <th>Valid</th>\n <th>Type</th>\n <th>Value</th>\n <th>Default</th>\n </thead>\n <tbody>\n <tr v-for=\"key in n.getInputsNames()\" :key=\"n.id + '-input-' + key\">\n <td>\n {{key}}\n <button v-if=\"n.hasInputDesc(key)\" type=\"button\" class=\"btn btn-transparent\" data-toggle=\"tooltip\" data-placement=\"right\" :title=\"n.getInputDesc(key)\" style=\"padding: 0;\"><i class=\"text-info far fa-question-circle\"></i></button>\n </td>\n <td>{{ getInputData(key).valid }}</td>\n <td>\n <template v-if=\"getInputData(key).value\">\n <template v-if=\"getInputData(key).value.metadata && getInputData(key).value.metadata.type\">{{getInputData(key).value.metadata}}</template>\n <template v-else>{{typeof n.m.getSnapshotValue(getInputData(key).value) }}</template>\n </template>\n </td>\n <td>\n <template v-if=\"getInputData(key).value\">\n <display-value :v=\"n.m.getSnapshotValue(getInputData(key).value)\"></display-value>\n </template>\n </td>\n <td>\n <template v-if=\"getInputData(key).default\">\n <display-value :v=\"n.m.getSnapshotValue(getInputData(key).default)\"></display-value>\n </template>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <div v-if=\"debug.cache\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"debug-node-cache\" data-toggle=\"collapse\" data-target=\"#debug-node-cache-collapse\" aria-expanded=\"false\" aria-controls=\"debug-node-cache-collapse\">\n <h5 class=\"mb-0 btn-link\">Cache</h5>\n </div>\n <div id=\"debug-node-cache-collapse\" class=\"collapse\" aria-labelledby=\"debug-node-cache\" data-parent=\"#debug-node\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Output</th>\n <th>Value</th>\n </thead>\n <tbody>\n <tr v-for=\"key in Object.keys(debug.cache)\" :key=\"n.id + '-cache-' + key\">\n <tr>\n <td>{{key}}</td>\n <td><display-value :v=\"n.m.getSnapshotValue(debug.cache[key])\"></display-value></td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <div v-if=\"debug.times && debug.times.emissions && (debug.times.emissions.lastRead || debug.times.emissions.lastInvalidate || debug.times.emissions.lastData )\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"debug-node-events\" data-toggle=\"collapse\" data-target=\"#debug-node-events-collapse\" aria-expanded=\"false\" aria-controls=\"debug-node-events-collapse\">\n <h5 class=\"mb-0 btn-link\">Last events</h5>\n </div>\n <div id=\"debug-node-events-collapse\" class=\"collapse\" aria-labelledby=\"debug-node-events\" data-parent=\"#debug-node\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n\n <div v-if=\"debug.times.emissions.lastRead\" class=\"mb-3\">\n <p><b><u>Last read {{showNumber(debug.times.emissions.nbRead)}}</u> <span class=\"float-right\">{{ showTime(debug.times.emissions.lastRead.date) }}</span></b></p>\n <span>Missing: <b>{{ debug.times.emissions.lastRead.data.join(', ') }}</b></span><br/>\n </div>\n\n <div v-if=\"debug.times.emissions.lastInvalidate\" class=\"mb-3\">\n <p><b><u>Last Invalidate {{showNumber(debug.times.emissions.nbInvalidate)}}</u> <span class=\"float-right\">{{ showTime(debug.times.emissions.lastInvalidate.date) }}</span></b></p>\n <span>Invalidated keys: <b>{{ debug.times.emissions.lastInvalidate.data.join(', ') }}</b></span><br/>\n </div>\n\n <div v-if=\"debug.times.emissions.lastData\" class=\"mb-3\">\n <p><b><u>Last Data {{ showNumber(debug.times.emissions.nbData) }}</u> <span class=\"float-right\">{{ showTime(debug.times.emissions.lastData.date) }}</span></b></p>\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Output</th>\n <th>Value</th>\n </thead>\n <tbody>\n <tr v-for=\"key in Object.keys(debug.times.emissions.lastData.data)\" :key=\"n.id + '-cache-' + key\">\n <td>{{key}}</td>\n <td><display-value :v=\"n.m.getSnapshotValue(debug.times.emissions.lastData.data[key])\"></display-value></td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n\n <div v-if=\"debug.times && debug.times.evaluations && (debug.times.evaluations.lastStart || debug.times.evaluations.lastEnd || debug.times.evaluations.lastCancel )\" class=\"card card-settings\">\n <div class=\"card-header\" id=\"debug-node-evaluations\" data-toggle=\"collapse\" data-target=\"#debug-node-evaluations-collapse\" aria-expanded=\"false\" aria-controls=\"debug-node-evaluations-collapse\">\n <h5 class=\"mb-0 btn-link\">Last evaluations</h5>\n </div>\n <div id=\"debug-node-evaluations-collapse\" class=\"collapse\" aria-labelledby=\"debug-node-evaluations\" data-parent=\"#debug-node\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n\n <div v-if=\"debug.times.evaluations.lastStart\" class=\"mb-3\">\n <p><b><u>Last start</u> <span class=\"float-right\">{{ showTime(debug.times.evaluations.lastStart.date) }}</span></b></p>\n </div>\n\n <div v-if=\"debug.times.evaluations.lastEnd\" class=\"mb-3\">\n <p><b><u>Last end</u> <span class=\"float-right\">{{ showTime(debug.times.evaluations.lastEnd.date) }}</span></b></p>\n </div>\n\n <div v-if=\"debug.times.evaluations.lastCancel\" class=\"mb-3\">\n <p><b><u>Last Cancel</u> <span class=\"float-right\">{{ showTime(debug.times.evaluations.lastCancel.date) }}</span></b></p>\n <span>reason: <b>{{ debug.times.evaluations.lastCancel.reason }}</b></span><br/>\n </div>\n </div>\n </div>\n </div>\n\n\n <div v-if=\"debug.performances\" class=\"card card-performances\">\n <div class=\"card-header\" id=\"debug-node-performances\" data-toggle=\"collapse\" data-target=\"#debug-node-performances-collapse\" aria-expanded=\"false\" aria-controls=\"debug-node-performances-collapse\">\n <h5 class=\"mb-0 btn-link\">Performances</h5>\n </div>\n\n <div id=\"debug-node-performances-collapse\" class=\"collapse\" aria-labelledby=\"debug-node-performances\" data-parent=\"#debug-node\">\n <div class=\"card-body\" style=\"padding-left: 15px;\">\n <table class=\"table-desc table-striped\">\n <thead class=\"thead-dark\">\n <th>Stat</th>\n <th>Value</th>\n </thead>\n <tbody>\n <tr><td>min</td><td>{{debug.performances.min && debug.performances.min.toFixed(0)}}ms</td></tr>\n <tr><td>max</td><td>{{debug.performances.max && debug.performances.max.toFixed(0)}}ms</td></tr>\n <tr><td>avg</td><td>{{debug.performances.avg && debug.performances.avg.toFixed(0)}}ms</td></tr>\n <tr><td>total</td><td>{{debug.performances.total && debug.performances.total.toFixed(0)}}ms</td></tr>\n <tr><td>Nb of runs</td><td>{{debug.performances.nbRuns}}</td></tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"modal debug-json-modal\" tabindex=\"-1\" role=\"dialog\">\n <div class=\"modal-dialog\" role=\"document\">\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Value debugger</h5>\n <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n <div class=\"json-editor\" style=\"height: 400px;\"></div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-primary btn-save\">Save changes</button>\n <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n</template>\n\n<script>\nimport _ from 'lodash-es';\nimport moment from 'moment';\n\nimport DisplayValueVue from './displayValue.vue';\n\nexport default {\n props: [\n \"id\"\n ],\n components: {\n \"display-value\" : DisplayValueVue,\n },\n data: function () {\n return {\n \"n\" : null,\n \"debug\": null\n };\n },\n created: function() {\n this.view = window.dualboxEditor.v;\n this.n = this.view.m.getNode(this.id);\n this.debug = this.n.getSnapshot(); // shortcut\n },\n beforeUpdate: function() {\n this.n = this.view.m.getNode(this.id); // it breaks updating node name\n this.debug = this.n.getSnapshot(); // shortcut\n },\n mounted: function() {\n\n },\n methods: {\n getSnapshotStatus : function(n) {\n if( this.n.isSnapshotStatus(0) ) return \"IDLE\";\n else if( this.n.isSnapshotStatus(1) ) return \"COMPUTING\";\n else if( this.n.isSnapshotStatus(2) ) return \"WAITING\";\n else if( this.n.isSnapshotStatus(3) ) return \"READY\";\n else throw \"Error: unknown status\";\n },\n\n getInputData: function(key) {\n return this.debug.data[key];\n },\n\n // show number if not null, undefined or 0\n showNumber: function(n) {\n return n? n: \"\";\n },\n\n showTime: function(d) {\n return moment(d).format('HH:mm:ss.SSS');\n }\n }\n}\n</script>\n"]}, media: undefined });
74700
74744
 
74701
74745
  };
74702
74746
  /* scoped */
@@ -74707,16 +74751,20 @@ __vue_render__$c._withStripped = true;
74707
74751
  const __vue_is_functional_template__$c = false;
74708
74752
  /* style inject SSR */
74709
74753
 
74754
+ /* style inject shadow dom */
74755
+
74710
74756
 
74711
74757
 
74712
- var debugNodeInfosVue = normalizeComponent_1(
74758
+ const __vue_component__$c = normalizeComponent_1(
74713
74759
  { render: __vue_render__$c, staticRenderFns: __vue_staticRenderFns__$c },
74714
74760
  __vue_inject_styles__$c,
74715
74761
  __vue_script__$c,
74716
74762
  __vue_scope_id__$c,
74717
74763
  __vue_is_functional_template__$c,
74718
74764
  __vue_module_identifier__$c,
74765
+ false,
74719
74766
  browser,
74767
+ undefined,
74720
74768
  undefined
74721
74769
  );
74722
74770
 
@@ -86795,11 +86843,11 @@ var script$d = {
86795
86843
  'eventVisibility' // are events visible
86796
86844
  ],
86797
86845
  components: {
86798
- 'graph-vue': graphVue,
86799
- 'add-node-vue': addNodeVue,
86800
- 'edit-main-settings': editMainSettingsVue,
86801
- 'edit-node-settings': editNodeSettingsVue,
86802
- 'debug-node-infos': debugNodeInfosVue,
86846
+ 'graph-vue': __vue_component__$1,
86847
+ 'add-node-vue': __vue_component__$5,
86848
+ 'edit-main-settings': __vue_component__$a,
86849
+ 'edit-node-settings': __vue_component__$b,
86850
+ 'debug-node-infos': __vue_component__$c,
86803
86851
  },
86804
86852
  data() {
86805
86853
  return {
@@ -86928,8 +86976,9 @@ var script$d = {
86928
86976
  removeTryCatch: $(this.$el).find('.run-removetrycatch').is(':checked'),
86929
86977
  makeSynchrone: $(this.$el).find('.run-makesynchrone').is(':checked'),
86930
86978
  record: $(this.$el).find('.run-record').is(':checked'),
86979
+ ressourceCaching: $(this.$el).find('.run-ressourcecaching').is(':checked'),
86931
86980
  }
86932
- }
86981
+ },
86933
86982
  }
86934
86983
  },
86935
86984
 
@@ -88053,6 +88102,13 @@ var __vue_render__$d = function() {
88053
88102
  }),
88054
88103
  _vm._v("Make Synchrone"),
88055
88104
  _vm._v(" "),
88105
+ _c("input", {
88106
+ staticClass:
88107
+ "form-control run-ressourcecaching mr-1 ml-3",
88108
+ attrs: { type: "checkbox" }
88109
+ }),
88110
+ _vm._v("Ressource caching"),
88111
+ _vm._v(" "),
88056
88112
  _c("div", { staticClass: "ml-auto" }, [
88057
88113
  _c("input", {
88058
88114
  staticClass: "form-control run-profiler mr-1 ml-3",
@@ -88194,7 +88250,7 @@ __vue_render__$d._withStripped = true;
88194
88250
  /* style */
88195
88251
  const __vue_inject_styles__$d = function (inject) {
88196
88252
  if (!inject) return
88197
- inject("data-v-357e9fe8_0", { source: "\n.code-panel {\n width: 30%;\n height: 100%;\n vertical-align: top;\n float: left;\n}\n.application-container {\n width: calc(70% - 5px);\n height: 100%;\n display: inline-block;\n vertical-align: top;\n float: right;\n}\n.code-controls,\n.run-options {\n width: 100%;\n height: 60px;\n}\n.application {\n width: 100%;\n height: calc(100% - 60px);\n background-color: #ccc;\n}\n.dragbar {\n height: 100%;\n width: 5px;\n background-color: #e7e7e7;\n display: inline-block;\n cursor: col-resize;\n}\n.code-content {\n position: relative;\n height: calc(100% - 56px);\n}\n.code-html-container {\n position: relative;\n height: 50%;\n border-bottom: 1px solid #e7e7e7;\n}\n.code-css-container {\n position: relative;\n height: calc(50% - 1px);\n overflow: hidden;\n}\n.code-css {\n width: 100%;\n height: 100%;\n}\n.code-html {\n height: calc(100% - 40px);\n width: 100%;\n}\n.CodeMirror {\n height: 100% !important;\n}\n.code-badge {\n position: absolute;\n top: 10px;\n right: 10px;\n padding: 10px;\n}\n.btn-light.focus,\n.btn-light:focus {\n box-shadow: none !important;\n}\n.button-bar {\n width: 60px;\n padding: 10px;\n border-bottom: 1px solid #e7e7e7;\n width: 100%;\n background-color: white;\n}\n.noselect {\n -webkit-user-select: none;\n /* Chrome/Safari */\n -moz-user-select: none;\n /* Firefox */\n -ms-user-select: none;\n /* IE10+ */\n -o-user-select: none;\n user-select: none;\n}\n.btn+.btn {\n margin-left: 5px;\n}\n.btn-graph-goto {\n box-shadow: none !important;\n}\n.nav-tabs {\n border-bottom: none;\n}\n.main-navigation a.nav-link {\n color: white;\n}\n.main-navigation a.nav-link.active {\n color: #212529;\n}\n.dualbox-editor-body {\n width: 100%;\n height: 100%;\n overflow: hidden;\n background-color: rgb(85, 85, 85);\n}\n.dualbox-graph-left-section {\n height: 100%;\n width: 500px;\n float: left;\n position: relative;\n overflow: hidden;\n margin-left: -465px;\n transition: margin-left 0.3s ease;\n}\n.dualbox-graph-left-window {\n width: calc(100% - 35px);\n height: calc(100% - 10px);\n margin-top: 10px;\n /* background-color: #ECF2F8; */\n background-color: #f8f9fa;\n /* border: 1px solid grey; */\n border-radius: 5px;\n position: relative;\n float: left;\n}\n.dualbox-graph-left-panel {\n width: 100%;\n height: 100%;\n}\n.btn-toggle-left-window {\n position: absolute;\n right: 0;\n top: 0;\n margin-right: -35px;\n z-index: 100;\n border-top-left-radius: 0px;\n border-bottom-left-radius: 0px;\n}\n.btn-toggle-left-window:hover,\n.btn-toggle-right-window:hover,\n.btn-toggle-left-window:focus,\n.btn-toggle-right-window:focus,\n.btn-toggle-left-window:active,\n.btn-toggle-right-window:active,\n.btn-toggle-left-window:active:hover,\n.btn-toggle-right-window:active:hover {\n color: #212529 !important;\n background-color: #f8f9fa !important;\n border-color: #f8f9fa !important;\n}\n.dualbox-graph-right-section {\n height: 100%;\n width: 500px;\n float: right;\n position: relative;\n overflow: hidden;\n margin-right: -465px;\n transition: margin-right 0.3s ease;\n}\n.dualbox-graph-right-window {\n width: calc(100% - 35px);\n height: calc(100% - 20px);\n margin-top: 10px;\n margin-bottom: 30px;\n /* background-color: #ECF2F8; */\n background-color: #f8f9fa;\n /* border: 1px solid grey; */\n border-radius: 5px;\n position: relative;\n float: right;\n}\n.dualbox-graph-right-panel {\n width: 100%;\n height: 100%;\n}\n.btn-toggle-right-window {\n position: absolute;\n left: 0;\n top: 0;\n margin-left: -35px;\n z-index: 100;\n border-top-right-radius: 0px;\n border-bottom-right-radius: 0px;\n}\n.dualbox-graph-tab {\n height: 100%;\n width: 100%;\n background-color: #555 !important;\n}\n.dualbox-graph-main {\n height: 100%;\n width: calc(100% - 70px);\n float: right;\n background-color: #555 !important;\n transition: width 0.3s ease;\n}\n.dualbox-graph-main.left-panel-expanded {\n width: calc(100% - 535px);\n margin-left: -465px;\n}\n.dualbox-graph-main.right-panel-expanded {\n width: calc(100% - 535px);\n}\n.dualbox-graph-main.left-panel-expanded.right-panel-expanded {\n width: calc(100% - 1000px);\n margin-left: -465px;\n}\n.opacity0 {\n opacity: 0;\n}\n.btn-editor-xs {\n width: 18px;\n padding: 3px !important;\n line-height: .5;\n border-radius: 2px;\n}\n.btn-editor-xs>i {\n font-size: 10px;\n}\n.btn-outline-discrete {\n border-color: rgba(0, 0, 0, 0.05);\n border-color: transparent;\n color: rgba(0, 0, 0, 0.3);\n}\n.dualbox-app-navigation {\n background-color: transparent;\n margin-bottom: 0;\n vertical-align: middle;\n padding-top: 7px;\n padding-bottom: 7px;\n font-weight: bold;\n user-select: none;\n}\n.app-topbar {\n border-bottom: none;\n padding-left: 15px;\n padding-right: 15px;\n display: flex;\n width: 100%;\n height: 58px;\n padding-top: 10px;\n padding-bottom: 10px;\n}\n.dark,\n.graph-tab.active,\n.nav-item.active .graph-tab {\n color: white !important;\n background-color: #555 !important;\n}\n.light {\n color: #4d4d4d !important;\n background-color: #f8f9fa !important;\n}\n.main-navigation .nav-link,\n.main-navigation .nav-link.active,\n.nav-item.active .nav-link {\n border-bottom: none;\n border-left: none;\n border-top: none;\n border-right: none;\n position: relative;\n top: 1px;\n}\n.btn:focus,\nbutton:focus {\n outline: none;\n box-shadow: none;\n}\n.btn-transparent,\n.btn-transparent:hover,\n.btn-transparent:focus {\n background-color: transparent;\n}\n.connection-control {\n position: absolute;\n height: 14px;\n width: 14px;\n background-color: transparent;\n z-index: 19;\n cursor: move;\n}\n.connection-control.selected {\n border-color: #0066ff;\n box-shadow: 1px 1px 10px #0066ff;\n}\n.connection-label {\n z-index: 22 !important;\n color: #004d00 !important;\n background-color: white !important;\n padding: 4px 4px;\n border: 2px solid #004d00;\n font-size: 16px !important;\n border-radius: 5px;\n}\n.input-color-tag {\n background-color: #F2D600;\n}\n.output-color-tag {\n background-color: #FFAB4A;\n}\n.ui-color-tag {\n background-color: #61BD4F;\n}\n.metanode-color-tag {\n background-color: #DDDDDD;\n}\n.input {}\n.output {}\n.fileUpload {\n position: relative;\n overflow: hidden;\n margin: 10px;\n}\n.fileUpload input.upload {\n position: absolute;\n top: 0;\n right: 0;\n margin: 0;\n padding: 0;\n font-size: 20px;\n cursor: pointer;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.module-edit-modal-body .btn+.btn {\n margin-bottom: 0;\n margin-left: 5px;\n}\n.btn-add-node {\n width: 46%;\n margin: 1%;\n}\nbutton.close {\n position: absolute;\n right: 0;\n margin-right: 5px !important;\n}\n.CodeMirror {\n height: auto;\n min-height: 300px;\n}\n.load-app,\n.save-app {\n margin-left: 5px;\n margin-right: 5px;\n}\n.btn-xs {\n padding: 0px 4px;\n font-size: 12px;\n}\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/main.vue"],"names":[],"mappings":";AACA;IACA,UAAA;IACA,YAAA;IACA,mBAAA;IACA,WAAA;AACA;AAEA;IACA,sBAAA;IACA,YAAA;IACA,qBAAA;IACA,mBAAA;IACA,YAAA;AACA;AAEA;;IAEA,WAAA;IACA,YAAA;AACA;AAEA;IACA,WAAA;IACA,yBAAA;IACA,sBAAA;AACA;AAEA;IACA,YAAA;IACA,UAAA;IACA,yBAAA;IACA,qBAAA;IACA,kBAAA;AACA;AAEA;IACA,kBAAA;IACA,yBAAA;AACA;AAEA;IACA,kBAAA;IACA,WAAA;IACA,gCAAA;AACA;AAEA;IACA,kBAAA;IACA,uBAAA;IACA,gBAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,yBAAA;IACA,WAAA;AACA;AAEA;IACA,uBAAA;AACA;AAEA;IACA,kBAAA;IACA,SAAA;IACA,WAAA;IACA,aAAA;AACA;AAEA;;IAEA,2BAAA;AACA;AAEA;IACA,WAAA;IACA,aAAA;IACA,gCAAA;IACA,WAAA;IACA,uBAAA;AACA;AAEA;IACA,yBAAA;IACA,kBAAA;IACA,sBAAA;IACA,YAAA;IACA,qBAAA;IACA,UAAA;IACA,oBAAA;IACA,iBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,2BAAA;AACA;AAEA;IACA,mBAAA;AACA;AAEA;IACA,YAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;IACA,gBAAA;IACA,iCAAA;AACA;AAEA;IACA,YAAA;IACA,YAAA;IACA,WAAA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;IACA,iCAAA;AACA;AAEA;IACA,wBAAA;IACA,yBAAA;IACA,gBAAA;IACA,+BAAA;IACA,yBAAA;IACA,4BAAA;IACA,kBAAA;IACA,kBAAA;IACA,WAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,QAAA;IACA,MAAA;IACA,mBAAA;IACA,YAAA;IACA,2BAAA;IACA,8BAAA;AACA;AAEA;;;;;;;;IAQA,yBAAA;IACA,oCAAA;IACA,gCAAA;AACA;AAEA;IACA,YAAA;IACA,YAAA;IACA,YAAA;IACA,kBAAA;IACA,gBAAA;IACA,oBAAA;IACA,kCAAA;AACA;AAEA;IACA,wBAAA;IACA,yBAAA;IACA,gBAAA;IACA,mBAAA;IACA,+BAAA;IACA,yBAAA;IACA,4BAAA;IACA,kBAAA;IACA,kBAAA;IACA,YAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,OAAA;IACA,MAAA;IACA,kBAAA;IACA,YAAA;IACA,4BAAA;IACA,+BAAA;AACA;AAEA;IACA,YAAA;IACA,WAAA;IACA,iCAAA;AACA;AAEA;IACA,YAAA;IACA,wBAAA;IACA,YAAA;IACA,iCAAA;IACA,2BAAA;AACA;AAEA;IACA,yBAAA;IACA,mBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,0BAAA;IACA,mBAAA;AACA;AAEA;IACA,UAAA;AACA;AAEA;IACA,WAAA;IACA,uBAAA;IACA,eAAA;IACA,kBAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,iCAAA;IACA,yBAAA;IACA,yBAAA;AACA;AAEA;IACA,6BAAA;IACA,gBAAA;IACA,sBAAA;IACA,gBAAA;IACA,mBAAA;IACA,iBAAA;IACA,iBAAA;AACA;AAEA;IACA,mBAAA;IACA,kBAAA;IACA,mBAAA;IACA,aAAA;IACA,WAAA;IACA,YAAA;IACA,iBAAA;IACA,oBAAA;AACA;AAEA;;;IAGA,uBAAA;IACA,iCAAA;AACA;AAEA;IACA,yBAAA;IACA,oCAAA;AACA;AAEA;;;IAGA,mBAAA;IACA,iBAAA;IACA,gBAAA;IACA,kBAAA;IACA,kBAAA;IACA,QAAA;AACA;AAEA;;IAEA,aAAA;IACA,gBAAA;AACA;AAEA;;;IAGA,6BAAA;AACA;AAEA;IACA,kBAAA;IACA,YAAA;IACA,WAAA;IACA,6BAAA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,qBAAA;IACA,gCAAA;AACA;AAEA;IACA,sBAAA;IACA,yBAAA;IACA,kCAAA;IACA,gBAAA;IACA,yBAAA;IACA,0BAAA;IACA,kBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA,QAAA;AAEA,SAAA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,QAAA;IACA,SAAA;IACA,UAAA;IACA,eAAA;IACA,eAAA;IACA,UAAA;IACA,wBAAA;AACA;AAEA;IACA,gBAAA;IACA,gBAAA;AACA;AAEA;IACA,UAAA;IACA,UAAA;AACA;AAEA;IACA,kBAAA;IACA,QAAA;IACA,4BAAA;AACA;AAEA;IACA,YAAA;IACA,iBAAA;AACA;AAEA;;IAEA,gBAAA;IACA,iBAAA;AACA;AAEA;IACA,gBAAA;IACA,eAAA;AACA","file":"main.vue","sourcesContent":["<style>\n.code-panel {\n width: 30%;\n height: 100%;\n vertical-align: top;\n float: left;\n}\n\n.application-container {\n width: calc(70% - 5px);\n height: 100%;\n display: inline-block;\n vertical-align: top;\n float: right;\n}\n\n.code-controls,\n.run-options {\n width: 100%;\n height: 60px;\n}\n\n.application {\n width: 100%;\n height: calc(100% - 60px);\n background-color: #ccc;\n}\n\n.dragbar {\n height: 100%;\n width: 5px;\n background-color: #e7e7e7;\n display: inline-block;\n cursor: col-resize;\n}\n\n.code-content {\n position: relative;\n height: calc(100% - 56px);\n}\n\n.code-html-container {\n position: relative;\n height: 50%;\n border-bottom: 1px solid #e7e7e7;\n}\n\n.code-css-container {\n position: relative;\n height: calc(50% - 1px);\n overflow: hidden;\n}\n\n.code-css {\n width: 100%;\n height: 100%;\n}\n\n.code-html {\n height: calc(100% - 40px);\n width: 100%;\n}\n\n.CodeMirror {\n height: 100% !important;\n}\n\n.code-badge {\n position: absolute;\n top: 10px;\n right: 10px;\n padding: 10px;\n}\n\n.btn-light.focus,\n.btn-light:focus {\n box-shadow: none !important;\n}\n\n.button-bar {\n width: 60px;\n padding: 10px;\n border-bottom: 1px solid #e7e7e7;\n width: 100%;\n background-color: white;\n}\n\n.noselect {\n -webkit-user-select: none;\n /* Chrome/Safari */\n -moz-user-select: none;\n /* Firefox */\n -ms-user-select: none;\n /* IE10+ */\n -o-user-select: none;\n user-select: none;\n}\n\n.btn+.btn {\n margin-left: 5px;\n}\n\n.btn-graph-goto {\n box-shadow: none !important;\n}\n\n.nav-tabs {\n border-bottom: none;\n}\n\n.main-navigation a.nav-link {\n color: white;\n}\n\n.main-navigation a.nav-link.active {\n color: #212529;\n}\n\n.dualbox-editor-body {\n width: 100%;\n height: 100%;\n overflow: hidden;\n background-color: rgb(85, 85, 85);\n}\n\n.dualbox-graph-left-section {\n height: 100%;\n width: 500px;\n float: left;\n position: relative;\n overflow: hidden;\n margin-left: -465px;\n transition: margin-left 0.3s ease;\n}\n\n.dualbox-graph-left-window {\n width: calc(100% - 35px);\n height: calc(100% - 10px);\n margin-top: 10px;\n /* background-color: #ECF2F8; */\n background-color: #f8f9fa;\n /* border: 1px solid grey; */\n border-radius: 5px;\n position: relative;\n float: left;\n}\n\n.dualbox-graph-left-panel {\n width: 100%;\n height: 100%;\n}\n\n.btn-toggle-left-window {\n position: absolute;\n right: 0;\n top: 0;\n margin-right: -35px;\n z-index: 100;\n border-top-left-radius: 0px;\n border-bottom-left-radius: 0px;\n}\n\n.btn-toggle-left-window:hover,\n.btn-toggle-right-window:hover,\n.btn-toggle-left-window:focus,\n.btn-toggle-right-window:focus,\n.btn-toggle-left-window:active,\n.btn-toggle-right-window:active,\n.btn-toggle-left-window:active:hover,\n.btn-toggle-right-window:active:hover {\n color: #212529 !important;\n background-color: #f8f9fa !important;\n border-color: #f8f9fa !important;\n}\n\n.dualbox-graph-right-section {\n height: 100%;\n width: 500px;\n float: right;\n position: relative;\n overflow: hidden;\n margin-right: -465px;\n transition: margin-right 0.3s ease;\n}\n\n.dualbox-graph-right-window {\n width: calc(100% - 35px);\n height: calc(100% - 20px);\n margin-top: 10px;\n margin-bottom: 30px;\n /* background-color: #ECF2F8; */\n background-color: #f8f9fa;\n /* border: 1px solid grey; */\n border-radius: 5px;\n position: relative;\n float: right;\n}\n\n.dualbox-graph-right-panel {\n width: 100%;\n height: 100%;\n}\n\n.btn-toggle-right-window {\n position: absolute;\n left: 0;\n top: 0;\n margin-left: -35px;\n z-index: 100;\n border-top-right-radius: 0px;\n border-bottom-right-radius: 0px;\n}\n\n.dualbox-graph-tab {\n height: 100%;\n width: 100%;\n background-color: #555 !important;\n}\n\n.dualbox-graph-main {\n height: 100%;\n width: calc(100% - 70px);\n float: right;\n background-color: #555 !important;\n transition: width 0.3s ease;\n}\n\n.dualbox-graph-main.left-panel-expanded {\n width: calc(100% - 535px);\n margin-left: -465px;\n}\n\n.dualbox-graph-main.right-panel-expanded {\n width: calc(100% - 535px);\n}\n\n.dualbox-graph-main.left-panel-expanded.right-panel-expanded {\n width: calc(100% - 1000px);\n margin-left: -465px;\n}\n\n.opacity0 {\n opacity: 0;\n}\n\n.btn-editor-xs {\n width: 18px;\n padding: 3px !important;\n line-height: .5;\n border-radius: 2px;\n}\n\n.btn-editor-xs>i {\n font-size: 10px;\n}\n\n.btn-outline-discrete {\n border-color: rgba(0, 0, 0, 0.05);\n border-color: transparent;\n color: rgba(0, 0, 0, 0.3);\n}\n\n.dualbox-app-navigation {\n background-color: transparent;\n margin-bottom: 0;\n vertical-align: middle;\n padding-top: 7px;\n padding-bottom: 7px;\n font-weight: bold;\n user-select: none;\n}\n\n.app-topbar {\n border-bottom: none;\n padding-left: 15px;\n padding-right: 15px;\n display: flex;\n width: 100%;\n height: 58px;\n padding-top: 10px;\n padding-bottom: 10px;\n}\n\n.dark,\n.graph-tab.active,\n.nav-item.active .graph-tab {\n color: white !important;\n background-color: #555 !important;\n}\n\n.light {\n color: #4d4d4d !important;\n background-color: #f8f9fa !important;\n}\n\n.main-navigation .nav-link,\n.main-navigation .nav-link.active,\n.nav-item.active .nav-link {\n border-bottom: none;\n border-left: none;\n border-top: none;\n border-right: none;\n position: relative;\n top: 1px;\n}\n\n.btn:focus,\nbutton:focus {\n outline: none;\n box-shadow: none;\n}\n\n.btn-transparent,\n.btn-transparent:hover,\n.btn-transparent:focus {\n background-color: transparent;\n}\n\n.connection-control {\n position: absolute;\n height: 14px;\n width: 14px;\n background-color: transparent;\n z-index: 19;\n cursor: move;\n}\n\n.connection-control.selected {\n border-color: #0066ff;\n box-shadow: 1px 1px 10px #0066ff;\n}\n\n.connection-label {\n z-index: 22 !important;\n color: #004d00 !important;\n background-color: white !important;\n padding: 4px 4px;\n border: 2px solid #004d00;\n font-size: 16px !important;\n border-radius: 5px;\n}\n\n.input-color-tag {\n background-color: #F2D600;\n}\n\n.output-color-tag {\n background-color: #FFAB4A;\n}\n\n.ui-color-tag {\n background-color: #61BD4F;\n}\n\n.metanode-color-tag {\n background-color: #DDDDDD;\n}\n\n.input {}\n\n.output {}\n\n.fileUpload {\n position: relative;\n overflow: hidden;\n margin: 10px;\n}\n\n.fileUpload input.upload {\n position: absolute;\n top: 0;\n right: 0;\n margin: 0;\n padding: 0;\n font-size: 20px;\n cursor: pointer;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n\n.module-edit-modal-body .btn+.btn {\n margin-bottom: 0;\n margin-left: 5px;\n}\n\n.btn-add-node {\n width: 46%;\n margin: 1%;\n}\n\nbutton.close {\n position: absolute;\n right: 0;\n margin-right: 5px !important;\n}\n\n.CodeMirror {\n height: auto;\n min-height: 300px;\n}\n\n.load-app,\n.save-app {\n margin-left: 5px;\n margin-right: 5px;\n}\n\n.btn-xs {\n padding: 0px 4px;\n font-size: 12px;\n}\n</style>\n\n<template>\n<div class=\"dualbox-editor-body\">\n <nav class=\"main-navigation navbar navbar-default\" style=\"position: relative; margin-bottom: 0px; padding: 0; padding-top: 5px; background-color: #2e6da4;\">\n <ul class=\"nav nav-tabs\">\n <li class=\"nav-item active\">\n <a class=\"nav-link graph-tab\" href=\"#editor-graph-tab\" data-toggle=\"tab\">Application Graph</a>\n </li>\n <li class=\"nav-item\">\n <a class=\"nav-link interface-tab\" href=\"#editor-interface-tab\" data-toggle=\"tab\">Interface Editor</a>\n </li>\n </ul>\n\n <div class=\"nav navbar-right\" style=\"vertical-align: top; margin-top: 5px; margin-right: 10px; margin-bottom: 5px;\">\n <div v-if=\"showLoadButton === true\">\n <button class=\"load-app btn btn-sm btn-light\" style=\"position: relative; bottom: 3px;\" @click=\"loadApp\">Load App</button>\n </div>\n <div v-if=\"showSaveButton\">\n <button class=\"save-app btn btn-sm btn-light\" style=\"position: relative; bottom: 3px;\" @click=\"saveApp\">Save App</button>\n </div>\n </div>\n </nav>\n <div class=\"tab-content dualbox-graph-tab\" style=\"width: 100%; height: calc(100% - 46px);\">\n <div class=\"tab-pane active\" id=\"editor-graph-tab\" style=\"width: 100%; height: 100%;\">\n <div class=\"dualbox-graph-left-section dark\">\n <div class=\"dualbox-graph-left-window\">\n <button class=\"btn btn-light btn-toggle-left-window\" @click=\"toggleLeftWindow\" title=\"shrink window\" data-expanded=\"false\"><i class=\"fa fa-angle-double-right\"></i></button>\n <div class=\"dualbox-graph-left-panel light\">\n <edit-node-settings v-if=\"leftPanelMode == 'node' && selectedNodeId !== null\" :id=\"selectedNodeId\" :key=\"selectedNodeId\"></edit-node-settings>\n <edit-main-settings v-else-if=\"leftPanelMode == 'main'\" :app=\"getCurrentApplication()\" @edited=\"onEdited()\"></edit-main-settings>\n </div>\n </div>\n </div>\n <div class=\"dualbox-graph-right-section dark\">\n <div class=\"dualbox-graph-right-window\">\n <button class=\"btn btn-light btn-toggle-right-window\" @click=\"toggleRightWindow\" title=\"shrink window\" data-expanded=\"false\"><i class=\"fa fa-angle-double-left\"></i></button>\n <div class=\"dualbox-graph-right-panel light\">\n <debug-node-infos v-if=\"debugNodeId !== null\" :id=\"debugNodeId\"></debug-node-infos>\n </div>\n </div>\n </div>\n <div class=\"container-fluid dualbox-graph-main\" @click=\"setMainMenu\">\n <div class=\"row\">\n <div class=\"app-topbar dark\">\n <div class=\"justify-content-left\">\n <div class=\"dropdown\">\n <button class=\"btn btn-primary dropdown-toggle d-none\" type=\"button\" id=\"add-node-dropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" style=\"margin-right: 5px;\">\n Add\n </button>\n <div class=\"dropdown-menu\" aria-labelledby=\"add-node-dropdown\">\n <a class=\"dropdown-item add-box\" @click=\"addBox\" href=\"#\">Add box</a>\n <a class=\"dropdown-item add-metabox\" @click=\"addMetabox\" href=\"#\">Add metabox</a>\n <a class=\"dropdown-item add-input\" @click=\"addInput\" href=\"#\">Add input</a>\n <a class=\"dropdown-item add-output\" @click=\"addOutput\" href=\"#\">Add output</a>\n <a class=\"dropdown-item import-metabox\" @click=\"importMetabox\" href=\"#\">Import metabox</a>\n </div>\n <button class=\"btn btn-light btn-undo\" title=\"undo (ctrl-z)\" @click=\"undo\"><i class=\"fa fa-undo\"></i></button>\n <button class=\"btn btn-light btn-redo\" title=\"redo (ctrl-y)\" @click=\"redo\"><i class=\"fa fa-repeat fa-redo\"></i></button>\n <div class=\"form-check d-inline-block ml-2\">\n <label class=\"form-check-label\">\n <input class=\"form-check-input show-events\" type=\"checkbox\" value=\"false\" @click=\"showEvents\">\n <span class=\"noselect\">Show events</span>\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"justify-content-center mx-auto\">\n <ol class=\"dualbox-app-navigation breadcrumb\"></ol>\n </div>\n\n <div class=\"justify-content-right\">\n <div class=\"dropdown selection-menu\" style=\"display: none;\">\n <button class=\"btn btn-primary dropdown-toggle\" type=\"button\" id=\"selection-dropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\n Selection\n </button>\n <div class=\"dropdown-menu dropdown-menu-right\" aria-labelledby=\"add-node-dropdown\">\n <a class=\"dropdown-item dualbox-merge-selection\" @click=\"mergeSelection\" href=\"#\">Merge</a>\n <a class=\"dropdown-item dualbox-remove-selection\" @click=\"removeSelection\" href=\"#\" style=\"color: red;\">Delete</a>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"row\" style=\"height: calc(100% - 58px);\">\n <graph-vue :app=\"app\" ref=\"graph\" :displayEvents=\"displayEvents\"></graph-vue>\n </div>\n </div>\n </div>\n <div class=\"tab-pane\" id=\"editor-interface-tab\" style=\"width 100%; height: 100%; background-color: white;\">\n <div class=\"db-editor-main\" style=\"width: 100%; height: 100%; overflow: hidden;\">\n <div class=\"code-panel\">\n <div class=\"button-bar form-inline code-controls\" style=\"position: relative;\">\n <button class=\"btn btn-primary btn-save-interface-element\" @click=\"saveInterfaceElement\">Save changes</button>\n </div>\n <div class=\"code-content\">\n <div class=\"code-html-container\">\n <div style=\"padding-top: 5px; padding-bottom: 5px; height: 50px; position: relative;\">\n <h3 style=\"position: absolute; top: 0; margin: 5px; font-size: 16px; z-index: 100; display: inline-block; margin-top: 5px;\">HTML</h3>\n <div class=\"d-inline-block ml-auto form-inline mr-2 mt-2\" style=\"position: absolute; top: 0; right: 0;\">\n <button class=\"btn btn-success btn-sm btn-add-interface\" @click=\"addInterface\"><i class=\"fas fa-plus\"></i></button>\n <select class=\"form-control btn-sm app-interface-select\" @change=\"selectInterface\" style=\"width: 150px; height: 32px;\">\n <option>Load UI...</option>\n <option v-for=\"interfaceName in getInterfacesNames()\" :value=\"interfaceName\">{{interfaceName}}</option>\n </select>\n <button class=\"btn btn-sm btn-light btn-edit-panel-description\" @click=\"editPanelDescription\"><i class=\"fas fa-info\" style=\"padding-left: 8px; padding-right: 8px;\"></i></button>\n <button class=\"btn btn-danger btn-sm btn-remove-interface\" @click=\"removeInterface\"><i class=\"fas fa-minus\"></i></button>\n </div>\n </div>\n <div class=\"code-html-text-container\" style=\"position: relative; height: calc(100% - 50px);\">\n <textarea class=\"code-html\"></textarea>\n </div>\n </div>\n <div class=\"code-css-container\">\n <div style=\"height: 30px;\">\n <h3 style=\"position: absolute; top: 0; margin: 5px; font-size: 16px; z-index: 100;\">CSS</h3>\n </div>\n <div class=\"colde-css-text-container\" style=\"position: relative; height: calc(100% - 30px);\">\n <textarea class=\"code-css\" v-model=\"appCss\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"dragbar\"></div>\n <div class=\"application-container\">\n <div class=\"button-bar form-inline run-options\" style=\"position: relative;\">\n <button class=\"btn btn-success btn-run mr-2\" @click=\"runApp\">Run</button>\n\n <select class=\"form-control run-loglevel mr-1 ml-2\">\n <option>error</option>\n <option>warn</option>\n <option>info</option>\n <option>log</option>\n <option>debug</option>\n </select>\n\n <input class=\"form-control run-noversioncheck mr-1 ml-3\" type=\"checkbox\" checked>No version checking</input>\n <input class=\"form-control run-removetrycatch mr-1 ml-3\" type=\"checkbox\">Remove Try/catch</input>\n <input class=\"form-control run-makesynchrone mr-1 ml-3\" type=\"checkbox\">Make Synchrone</input>\n\n <div class=\"ml-auto\">\n <input class=\"form-control run-profiler mr-1 ml-3\" type=\"checkbox\">Profiler</input>\n <input class=\"form-control run-record mr-1 ml-3\" type=\"checkbox\">Record</input>\n <button class=\"btn btn-secondary btn-snapshot\" @click=\"takeAndLoadSnapshot\">Snapshot</button>\n </div>\n </div>\n <div class=\"application capture-left-click capture-right-click\"></div>\n </div>\n </div>\n </div>\n </div>\n <add-node-vue :display=\"this.addingBox\" :mousePosition=\"this.newBoxPosition\" @closed=\"onAddBoxClosed\"></add-node-vue>\n</div>\n</template>\n\n<script>\nimport _ from 'lodash-es';\nimport swal from 'sweetalert2';\n\nimport graphVue from './graph.vue';\nimport addNodeVue from './addNode.vue';\nimport editMainSettingsVue from './editMainSettings.vue';\nimport editNodeSettingsVue from './editNodeSettings.vue';\nimport debugNodeInfosVue from './debugNodeInfos.vue';\n\n// CodeMirror\nimport CodeMirror from 'codemirror/lib/codemirror.js';\nimport 'codemirror/mode/xml/xml.js';\nimport 'codemirror/mode/css/css.js';\nimport 'codemirror/mode/javascript/javascript.js';\nimport 'codemirror/mode/htmlmixed/htmlmixed.js';\n\nimport htmltool from '@dualbox/dualbox-lib-htmltool';\n\nexport default {\n props: [\n 'app', // the app\n\n // Display configuration (online or offline ?)\n 'showLoadButton',\n 'showSaveButton',\n 'saveButtonFunction',\n\n // modes\n 'eventVisibility' // are events visible\n ],\n components: {\n 'graph-vue': graphVue,\n 'add-node-vue': addNodeVue,\n 'edit-main-settings': editMainSettingsVue,\n 'edit-node-settings': editNodeSettingsVue,\n 'debug-node-infos': debugNodeInfosVue,\n },\n data() {\n return {\n // modes\n addingBox: false,\n leftPanelMode: 'main', // 'main' to display main menu, 'node' for a node\n selectedNodeId: null, // id of the node to display in left menu\n debugNodeId: null, // on a snapshot, id of the node to display debug infos\n newBoxPosition: null, // track mouse position relative to the graph when adding a node\n displayEvents: false,\n\n // the specific app css\n appCss: \"\",\n }\n },\n created: function () {\n this.view = window.dualboxEditor.v;\n // TODO: restore this when all menus are migrated to Vue.js\n\n this.cssCode = null;\n this.htmlCode = null;\n },\n updated: function () {\n //console.log('updating main view with: ' + JSON.stringify(this.app));\n this.appCss = (this.app && this.app.css) || \"\";\n\n // Update html and css code editor\n this.updateCode();\n },\n mounted: function () {\n //this.view.setMainMenu();\n\n $(this.$el).bind('expandSettings', function (e) {\n // expand\n $(this).find('.dualbox-graph-left-section').css('margin-left', '0');\n $(this).find('.dualbox-graph-main').addClass('left-panel-expanded');\n $(this).find('.btn-toggle-left-window').data('expanded', true).find('i')\n .removeClass('fa-angle-double-right')\n .addClass('fa-angle-double-left')\n .attr('title', 'shrink window');\n });\n\n $(this.$el).bind('shrinkSettings', function (e) {\n // shrink\n $(this).find('.dualbox-graph-left-section').css('margin-left', '-465px');\n $(this).find('.dualbox-graph-main').removeClass('left-panel-expanded');\n $(this).find('.btn-toggle-left-window').data('expanded', false).find('i')\n .removeClass('fa-angle-double-left')\n .addClass('fa-angle-double-right')\n .attr('title', 'expand window');\n });\n\n $(this.$el).bind('expandDebug', function (e) {\n // expand\n $(this).find('.dualbox-graph-right-section').css('margin-right', '0');\n $(this).find('.dualbox-graph-main').addClass('right-panel-expanded');\n $(this).find('.btn-toggle-right-window').data('expanded', true).find('i')\n .removeClass('fa-angle-double-left')\n .addClass('fa-angle-double-right')\n .attr('title', 'shrink window');\n });\n\n $(this.$el).bind('shrinkDebug', function (e) {\n // shrink\n $(this).find('.dualbox-graph-right-section').css('margin-right', '-465px');\n $(this).find('.dualbox-graph-main').removeClass('right-panel-expanded');\n $(this).find('.btn-toggle-right-window').data('expanded', false).find('i')\n .removeClass('fa-angle-double-right')\n .addClass('fa-angle-double-left')\n .attr('title', 'expand window');\n });\n\n // bind tabs\n var self = this;\n $(this.$el).find(\"a[data-toggle='tab']\").on(\"shown.bs.tab\", function (e) {\n var target = $(e.target).attr(\"href\") // activated tab\n if (target == \"#editor-graph-tab\") {\n self.view.killApp();\n } else if (target == \"#editor-interface-tab\") {\n self.htmlCode.refresh();\n self.cssCode.refresh();\n self.view.runApp(self.getOptions());\n }\n });\n\n $(this.$el).find(\"a[data-toggle='tab']\").on('click', function (e) {\n e.preventDefault()\n $(this).tab('show');\n });\n\n // Update html and css code editor\n this.updateCode();\n\n // Resize horizontally\n $(this.$el).find('.dragbar').mousedown(function (e) {\n e.preventDefault();\n $(document).mouseup(function (e) {\n $(document).unbind('mousemove');\n });\n $(document).mousemove(function (e) {\n $('.code-panel').css('width', e.pageX + \"px\");\n $('.application-container').css('width', ($(\".db-editor-main\").width() - e.pageX - 5) + \"px\");\n })\n });\n\n // prevent default behavior for ctrl+s / cmd+s\n $(document).keydown(function (event) {\n if ((event.ctrlKey || event.metaKey) && event.which == 83) {\n event.preventDefault();\n return false;\n }\n });\n },\n destroyed: function() {\n console.log('Graph vue destroyed');\n $('.ContextMenu').remove();\n },\n methods: {\n \"getOptions\": function () {\n return {\n profiler: $(this.$el).find('.run-profiler').is(':checked'),\n logLevel: $(this.$el).find('.run-loglevel').val(),\n options: {\n noVersionCheck: $(this.$el).find('.run-noversioncheck').is(':checked'),\n debug: {\n removeTryCatch: $(this.$el).find('.run-removetrycatch').is(':checked'),\n makeSynchrone: $(this.$el).find('.run-makesynchrone').is(':checked'),\n record: $(this.$el).find('.run-record').is(':checked'),\n }\n }\n }\n },\n\n \"updateCode\": function () {\n // instanciate codemirror for html and css\n if (!this.htmlCode) {\n this.htmlCode = CodeMirror.fromTextArea($(this.$el).find(\".code-html\")[0], {\n lineNumbers: true,\n mode: \"htmlmixed\",\n lineWrapping: true,\n extraKeys: {\n \"Ctrl-S\": () => {\n this.saveInterfaceElement();\n this.runApp();\n },\n \"Cmd-S\": () => {\n this.saveInterfaceElement();\n this.runApp();\n }\n }\n });\n }\n if (!this.cssCode) {\n this.cssCode = CodeMirror.fromTextArea($(this.$el).find(\".code-css\")[0], {\n lineNumbers: true,\n mode: \"css\",\n lineWrapping: true,\n extraKeys: {\n \"Ctrl-S\": () => {\n // save css code into app\n this.view.m.data.root.css = this.cssCode.getValue();\n this.runApp();\n },\n \"Cmd-S\": () => {\n // save css code into app\n this.view.m.data.root.css = this.cssCode.getValue();\n this.runApp();\n }\n }\n });\n }\n this.cssCode.setValue(this.view.m.get().css || \"\");\n },\n\n \"loadApp\": function () {\n var self = this;\n\n // create a fake input and click it to select a file\n var input = $('<input/>', {\n \"type\": \"file\",\n \"class\": \"upload\",\n \"accept\": \".json\"\n });\n input.change(function (e) {\n // if we're not here, go to 1st tab\n $(\"a[data-toggle='tab'][href='#editor-graph-tab']\").click();\n\n // parse the file JSON and load it\n var files = e.target.files; // FileList object\n var r = new FileReader();\n r.onload = function (e) {\n var contents = e.target.result;\n var json = JSON.parse(contents);\n self.view.e.setApp(json);\n };\n\n r.readAsText(files[0]);\n });\n input.click();\n },\n \"saveApp\": function () {\n // bind the app load\n if (this.saveButtonFunction) {\n var saveButtonFunction = (e) => {\n var json = this.view.m.getCleanJson();\n return this.saveButtonFunction(json);\n }\n } else {\n var saveButtonFunction = (e) => {\n var app = this.view.m.getCleanJson();\n var text = JSON.stringify(app, null, 2);\n var blob = new Blob([text], {\n \"type\": \"application/octet-stream\"\n });\n\n var a = document.createElement('a');\n a.href = window.URL.createObjectURL(blob);\n a.download = \"app.json\";\n\n // simulate a click on the link\n if (document.createEvent) {\n var event = document.createEvent(\"MouseEvents\");\n event.initEvent(\"click\", true, true);\n a.dispatchEvent(event);\n } else {\n a.click();\n }\n }\n }\n saveButtonFunction();\n },\n \"getCurrentMousePosition\": function (e) {\n return this.$refs.graph.getCurrentMousePosition(e);\n },\n \"addBox\": function (e) {\n this.addingBox = true;\n this.newBoxPosition = this.getCurrentMousePosition(e);\n this.$forceUpdate();\n },\n \"onAddBoxClosed\": function () {\n this.addingBox = false;\n this.$forceUpdate();\n },\n \"addMetabox\": function (e) {\n var self = this;\n e.preventDefault();\n e.stopPropagation();\n\n swal({\n input: 'text',\n title: 'Choose a name for the metabox',\n }).then(function (result) {\n if (result.value) {\n self.view.c.addNewMetabox(result.value);\n }\n });\n },\n \"addInput\": function (e) {\n this.view.c.createInput();\n },\n \"addOutput\": function (e) {\n this.view.c.createOutput();\n },\n \"importMetabox\": async function (e) {\n var self = this;\n\n const {\n value: file\n } = await swal({\n title: 'Select your metabox file',\n input: 'file',\n inputAttributes: {\n 'accept': 'application/json',\n 'aria-label': 'Select your metabox file'\n }\n })\n\n if (file) {\n const reader = new FileReader()\n reader.onload = (e) => {\n var json = JSON.parse(e.target.result);\n\n self.view.e.loadPackages(json).then(async () => {\n const {\n value: name\n } = await swal({\n title: 'Choose a name for your metabox',\n input: 'text',\n showCancelButton: true,\n inputValidator: (value) => {\n return !value && 'You need to write something!'\n }\n });\n\n self.view.c.addNewMetabox(name, json);\n }).catch((err) => {\n console.error(err);\n });\n }\n reader.readAsText(file)\n }\n },\n\n getInterfacesNames: function () {\n return _.keys(_.get(this.view.m, [\"data\", \"root\", \"interface\"]) || {});\n },\n\n \"selectInterface\": function (e) {\n // Load the interface HTML when selected\n var uiName = $(e.target).val();\n if (uiName !== \"\" && uiName !== \"Load UI...\") {\n var itf = this.view.m.data.root.interface;\n var htmlString = htmltool.json2html(itf[uiName]);\n var prettyString = htmltool.htmlPrettyPrint(htmlString);\n this.htmlCode.setValue(prettyString);\n } else {\n this.htmlCode.setValue(\"\");\n }\n },\n \"saveInterfaceElement\": function (e) {\n var currentInterface = $(this.$el).find('.app-interface-select').val();\n if (currentInterface !== \"\") {\n var currentHTML = this.htmlCode.getValue();\n\n // save html code into app\n this.view.m.data.root.interface[currentInterface] = htmltool.html2json(currentHTML);\n }\n\n // save css code into app\n this.view.m.data.root.css = this.cssCode.getValue();\n },\n \"addInterface\": function (e) {\n var self = this;\n\n swal.mixin({\n confirmButtonText: 'Next &rarr;',\n showCancelButton: true,\n progressSteps: ['1', '2', '3']\n }).queue([{\n input: 'text',\n title: 'Choose a name',\n text: 'Enter a name for the new interface'\n },\n {\n input: 'select',\n title: 'Choose the type',\n text: 'Is it a viewer panel or a control panel?',\n inputOptions: {\n 'control': 'A control panel',\n 'viewer': 'A viewer',\n },\n },\n {\n input: 'select',\n title: 'Choose the position',\n text: 'Where do you want to position your panel?',\n inputOptions: {\n 'top-left': 'At the top-left',\n 'top-center': 'At the top-center',\n 'top-right': 'At the top-right',\n 'center-left': 'At the center-left',\n 'center': 'At the center',\n 'center-right': 'At the center-right',\n 'bottom-left': 'At the bottom-left',\n 'bottom-center': 'At the bottom-center',\n 'bottom-right': 'At the bottom-right',\n 'whole-screen': 'I want my panel in full-screen',\n },\n }\n ]).then((result) => {\n if (result.value) {\n var name = result.value[0];\n var type = result.value[1];\n var position = result.value[2];\n\n if (name === \"\") {\n swal.showInputError(\"the name is empty!\");\n return false\n }\n\n var appInterface = self.view.m.data.root.interface;\n if (appInterface[name]) {\n swal.showInputError(\"Interface \" + name + \" already exists!\");\n return false\n } else {\n var style = {};\n switch (position) {\n case 'top-left':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'left': 0,\n 'margin': '15px'\n };\n break;\n case 'top-center':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'margin': '15px auto'\n };\n break;\n case 'top-right':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'right': 0,\n 'margin': '15px'\n };\n break;\n case 'center-left':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'bottom': 0,\n 'left': 0,\n 'margin': 'auto 15px'\n };\n break;\n case 'center':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'bottom': 0,\n 'left': 0,\n 'right': 0,\n 'margin': 'auto'\n };\n break;\n case 'center-right':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'bottom': 0,\n 'right': 0,\n 'margin': 'auto 15px'\n };\n break;\n case 'bottom-left':\n style = {\n 'position': 'absolute',\n 'bottom': 0,\n 'left': 0,\n 'margin': '15px'\n };\n break;\n case 'bottom-center':\n style = {\n 'position': 'absolute',\n 'bottom': 0,\n 'left': 0,\n 'right': 0,\n 'margin': '15px auto'\n };\n break;\n case 'bottom-right':\n style = {\n 'position': 'absolute',\n 'bottom': 0,\n 'right': 0,\n 'margin': '15px'\n };\n break;\n case 'whole-screen':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'left': 0\n };\n break;\n }\n\n // some prefilled data\n style['width'] = \"300px\";\n style['padding'] = \"15px\";\n style['border'] = \"1px solid #ccc\";\n style['border-radius'] = \"4px\";\n style['background'] = \"white\";\n if (position.startsWith(\"center\")) {\n style['height'] = \"60px\"; // must define height\n } else {\n style['height'] = \"auto\";\n }\n\n // add a basic control\n appInterface[name] = {\n type: \"Element\",\n tagName: \"div\",\n attributes: {\n className: [\n \"dualbox\",\n \"dualbox-container\",\n \"dualbox-container-\" + name,\n type == \"viewer\" ? \"dualbox-viewer\" : \"dualbox-controls\"\n ],\n style: style,\n },\n children: []\n }\n\n // add the value to our select, and load it\n $(self.$el).find(\".app-interface-select\").append(\n $(\"<option/>\", {\n \"value\": name\n }).append(name)\n );\n $(document).ready(() => {\n $(self.$el).find('.app-interface-select').val(name).change();\n\n // set it into the editor\n var htmlString = htmltool.json2html(appInterface[name]);\n var prettyString = htmltool.htmlPrettyPrint(htmlString);\n this.htmlCode.setValue(prettyString);\n self.updateCode();\n });\n\n self.view.runApp(self.getOptions());\n }\n }\n })\n },\n \"removeInterface\": function (e) {\n var self = this;\n var name = $('.app-interface-select').val();\n\n swal({\n title: \"Confirm deleting \" + name + \" ?\",\n type: \"warning\",\n showCancelButton: true,\n confirmButtonColor: \"#DD6B55\",\n confirmButtonText: \"Yes, delete it!\",\n closeOnConfirm: true,\n closeOnCancel: true\n }).then((result) => {\n if (result.value) {\n // set the interface back to first value\n $(this.$el).find(\".app-interface-select option[value='\" + name + \"']\").remove();\n $(this.$el).find(\".app-interface-select\").change();\n delete self.view.m.data.root.interface[name];\n self.htmlCode.setValue(\"\");\n self.view.runApp(self.getOptions());\n }\n });\n },\n \"editPanelDescription\": function (e) {\n var self = this;\n var name = $('.app-interface-select').val();\n\n swal({\n title: \"Enter a description for this panel!\",\n input: \"textarea\",\n inputValue: this.view.m.data.root.interface[name].description || \"\",\n showCancelButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true,\n animation: \"slide-from-top\",\n inputPlaceholder: \"Write something\"\n }).then((result) => {\n if (result.value === \"\") {\n swal.showInputError(\"You need to write something!\");\n return false\n } else {\n self.view.m.data.root.interface[name].description = result.value;\n }\n });\n },\n \"toggleLeftWindow\": function (e) {\n var expanded = $(e.target).closest('button').data('expanded');\n if (expanded) {\n $(this.$el).trigger('shrinkSettings');\n } else {\n $(this.$el).trigger('expandSettings');\n }\n },\n \"toggleRightWindow\": function (e) {\n var expanded = $(e.target).closest('button').data('expanded');\n if (expanded) {\n $(this.$el).trigger('shrinkDebug');\n } else {\n $(this.$el).trigger('expandDebug');\n }\n },\n\n \"showEvents\": function (e) {\n //this.view.setEventsVisibility( $(e.target).is(':checked') );\n this.displayEvents = $(e.target).is(':checked');\n },\n\n \"runApp\": function (e) {\n this.view.runApp(this.getOptions());\n },\n\n \"takeAndLoadSnapshot\": function (e) {\n this.view.takeAndLoadSnapshot();\n },\n\n \"undo\": function (e) {\n this.view.c.undo();\n },\n\n \"redo\": function (e) {\n this.view.c.redo();\n },\n\n \"removeSelection\": function (e) {\n this.view.c.deleteSelection();\n },\n\n \"mergeSelection\": function (e) {\n this.view.c.mergeSelection();\n },\n\n \"setMainMenu\": async function (e) {\n await this.view.setMainMenu();\n },\n\n \"getCurrentApplication\": function (e) {\n // trick to make this function reactive to \"app\" field update\n if (this.app) {\n return this.view.m.getCurrentApp(true);\n } else {\n throw \"Error: no app found\";\n }\n },\n\n \"onEdited\": function (e) {\n console.log('Something was edited, forcing new render');\n this.$forceUpdate();\n },\n\n \"ready\": function () {\n return new Promise(resolve => {\n this.$nextTick(() => {\n window.requestAnimationFrame(() => {\n $(this.$el).ready(resolve);\n })\n })\n })\n }\n }\n}\n</script>\n"]}, media: undefined });
88253
+ inject("data-v-8de0abf4_0", { source: "\n.code-panel {\n width: 30%;\n height: 100%;\n vertical-align: top;\n float: left;\n}\n.application-container {\n width: calc(70% - 5px);\n height: 100%;\n display: inline-block;\n vertical-align: top;\n float: right;\n}\n.code-controls,\n.run-options {\n width: 100%;\n height: 60px;\n}\n.application {\n width: 100%;\n height: calc(100% - 60px);\n background-color: #ccc;\n}\n.dragbar {\n height: 100%;\n width: 5px;\n background-color: #e7e7e7;\n display: inline-block;\n cursor: col-resize;\n}\n.code-content {\n position: relative;\n height: calc(100% - 56px);\n}\n.code-html-container {\n position: relative;\n height: 50%;\n border-bottom: 1px solid #e7e7e7;\n}\n.code-css-container {\n position: relative;\n height: calc(50% - 1px);\n overflow: hidden;\n}\n.code-css {\n width: 100%;\n height: 100%;\n}\n.code-html {\n height: calc(100% - 40px);\n width: 100%;\n}\n.CodeMirror {\n height: 100% !important;\n}\n.code-badge {\n position: absolute;\n top: 10px;\n right: 10px;\n padding: 10px;\n}\n.btn-light.focus,\n.btn-light:focus {\n box-shadow: none !important;\n}\n.button-bar {\n width: 60px;\n padding: 10px;\n border-bottom: 1px solid #e7e7e7;\n width: 100%;\n background-color: white;\n}\n.noselect {\n -webkit-user-select: none;\n /* Chrome/Safari */\n -moz-user-select: none;\n /* Firefox */\n -ms-user-select: none;\n /* IE10+ */\n -o-user-select: none;\n user-select: none;\n}\n.btn+.btn {\n margin-left: 5px;\n}\n.btn-graph-goto {\n box-shadow: none !important;\n}\n.nav-tabs {\n border-bottom: none;\n}\n.main-navigation a.nav-link {\n color: white;\n}\n.main-navigation a.nav-link.active {\n color: #212529;\n}\n.dualbox-editor-body {\n width: 100%;\n height: 100%;\n overflow: hidden;\n background-color: rgb(85, 85, 85);\n}\n.dualbox-graph-left-section {\n height: 100%;\n width: 500px;\n float: left;\n position: relative;\n overflow: hidden;\n margin-left: -465px;\n transition: margin-left 0.3s ease;\n}\n.dualbox-graph-left-window {\n width: calc(100% - 35px);\n height: calc(100% - 10px);\n margin-top: 10px;\n /* background-color: #ECF2F8; */\n background-color: #f8f9fa;\n /* border: 1px solid grey; */\n border-radius: 5px;\n position: relative;\n float: left;\n}\n.dualbox-graph-left-panel {\n width: 100%;\n height: 100%;\n}\n.btn-toggle-left-window {\n position: absolute;\n right: 0;\n top: 0;\n margin-right: -35px;\n z-index: 100;\n border-top-left-radius: 0px;\n border-bottom-left-radius: 0px;\n}\n.btn-toggle-left-window:hover,\n.btn-toggle-right-window:hover,\n.btn-toggle-left-window:focus,\n.btn-toggle-right-window:focus,\n.btn-toggle-left-window:active,\n.btn-toggle-right-window:active,\n.btn-toggle-left-window:active:hover,\n.btn-toggle-right-window:active:hover {\n color: #212529 !important;\n background-color: #f8f9fa !important;\n border-color: #f8f9fa !important;\n}\n.dualbox-graph-right-section {\n height: 100%;\n width: 500px;\n float: right;\n position: relative;\n overflow: hidden;\n margin-right: -465px;\n transition: margin-right 0.3s ease;\n}\n.dualbox-graph-right-window {\n width: calc(100% - 35px);\n height: calc(100% - 20px);\n margin-top: 10px;\n margin-bottom: 30px;\n /* background-color: #ECF2F8; */\n background-color: #f8f9fa;\n /* border: 1px solid grey; */\n border-radius: 5px;\n position: relative;\n float: right;\n}\n.dualbox-graph-right-panel {\n width: 100%;\n height: 100%;\n}\n.btn-toggle-right-window {\n position: absolute;\n left: 0;\n top: 0;\n margin-left: -35px;\n z-index: 100;\n border-top-right-radius: 0px;\n border-bottom-right-radius: 0px;\n}\n.dualbox-graph-tab {\n height: 100%;\n width: 100%;\n background-color: #555 !important;\n}\n.dualbox-graph-main {\n height: 100%;\n width: calc(100% - 70px);\n float: right;\n background-color: #555 !important;\n transition: width 0.3s ease;\n}\n.dualbox-graph-main.left-panel-expanded {\n width: calc(100% - 535px);\n margin-left: -465px;\n}\n.dualbox-graph-main.right-panel-expanded {\n width: calc(100% - 535px);\n}\n.dualbox-graph-main.left-panel-expanded.right-panel-expanded {\n width: calc(100% - 1000px);\n margin-left: -465px;\n}\n.opacity0 {\n opacity: 0;\n}\n.btn-editor-xs {\n width: 18px;\n padding: 3px !important;\n line-height: .5;\n border-radius: 2px;\n}\n.btn-editor-xs>i {\n font-size: 10px;\n}\n.btn-outline-discrete {\n border-color: rgba(0, 0, 0, 0.05);\n border-color: transparent;\n color: rgba(0, 0, 0, 0.3);\n}\n.dualbox-app-navigation {\n background-color: transparent;\n margin-bottom: 0;\n vertical-align: middle;\n padding-top: 7px;\n padding-bottom: 7px;\n font-weight: bold;\n user-select: none;\n}\n.app-topbar {\n border-bottom: none;\n padding-left: 15px;\n padding-right: 15px;\n display: flex;\n width: 100%;\n height: 58px;\n padding-top: 10px;\n padding-bottom: 10px;\n}\n.dark,\n.graph-tab.active,\n.nav-item.active .graph-tab {\n color: white !important;\n background-color: #555 !important;\n}\n.light {\n color: #4d4d4d !important;\n background-color: #f8f9fa !important;\n}\n.main-navigation .nav-link,\n.main-navigation .nav-link.active,\n.nav-item.active .nav-link {\n border-bottom: none;\n border-left: none;\n border-top: none;\n border-right: none;\n position: relative;\n top: 1px;\n}\n.btn:focus,\nbutton:focus {\n outline: none;\n box-shadow: none;\n}\n.btn-transparent,\n.btn-transparent:hover,\n.btn-transparent:focus {\n background-color: transparent;\n}\n.connection-control {\n position: absolute;\n height: 14px;\n width: 14px;\n background-color: transparent;\n z-index: 19;\n cursor: move;\n}\n.connection-control.selected {\n border-color: #0066ff;\n box-shadow: 1px 1px 10px #0066ff;\n}\n.connection-label {\n z-index: 22 !important;\n color: #004d00 !important;\n background-color: white !important;\n padding: 4px 4px;\n border: 2px solid #004d00;\n font-size: 16px !important;\n border-radius: 5px;\n}\n.input-color-tag {\n background-color: #F2D600;\n}\n.output-color-tag {\n background-color: #FFAB4A;\n}\n.ui-color-tag {\n background-color: #61BD4F;\n}\n.metanode-color-tag {\n background-color: #DDDDDD;\n}\n.input {}\n.output {}\n.fileUpload {\n position: relative;\n overflow: hidden;\n margin: 10px;\n}\n.fileUpload input.upload {\n position: absolute;\n top: 0;\n right: 0;\n margin: 0;\n padding: 0;\n font-size: 20px;\n cursor: pointer;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n.module-edit-modal-body .btn+.btn {\n margin-bottom: 0;\n margin-left: 5px;\n}\n.btn-add-node {\n width: 46%;\n margin: 1%;\n}\nbutton.close {\n position: absolute;\n right: 0;\n margin-right: 5px !important;\n}\n.CodeMirror {\n height: auto;\n min-height: 300px;\n}\n.load-app,\n.save-app {\n margin-left: 5px;\n margin-right: 5px;\n}\n.btn-xs {\n padding: 0px 4px;\n font-size: 12px;\n}\n", map: {"version":3,"sources":["/home/seb/dev/dualbox/editor/js/src/v/templates/main.vue"],"names":[],"mappings":";AACA;IACA,UAAA;IACA,YAAA;IACA,mBAAA;IACA,WAAA;AACA;AAEA;IACA,sBAAA;IACA,YAAA;IACA,qBAAA;IACA,mBAAA;IACA,YAAA;AACA;AAEA;;IAEA,WAAA;IACA,YAAA;AACA;AAEA;IACA,WAAA;IACA,yBAAA;IACA,sBAAA;AACA;AAEA;IACA,YAAA;IACA,UAAA;IACA,yBAAA;IACA,qBAAA;IACA,kBAAA;AACA;AAEA;IACA,kBAAA;IACA,yBAAA;AACA;AAEA;IACA,kBAAA;IACA,WAAA;IACA,gCAAA;AACA;AAEA;IACA,kBAAA;IACA,uBAAA;IACA,gBAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,yBAAA;IACA,WAAA;AACA;AAEA;IACA,uBAAA;AACA;AAEA;IACA,kBAAA;IACA,SAAA;IACA,WAAA;IACA,aAAA;AACA;AAEA;;IAEA,2BAAA;AACA;AAEA;IACA,WAAA;IACA,aAAA;IACA,gCAAA;IACA,WAAA;IACA,uBAAA;AACA;AAEA;IACA,yBAAA;IACA,kBAAA;IACA,sBAAA;IACA,YAAA;IACA,qBAAA;IACA,UAAA;IACA,oBAAA;IACA,iBAAA;AACA;AAEA;IACA,gBAAA;AACA;AAEA;IACA,2BAAA;AACA;AAEA;IACA,mBAAA;AACA;AAEA;IACA,YAAA;AACA;AAEA;IACA,cAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;IACA,gBAAA;IACA,iCAAA;AACA;AAEA;IACA,YAAA;IACA,YAAA;IACA,WAAA;IACA,kBAAA;IACA,gBAAA;IACA,mBAAA;IACA,iCAAA;AACA;AAEA;IACA,wBAAA;IACA,yBAAA;IACA,gBAAA;IACA,+BAAA;IACA,yBAAA;IACA,4BAAA;IACA,kBAAA;IACA,kBAAA;IACA,WAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,QAAA;IACA,MAAA;IACA,mBAAA;IACA,YAAA;IACA,2BAAA;IACA,8BAAA;AACA;AAEA;;;;;;;;IAQA,yBAAA;IACA,oCAAA;IACA,gCAAA;AACA;AAEA;IACA,YAAA;IACA,YAAA;IACA,YAAA;IACA,kBAAA;IACA,gBAAA;IACA,oBAAA;IACA,kCAAA;AACA;AAEA;IACA,wBAAA;IACA,yBAAA;IACA,gBAAA;IACA,mBAAA;IACA,+BAAA;IACA,yBAAA;IACA,4BAAA;IACA,kBAAA;IACA,kBAAA;IACA,YAAA;AACA;AAEA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,OAAA;IACA,MAAA;IACA,kBAAA;IACA,YAAA;IACA,4BAAA;IACA,+BAAA;AACA;AAEA;IACA,YAAA;IACA,WAAA;IACA,iCAAA;AACA;AAEA;IACA,YAAA;IACA,wBAAA;IACA,YAAA;IACA,iCAAA;IACA,2BAAA;AACA;AAEA;IACA,yBAAA;IACA,mBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,0BAAA;IACA,mBAAA;AACA;AAEA;IACA,UAAA;AACA;AAEA;IACA,WAAA;IACA,uBAAA;IACA,eAAA;IACA,kBAAA;AACA;AAEA;IACA,eAAA;AACA;AAEA;IACA,iCAAA;IACA,yBAAA;IACA,yBAAA;AACA;AAEA;IACA,6BAAA;IACA,gBAAA;IACA,sBAAA;IACA,gBAAA;IACA,mBAAA;IACA,iBAAA;IACA,iBAAA;AACA;AAEA;IACA,mBAAA;IACA,kBAAA;IACA,mBAAA;IACA,aAAA;IACA,WAAA;IACA,YAAA;IACA,iBAAA;IACA,oBAAA;AACA;AAEA;;;IAGA,uBAAA;IACA,iCAAA;AACA;AAEA;IACA,yBAAA;IACA,oCAAA;AACA;AAEA;;;IAGA,mBAAA;IACA,iBAAA;IACA,gBAAA;IACA,kBAAA;IACA,kBAAA;IACA,QAAA;AACA;AAEA;;IAEA,aAAA;IACA,gBAAA;AACA;AAEA;;;IAGA,6BAAA;AACA;AAEA;IACA,kBAAA;IACA,YAAA;IACA,WAAA;IACA,6BAAA;IACA,WAAA;IACA,YAAA;AACA;AAEA;IACA,qBAAA;IACA,gCAAA;AACA;AAEA;IACA,sBAAA;IACA,yBAAA;IACA,kCAAA;IACA,gBAAA;IACA,yBAAA;IACA,0BAAA;IACA,kBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA;IACA,yBAAA;AACA;AAEA,QAAA;AAEA,SAAA;AAEA;IACA,kBAAA;IACA,gBAAA;IACA,YAAA;AACA;AAEA;IACA,kBAAA;IACA,MAAA;IACA,QAAA;IACA,SAAA;IACA,UAAA;IACA,eAAA;IACA,eAAA;IACA,UAAA;IACA,wBAAA;AACA;AAEA;IACA,gBAAA;IACA,gBAAA;AACA;AAEA;IACA,UAAA;IACA,UAAA;AACA;AAEA;IACA,kBAAA;IACA,QAAA;IACA,4BAAA;AACA;AAEA;IACA,YAAA;IACA,iBAAA;AACA;AAEA;;IAEA,gBAAA;IACA,iBAAA;AACA;AAEA;IACA,gBAAA;IACA,eAAA;AACA","file":"main.vue","sourcesContent":["<style>\n.code-panel {\n width: 30%;\n height: 100%;\n vertical-align: top;\n float: left;\n}\n\n.application-container {\n width: calc(70% - 5px);\n height: 100%;\n display: inline-block;\n vertical-align: top;\n float: right;\n}\n\n.code-controls,\n.run-options {\n width: 100%;\n height: 60px;\n}\n\n.application {\n width: 100%;\n height: calc(100% - 60px);\n background-color: #ccc;\n}\n\n.dragbar {\n height: 100%;\n width: 5px;\n background-color: #e7e7e7;\n display: inline-block;\n cursor: col-resize;\n}\n\n.code-content {\n position: relative;\n height: calc(100% - 56px);\n}\n\n.code-html-container {\n position: relative;\n height: 50%;\n border-bottom: 1px solid #e7e7e7;\n}\n\n.code-css-container {\n position: relative;\n height: calc(50% - 1px);\n overflow: hidden;\n}\n\n.code-css {\n width: 100%;\n height: 100%;\n}\n\n.code-html {\n height: calc(100% - 40px);\n width: 100%;\n}\n\n.CodeMirror {\n height: 100% !important;\n}\n\n.code-badge {\n position: absolute;\n top: 10px;\n right: 10px;\n padding: 10px;\n}\n\n.btn-light.focus,\n.btn-light:focus {\n box-shadow: none !important;\n}\n\n.button-bar {\n width: 60px;\n padding: 10px;\n border-bottom: 1px solid #e7e7e7;\n width: 100%;\n background-color: white;\n}\n\n.noselect {\n -webkit-user-select: none;\n /* Chrome/Safari */\n -moz-user-select: none;\n /* Firefox */\n -ms-user-select: none;\n /* IE10+ */\n -o-user-select: none;\n user-select: none;\n}\n\n.btn+.btn {\n margin-left: 5px;\n}\n\n.btn-graph-goto {\n box-shadow: none !important;\n}\n\n.nav-tabs {\n border-bottom: none;\n}\n\n.main-navigation a.nav-link {\n color: white;\n}\n\n.main-navigation a.nav-link.active {\n color: #212529;\n}\n\n.dualbox-editor-body {\n width: 100%;\n height: 100%;\n overflow: hidden;\n background-color: rgb(85, 85, 85);\n}\n\n.dualbox-graph-left-section {\n height: 100%;\n width: 500px;\n float: left;\n position: relative;\n overflow: hidden;\n margin-left: -465px;\n transition: margin-left 0.3s ease;\n}\n\n.dualbox-graph-left-window {\n width: calc(100% - 35px);\n height: calc(100% - 10px);\n margin-top: 10px;\n /* background-color: #ECF2F8; */\n background-color: #f8f9fa;\n /* border: 1px solid grey; */\n border-radius: 5px;\n position: relative;\n float: left;\n}\n\n.dualbox-graph-left-panel {\n width: 100%;\n height: 100%;\n}\n\n.btn-toggle-left-window {\n position: absolute;\n right: 0;\n top: 0;\n margin-right: -35px;\n z-index: 100;\n border-top-left-radius: 0px;\n border-bottom-left-radius: 0px;\n}\n\n.btn-toggle-left-window:hover,\n.btn-toggle-right-window:hover,\n.btn-toggle-left-window:focus,\n.btn-toggle-right-window:focus,\n.btn-toggle-left-window:active,\n.btn-toggle-right-window:active,\n.btn-toggle-left-window:active:hover,\n.btn-toggle-right-window:active:hover {\n color: #212529 !important;\n background-color: #f8f9fa !important;\n border-color: #f8f9fa !important;\n}\n\n.dualbox-graph-right-section {\n height: 100%;\n width: 500px;\n float: right;\n position: relative;\n overflow: hidden;\n margin-right: -465px;\n transition: margin-right 0.3s ease;\n}\n\n.dualbox-graph-right-window {\n width: calc(100% - 35px);\n height: calc(100% - 20px);\n margin-top: 10px;\n margin-bottom: 30px;\n /* background-color: #ECF2F8; */\n background-color: #f8f9fa;\n /* border: 1px solid grey; */\n border-radius: 5px;\n position: relative;\n float: right;\n}\n\n.dualbox-graph-right-panel {\n width: 100%;\n height: 100%;\n}\n\n.btn-toggle-right-window {\n position: absolute;\n left: 0;\n top: 0;\n margin-left: -35px;\n z-index: 100;\n border-top-right-radius: 0px;\n border-bottom-right-radius: 0px;\n}\n\n.dualbox-graph-tab {\n height: 100%;\n width: 100%;\n background-color: #555 !important;\n}\n\n.dualbox-graph-main {\n height: 100%;\n width: calc(100% - 70px);\n float: right;\n background-color: #555 !important;\n transition: width 0.3s ease;\n}\n\n.dualbox-graph-main.left-panel-expanded {\n width: calc(100% - 535px);\n margin-left: -465px;\n}\n\n.dualbox-graph-main.right-panel-expanded {\n width: calc(100% - 535px);\n}\n\n.dualbox-graph-main.left-panel-expanded.right-panel-expanded {\n width: calc(100% - 1000px);\n margin-left: -465px;\n}\n\n.opacity0 {\n opacity: 0;\n}\n\n.btn-editor-xs {\n width: 18px;\n padding: 3px !important;\n line-height: .5;\n border-radius: 2px;\n}\n\n.btn-editor-xs>i {\n font-size: 10px;\n}\n\n.btn-outline-discrete {\n border-color: rgba(0, 0, 0, 0.05);\n border-color: transparent;\n color: rgba(0, 0, 0, 0.3);\n}\n\n.dualbox-app-navigation {\n background-color: transparent;\n margin-bottom: 0;\n vertical-align: middle;\n padding-top: 7px;\n padding-bottom: 7px;\n font-weight: bold;\n user-select: none;\n}\n\n.app-topbar {\n border-bottom: none;\n padding-left: 15px;\n padding-right: 15px;\n display: flex;\n width: 100%;\n height: 58px;\n padding-top: 10px;\n padding-bottom: 10px;\n}\n\n.dark,\n.graph-tab.active,\n.nav-item.active .graph-tab {\n color: white !important;\n background-color: #555 !important;\n}\n\n.light {\n color: #4d4d4d !important;\n background-color: #f8f9fa !important;\n}\n\n.main-navigation .nav-link,\n.main-navigation .nav-link.active,\n.nav-item.active .nav-link {\n border-bottom: none;\n border-left: none;\n border-top: none;\n border-right: none;\n position: relative;\n top: 1px;\n}\n\n.btn:focus,\nbutton:focus {\n outline: none;\n box-shadow: none;\n}\n\n.btn-transparent,\n.btn-transparent:hover,\n.btn-transparent:focus {\n background-color: transparent;\n}\n\n.connection-control {\n position: absolute;\n height: 14px;\n width: 14px;\n background-color: transparent;\n z-index: 19;\n cursor: move;\n}\n\n.connection-control.selected {\n border-color: #0066ff;\n box-shadow: 1px 1px 10px #0066ff;\n}\n\n.connection-label {\n z-index: 22 !important;\n color: #004d00 !important;\n background-color: white !important;\n padding: 4px 4px;\n border: 2px solid #004d00;\n font-size: 16px !important;\n border-radius: 5px;\n}\n\n.input-color-tag {\n background-color: #F2D600;\n}\n\n.output-color-tag {\n background-color: #FFAB4A;\n}\n\n.ui-color-tag {\n background-color: #61BD4F;\n}\n\n.metanode-color-tag {\n background-color: #DDDDDD;\n}\n\n.input {}\n\n.output {}\n\n.fileUpload {\n position: relative;\n overflow: hidden;\n margin: 10px;\n}\n\n.fileUpload input.upload {\n position: absolute;\n top: 0;\n right: 0;\n margin: 0;\n padding: 0;\n font-size: 20px;\n cursor: pointer;\n opacity: 0;\n filter: alpha(opacity=0);\n}\n\n.module-edit-modal-body .btn+.btn {\n margin-bottom: 0;\n margin-left: 5px;\n}\n\n.btn-add-node {\n width: 46%;\n margin: 1%;\n}\n\nbutton.close {\n position: absolute;\n right: 0;\n margin-right: 5px !important;\n}\n\n.CodeMirror {\n height: auto;\n min-height: 300px;\n}\n\n.load-app,\n.save-app {\n margin-left: 5px;\n margin-right: 5px;\n}\n\n.btn-xs {\n padding: 0px 4px;\n font-size: 12px;\n}\n</style>\n\n<template>\n<div class=\"dualbox-editor-body\">\n <nav class=\"main-navigation navbar navbar-default\" style=\"position: relative; margin-bottom: 0px; padding: 0; padding-top: 5px; background-color: #2e6da4;\">\n <ul class=\"nav nav-tabs\">\n <li class=\"nav-item active\">\n <a class=\"nav-link graph-tab\" href=\"#editor-graph-tab\" data-toggle=\"tab\">Application Graph</a>\n </li>\n <li class=\"nav-item\">\n <a class=\"nav-link interface-tab\" href=\"#editor-interface-tab\" data-toggle=\"tab\">Interface Editor</a>\n </li>\n </ul>\n\n <div class=\"nav navbar-right\" style=\"vertical-align: top; margin-top: 5px; margin-right: 10px; margin-bottom: 5px;\">\n <div v-if=\"showLoadButton === true\">\n <button class=\"load-app btn btn-sm btn-light\" style=\"position: relative; bottom: 3px;\" @click=\"loadApp\">Load App</button>\n </div>\n <div v-if=\"showSaveButton\">\n <button class=\"save-app btn btn-sm btn-light\" style=\"position: relative; bottom: 3px;\" @click=\"saveApp\">Save App</button>\n </div>\n </div>\n </nav>\n <div class=\"tab-content dualbox-graph-tab\" style=\"width: 100%; height: calc(100% - 46px);\">\n <div class=\"tab-pane active\" id=\"editor-graph-tab\" style=\"width: 100%; height: 100%;\">\n <div class=\"dualbox-graph-left-section dark\">\n <div class=\"dualbox-graph-left-window\">\n <button class=\"btn btn-light btn-toggle-left-window\" @click=\"toggleLeftWindow\" title=\"shrink window\" data-expanded=\"false\"><i class=\"fa fa-angle-double-right\"></i></button>\n <div class=\"dualbox-graph-left-panel light\">\n <edit-node-settings v-if=\"leftPanelMode == 'node' && selectedNodeId !== null\" :id=\"selectedNodeId\" :key=\"selectedNodeId\"></edit-node-settings>\n <edit-main-settings v-else-if=\"leftPanelMode == 'main'\" :app=\"getCurrentApplication()\" @edited=\"onEdited()\"></edit-main-settings>\n </div>\n </div>\n </div>\n <div class=\"dualbox-graph-right-section dark\">\n <div class=\"dualbox-graph-right-window\">\n <button class=\"btn btn-light btn-toggle-right-window\" @click=\"toggleRightWindow\" title=\"shrink window\" data-expanded=\"false\"><i class=\"fa fa-angle-double-left\"></i></button>\n <div class=\"dualbox-graph-right-panel light\">\n <debug-node-infos v-if=\"debugNodeId !== null\" :id=\"debugNodeId\"></debug-node-infos>\n </div>\n </div>\n </div>\n <div class=\"container-fluid dualbox-graph-main\" @click=\"setMainMenu\">\n <div class=\"row\">\n <div class=\"app-topbar dark\">\n <div class=\"justify-content-left\">\n <div class=\"dropdown\">\n <button class=\"btn btn-primary dropdown-toggle d-none\" type=\"button\" id=\"add-node-dropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\" style=\"margin-right: 5px;\">\n Add\n </button>\n <div class=\"dropdown-menu\" aria-labelledby=\"add-node-dropdown\">\n <a class=\"dropdown-item add-box\" @click=\"addBox\" href=\"#\">Add box</a>\n <a class=\"dropdown-item add-metabox\" @click=\"addMetabox\" href=\"#\">Add metabox</a>\n <a class=\"dropdown-item add-input\" @click=\"addInput\" href=\"#\">Add input</a>\n <a class=\"dropdown-item add-output\" @click=\"addOutput\" href=\"#\">Add output</a>\n <a class=\"dropdown-item import-metabox\" @click=\"importMetabox\" href=\"#\">Import metabox</a>\n </div>\n <button class=\"btn btn-light btn-undo\" title=\"undo (ctrl-z)\" @click=\"undo\"><i class=\"fa fa-undo\"></i></button>\n <button class=\"btn btn-light btn-redo\" title=\"redo (ctrl-y)\" @click=\"redo\"><i class=\"fa fa-repeat fa-redo\"></i></button>\n <div class=\"form-check d-inline-block ml-2\">\n <label class=\"form-check-label\">\n <input class=\"form-check-input show-events\" type=\"checkbox\" value=\"false\" @click=\"showEvents\">\n <span class=\"noselect\">Show events</span>\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"justify-content-center mx-auto\">\n <ol class=\"dualbox-app-navigation breadcrumb\"></ol>\n </div>\n\n <div class=\"justify-content-right\">\n <div class=\"dropdown selection-menu\" style=\"display: none;\">\n <button class=\"btn btn-primary dropdown-toggle\" type=\"button\" id=\"selection-dropdown\" data-toggle=\"dropdown\" aria-haspopup=\"true\" aria-expanded=\"false\">\n Selection\n </button>\n <div class=\"dropdown-menu dropdown-menu-right\" aria-labelledby=\"add-node-dropdown\">\n <a class=\"dropdown-item dualbox-merge-selection\" @click=\"mergeSelection\" href=\"#\">Merge</a>\n <a class=\"dropdown-item dualbox-remove-selection\" @click=\"removeSelection\" href=\"#\" style=\"color: red;\">Delete</a>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"row\" style=\"height: calc(100% - 58px);\">\n <graph-vue :app=\"app\" ref=\"graph\" :displayEvents=\"displayEvents\"></graph-vue>\n </div>\n </div>\n </div>\n <div class=\"tab-pane\" id=\"editor-interface-tab\" style=\"width 100%; height: 100%; background-color: white;\">\n <div class=\"db-editor-main\" style=\"width: 100%; height: 100%; overflow: hidden;\">\n <div class=\"code-panel\">\n <div class=\"button-bar form-inline code-controls\" style=\"position: relative;\">\n <button class=\"btn btn-primary btn-save-interface-element\" @click=\"saveInterfaceElement\">Save changes</button>\n </div>\n <div class=\"code-content\">\n <div class=\"code-html-container\">\n <div style=\"padding-top: 5px; padding-bottom: 5px; height: 50px; position: relative;\">\n <h3 style=\"position: absolute; top: 0; margin: 5px; font-size: 16px; z-index: 100; display: inline-block; margin-top: 5px;\">HTML</h3>\n <div class=\"d-inline-block ml-auto form-inline mr-2 mt-2\" style=\"position: absolute; top: 0; right: 0;\">\n <button class=\"btn btn-success btn-sm btn-add-interface\" @click=\"addInterface\"><i class=\"fas fa-plus\"></i></button>\n <select class=\"form-control btn-sm app-interface-select\" @change=\"selectInterface\" style=\"width: 150px; height: 32px;\">\n <option>Load UI...</option>\n <option v-for=\"interfaceName in getInterfacesNames()\" :value=\"interfaceName\">{{interfaceName}}</option>\n </select>\n <button class=\"btn btn-sm btn-light btn-edit-panel-description\" @click=\"editPanelDescription\"><i class=\"fas fa-info\" style=\"padding-left: 8px; padding-right: 8px;\"></i></button>\n <button class=\"btn btn-danger btn-sm btn-remove-interface\" @click=\"removeInterface\"><i class=\"fas fa-minus\"></i></button>\n </div>\n </div>\n <div class=\"code-html-text-container\" style=\"position: relative; height: calc(100% - 50px);\">\n <textarea class=\"code-html\"></textarea>\n </div>\n </div>\n <div class=\"code-css-container\">\n <div style=\"height: 30px;\">\n <h3 style=\"position: absolute; top: 0; margin: 5px; font-size: 16px; z-index: 100;\">CSS</h3>\n </div>\n <div class=\"colde-css-text-container\" style=\"position: relative; height: calc(100% - 30px);\">\n <textarea class=\"code-css\" v-model=\"appCss\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"dragbar\"></div>\n <div class=\"application-container\">\n <div class=\"button-bar form-inline run-options\" style=\"position: relative;\">\n <button class=\"btn btn-success btn-run mr-2\" @click=\"runApp\">Run</button>\n\n <select class=\"form-control run-loglevel mr-1 ml-2\">\n <option>error</option>\n <option>warn</option>\n <option>info</option>\n <option>log</option>\n <option>debug</option>\n </select>\n\n <input class=\"form-control run-noversioncheck mr-1 ml-3\" type=\"checkbox\" checked>No version checking</input>\n <input class=\"form-control run-removetrycatch mr-1 ml-3\" type=\"checkbox\">Remove Try/catch</input>\n <input class=\"form-control run-makesynchrone mr-1 ml-3\" type=\"checkbox\">Make Synchrone</input>\n <input class=\"form-control run-ressourcecaching mr-1 ml-3\" type=\"checkbox\">Ressource caching</input>\n\n <div class=\"ml-auto\">\n <input class=\"form-control run-profiler mr-1 ml-3\" type=\"checkbox\">Profiler</input>\n <input class=\"form-control run-record mr-1 ml-3\" type=\"checkbox\">Record</input>\n <button class=\"btn btn-secondary btn-snapshot\" @click=\"takeAndLoadSnapshot\">Snapshot</button>\n </div>\n </div>\n <div class=\"application capture-left-click capture-right-click\"></div>\n </div>\n </div>\n </div>\n </div>\n <add-node-vue :display=\"this.addingBox\" :mousePosition=\"this.newBoxPosition\" @closed=\"onAddBoxClosed\"></add-node-vue>\n</div>\n</template>\n\n<script>\nimport _ from 'lodash-es';\nimport swal from 'sweetalert2';\n\nimport graphVue from './graph.vue';\nimport addNodeVue from './addNode.vue';\nimport editMainSettingsVue from './editMainSettings.vue';\nimport editNodeSettingsVue from './editNodeSettings.vue';\nimport debugNodeInfosVue from './debugNodeInfos.vue';\n\n// CodeMirror\nimport CodeMirror from 'codemirror/lib/codemirror.js';\nimport 'codemirror/mode/xml/xml.js';\nimport 'codemirror/mode/css/css.js';\nimport 'codemirror/mode/javascript/javascript.js';\nimport 'codemirror/mode/htmlmixed/htmlmixed.js';\n\nimport htmltool from '@dualbox/dualbox-lib-htmltool';\n\nexport default {\n props: [\n 'app', // the app\n\n // Display configuration (online or offline ?)\n 'showLoadButton',\n 'showSaveButton',\n 'saveButtonFunction',\n\n // modes\n 'eventVisibility' // are events visible\n ],\n components: {\n 'graph-vue': graphVue,\n 'add-node-vue': addNodeVue,\n 'edit-main-settings': editMainSettingsVue,\n 'edit-node-settings': editNodeSettingsVue,\n 'debug-node-infos': debugNodeInfosVue,\n },\n data() {\n return {\n // modes\n addingBox: false,\n leftPanelMode: 'main', // 'main' to display main menu, 'node' for a node\n selectedNodeId: null, // id of the node to display in left menu\n debugNodeId: null, // on a snapshot, id of the node to display debug infos\n newBoxPosition: null, // track mouse position relative to the graph when adding a node\n displayEvents: false,\n\n // the specific app css\n appCss: \"\",\n }\n },\n created: function () {\n this.view = window.dualboxEditor.v;\n // TODO: restore this when all menus are migrated to Vue.js\n\n this.cssCode = null;\n this.htmlCode = null;\n },\n updated: function () {\n //console.log('updating main view with: ' + JSON.stringify(this.app));\n this.appCss = (this.app && this.app.css) || \"\";\n\n // Update html and css code editor\n this.updateCode();\n },\n mounted: function () {\n //this.view.setMainMenu();\n\n $(this.$el).bind('expandSettings', function (e) {\n // expand\n $(this).find('.dualbox-graph-left-section').css('margin-left', '0');\n $(this).find('.dualbox-graph-main').addClass('left-panel-expanded');\n $(this).find('.btn-toggle-left-window').data('expanded', true).find('i')\n .removeClass('fa-angle-double-right')\n .addClass('fa-angle-double-left')\n .attr('title', 'shrink window');\n });\n\n $(this.$el).bind('shrinkSettings', function (e) {\n // shrink\n $(this).find('.dualbox-graph-left-section').css('margin-left', '-465px');\n $(this).find('.dualbox-graph-main').removeClass('left-panel-expanded');\n $(this).find('.btn-toggle-left-window').data('expanded', false).find('i')\n .removeClass('fa-angle-double-left')\n .addClass('fa-angle-double-right')\n .attr('title', 'expand window');\n });\n\n $(this.$el).bind('expandDebug', function (e) {\n // expand\n $(this).find('.dualbox-graph-right-section').css('margin-right', '0');\n $(this).find('.dualbox-graph-main').addClass('right-panel-expanded');\n $(this).find('.btn-toggle-right-window').data('expanded', true).find('i')\n .removeClass('fa-angle-double-left')\n .addClass('fa-angle-double-right')\n .attr('title', 'shrink window');\n });\n\n $(this.$el).bind('shrinkDebug', function (e) {\n // shrink\n $(this).find('.dualbox-graph-right-section').css('margin-right', '-465px');\n $(this).find('.dualbox-graph-main').removeClass('right-panel-expanded');\n $(this).find('.btn-toggle-right-window').data('expanded', false).find('i')\n .removeClass('fa-angle-double-right')\n .addClass('fa-angle-double-left')\n .attr('title', 'expand window');\n });\n\n // bind tabs\n var self = this;\n $(this.$el).find(\"a[data-toggle='tab']\").on(\"shown.bs.tab\", function (e) {\n var target = $(e.target).attr(\"href\") // activated tab\n if (target == \"#editor-graph-tab\") {\n self.view.killApp();\n } else if (target == \"#editor-interface-tab\") {\n self.htmlCode.refresh();\n self.cssCode.refresh();\n self.view.runApp(self.getOptions());\n }\n });\n\n $(this.$el).find(\"a[data-toggle='tab']\").on('click', function (e) {\n e.preventDefault()\n $(this).tab('show');\n });\n\n // Update html and css code editor\n this.updateCode();\n\n // Resize horizontally\n $(this.$el).find('.dragbar').mousedown(function (e) {\n e.preventDefault();\n $(document).mouseup(function (e) {\n $(document).unbind('mousemove');\n });\n $(document).mousemove(function (e) {\n $('.code-panel').css('width', e.pageX + \"px\");\n $('.application-container').css('width', ($(\".db-editor-main\").width() - e.pageX - 5) + \"px\");\n })\n });\n\n // prevent default behavior for ctrl+s / cmd+s\n $(document).keydown(function (event) {\n if ((event.ctrlKey || event.metaKey) && event.which == 83) {\n event.preventDefault();\n return false;\n }\n });\n },\n destroyed: function() {\n console.log('Graph vue destroyed');\n $('.ContextMenu').remove();\n },\n methods: {\n \"getOptions\": function () {\n return {\n profiler: $(this.$el).find('.run-profiler').is(':checked'),\n logLevel: $(this.$el).find('.run-loglevel').val(),\n options: {\n noVersionCheck: $(this.$el).find('.run-noversioncheck').is(':checked'),\n debug: {\n removeTryCatch: $(this.$el).find('.run-removetrycatch').is(':checked'),\n makeSynchrone: $(this.$el).find('.run-makesynchrone').is(':checked'),\n record: $(this.$el).find('.run-record').is(':checked'),\n ressourceCaching: $(this.$el).find('.run-ressourcecaching').is(':checked'),\n }\n },\n }\n },\n\n \"updateCode\": function () {\n // instanciate codemirror for html and css\n if (!this.htmlCode) {\n this.htmlCode = CodeMirror.fromTextArea($(this.$el).find(\".code-html\")[0], {\n lineNumbers: true,\n mode: \"htmlmixed\",\n lineWrapping: true,\n extraKeys: {\n \"Ctrl-S\": () => {\n this.saveInterfaceElement();\n this.runApp();\n },\n \"Cmd-S\": () => {\n this.saveInterfaceElement();\n this.runApp();\n }\n }\n });\n }\n if (!this.cssCode) {\n this.cssCode = CodeMirror.fromTextArea($(this.$el).find(\".code-css\")[0], {\n lineNumbers: true,\n mode: \"css\",\n lineWrapping: true,\n extraKeys: {\n \"Ctrl-S\": () => {\n // save css code into app\n this.view.m.data.root.css = this.cssCode.getValue();\n this.runApp();\n },\n \"Cmd-S\": () => {\n // save css code into app\n this.view.m.data.root.css = this.cssCode.getValue();\n this.runApp();\n }\n }\n });\n }\n this.cssCode.setValue(this.view.m.get().css || \"\");\n },\n\n \"loadApp\": function () {\n var self = this;\n\n // create a fake input and click it to select a file\n var input = $('<input/>', {\n \"type\": \"file\",\n \"class\": \"upload\",\n \"accept\": \".json\"\n });\n input.change(function (e) {\n // if we're not here, go to 1st tab\n $(\"a[data-toggle='tab'][href='#editor-graph-tab']\").click();\n\n // parse the file JSON and load it\n var files = e.target.files; // FileList object\n var r = new FileReader();\n r.onload = function (e) {\n var contents = e.target.result;\n var json = JSON.parse(contents);\n self.view.e.setApp(json);\n };\n\n r.readAsText(files[0]);\n });\n input.click();\n },\n \"saveApp\": function () {\n // bind the app load\n if (this.saveButtonFunction) {\n var saveButtonFunction = (e) => {\n var json = this.view.m.getCleanJson();\n return this.saveButtonFunction(json);\n }\n } else {\n var saveButtonFunction = (e) => {\n var app = this.view.m.getCleanJson();\n var text = JSON.stringify(app, null, 2);\n var blob = new Blob([text], {\n \"type\": \"application/octet-stream\"\n });\n\n var a = document.createElement('a');\n a.href = window.URL.createObjectURL(blob);\n a.download = \"app.json\";\n\n // simulate a click on the link\n if (document.createEvent) {\n var event = document.createEvent(\"MouseEvents\");\n event.initEvent(\"click\", true, true);\n a.dispatchEvent(event);\n } else {\n a.click();\n }\n }\n }\n saveButtonFunction();\n },\n \"getCurrentMousePosition\": function (e) {\n return this.$refs.graph.getCurrentMousePosition(e);\n },\n \"addBox\": function (e) {\n this.addingBox = true;\n this.newBoxPosition = this.getCurrentMousePosition(e);\n this.$forceUpdate();\n },\n \"onAddBoxClosed\": function () {\n this.addingBox = false;\n this.$forceUpdate();\n },\n \"addMetabox\": function (e) {\n var self = this;\n e.preventDefault();\n e.stopPropagation();\n\n swal({\n input: 'text',\n title: 'Choose a name for the metabox',\n }).then(function (result) {\n if (result.value) {\n self.view.c.addNewMetabox(result.value);\n }\n });\n },\n \"addInput\": function (e) {\n this.view.c.createInput();\n },\n \"addOutput\": function (e) {\n this.view.c.createOutput();\n },\n \"importMetabox\": async function (e) {\n var self = this;\n\n const {\n value: file\n } = await swal({\n title: 'Select your metabox file',\n input: 'file',\n inputAttributes: {\n 'accept': 'application/json',\n 'aria-label': 'Select your metabox file'\n }\n })\n\n if (file) {\n const reader = new FileReader()\n reader.onload = (e) => {\n var json = JSON.parse(e.target.result);\n\n self.view.e.loadPackages(json).then(async () => {\n const {\n value: name\n } = await swal({\n title: 'Choose a name for your metabox',\n input: 'text',\n showCancelButton: true,\n inputValidator: (value) => {\n return !value && 'You need to write something!'\n }\n });\n\n self.view.c.addNewMetabox(name, json);\n }).catch((err) => {\n console.error(err);\n });\n }\n reader.readAsText(file)\n }\n },\n\n getInterfacesNames: function () {\n return _.keys(_.get(this.view.m, [\"data\", \"root\", \"interface\"]) || {});\n },\n\n \"selectInterface\": function (e) {\n // Load the interface HTML when selected\n var uiName = $(e.target).val();\n if (uiName !== \"\" && uiName !== \"Load UI...\") {\n var itf = this.view.m.data.root.interface;\n var htmlString = htmltool.json2html(itf[uiName]);\n var prettyString = htmltool.htmlPrettyPrint(htmlString);\n this.htmlCode.setValue(prettyString);\n } else {\n this.htmlCode.setValue(\"\");\n }\n },\n \"saveInterfaceElement\": function (e) {\n var currentInterface = $(this.$el).find('.app-interface-select').val();\n if (currentInterface !== \"\") {\n var currentHTML = this.htmlCode.getValue();\n\n // save html code into app\n this.view.m.data.root.interface[currentInterface] = htmltool.html2json(currentHTML);\n }\n\n // save css code into app\n this.view.m.data.root.css = this.cssCode.getValue();\n },\n \"addInterface\": function (e) {\n var self = this;\n\n swal.mixin({\n confirmButtonText: 'Next &rarr;',\n showCancelButton: true,\n progressSteps: ['1', '2', '3']\n }).queue([{\n input: 'text',\n title: 'Choose a name',\n text: 'Enter a name for the new interface'\n },\n {\n input: 'select',\n title: 'Choose the type',\n text: 'Is it a viewer panel or a control panel?',\n inputOptions: {\n 'control': 'A control panel',\n 'viewer': 'A viewer',\n },\n },\n {\n input: 'select',\n title: 'Choose the position',\n text: 'Where do you want to position your panel?',\n inputOptions: {\n 'top-left': 'At the top-left',\n 'top-center': 'At the top-center',\n 'top-right': 'At the top-right',\n 'center-left': 'At the center-left',\n 'center': 'At the center',\n 'center-right': 'At the center-right',\n 'bottom-left': 'At the bottom-left',\n 'bottom-center': 'At the bottom-center',\n 'bottom-right': 'At the bottom-right',\n 'whole-screen': 'I want my panel in full-screen',\n },\n }\n ]).then((result) => {\n if (result.value) {\n var name = result.value[0];\n var type = result.value[1];\n var position = result.value[2];\n\n if (name === \"\") {\n swal.showInputError(\"the name is empty!\");\n return false\n }\n\n var appInterface = self.view.m.data.root.interface;\n if (appInterface[name]) {\n swal.showInputError(\"Interface \" + name + \" already exists!\");\n return false\n } else {\n var style = {};\n switch (position) {\n case 'top-left':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'left': 0,\n 'margin': '15px'\n };\n break;\n case 'top-center':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'margin': '15px auto'\n };\n break;\n case 'top-right':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'right': 0,\n 'margin': '15px'\n };\n break;\n case 'center-left':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'bottom': 0,\n 'left': 0,\n 'margin': 'auto 15px'\n };\n break;\n case 'center':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'bottom': 0,\n 'left': 0,\n 'right': 0,\n 'margin': 'auto'\n };\n break;\n case 'center-right':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'bottom': 0,\n 'right': 0,\n 'margin': 'auto 15px'\n };\n break;\n case 'bottom-left':\n style = {\n 'position': 'absolute',\n 'bottom': 0,\n 'left': 0,\n 'margin': '15px'\n };\n break;\n case 'bottom-center':\n style = {\n 'position': 'absolute',\n 'bottom': 0,\n 'left': 0,\n 'right': 0,\n 'margin': '15px auto'\n };\n break;\n case 'bottom-right':\n style = {\n 'position': 'absolute',\n 'bottom': 0,\n 'right': 0,\n 'margin': '15px'\n };\n break;\n case 'whole-screen':\n style = {\n 'position': 'absolute',\n 'top': 0,\n 'left': 0\n };\n break;\n }\n\n // some prefilled data\n style['width'] = \"300px\";\n style['padding'] = \"15px\";\n style['border'] = \"1px solid #ccc\";\n style['border-radius'] = \"4px\";\n style['background'] = \"white\";\n if (position.startsWith(\"center\")) {\n style['height'] = \"60px\"; // must define height\n } else {\n style['height'] = \"auto\";\n }\n\n // add a basic control\n appInterface[name] = {\n type: \"Element\",\n tagName: \"div\",\n attributes: {\n className: [\n \"dualbox\",\n \"dualbox-container\",\n \"dualbox-container-\" + name,\n type == \"viewer\" ? \"dualbox-viewer\" : \"dualbox-controls\"\n ],\n style: style,\n },\n children: []\n }\n\n // add the value to our select, and load it\n $(self.$el).find(\".app-interface-select\").append(\n $(\"<option/>\", {\n \"value\": name\n }).append(name)\n );\n $(document).ready(() => {\n $(self.$el).find('.app-interface-select').val(name).change();\n\n // set it into the editor\n var htmlString = htmltool.json2html(appInterface[name]);\n var prettyString = htmltool.htmlPrettyPrint(htmlString);\n this.htmlCode.setValue(prettyString);\n self.updateCode();\n });\n\n self.view.runApp(self.getOptions());\n }\n }\n })\n },\n \"removeInterface\": function (e) {\n var self = this;\n var name = $('.app-interface-select').val();\n\n swal({\n title: \"Confirm deleting \" + name + \" ?\",\n type: \"warning\",\n showCancelButton: true,\n confirmButtonColor: \"#DD6B55\",\n confirmButtonText: \"Yes, delete it!\",\n closeOnConfirm: true,\n closeOnCancel: true\n }).then((result) => {\n if (result.value) {\n // set the interface back to first value\n $(this.$el).find(\".app-interface-select option[value='\" + name + \"']\").remove();\n $(this.$el).find(\".app-interface-select\").change();\n delete self.view.m.data.root.interface[name];\n self.htmlCode.setValue(\"\");\n self.view.runApp(self.getOptions());\n }\n });\n },\n \"editPanelDescription\": function (e) {\n var self = this;\n var name = $('.app-interface-select').val();\n\n swal({\n title: \"Enter a description for this panel!\",\n input: \"textarea\",\n inputValue: this.view.m.data.root.interface[name].description || \"\",\n showCancelButton: true,\n closeOnConfirm: false,\n showLoaderOnConfirm: true,\n animation: \"slide-from-top\",\n inputPlaceholder: \"Write something\"\n }).then((result) => {\n if (result.value === \"\") {\n swal.showInputError(\"You need to write something!\");\n return false\n } else {\n self.view.m.data.root.interface[name].description = result.value;\n }\n });\n },\n \"toggleLeftWindow\": function (e) {\n var expanded = $(e.target).closest('button').data('expanded');\n if (expanded) {\n $(this.$el).trigger('shrinkSettings');\n } else {\n $(this.$el).trigger('expandSettings');\n }\n },\n \"toggleRightWindow\": function (e) {\n var expanded = $(e.target).closest('button').data('expanded');\n if (expanded) {\n $(this.$el).trigger('shrinkDebug');\n } else {\n $(this.$el).trigger('expandDebug');\n }\n },\n\n \"showEvents\": function (e) {\n //this.view.setEventsVisibility( $(e.target).is(':checked') );\n this.displayEvents = $(e.target).is(':checked');\n },\n\n \"runApp\": function (e) {\n this.view.runApp(this.getOptions());\n },\n\n \"takeAndLoadSnapshot\": function (e) {\n this.view.takeAndLoadSnapshot();\n },\n\n \"undo\": function (e) {\n this.view.c.undo();\n },\n\n \"redo\": function (e) {\n this.view.c.redo();\n },\n\n \"removeSelection\": function (e) {\n this.view.c.deleteSelection();\n },\n\n \"mergeSelection\": function (e) {\n this.view.c.mergeSelection();\n },\n\n \"setMainMenu\": async function (e) {\n await this.view.setMainMenu();\n },\n\n \"getCurrentApplication\": function (e) {\n // trick to make this function reactive to \"app\" field update\n if (this.app) {\n return this.view.m.getCurrentApp(true);\n } else {\n throw \"Error: no app found\";\n }\n },\n\n \"onEdited\": function (e) {\n console.log('Something was edited, forcing new render');\n this.$forceUpdate();\n },\n\n \"ready\": function () {\n return new Promise(resolve => {\n this.$nextTick(() => {\n window.requestAnimationFrame(() => {\n $(this.$el).ready(resolve);\n })\n })\n })\n }\n }\n}\n</script>\n"]}, media: undefined });
88198
88254
 
88199
88255
  };
88200
88256
  /* scoped */
@@ -88205,24 +88261,28 @@ __vue_render__$d._withStripped = true;
88205
88261
  const __vue_is_functional_template__$d = false;
88206
88262
  /* style inject SSR */
88207
88263
 
88264
+ /* style inject shadow dom */
88265
+
88208
88266
 
88209
88267
 
88210
- var mainVue = normalizeComponent_1(
88268
+ const __vue_component__$d = normalizeComponent_1(
88211
88269
  { render: __vue_render__$d, staticRenderFns: __vue_staticRenderFns__$d },
88212
88270
  __vue_inject_styles__$d,
88213
88271
  __vue_script__$d,
88214
88272
  __vue_scope_id__$d,
88215
88273
  __vue_is_functional_template__$d,
88216
88274
  __vue_module_identifier__$d,
88275
+ false,
88217
88276
  browser,
88277
+ undefined,
88218
88278
  undefined
88219
88279
  );
88220
88280
 
88221
88281
  var templates = {
88222
- "mainVue" : mainVue,
88223
- "editMainSettingsVue" : editMainSettingsVue,
88224
- "editNodeSettingsVue" : editNodeSettingsVue,
88225
- "debugNodeInfosVue" : debugNodeInfosVue
88282
+ "mainVue" : __vue_component__$d,
88283
+ "editMainSettingsVue" : __vue_component__$a,
88284
+ "editNodeSettingsVue" : __vue_component__$b,
88285
+ "debugNodeInfosVue" : __vue_component__$c
88226
88286
  };
88227
88287
 
88228
88288
  /**
@@ -88411,7 +88471,7 @@ class GraphView {
88411
88471
  // add main template
88412
88472
  this.div.append($('<div/>', { 'id': 'mainvue' })); // add a target
88413
88473
  this.div.ready(() => {
88414
- var MainVue = Vue.extend(mainVue); // create a class from our .vue template
88474
+ var MainVue = Vue.extend(__vue_component__$d); // create a class from our .vue template
88415
88475
  this.mainVue = new MainVue({
88416
88476
  el: "#mainvue",
88417
88477
  propsData: {
@@ -88562,11 +88622,10 @@ class GraphView {
88562
88622
  }
88563
88623
 
88564
88624
  async openDebug(id) {
88565
- var expandDebug = () => {
88566
- this.div.find('.dualbox-editor-body').trigger('expandDebug');
88567
- };
88625
+ await this.setDebugMenu(id);
88568
88626
 
88569
- return await this.setDebugMenu(id, expandDebug);
88627
+ // TODO: do this the vue.js way
88628
+ this.div.find('.dualbox-editor-body').trigger('expandDebug');
88570
88629
  }
88571
88630
 
88572
88631
  // TODO: use proper vue.js reactivity here