node-red-contrib-boolean-logic-ultimate 1.0.63 → 1.1.0

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.
@@ -1,54 +1,82 @@
1
1
  module.exports = function (RED) {
2
- function InvertUltimate(config) {
3
- RED.nodes.createNode(this, config);
4
- this.config = config;
5
- var node = this;
2
+ function InvertUltimate(config) {
3
+ RED.nodes.createNode(this, config);
4
+ this.config = config;
5
+ var node = this;
6
6
 
7
+ function setNodeStatus({ fill, shape, text }) {
8
+ let dDate = new Date();
9
+ node.status({
10
+ fill: fill,
11
+ shape: shape,
12
+ text:
13
+ text +
14
+ " (" +
15
+ dDate.getDate() +
16
+ ", " +
17
+ dDate.toLocaleTimeString() +
18
+ ")",
19
+ });
20
+ }
7
21
 
8
- function setNodeStatus({ fill, shape, text }) {
9
- let dDate = new Date();
10
- node.status({ fill: fill, shape: shape, text: text + " (" + dDate.getDate() + ", " + dDate.toLocaleTimeString() + ")" })
11
- }
22
+ setNodeStatus({ fill: "grey", shape: "dot", text: "Waiting" });
12
23
 
13
- setNodeStatus({ fill: "grey", shape: "dot", text: "Waiting" });
24
+ this.on("input", function (msg) {
25
+ // 11/11/2021 Clone input message and replace only relevant topics
26
+ const utils = require("./utils.js");
27
+ let sPayload = utils.fetchFromObject(
28
+ msg,
29
+ config.payloadPropName || "payload"
30
+ );
14
31
 
15
- this.on('input', function (msg) {
32
+ // 15/11/2021 inform user about undefined topic or payload
33
+ if (sPayload === undefined) {
34
+ setNodeStatus({
35
+ fill: "red",
36
+ shape: "dot",
37
+ text: "Received invalid payload from " + msg.topic || "",
38
+ });
39
+ return;
40
+ }
16
41
 
42
+ var bRes = null;
43
+ try {
44
+ bRes = utils.ToBoolean(
45
+ sPayload,
46
+ RED.nodes.getNode(config.translatorConfig) // Retrieve the config node. It can be null, but it's handled in utils.js; // 15/11/2021 Convert input to boolean.);
47
+ );
48
+ } catch (error) {}
49
+ if (bRes === undefined || bRes === null) {
50
+ setNodeStatus({
51
+ fill: "red",
52
+ shape: "dot",
53
+ text:
54
+ "Received non convertible boolean value " +
55
+ sPayload +
56
+ " from " +
57
+ msg.topic,
58
+ });
59
+ return;
60
+ }
17
61
 
18
- // 11/11/2021 Clone input message and replace only relevant topics
19
- const utils = require("./utils.js");
20
- let sPayload = utils.fetchFromObject(msg, config.payloadPropName || "payload");
62
+ var msgOUt = RED.util.cloneMessage(msg);
63
+ try {
64
+ msgOUt.payload = !bRes;
65
+ setNodeStatus({
66
+ fill: "green",
67
+ shape: "dot",
68
+ text: "(Send) " + msgOUt.payload,
69
+ });
70
+ node.send(msgOUt);
71
+ } catch (error) {
72
+ setNodeStatus({
73
+ fill: "red",
74
+ shape: "dot",
75
+ text: "Unable to invert the input payload " + bRes,
76
+ });
77
+ }
78
+ });
79
+ }
21
80
 
22
- // 15/11/2021 inform user about undefined topic or payload
23
- if (sPayload === undefined ) {
24
- setNodeStatus({ fill: "red", shape: "dot", text: "Received invalid payload from " + msg.topic || "" });
25
- return;
26
- }
27
-
28
- var bRes = null;
29
- try {
30
- bRes = utils.ToBoolean(sPayload);
31
- } catch (error) {
32
- }
33
- if (bRes === undefined || bRes === null) {
34
- setNodeStatus({ fill: "red", shape: "dot", text: "Received non convertible boolean value " + sPayload + " from " + msg.topic });
35
- return;
36
- }
37
-
38
- var msgOUt = RED.util.cloneMessage(msg);
39
- try {
40
- msgOUt.payload = !bRes;
41
- setNodeStatus({ fill: "green", shape: "dot", text: "(Send) " + msgOUt.payload });
42
- node.send(msgOUt);
43
- } catch (error) {
44
- setNodeStatus({ fill: "red", shape: "dot", text: "Unable to invert the input payload " + bRes });
45
- }
46
-
47
- });
48
-
49
- }
50
-
51
-
52
-
53
- RED.nodes.registerType("InvertUltimate", InvertUltimate);
54
- }
81
+ RED.nodes.registerType("InvertUltimate", InvertUltimate);
82
+ };
@@ -7,7 +7,8 @@
7
7
  triggertopic: { value: "trigger" },
8
8
  initializewith: { value: "0" },
9
9
  autoToggle: { value: "0" },
10
- payloadPropName: { value: "payload", required: false }
10
+ payloadPropName: { value: "payload", required: false },
11
+ translatorConfig: { type: "translator-config", required: false }
11
12
  },
12
13
  inputs: 1,
13
14
  outputs: 2,
@@ -85,6 +86,15 @@
85
86
  <option value="120">Toggle above option after 120 seconds</option>
86
87
  </select>
87
88
  </div>
89
+ <div class="form-row">
90
+ <br />
91
+ <b>Translator</b>
92
+ <br />
93
+ <label for="node-input-translatorConfig">
94
+ <font color="green" size="4px"><i class="fa fa-sign-in" aria-hidden="true"></i></font> Input
95
+ </label>
96
+ <input type="text" id="node-input-translatorConfig" />
97
+ </div>
88
98
  </script>
89
99
 
90
100
  <script type="text/markdown" data-help-name="RailwaySwitchUltimate">
@@ -95,6 +105,7 @@
95
105
  | Switcher topic | Whenever the node receives a payload from this **topic**, it switches the input messages to an output. |
96
106
  | With Input | It's the msg property to be evaluated. *By default, it is "payload", but you can also specify other properties, for example "payload.value"* |
97
107
  | Then | This property, allow you to auto toggle the selected start state after some time. |
108
+ | Translator Input | Translates the incoming <code>payload</code> value, to true/false. This allows the compatibility with, for example, **HomeAssistant** nodes. |
98
109
 
99
110
  * Input messages
100
111
 
@@ -1,81 +1,120 @@
1
1
  module.exports = function (RED) {
2
- function RailwaySwitchUltimate(config) {
3
- RED.nodes.createNode(this, config);
4
- this.config = config;
5
- var node = this;
6
- node.currentMsg = {}; // Stores current payload
7
- node.sTriggerTopic = node.config.triggertopic.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '') || "trigger"; // Topic controlling the iRailway
8
- node.iRailway = Number(node.config.initializewith); // Railway selector
9
- node.autoToggle = config.autoToggle === undefined ? 0 : parseInt(config.autoToggle); // Auto toggle the selected "initializewith" after a while (useful for homekit bridged, that sends junk after start)
10
- node.timerAutoToggle = null;
2
+ function RailwaySwitchUltimate(config) {
3
+ RED.nodes.createNode(this, config);
4
+ this.config = config;
5
+ var node = this;
6
+ node.currentMsg = {}; // Stores current payload
7
+ node.sTriggerTopic =
8
+ node.config.triggertopic.replace(
9
+ /[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi,
10
+ ""
11
+ ) || "trigger"; // Topic controlling the iRailway
12
+ node.iRailway = Number(node.config.initializewith); // Railway selector
13
+ node.autoToggle =
14
+ config.autoToggle === undefined ? 0 : parseInt(config.autoToggle); // Auto toggle the selected "initializewith" after a while (useful for homekit bridged, that sends junk after start)
15
+ node.timerAutoToggle = null;
11
16
 
12
- function setNodeStatus({ fill, shape, text }) {
13
- let dDate = new Date();
14
- node.status({ fill: fill, shape: shape, text: text + " (" + dDate.getDate() + ", " + dDate.toLocaleTimeString() + ")" })
15
- }
17
+ function setNodeStatus({ fill, shape, text }) {
18
+ let dDate = new Date();
19
+ node.status({
20
+ fill: fill,
21
+ shape: shape,
22
+ text:
23
+ text +
24
+ " (" +
25
+ dDate.getDate() +
26
+ ", " +
27
+ dDate.toLocaleTimeString() +
28
+ ")",
29
+ });
30
+ }
16
31
 
17
- node.alignStatus = () => {
18
- let sAutoToggle = node.autoToggle > 0 ? " (Autotoggle in " + node.autoToggle + "s)" : "";
19
- if (node.iRailway === 0) {
20
- setNodeStatus({ fill: "green", shape: "dot", text: "-> UPPER PIN" + sAutoToggle });
21
- } else {
22
- setNodeStatus({ fill: "blue", shape: "dot", text: "-> LOWER PIN" + sAutoToggle });
23
- }
24
- }
32
+ node.alignStatus = () => {
33
+ let sAutoToggle =
34
+ node.autoToggle > 0 ? " (Autotoggle in " + node.autoToggle + "s)" : "";
35
+ if (node.iRailway === 0) {
36
+ setNodeStatus({
37
+ fill: "green",
38
+ shape: "dot",
39
+ text: "-> UPPER PIN" + sAutoToggle,
40
+ });
41
+ } else {
42
+ setNodeStatus({
43
+ fill: "blue",
44
+ shape: "dot",
45
+ text: "-> LOWER PIN" + sAutoToggle,
46
+ });
47
+ }
48
+ };
25
49
 
26
- if (node.autoToggle > 0) {
27
- node.timerAutoToggle = setTimeout(() => {
28
- node.autoToggle = 0;
29
- node.iRailway === 0 ? node.iRailway = 1 : node.iRailway = 0;
30
- node.alignStatus();
31
- }, node.autoToggle * 1000);
32
- }
50
+ if (node.autoToggle > 0) {
51
+ node.timerAutoToggle = setTimeout(() => {
52
+ node.autoToggle = 0;
53
+ node.iRailway === 0 ? (node.iRailway = 1) : (node.iRailway = 0);
54
+ node.alignStatus();
55
+ }, node.autoToggle * 1000);
56
+ }
33
57
 
34
- node.alignStatus();
58
+ node.alignStatus();
35
59
 
36
- this.on('input', function (msg) {
37
- var sIncomingTopic = "";
38
- if (msg.hasOwnProperty("topic")) {
39
- // 06/11/2019
40
- if (!msg.hasOwnProperty("topic") || msg.topic === undefined) msg.topic = "NoTopicReceived";
41
- sIncomingTopic = msg.topic.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, ''); // Cut unwanted Characters
42
- if (sIncomingTopic === node.sTriggerTopic) {
60
+ this.on("input", function (msg) {
61
+ var sIncomingTopic = "";
62
+ if (msg.hasOwnProperty("topic")) {
63
+ // 06/11/2019
64
+ if (!msg.hasOwnProperty("topic") || msg.topic === undefined)
65
+ msg.topic = "NoTopicReceived";
66
+ sIncomingTopic = msg.topic.replace(
67
+ /[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi,
68
+ ""
69
+ ); // Cut unwanted Characters
70
+ if (sIncomingTopic === node.sTriggerTopic) {
71
+ const utils = require("./utils.js");
72
+ let sPayload = utils.fetchFromObject(
73
+ msg,
74
+ config.payloadPropName || "payload"
75
+ );
43
76
 
77
+ // 15/11/2021 inform user about undefined topic or payload
78
+ if (sPayload === undefined) {
79
+ setNodeStatus({
80
+ fill: "red",
81
+ shape: "dot",
82
+ text: "Received invalid payload from " + msg.topic || "",
83
+ });
84
+ return;
85
+ }
44
86
 
45
- const utils = require("./utils.js");
46
- let sPayload = utils.fetchFromObject(msg, config.payloadPropName || "payload");
47
-
48
- // 15/11/2021 inform user about undefined topic or payload
49
- if (sPayload === undefined ) {
50
- setNodeStatus({ fill: "red", shape: "dot", text: "Received invalid payload from " + msg.topic || "" });
51
- return;
52
- }
53
-
54
- msg.payload = utils.ToBoolean(sPayload); // 15/11/2021 Convert input to boolean.
87
+ msg.payload = utils.ToBoolean(
88
+ sPayload,
89
+ RED.nodes.getNode(config.translatorConfig) // Retrieve the config node. It can be null, but it's handled in utils.js;
90
+ );
91
+ if (msg.payload === undefined) return null;
92
+ if (node.timerAutoToggle !== null)
93
+ // 28/01/2022 Stop autotoggle
94
+ clearInterval(node.timerAutoToggle);
55
95
 
56
- // 28/01/2022 Stop autotoggle
57
- if (node.timerAutoToggle !== null) clearInterval(node.timerAutoToggle);
96
+ if (msg.payload === false) node.iRailway = 0;
97
+ if (msg.payload === true) node.iRailway = 1;
98
+ if (node.iRailway === 0) {
99
+ setNodeStatus({
100
+ fill: "green",
101
+ shape: "dot",
102
+ text: "-> UPPER PIN",
103
+ });
104
+ } else {
105
+ setNodeStatus({ fill: "blue", shape: "dot", text: "-> LOWER PIN" });
106
+ }
107
+ return; // DONT'S SEND THIS MESSAGE
108
+ }
109
+ }
110
+ node.currentMsg = RED.util.cloneMessage(msg);
111
+ if (node.iRailway === 0) {
112
+ node.send([msg, null]);
113
+ } else {
114
+ node.send([null, msg]);
115
+ }
116
+ });
117
+ }
58
118
 
59
- if (msg.payload === false) node.iRailway = 0;
60
- if (msg.payload === true) node.iRailway = 1;
61
- if (node.iRailway === 0) {
62
- setNodeStatus({ fill: "green", shape: "dot", text: "-> UPPER PIN" });
63
- } else {
64
- setNodeStatus({ fill: "blue", shape: "dot", text: "-> LOWER PIN" });
65
- }
66
- return; // DONT'S SEND THIS MESSAGE
67
- }
68
- }
69
- node.currentMsg = RED.util.cloneMessage(msg);
70
- if (node.iRailway === 0) {
71
- node.send([msg, null]);
72
- } else {
73
- node.send([null, msg]);
74
- }
75
- });
76
-
77
- }
78
-
79
-
80
- RED.nodes.registerType("RailwaySwitchUltimate", RailwaySwitchUltimate);
81
- }
119
+ RED.nodes.registerType("RailwaySwitchUltimate", RailwaySwitchUltimate);
120
+ };
@@ -7,7 +7,8 @@
7
7
  value: "Toggle"
8
8
  },
9
9
  valueToToggle: { value: "true" },
10
- payloadPropName: { value: "payload", required: false }
10
+ payloadPropName: { value: "payload", required: false },
11
+ translatorConfig: { type: "translator-config", required: false }
11
12
  },
12
13
  inputs: 1,
13
14
  outputs: 1,
@@ -55,7 +56,15 @@
55
56
  <i class="fa fa-home"></i>&nbsp;Output Home Assistant "on"/"off" instead of true/false
56
57
  </label>
57
58
  </div> -->
58
-
59
+ <div class="form-row">
60
+ <br />
61
+ <b>Translator</b>
62
+ <br />
63
+ <label for="node-input-translatorConfig">
64
+ <font color="green" size="4px"><i class="fa fa-sign-in" aria-hidden="true"></i></font> Input
65
+ </label>
66
+ <input type="text" id="node-input-translatorConfig" />
67
+ </div>
59
68
 
60
69
  </script>
61
70
 
@@ -65,6 +74,7 @@
65
74
  |Property|Description|
66
75
  |--|--|
67
76
  | Input | It's the msg property to be evaluated. *By default, it is "payload", but you can also specify other properties, for example "payload.value"* |
77
+ | Translator Input | Translates the incoming <code>payload</code> value, to true/false. This allows the compatibility with, for example, **HomeAssistant** nodes. |
68
78
 
69
79
  * Input message
70
80
 
@@ -4,7 +4,7 @@ module.exports = function (RED) {
4
4
  this.config = config;
5
5
  var node = this;
6
6
  const utils = require("./utils.js");
7
- node.valueToToggle = config.valueToToggle === undefined ? true : utils.ToBoolean(config.valueToToggle);
7
+ node.valueToToggle = config.valueToToggle === undefined ? true : utils.ToBoolean(config.valueToToggle, RED.nodes.getNode(config.translatorConfig)) // Retrieve the config node. It can be null, but it's handled in utils.js);
8
8
 
9
9
  function setNodeStatus({ fill, shape, text }) {
10
10
  let dDate = new Date();
@@ -0,0 +1,63 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('translator-config', {
3
+ category: 'config',
4
+ defaults: {
5
+ name: { value: "" },
6
+ commandText: { value: 'on:true\noff:false\nactive:true\ninactive:false\nopen:true\nclosed:false\nclose:false\n1:true\n0:false\ntrue:true\nfalse:false\nhome:true\nnot_home:false', required: false }
7
+ },
8
+ label: function () {
9
+ return this.name;
10
+ },
11
+ oneditprepare: function () {
12
+ var node = this;
13
+ node.editor = RED.editor.createEditor({
14
+ id: 'node-input-editorcommandText',
15
+ mode: 'ace/mode/text',
16
+ value: node.commandText
17
+ });
18
+ },
19
+ oneditsave: function () {
20
+ var node = this;
21
+ node.commandText = node.editor.getValue();
22
+ node.editor.destroy();
23
+ delete node.editor;
24
+ },
25
+ oneditcancel: function () {
26
+ var node = this;
27
+ node.editor.destroy();
28
+ delete node.editor;
29
+ },
30
+ });
31
+ </script>
32
+
33
+ <script type="text/html" data-template-name="translator-config">
34
+ <div class="form-row">
35
+ <label for="node-config-input-name">
36
+ <i class="fa fa-tag"></i> Name
37
+ </label>
38
+ <input type="text" id="node-config-input-name">
39
+ </div>
40
+ <div class="form-row">
41
+ <label style="width:300px;" for="node-input-commandText"><i class="fa fa-tasks"></i> Translate</label>
42
+ <div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-editorcommandText"></div>
43
+ </div>
44
+ </script>
45
+
46
+ <script type="text/markdown" data-help-name="translator-config">
47
+ <p>This node translates the input msg to valid true/false values.<p>
48
+
49
+
50
+ It can translate an input payload, to a true/false boolean values.<br />
51
+ Each row in the text box, represents a translation command. <br/>
52
+ There are some default translation's rows, to make the *boolean-logic-ultimate* nodes compatible with Homeassistant. <br/>
53
+ You can add your own translation row.<br/>
54
+
55
+ |Property|Description|
56
+ |--|--|
57
+ | Translate | Add, delete or edit your own translation command. The row's translation command must be **input string:true(or false)**. For example: <code>open:true</code> <code>closed:false</code> |
58
+
59
+ <br/>
60
+
61
+
62
+ [Find it useful?](https://www.paypal.me/techtoday)
63
+ </script>
@@ -0,0 +1,8 @@
1
+ module.exports = function(RED) {
2
+ function TranslatorConfig(n) {
3
+ RED.nodes.createNode(this,n);
4
+ this.commandText = n.commandText;
5
+
6
+ }
7
+ RED.nodes.registerType("translator-config",TranslatorConfig);
8
+ }
@@ -1,48 +1,57 @@
1
- module.exports.ToBoolean = function ToBoolean(value) {
2
- let res = false;
3
- let decimal = /^\s*[+-]{0,1}\s*([\d]+(\.[\d]*)*)\s*$/
4
-
5
- if (typeof value === 'boolean') {
6
- return value;
7
- } else if (typeof value === 'string') {
8
-
9
- if (value.toLowerCase() === "on") return true;
10
- if (value.toLowerCase() === "off") return false;
11
-
12
- if (value.toLowerCase() === "active") return true;
13
- if (value.toLowerCase() === "inactive") return false;
14
-
15
- if (value.toLowerCase() === "open") return true;
16
- if (value.toLowerCase() === "closed") return false;
17
- if (value.toLowerCase() === "close") return false;
18
-
19
- if (value.toLowerCase() === "1") return true;
20
- if (value.toLowerCase() === "0") return false;
21
-
22
- if (value.toLowerCase() === "true") return true;
23
- if (value.toLowerCase() === "false") return false;
24
-
25
- if (value.toLowerCase() === "home") return true;
26
- if (value.toLowerCase() === "not_home") return false;
27
-
28
- } else if (typeof value === 'number') {
29
- // Is it formated as a decimal number?
30
- if (decimal.test(value)) {
31
- res = parseFloat(value) != 0;
32
- }
33
- else {
34
- res = value.toLowerCase() === "true";
1
+ module.exports.ToBoolean = function ToBoolean(value, _configTranslationNode) {
2
+ let res = false;
3
+ let decimal = /^\s*[+-]{0,1}\s*([\d]+(\.[\d]*)*)\s*$/;
4
+
5
+ if (typeof value === "boolean") {
6
+ return value;
7
+ } else if (typeof value === "string") {
8
+ try {
9
+ let translationTable = [];
10
+ if (_configTranslationNode === null) {
11
+ translationTable = DEFAULTTRANSLATIONINPUT.split("\n");
12
+ } else {
13
+ translationTable = _configTranslationNode.commandText.split("\n");
14
+ }
15
+ for (let index = 0; index < translationTable.length; index++) {
16
+ let inputPayloadToBeTranslated = translationTable[index].split(":")[0];
17
+ let outputBoolean = Boolean(translationTable[index].split(":")[1]);
18
+ if (
19
+ value.toLowerCase() === inputPayloadToBeTranslated.toLowerCase() &&
20
+ inputPayloadToBeTranslated.toLowerCase() !== ""
21
+ ) {
22
+ return translationTable[index].split(":")[1] === "true"
23
+ ? true
24
+ : false;
35
25
  }
36
- return res;
26
+ }
27
+ } catch (error) {
28
+ console.log("Boolean-Logic-Ultimate:utils:toBoolean: " + error.message);
37
29
  }
30
+ } else if (typeof value === "number") {
31
+ // Is it formated as a decimal number?
32
+ if (decimal.test(value)) {
33
+ res = parseFloat(value) != 0;
34
+ } else {
35
+ res = value.toLowerCase() === "true";
36
+ }
37
+ return res;
38
+ }
38
39
  };
39
40
 
40
- module.exports.fetchFromObject = function fetchFromObject(_msg, _payloadPropName) {
41
- // The output cannot be an oblect. In case, return undefined.
42
- var _index = _payloadPropName.indexOf('.')
43
- if (_index > -1) {
44
- return fetchFromObject(_msg[_payloadPropName.substring(0, _index)], _payloadPropName.substr(_index + 1));
45
- }
46
- if (typeof _msg[_payloadPropName] === "object") return undefined;
47
- return _msg[_payloadPropName];
41
+ module.exports.fetchFromObject = function fetchFromObject(
42
+ _msg,
43
+ _payloadPropName
44
+ ) {
45
+ // The output cannot be an oblect. In case, return undefined.
46
+ var _index = _payloadPropName.indexOf(".");
47
+ if (_index > -1) {
48
+ return fetchFromObject(
49
+ _msg[_payloadPropName.substring(0, _index)],
50
+ _payloadPropName.substr(_index + 1)
51
+ );
52
+ }
53
+ if (typeof _msg[_payloadPropName] === "object") return undefined;
54
+ return _msg[_payloadPropName];
48
55
  };
56
+ const DEFAULTTRANSLATIONINPUT =
57
+ "on:true\noff:false\nactive:true\ninactive:false\nopen:true\nclosed:false\nclose:false\n1:true\n0:false\ntrue:true\nfalse:false\nhome:true\nnot_home:false";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-boolean-logic-ultimate",
3
- "version": "1.0.63",
3
+ "version": "1.1.0",
4
4
  "description": "A set of Node-RED enhanced boolean logic and utility nodes, flow interruption, blinker, invert, filter, toggle etc.., with persistent values after reboot. Compatible also with Homeassistant values.",
5
5
  "author": "Supergiovane (https://github.com/Supergiovane)",
6
6
  "dependencies": {
@@ -33,7 +33,8 @@
33
33
  "SumUltimate": "boolean-logic-ultimate/SumUltimate.js",
34
34
  "toggleUltimate": "boolean-logic-ultimate/toggleUltimate.js",
35
35
  "RailwaySwitchUltimate": "boolean-logic-ultimate/RailwaySwitchUltimate.js",
36
- "Comparator": "boolean-logic-ultimate/Comparator.js"
36
+ "Comparator": "boolean-logic-ultimate/Comparator.js",
37
+ "translator-config": "boolean-logic-ultimate/translator-config.js"
37
38
  }
38
39
  }
39
40
  }