@gregoriusrippenstein/node-red-contrib-introspection 0.9.3 → 0.9.5

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.
package/README.md CHANGED
@@ -94,7 +94,7 @@ Also this is an experimental feature liable to be [enhanced](https://discourse.n
94
94
 
95
95
  This now has a [treeList](https://nodered.org/docs/api/ui/treeList/) of nodes and how often they received a message. Clicking on the node in the list will highlight the node, double-click will open the nodes edit panel.
96
96
 
97
- *UPDATE2*:
97
+ *UPDATE TWO*:
98
98
 
99
99
  It is now possible to send all messages to the debug panel. By toggling the 'msg to debug' checkbox, *all messages* will be sent to the Node-RED debug panel. This can be toggled on and off independently of the message tracing. That is, as long as message tracing is activated. It is therefore possible (as shown in the animation above) to active message tracing, then activate msg to debug to have msg appear in the debug panel and then deactive the msg to debug. The message tracing continues unabated.
100
100
 
@@ -104,6 +104,12 @@ This makes it possible to trace messages, if something critical happens, to acti
104
104
 
105
105
  Also this feature causes **no extra overhead** on the backend server if it is *not in use* - the hooks for capturing the data are removed if this feature is deactivated.
106
106
 
107
+ *UPDATE THREE*:
108
+
109
+ Tracing and debug-message tracing are now separate operations and neither works on *all* nodes by default. To use either feature, a selection of nodes must now be made beforehand (in the flow editor window) and then tracing activated. If you really want to trace **all** nodes, then select none in the editor (deselect all nodes) and check the corresponding "All?" checkbox - there is one for debug messages and one for message tracing.
110
+
111
+ Tracing or debugging **all** nodes is **no longer** the default action.
112
+
107
113
  ## Palette Nodes
108
114
 
109
115
  ### Sink & Seeker
@@ -1,10 +1,13 @@
1
- module.exports = function(RED) {
1
+ module.exports = function (RED) {
2
2
  let UglifyJS = require('uglify-js');
3
3
  let CleanCSS = require('clean-css');
4
4
 
5
- const OnReceiveHookName = "onReceive.introspectionMsgTracer"
5
+ const OnReceiveTracingHookName = "onReceive.introspectionMsgTracer"
6
+ const OnReceiveDebugHookName = "onReceive.introspectionMsgDebug"
7
+
6
8
  const OnPreuninstallHookName = "preUninstall.introspectionMsgTracer"
7
- const debugLength = RED.settings.debugMaxLength || 1000
9
+
10
+ const debugLength = RED.settings.debugMaxLength || 1000
8
11
 
9
12
  function msgTracerOnReceiveHook(evnt) {
10
13
  try {
@@ -18,8 +21,6 @@ module.exports = function(RED) {
18
21
  nodeid: evnt.destination.id
19
22
  })
20
23
  )
21
-
22
- return nde
23
24
  } catch (ex) {
24
25
  console.error(ex)
25
26
  }
@@ -27,42 +28,41 @@ module.exports = function(RED) {
27
28
 
28
29
  function msgTracerOnReceiveHookWithDebug(evnt) {
29
30
  try {
30
- let nde = msgTracerOnReceiveHook(evnt)
31
+ let nde = RED.nodes.getNode(evnt.destination.id)
31
32
 
32
33
  // don't publish debug messages for junctions because they
33
34
  // cause errors in handleDebugMessages in the client.
34
- if ( nde.type == "junction") { return }
35
+ if (nde.type == "junction") { return }
35
36
 
36
37
  // taken from the [debug node](https://github.com/node-red/node-red/blob/2854351909dee9f92597faba3f37239134294eec/packages/node_modules/%40node-red/nodes/core/common/21-debug.js#L227)
37
- let msg = {
38
- id: nde.id,
39
- z: nde.z,
40
- _alias: nde._alias,
41
- path: nde._flow.path,
42
- name: nde.name,
43
- topic: evnt.msg.topic,
38
+ let msg = {
39
+ id: nde.id,
40
+ z: nde.z,
41
+ _alias: nde._alias,
42
+ path: nde._flow.path,
43
+ name: nde.name,
44
+ topic: evnt.msg.topic,
44
45
  msg: evnt.msg
45
46
  }
46
47
 
47
48
  msg = RED.util.encodeObject(msg, { maxLength: debugLength });
48
- RED.comms.publish("debug",msg);
49
-
49
+ RED.comms.publish("debug", msg);
50
50
  } catch (ex) {
51
51
  console.error(ex)
52
52
  }
53
53
  }
54
54
 
55
55
  function ClientCodeFunctionality(config) {
56
- RED.nodes.createNode(this,config);
56
+ RED.nodes.createNode(this, config);
57
57
 
58
58
  var node = this;
59
59
  var cfg = config;
60
60
 
61
- node.on('close', function() {
61
+ node.on('close', function () {
62
62
  node.status({});
63
63
  });
64
64
 
65
- node.on("input", function(msg, send, done) {
65
+ node.on("input", function (msg, send, done) {
66
66
  // msg object may cause problem if there are circular references, so
67
67
  // do a pre-stringify before erroring out.
68
68
  try {
@@ -87,20 +87,32 @@ module.exports = function(RED) {
87
87
  RED.nodes.registerType("ClientCode", ClientCodeFunctionality);
88
88
 
89
89
  /**
90
- * These are the two endpoints for the message tracer functionality.
90
+ * These are the four endpoints for the message tracer functionality.
91
91
  * Rather badly placed in the ClientCode node code but the author
92
92
  * didn't find a better place. The world is confusing, why should
93
93
  * this codebase be any different.
94
94
  */
95
- RED.httpAdmin.post("/MsgTracer/msgtracing/on",
96
- RED.auth.needsPermission("ClientCode.write"),
95
+ RED.httpAdmin.post("/MsgTracer/debug/on",
96
+ RED.auth.needsPermission("MsgTracer.write"),
97
97
  (req, res) => {
98
98
  try {
99
- RED.hooks.remove(OnReceiveHookName)
100
- if ( req.body.withDebug ) {
101
- RED.hooks.add(OnReceiveHookName, msgTracerOnReceiveHookWithDebug)
102
- } else {
103
- RED.hooks.add(OnReceiveHookName, msgTracerOnReceiveHook)
99
+
100
+ /*
101
+ * If selected nodes is empty by allIsOn is on, then trace all messages.
102
+ * If node selection is non-empty, then trace those nodes.
103
+ */
104
+ if (req.body.nodesSelected.length == 0 && req.body.allIsOn) {
105
+ RED.hooks.remove(OnReceiveDebugHookName)
106
+ RED.hooks.add(OnReceiveDebugHookName, msgTracerOnReceiveHookWithDebug)
107
+ } else if (req.body.nodesSelected.length > 0) {
108
+ RED.hooks.remove(OnReceiveDebugHookName)
109
+
110
+ let nodesToBeTraced = [...req.body.nodesSelected]
111
+ RED.hooks.add(OnReceiveDebugHookName, (evnt) => {
112
+ if (nodesToBeTraced.indexOf(evnt.destination.id) > -1) {
113
+ msgTracerOnReceiveHookWithDebug(evnt)
114
+ }
115
+ })
104
116
  }
105
117
 
106
118
  // add hook on uninstall package so that the hook for the
@@ -108,24 +120,62 @@ module.exports = function(RED) {
108
120
  RED.hooks.remove(OnPreuninstallHookName)
109
121
  RED.hooks.add(OnPreuninstallHookName, (evnt) => {
110
122
  if (evnt.module == "@gregoriusrippenstein/node-red-contrib-introspection") {
111
- RED.hooks.remove(OnReceiveHookName)
123
+ RED.hooks.remove(OnReceiveTracingHookName)
124
+ RED.hooks.remove(OnReceiveDebugHookName)
112
125
  RED.hooks.remove(OnPreuninstallHookName)
113
126
  }
114
127
  })
115
128
 
116
129
  res.sendStatus(200);
117
- } catch (err) {
130
+ } catch (ex) {
118
131
  res.sendStatus(500);
119
132
  }
120
133
  });
121
134
 
122
- RED.httpAdmin.post("/MsgTracer/msgtracing/off",
123
- RED.auth.needsPermission("ClientCode.write"),
135
+ RED.httpAdmin.post("/MsgTracer/debug/off",
136
+ RED.auth.needsPermission("MsgTracer.write"),
124
137
  (req, res) => {
125
138
  try {
139
+ RED.hooks.remove(OnReceiveDebugHookName)
140
+ res.sendStatus(200);
141
+ } catch (err) {
142
+ res.sendStatus(500);
143
+ }
144
+ });
145
+
146
+ RED.httpAdmin.post("/MsgTracer/msgtracing/on",
147
+ RED.auth.needsPermission("MsgTracer.write"),
148
+ (req, res) => {
149
+ try {
150
+
151
+ /*
152
+ * If selected nodes is empty by allIsOn is on, then trace all messages.
153
+ * If node selection is non-empty, then trace those nodes.
154
+ */
155
+ if (req.body.nodesSelected.length == 0 && req.body.allIsOn) {
156
+ RED.hooks.remove(OnReceiveTracingHookName)
157
+ RED.hooks.add(OnReceiveTracingHookName, msgTracerOnReceiveHook)
158
+ } else if (req.body.nodesSelected.length > 0) {
159
+ RED.hooks.remove(OnReceiveTracingHookName)
160
+
161
+ let nodesToBeTraced = [...req.body.nodesSelected]
162
+ RED.hooks.add(OnReceiveTracingHookName, (evnt) => {
163
+ if (nodesToBeTraced.indexOf(evnt.destination.id) > -1) {
164
+ msgTracerOnReceiveHook(evnt)
165
+ }
166
+ })
167
+ }
126
168
 
127
- RED.hooks.remove(OnReceiveHookName)
169
+ // add hook on uninstall package so that the hook for the
170
+ // message tracer is removed on uninstall of this package.
128
171
  RED.hooks.remove(OnPreuninstallHookName)
172
+ RED.hooks.add(OnPreuninstallHookName, (evnt) => {
173
+ if (evnt.module == "@gregoriusrippenstein/node-red-contrib-introspection") {
174
+ RED.hooks.remove(OnReceiveTracingHookName)
175
+ RED.hooks.remove(OnReceiveDebugHookName)
176
+ RED.hooks.remove(OnPreuninstallHookName)
177
+ }
178
+ })
129
179
 
130
180
  res.sendStatus(200);
131
181
  } catch (err) {
@@ -133,19 +183,34 @@ module.exports = function(RED) {
133
183
  }
134
184
  });
135
185
 
186
+ RED.httpAdmin.post("/MsgTracer/msgtracing/off",
187
+ RED.auth.needsPermission("MsgTracer.write"),
188
+ (req, res) => {
189
+ try {
190
+ RED.hooks.remove(OnReceiveTracingHookName)
191
+ res.sendStatus(200);
192
+ } catch (err) {
193
+ res.sendStatus(500);
194
+ }
195
+ });
196
+
197
+
198
+ /*
199
+ * Back to the client code http endpoints.
200
+ */
136
201
  RED.httpAdmin.post("/ClientCode/:id",
137
202
  RED.auth.needsPermission("ClientCode.write"),
138
- (req,res) => {
203
+ (req, res) => {
139
204
  var node = RED.nodes.getNode(req.params.id);
140
205
  if (node != null) {
141
206
  try {
142
- if (req.body && node.type == "ClientCode" ) {
207
+ if (req.body && node.type == "ClientCode") {
143
208
  node.send(req.body);
144
209
  res.sendStatus(200);
145
210
  } else {
146
211
  res.sendStatus(404);
147
212
  }
148
- } catch(err) {
213
+ } catch (err) {
149
214
  res.sendStatus(500);
150
215
  }
151
216
  } else {
@@ -177,12 +242,12 @@ module.exports = function(RED) {
177
242
  RED.auth.needsPermission("ClientCode.write"),
178
243
  (req, res) => {
179
244
  try {
180
- if (req.body ) {
181
- req.body.nodes.forEach( n => {
245
+ if (req.body) {
246
+ req.body.nodes.forEach(n => {
182
247
 
183
- if (n.format == "css" && !/[@]obfuscate-ignore/.test(n.template) ) {
248
+ if (n.format == "css" && !/[@]obfuscate-ignore/.test(n.template)) {
184
249
  let output = new CleanCSS(req.body.csscfg).minify(n.template);
185
- if ( output.styles && (output.errors || []).length == 0 ) {
250
+ if (output.styles && (output.errors || []).length == 0) {
186
251
  n.template = output.styles
187
252
  } else {
188
253
  n._error = output.errors
@@ -206,13 +271,13 @@ module.exports = function(RED) {
206
271
  }
207
272
  }
208
273
 
209
- if (n.format == "javascript" && !/[@]obfuscate-ignore/.test(n.template)) {
274
+ if (n.format == "javascript" && !/[@]obfuscate-ignore/.test(n.template)) {
210
275
  /* this handles PkgFile nodes and template nodes */
211
276
  let result = UglifyJS.minify(n.template, req.body.jscfg)
212
277
 
213
- if ( result.code && !result.error) {
278
+ if (result.code && !result.error) {
214
279
  n.template = result.code
215
- } else {
280
+ } else {
216
281
  n._error = result.error
217
282
  n._code = result.code
218
283
  }
@@ -222,13 +287,13 @@ module.exports = function(RED) {
222
287
  let result = UglifyJS.minify(n.func, req.body.jscfg)
223
288
 
224
289
  if (result.code && !result.error) {
225
- n.func = result.code
290
+ n.func = result.code
226
291
  } else {
227
292
  n._error = result.error
228
293
  n._code = result.code
229
294
  }
230
295
  }
231
-
296
+
232
297
  })
233
298
  res.status(200).send(req.body.nodes);
234
299
  } else {
@@ -238,6 +303,4 @@ module.exports = function(RED) {
238
303
  res.sendStatus(500);
239
304
  }
240
305
  });
241
-
242
-
243
306
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gregoriusrippenstein/node-red-contrib-introspection",
3
- "version": "0.9.3",
3
+ "version": "0.9.5",
4
4
  "dependencies": {
5
5
  "got": "^13",
6
6
  "uglify-js": "^3.17.4",
@@ -4,7 +4,7 @@
4
4
 
5
5
  let obfuscateHelpers={getFlowDataFromCurrentWorkspace:e=>{var e=e||RED.workspaces.active(),t=RED.nodes.groups(e),e=(t=(t=t.concat(RED.nodes.junctions(e))).concat(RED.nodes.filterNodes({z:e})),RED.nodes.eachConfig(function(e){e.z===RED.workspaces.active()&&!1===e._def.hasUsers&&t.push(e)}),RED.nodes.workspace(e)||RED.nodes.subflow(e));return t.unshift(e),RED.nodes.createExportableNodeSet(t)},openImportDialog:e=>{RED.clipboard.import();let t=e;setTimeout(()=>{$("#red-ui-clipboard-dialog-import-text").val(JSON.stringify(t)).trigger("paste")},300)}};function obfuscatieCurrentFlow(l){let p=obfuscateHelpers.getFlowDataFromCurrentWorkspace(),f=(l.remove_groups&&(p=p.filter(e=>"group"!=e.type)).forEach(e=>{delete e.g}),{}),t={},d={},c={},s=[],h={},r={};if(p.forEach(e=>{"subflow"==(f[e.id]=e).type&&(r[e.id]=e),"junction"==e.type&&(t[e.id]=e),"link out"==e.type&&(c[e.id]=e),"link in"==e.type&&(d[e.id]=e),"link call"==e.type&&s.push(e.id),"catch"==e.type&&(h[e.id]=(e.wires||[])[0]||[])}),l.remove_junctions&&(Object.keys(t).forEach(n=>{let s=t[n];r[s.z]||p.forEach(t=>{for(let e=0;e<(t.wires||[]).length;e++){var r=t.wires[e].indexOf(n);-1<r&&(t.wires[e].splice(r,1),t.wires[e].push(...s.wires[0]))}})}),p=p.filter(e=>!("junction"==e.type&&!r[e.z]))),l.remove_linkout_nodes||l.remove_linkcall_nodes){let r=[],n=[],i=[],a=(l.remove_linkout_nodes&&!l.copy_linkin_nodes&&Object.keys(c).forEach(n=>{var e=c[n];let s=e.links||[];s.reduce((e,t)=>e&&(!!d[t]||l.ignore_off_flow_links),!0)&&"return"!=e.mode&&(r.push(n),p.forEach(r=>{for(let t=0;t<(r.wires||[]).length;t++){var e=r.wires[t].indexOf(n);-1<e&&(r.wires[t].splice(e,1),s.forEach(e=>{d[e]&&r.wires[t].push(...d[e].wires[0])}))}}))}),(s,e)=>{if(!e)return!1;let t=[],o=[],r=[];function u(e){if(r.indexOf(e.id)<0)switch(r.push(e.id),t.push(e),e.type){case"link out":if("return"!=e.mode)throw"not handable";break;case"link call":throw"unhandled";default:RED.nodes.getNodeLinks(e).forEach(function(e){u(e.target)})}}try{RED.nodes.getNodeLinks(e).forEach(function(e){u(e.target),o.push(e.target.id)});if(Object.keys(h).forEach(e=>{((t,e)=>{try{return e.map(e=>e.id).forEach(e=>{if(t.includes(e))throw"yes"}),!1}catch(e){return!0}})(h[e],t)&&t.push(f[e])}),0==t.length)return!1;let r={};var i=t[0];let n={x:s.x-i.x,y:s.y-i.y};var a=t.map(e=>{var t=structuredClone(f[e.id]);return t||console.log("WARNING: nodeid not found",[e.id,f[e.id]]),t.id=RED.nodes.id(),t.x+=n.x,t.y+=n.y,r[e.id]=t});return a.forEach(e=>{"catch"==e.type&&Array.isArray(e.scope)&&(e.scope=e.scope.map(e=>{var t=r[e];return t&&t.id||e})),e.wires&&(e.wires=e.wires.map(e=>e.map(e=>{var t=r[e];return t&&"link out"==t.type?[...s.wires[0],(t||{}).id||e]:(t||{}).id||e}).flat()))}),{nodes:a.filter(e=>"link out"!=e.type),entryNodes:o.map(e=>r[e])}}catch(e){return!1}});l.remove_linkout_nodes&&l.copy_linkin_nodes&&Object.keys(c).forEach(s=>{let o=c[s],u=o.links||[];if("return"!=o.mode){let t=u.map(e=>{var t=d[e],t=a(o,t);return t?[e,t]:[void 0,void 0]});t.reduce((e,t)=>e&&(!!t[0]||l.ignore_off_flow_links),!0)&&(r.push(s),p.forEach(n=>{for(let r=0;r<(n.wires||[]).length;r++){var e=n.wires[r].indexOf(s);-1<e&&(n.wires[r].splice(e,1),(t=u.map(e=>{var t=d[e],t=a(o,t);return t?[e,t]:[void 0,void 0]})).forEach(([,e])=>{var t;e&&(t=e.entryNodes.map(e=>e.id),n.wires[r].push(...t),i.push(...e.nodes))}))}}))}}),l.remove_linkcall_nodes&&s.forEach(s=>{var e=f[s],t=d[e.links[0]];let o=a(e,t);t&&o&&(n.push(e.id),p.forEach(t=>{for(let e=0;e<(t.wires||[]).length;e++){var r,n=t.wires[e].indexOf(s);-1<n&&(r=o.entryNodes.map(e=>e.id),t.wires[e].splice(n,1),t.wires[e].push(...r),i.push(...o.nodes))}}))}),(p=p.filter(e=>r.indexOf(e.id)<0&&n.indexOf(e.id)<0)).push(...i)}if((p=l.remove_debugs?p.filter(e=>"debug"!=e.type&&"comment"!=e.type):p).forEach(e=>{l.name&&(e.name=RED.nodes.id()),l.shrink_node&&(e.l=!1),l.info&&(e.info="",delete e.outputLabels,delete e.inputLabels),l.add_license&&(l.append_license?e.info=(e.info||"")+"\n---\n\n"+l.license_text:e.info=l.license_text),l.position&&(e.x=150,e.y=150),l.remove_icons&&delete e.icon}),l.replace_switch){let n=(t,r)=>{for(let e=0;e<r.rules.length;e++){var n=r.rules[e];if("nnull"==n.t)t.push("if ( _propValue != null ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("null"==n.t)t.push("if ( _propValue == null ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("eq"==n.t&&"str"==n.vt){s=n.v;s=btoa(encodeURIComponent(s).replace(/%([0-9A-F]{2})/g,function(e,t){return String.fromCharCode("0x"+t)}));t.push("if ( _propValue === Buffer.from('"+s+"', 'base64').toString('utf-8') ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }")}else if("gt"==n.t&&"num"==n.vt)t.push("if ( _propValue > "+n.v+" ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("eq"==n.t&&"num"==n.vt)t.push("if ( _propValue == "+n.v+" ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }");else if("empty"==n.t)t.push('let p = _propValue ; if ( (Array.isArray(p) && p.length == 0) || ((typeof p === "object") && p != null && Object.keys(p).length == 0) || ((typeof p === "string") && p.length == 0) ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }');else if("nempty"==n.t)t.push('let p = _propValue ; if ( (Array.isArray(p) && p.length > 0) || ((typeof p === "object") && p != null && Object.keys(p).length > 0) || ((typeof p === "string") && p.length > 0) ) { _returnValue.push(msg) ; return node.send(_returnValue) } else { _returnValue.push(undefined) }');else{if("else"!=n.t)throw"unhandled";t.push("_returnValue.push(msg)","return node.send(_returnValue)")}}var s};p=p.map(t=>{if("switch"!=t.type)return t;var e={id:t.id,name:t.name,type:"function",x:t.x,y:t.y,func:"",outputs:t.outputs,timeout:"",noerr:0,initialize:"",finalize:"",libs:[{var:"process",module:"process"},{var:"jsonata",module:"jsonata"}],wires:t.wires};t.hasOwnProperty("z")&&(e.z=t.z),t.hasOwnProperty("l")&&(e.l=t.l);try{var r=[];if(t.checkAll)throw"unhandled";if("msg"==t.propertyType)r.push("((msg,node) => {","let _propValue = undefined","try { _propValue = RED.util.getMessageProperty(msg, '"+t.property+"') } catch (ex) {}","let _returnValue = []"),n(r,t),r.push("})(msg,node);");else{if("jsonata"!=t.propertyType)throw"unhandled";r.push("jsonata('"+t.property+"').evaluate(msg).then(_propValue => {","let _returnValue = []"),n(r,t),r.push("})")}return e.func=r.join("\n"),e}catch(e){return t}})}if(l.replace_change){let s=e=>btoa(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g,function(e,t){return String.fromCharCode("0x"+t)}));p=p.map(t=>{if("change"!=t.type)return t;var e={id:t.id,name:t.name,type:"function",x:t.x,y:t.y,func:"",outputs:1,timeout:"",noerr:0,initialize:"",finalize:"",libs:[{var:"process",module:"process"},{var:"jsonata",module:"jsonata"}],wires:t.wires};t.hasOwnProperty("z")&&(e.z=t.z),t.hasOwnProperty("l")&&(e.l=t.l);try{var r=["(async (msg,node) => {","let __s = RED.util.setMessageProperty","let __g = RED.util.getMessageProperty"];for(let e=0;e<t.rules.length;e++){var n=t.rules[e];if("set"==n.t){if(n.dc)throw"unhandled";if("msg"==n.pt&&"str"==n.tot)r.push("__s(msg,'"+n.p+"', Buffer.from('"+s(n.to)+"', 'base64').toString('utf-8') )");else if("msg"==n.pt&&"bool"==n.tot)r.push("__s(msg,'"+n.p+"', "+n.to+")");else if("msg"==n.pt&&"num"==n.tot)r.push("__s(msg,'"+n.p+"', Number(Buffer.from('"+s(n.to)+"', 'base64').toString('utf-8')))");else if("msg"==n.pt&&"json"==n.tot)r.push("__s(msg,'"+n.p+"', JSON.parse(Buffer.from('"+s(n.to)+"', 'base64').toString('utf-8')))");else if("msg"==n.pt&&"msg"==n.tot)r.push("try { __s(msg,'"+n.p+"', __g(msg, '"+n.to+"')) } catch (ex) {}");else if("msg"==n.pt&&"env"==n.tot)r.push("__s(msg,'"+n.p+"', process.env['"+n.to+"'])");else{if("msg"!=n.pt||"jsonata"!=n.tot||!n.to.startsWith("/* @obfuscate-safe */"))throw"unhandlable";r.push("__s(msg,'"+n.p+"', await jsonata(Buffer.from('"+s(n.to)+"', 'base64').toString('utf-8')).evaluate(msg) )")}}else{if("delete"!=n.t||"msg"!=n.pt)throw"unhandlable";r.push("delete msg."+n.p)}}return r.push("node.send(msg) })(msg,node);"),e.func=r.join("\n"),e}catch(e){return console.log(e),t}})}if(l.javascript){let r={},t=[];p.forEach(e=>{"javascript"!=(r[e.id]=e).format&&"function"!=e.type&&"css"!=e.format&&"json"!=e.format||t.push(e)});var e={parse:{bare_returns:!0,expression:!1},compress:{},mangle:{reserved:["$","export","require"]},output:null,sourceMap:null,nameCache:null,toplevel:!1,warnings:!1},o={compatibility:"*",level:2};$.ajax({url:"ClientCode/"+RED.nodes.id()+"/ugify",type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({nodes:t,jscfg:e,csscfg:o}),success:function(e){e.forEach(e=>{var t=r[e.id];e._error&&console.log("ERROR NODE",e),"function"==t.type?t.func=e.func:"javascript"!=t.format&&"css"!=t.format&&"json"!=t.format||(t.template=e.template)}),obfuscateHelpers.openImportDialog(p)},error:function(e,t,r){RED.notify("ClientCode Communcation Failure: "+n.id+": "+t,{type:"error",timeout:3e3})}})}else obfuscateHelpers.openImportDialog(p)}
6
6
 
7
- function setupTreelist(){var e=collectOrphans();if(0==e.length){RED.notify("No Orphans Found",{type:"success",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var n;t.node&&(n=t.node.id,setTimeout(()=>{var e=RED.nodes.node(n);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),n==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectOrphans(){const t=new Set;var n=[],i=(RED.nodes.eachLink(e=>{t.add(e.source),t.add(e.target)}),RED.nodes.eachNode(e=>{(!t.has(e)||"link out"==e.type&&"link"==e.mode&&0==e.links.reduce((e,t)=>e||!!RED.nodes.node(t),!1))&&n.push(e)}),[]),r={};return n.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var n=t.label,n=("function"==typeof n?n.call(e):n)||"",o=e.type;if(0===o.indexOf("subflow:"))return}t&&n||(n=e.type),r[e.id]={node:e,label:n,sublabel:o,selected:!1,checkbox:!1},i.push(r[e.id])}),i}
7
+ function setupTreelist(){var e=collectOrphans();if(0==e.length){RED.notify("No Orphans Found",{type:"success",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var n;t.node&&(n=t.node.id,setTimeout(()=>{var e=RED.nodes.node(n);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),n==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectOrphans(){let t=new Set;var n=[],i=(RED.nodes.eachLink(e=>{t.add(e.source),t.add(e.target)}),RED.nodes.eachNode(e=>{(!t.has(e)||"link out"==e.type&&"link"==e.mode&&0==e.links.reduce((e,t)=>e||!!RED.nodes.node(t),!1))&&n.push(e)}),[]),r={};return n.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var n=t.label,n=("function"==typeof n?n.call(e):n)||"",o=e.type;if(0===o.indexOf("subflow:"))return}t&&n||(n=e.type),r[e.id]={node:e,label:n,sublabel:o,selected:!1,checkbox:!1},i.push(r[e.id])}),i}
8
8
 
9
9
  function nr_intro_generate_svg_4_0(r,t){return e=>{try{handleSvgObject($($("#red-ui-workspace-chart").find("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function nr_intro_generate_svg_3_1(r,t){return e=>{try{handleSvgObject($($("#red-ui-workspace-chart").find("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function nr_intro_generate_svg_3_0(r,t){return e=>{try{handleSvgObject($($("svg")[0]),e,t)}catch(t){var n="Error Generating SVG: "+JSON.stringify(t);r.notify(n,{type:"error"}),e('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+n+"</text></svg>")}}}function handleSvgObject(a,e,t){var n=a.clone(),r=(n.find("foreignObject").remove(),n.find("svg.__screenshot").remove(),'width="'+a.attr("width")+'" height="'+a.attr("height")+'"'),s=RED.settings.version.split("."),i=parseInt(s[0]),s=parseInt(s[1]);if(3<=i&&1<=s){var o=$($($(a).children("g")[0]).children("g")[0]).children("g"),l={x:8e3,y:8e3,w:-1,h:-1};for(let t=1;t<o.length;t++){var g=o[t].getBBox();0==g.width&&0==g.height||(l.x=Math.min(g.x,l.x),l.y=Math.min(g.y,l.y),l.w=Math.max(g.width,l.w),l.h=Math.max(g.height,l.h))}r+=` viewBox='${l.x} ${l.y} ${l.w} ${l.h}'`}function c(t,e){for(var n=0;n<t.length;n++){var s=t.item(n),i=e[n];["stroke-width","fill-opacity","stroke-opacity","opacity","stroke-dasharray"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))}),["fill","stroke"].forEach(function(t){var e,n,r=(e=$(i).attr(t)||$(i).css(t))&&null!==e&&"none"!=e?(n=e.match(/^#(.)(.)(.)$/))?"#"+n[1]+n[1]+n[2]+n[2]+n[3]+n[3]:(n=e.match(/^#......$/))?e:null===(n=e.match(/^rgb\(([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?(r=e.match(/^rgba\(([0-9]+),\s+([0-9]+),\s+([0-9]+),\s+([0-9]+)/))?{clr:"#"+("0"+parseInt(r[1],10).toString(16)).slice(-2)+("0"+parseInt(r[2],10).toString(16)).slice(-2)+("0"+parseInt(r[3],10).toString(16)).slice(-2),opa:r[4]}:(console.log("Screenshot node: returned unknown color: "+e),e):"#"+("0"+parseInt(n[1],10).toString(16)).slice(-2)+("0"+parseInt(n[2],10).toString(16)).slice(-2)+("0"+parseInt(n[3],10).toString(16)).slice(-2):"none";"object"==typeof r?(s.setAttribute(t+"-opacity",r.opa),s.setAttribute(t,r.clr)):s.setAttribute(t,r)}),$(i).hasClass("hide")&&("g"==s.tagName&&s.setAttribute("opacity","0"),s.setAttribute("visibility","hidden"))}}var i='<?xml version="1.0" standalone="no"?>\r\n<svg '+r+' pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" class="__screenshot" xmlns:xlink="http://www.w3.org/1999/xlink">\r\n',s=n.html(),h=(new DOMParser).parseFromString(i+s+"\r\n</svg>","image/svg+xml"),v=t=>t,f=(t.rmidsandclasses&&(v=e=>(["g","rect","line","path","circle","image","text"].forEach(t=>{$(e.getElementsByTagName(t)).each((t,e)=>{e.setAttribute("class",""),e.setAttribute("id","")})}),e)),["g","rect","line","path","circle","image"].forEach(function(t){c(h.getElementsByTagName(t),a.find(t))}),["text"].forEach(function(t){c(h.getElementsByTagName(t),a.find(t));for(var e=h.getElementsByTagName(t),n=a.find(t),r=0;r<e.length;r++){var s=e.item(r),i=n[r];["font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","text-anchor","dominant-baseline"].forEach(function(t){s.setAttribute(t,$(i).attr(t)||$(i).css(t))})}}),h.getElementsByTagName("image")),w={},m=(n,r,s)=>{var i=n.getAttribute("xlink:href")||n.getAttribute("href"),a=i.substr(-4,4).toLowerCase(),o={".jpg":"jpeg",jpeg:"jpeg",".png":"png",".svg":"svg+xml"};if(w[i])return n.setAttribute("xlink:href","data:image/"+o[a]+";base64,"+w[i]),s(r-1);switch(a){case".jpg":case"jpeg":case".png":var l=new XMLHttpRequest;l.open("GET",i,!0),l.responseType="arraybuffer";l.onload=function(t){var e=l.response;e&&(e=(t=>{for(var e="",n=new Uint8Array(t),r=n.byteLength,s=0;s<r;s++)e+=String.fromCharCode(n[s]);return window.btoa(e)})(e),w[i]=e,n.setAttribute("xlink:href","data:image/"+o[a]+";base64,"+e)),s(r-1)},l.send(null);break;case".svg":$.get(i,function(t){var e=new XMLSerializer,e=btoa(e.serializeToString(t));w[i]=e,n.setAttribute("xlink:href","data:image/svg+xml;base64,"+e),s(r-1)})}},d=t=>{t<0?e((new XMLSerializer).serializeToString(v(h))):m(f.item(t),t,d)};0<f.length?m(f.item(f.length-1),f.length-1,d):e((new XMLSerializer).serializeToString(v(h)))}function generatorFunctionForVersion(t,e){var n,r=t.settings.version.split("."),s=r[0],r=r[1];if("3"==s){if("0"==r)return nr_intro_generate_svg_3_0(t,e);if("1"==r)return nr_intro_generate_svg_3_1(t,e)}return"4"==s&&"0"==r?nr_intro_generate_svg_4_0(t,e):(n=t,t=>{var e="Node-RED version ("+n.settings.version+") not supported";n.notify(e,{type:"error"}),t&&t('<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="1000" height="1000" viewBox="0 0 1000 1000" pointer-events="all" style="cursor: crosshair; touch-action: none;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>.small { font: bold 20px sans-serif; fill: red;}</style><text x="10" y="30" class="small">'+e+"</text></svg>")})}function addPanZoom(){var t=d3.select("#node-input-screenshot-svgcontainer svg"),e=(t.html("<g>"+t.html()+"</g>"),setTimeout(()=>{var t=$("#node-input-screenshot-svgcontainer svg"),e=$(t).attr("viewBox").split(" ");t.animate({height:parseInt(e[3]),width:parseInt(e[2])},800,"swing")},100),t.select("g")),n=d3.behavior.zoom().scaleExtent([.1,200]).on("zoom",function(t){e.attr({transform:"translate("+n.translate()+") scale("+n.scale()+")"})});t.call(n)}
10
10
 
@@ -14,7 +14,7 @@
14
14
 
15
15
  function setupTreelistAllLinksForLinkIn(e){e=collectAllLinksNodes(e);if(0==e.length){RED.notify("No links found",{type:"error",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var n;t.node&&(n=t.node.id,setTimeout(()=>{var e=RED.nodes.node(n);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e,"editor-tab-description")),n==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectAllLinksNodes(t){let n=[];RED.nodes.eachNode(e=>{"link call"!=e.type&&"link out"!=e.type||-1<e.links.indexOf(t)&&n.push(e)});var i=[],r={};return n.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var n,o=t.label,o=("function"==typeof o?o.call(e):o)||"";if(0===(n=e.type).indexOf("subflow:"))return}t&&o||(o=e.type),r[e.id]={node:e,label:o,sublabel:n,selected:!1,checkbox:!1},i.push(r[e.id])}),i}function collectNodeStats(){let t={},n=[],o={workspaces:0,junctions:0,subflows:0,configs:0,groups:0,wires:0,nodes:0},i=(RED.nodes.eachConfig(e=>{o.configs+=1}),RED.nodes.eachLink(e=>{o.wires+=1}),RED.nodes.eachJunction(e=>{o.junctions+=1}),RED.nodes.eachGroup(e=>{o.groups+=1}),RED.nodes.eachWorkspace(e=>{o.workspaces+=1}),RED.nodes.eachSubflow(e=>{o.subflows+=1}),RED.nodes.eachNode(e=>{o.nodes+=1,t[e.type]=(t[e.type]||0)+1}),Object.keys(t).forEach(e=>{n.push({label:e,sublabel:t[e],selected:!1,checkbox:!1})}),[]),r=0;return Object.keys(o).forEach(e=>{r+=o[e],i.push({label:e,sublabel:o[e],selected:!1,checkbox:!1})}),[{label:"__ TOTALS",sublabel:r,selected:!1,checkbox:!1,children:i}].concat(n.sort((e,t)=>e.label>t.label))}function setupTreeListForNodeStats(){var e=collectNodeStats();try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){}).on("treelistconfirm",function(e,t){}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e)}
16
16
 
17
- function setupTreeMsgTracerlist(){try{$("#node-input-msgtracer-trace-treelist").treeList("empty"),$("#node-input-msgtracer-trace-treelist").treeList("data",[])}catch(e){$("#node-input-msgtracer-trace-treelist").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw(),$("#node-input-msgtracer-toggle").is(":checked")||($(".red-ui-debug-msg").css("background-color",""),$(".red-ui-debug-msg-node-"+t.node.id).css("background-color","red")))}).on("treelistconfirm",function(e,t){var r;t.node&&(r=t.node.id,setTimeout(()=>{var e=RED.nodes.node(r);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),r==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-msgtracer-trace-treelist-filter").show();var r=$("#node-input-msgtracer-trace-treelist-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-msgtracer-trace-treelist").treeList("filter",null),r.searchBox("count","")):(e=$("#node-input-msgtracer-trace-treelist").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)||-1<e.node.id.toLowerCase().indexOf(t)}),r.searchBox("count",e+" / "+$("#node-input-msgtracer-trace-treelist").treeList("data").length))}})}}function toggleMsgTracingInBackend(e){let t=$("#node-input-msgtracer-toggle").is(":checked"),r=$("#node-input-msgtracer-msgtodebug").is(":checked");$.ajax({url:"MsgTracer/msgtracing/"+(t?"on":"off"),type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({withDebug:r}),success:function(e){RED.notify("Message tracing is <b>"+(t?"on":"off")+"</b> and msg to debug is <b>"+(r?"on":"off")+"</b>",{type:"success",timeout:3e3})},error:function(e,t,r){RED.notify("Message tracing failed: "+t,{type:"error",timeout:3e3})}})}function handleMsgTracerToggles(e){$("#node-input-msgtracer-toggle").is(":checked")&&setupTreeMsgTracerlist(),toggleMsgTracingInBackend(e)}
17
+ function setupTreeMsgTracerlist(){try{$("#node-input-msgtracer-trace-treelist").treeList("empty"),$("#node-input-msgtracer-trace-treelist").treeList("data",[])}catch(e){$("#node-input-msgtracer-trace-treelist").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw(),$("#node-input-msgtracer-toggle").is(":checked")||($(".red-ui-debug-msg").css("background-color",""),$(".red-ui-debug-msg-node-"+t.node.id).css("background-color","red")))}).on("treelistconfirm",function(e,t){var o;t.node&&(o=t.node.id,setTimeout(()=>{var e=RED.nodes.node(o);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),o==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-msgtracer-trace-treelist-filter").show();var o=$("#node-input-msgtracer-trace-treelist-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-msgtracer-trace-treelist").treeList("filter",null),o.searchBox("count","")):(e=$("#node-input-msgtracer-trace-treelist").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)||-1<e.node.id.toLowerCase().indexOf(t)}),o.searchBox("count",e+" / "+$("#node-input-msgtracer-trace-treelist").treeList("data").length))}})}}function toggleDebugTracingInBackend(e){let t=$("#node-input-msgtracer-msgtodebug").is(":checked");var o=$("#node-input-msgtracer-msgtodebug-all").is(":checked"),r=RED.view.selection().nodes;r||o||!t?r&&0<r.length&&o&&t?($("#node-input-msgtracer-msgtodebug").prop("checked",!1),$("#node-input-msgtracer-msgtodebug-all").prop("checked",!1),RED.notify("Debug Messages not toggled, both nodes selected and all nodes is on.",{type:"error",timeout:3e3})):(t||$("#node-input-msgtracer-msgtodebug-all").prop("checked",!1),$.ajax({url:"MsgTracer/debug/"+(t?"on":"off"),type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({nodesSelected:(RED.view.selection().nodes||[]).map(e=>e.id),allIsOn:o}),success:function(e){RED.notify("Message debugging is <b>"+(t?"on":"off")+"</b>",{type:"success",timeout:3e3})},error:function(e,t,o){RED.notify("Message tracing failed: "+t,{type:"error",timeout:3e3})}})):($("#node-input-msgtracer-msgtodebug").prop("checked",!1),RED.notify("Debug Messages not toggled, first select nodes to be debugged <b>or</b> toggle 'all nodes' to on.",{type:"error",timeout:3e3}))}function toggleMsgTracingInBackend(e){let t=$("#node-input-msgtracer-toggle").is(":checked");var o=$("#node-input-msgtracer-toggle-all").is(":checked"),r=RED.view.selection().nodes;r||o||!t?r&&0<r.length&&o&&t?($("#node-input-msgtracer-toggle-all").prop("checked",!1),$("#node-input-msgtracer-toggle").prop("checked",!1),RED.notify("Message tracing not toggled, nodes are selected <b>and</b> all nodes is checked.",{type:"error",timeout:3e3})):(t||$("#node-input-msgtracer-toggle-all").prop("checked",!1),t&&setupTreeMsgTracerlist(),$.ajax({url:"MsgTracer/msgtracing/"+(t?"on":"off"),type:"POST",contentType:"application/json; charset=utf-8",data:JSON.stringify({nodesSelected:(RED.view.selection().nodes||[]).map(e=>e.id),allIsOn:o}),success:function(e){RED.notify("Message tracing is <b>"+(t?"on":"off")+"</b>",{type:"success",timeout:3e3})},error:function(e,t,o){RED.notify("Message tracing failed: "+t,{type:"error",timeout:3e3})}})):($("#node-input-msgtracer-toggle").prop("checked",!1),RED.notify("Message tracing not toggled, first select nodes to be traced <b>or</b> toggle 'all nodes' to on.",{type:"error",timeout:3e3}))}
18
18
 
19
19
  // Add your plugin as a new tabsheet in the right sidebar AFTER the flow editor is completely started
20
20
  var initialiseConfigNodeOnce = () => {
@@ -257,8 +257,8 @@
257
257
  $("#node-input-msgtracer-trace-treelist").treeList('data', [])
258
258
  })
259
259
 
260
- $('#node-input-msgtracer-msgtodebug').on("change", toggleMsgTracingInBackend)
261
- $('#node-input-msgtracer-toggle').on("change", handleMsgTracerToggles)
260
+ $('#node-input-msgtracer-msgtodebug').on("change", toggleDebugTracingInBackend)
261
+ $('#node-input-msgtracer-toggle').on("change", toggleMsgTracingInBackend)
262
262
 
263
263
  RED.actions.add( "introspection:show-link-call-links", highlightAllLinkCalls)
264
264
 
@@ -366,53 +366,69 @@
366
366
  class="red-ui-button"><i class="fa fa-cc"></i> Undocumented</button>
367
367
  <button id="node-input-linkin-nodes-find-btn"
368
368
  class="red-ui-button"><i class="fa fa-link"></i> Link Ins</button>
369
+ <button id="node-input-linkcalls-find-btn"
370
+ class="red-ui-button"><i class="fa fa-link"></i> Link Calls</button>
371
+ <button id="node-input-orphan-clear-workspace-btn"
372
+ class="red-ui-button">Clear dots</button>
369
373
  <button id="node-input-statistics-btn"
370
374
  class="red-ui-button"><i class="fa fa-pie-chart"></i> Stats</button>
371
375
  </div>
372
376
 
373
377
  <div class="form-row"
374
- style="margin-left: 10px; position: relative; min-height: 200px; height: 450px; margin-right: 15px;">
378
+ style="margin-left: 10px; position: relative; min-height: 200px; height: 430px; margin-right: 15px;">
375
379
  <div style="margin-bottom: 5px; width: 35%; padding-left: 60%;">
376
380
  <input type="text" id="node-input-orphan-target-filter" style="display: none;">
377
381
  </div>
378
382
  <div id="node-input-orphan-target-container-div"></div>
379
383
  </div>
380
384
 
381
- <div class="form-row" style="margin-left: 10px; margin-top: 40px">
382
- <button id="node-input-linkcalls-find-btn"
383
- class="red-ui-button"><i class="fa fa-link"></i> Link Calls</button>
384
- <button id="node-input-orphan-clear-workspace-btn"
385
- class="red-ui-button">Clear dots</button>
386
- </div>
385
+ <!-- message tracing stuff -->
387
386
 
388
387
  <div class="form-row" style="margin-left: 10px; margin-top: 40px">
389
388
  <label for="node-input-msgtracer-toggle" class="w-25">
390
- <i class="fa fa-stethoscope"></i>
391
- <span>Trace Messages?</span>
389
+ <i class="fa fa-stethoscope"></i>
390
+ <span>Trace selected nodes?</span>
392
391
  </label>
393
392
  <input type="checkbox" id="node-input-msgtracer-toggle"
394
- style="display:inline-block; width:15px; vertical-align:baseline;">
393
+ style="display:inline-block; width:15px; vertical-align:baseline;">
395
394
 
396
- <label for="node-input-msgtracer-msgtodebug" class="w-25">
397
- <i class="fa fa-bug"></i>
398
- <span>Msg to Debug?</span>
395
+ <label for="node-input-msgtracer-toggle-all" class="w-25">
396
+ <i class="fa fa-warning"></i>
397
+ <span>All nodes?</span>
399
398
  </label>
400
- <input type="checkbox" id="node-input-msgtracer-msgtodebug"
401
- style="display:inline-block; width:15px; vertical-align:baseline;">
399
+ <input type="checkbox" id="node-input-msgtracer-toggle-all"
400
+ style="display:inline-block; width:15px; vertical-align:baseline;">
402
401
 
403
402
  <button id="node-input-msgtrace-clear-trace-btn" style="margin-left: 10px;"
404
403
  class="red-ui-button">Clear Trace</button>
405
- <button id="node-input-msgtrace-clear-debug-btn" style="margin-left: 10px;"
406
- class="red-ui-button">Clear Debug</button>
407
404
  </div>
408
405
 
409
406
  <div class="form-row"
410
- style="margin-left: 10px; position: relative; min-height: 200px; height: 450px; margin-right: 15px;">
407
+ style="margin-left: 10px; position: relative; min-height: 200px; height: 430px; margin-right: 15px;">
411
408
  <div style="margin-bottom: 5px; width: 35%; padding-left: 60%;">
412
409
  <input type="text" id="node-input-msgtracer-trace-treelist-filter" style="display: none;">
413
410
  </div>
414
411
  <div id="node-input-msgtracer-trace-treelist"></div>
415
412
  </div>
413
+
414
+ <div class="form-row" style="margin-left: 10px; margin-top: 40px;">
415
+ <label for="node-input-msgtracer-msgtodebug" class="w-25">
416
+ <i class="fa fa-bug"></i>
417
+ <span>Msgs from selected nodes to Debug?</span>
418
+ </label>
419
+ <input type="checkbox" id="node-input-msgtracer-msgtodebug"
420
+ style="display:inline-block; width:15px; vertical-align:baseline;">
421
+
422
+ <label for="node-input-msgtracer-msgtodebug-all" class="w-25">
423
+ <i class="fa fa-warning"></i>
424
+ <span>All nodes?</span>
425
+ </label>
426
+ <input type="checkbox" id="node-input-msgtracer-msgtodebug-all"
427
+ style="display:inline-block; width:15px; vertical-align:baseline;">
428
+
429
+ <button id="node-input-msgtrace-clear-debug-btn" style="margin-left: 10px;"
430
+ class="red-ui-button">Clear Debug</button>
431
+ </div>
416
432
  </div>
417
433
 
418
434
  <!-- Obfuscation Tab in Sidebar -->