@briza/illogical 1.4.3 → 1.5.2

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.
Files changed (35) hide show
  1. package/changelog.md +13 -0
  2. package/lib/illogical.esm.js +82 -176
  3. package/lib/illogical.js +82 -175
  4. package/package.json +23 -23
  5. package/readme.md +21 -7
  6. package/types/common/evaluable.d.ts +57 -57
  7. package/types/common/type-check.d.ts +28 -32
  8. package/types/common/util.d.ts +11 -11
  9. package/types/expression/comparison/eq.d.ts +18 -22
  10. package/types/expression/comparison/ge.d.ts +18 -22
  11. package/types/expression/comparison/gt.d.ts +18 -22
  12. package/types/expression/comparison/in.d.ts +23 -27
  13. package/types/expression/comparison/index.d.ts +45 -49
  14. package/types/expression/comparison/le.d.ts +18 -22
  15. package/types/expression/comparison/lt.d.ts +18 -22
  16. package/types/expression/comparison/ne.d.ts +18 -22
  17. package/types/expression/comparison/not-in.d.ts +23 -27
  18. package/types/expression/comparison/overlap.d.ts +23 -27
  19. package/types/expression/comparison/prefix.d.ts +23 -27
  20. package/types/expression/comparison/present.d.ts +25 -29
  21. package/types/expression/comparison/suffix.d.ts +23 -27
  22. package/types/expression/comparison/undefined.d.ts +28 -32
  23. package/types/expression/logical/and.d.ts +23 -27
  24. package/types/expression/logical/index.d.ts +32 -36
  25. package/types/expression/logical/nor.d.ts +23 -27
  26. package/types/expression/logical/not.d.ts +23 -27
  27. package/types/expression/logical/or.d.ts +23 -27
  28. package/types/expression/logical/xor.d.ts +23 -27
  29. package/types/index.d.ts +73 -71
  30. package/types/operand/collection.d.ts +36 -40
  31. package/types/operand/index.d.ts +25 -29
  32. package/types/operand/reference.d.ts +44 -48
  33. package/types/operand/value.d.ts +31 -35
  34. package/types/parser/index.d.ts +39 -43
  35. package/types/parser/options.d.ts +61 -65
package/changelog.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # illogical changelog
2
2
 
3
+ ## 1.5.2
4
+
5
+ - Update dependencies.
6
+
7
+ ## 1.5.1
8
+
9
+ - Fix issue with nested conditions not being completely simplified.
10
+
11
+ ## 1.5.0
12
+
13
+ - Add simplify capability to strictly evaluate the expression for all referred values
14
+ not present in the context except for a specified list of optional keys
15
+
3
16
  ## 1.4.3
4
17
 
5
18
  - Prevent unexpected parsing of any expression used as an operand in a comparison expression
@@ -1,23 +1,3 @@
1
- function _defineProperty(obj, key, value) {
2
- if (key in obj) {
3
- Object.defineProperty(obj, key, {
4
- value: value,
5
- enumerable: true,
6
- configurable: true,
7
- writable: true
8
- });
9
- } else {
10
- obj[key] = value;
11
- }
12
-
13
- return obj;
14
- }
15
-
16
- /**
17
- * Common module.
18
- * @module illogical/common
19
- */
20
-
21
1
  /**
22
2
  * Is number predicate.
23
3
  * @param value Tested value.
@@ -68,10 +48,20 @@ function isEvaluable(value) {
68
48
  return typeof value === 'object' && value !== null && !Array.isArray(value);
69
49
  }
70
50
 
71
- /**
72
- * Common module.
73
- * @module illogical/common
74
- */
51
+ function _defineProperty(obj, key, value) {
52
+ if (key in obj) {
53
+ Object.defineProperty(obj, key, {
54
+ value: value,
55
+ enumerable: true,
56
+ configurable: true,
57
+ writable: true
58
+ });
59
+ } else {
60
+ obj[key] = value;
61
+ }
62
+
63
+ return obj;
64
+ }
75
65
 
76
66
  /**
77
67
  * Valid types for context members
@@ -107,12 +97,12 @@ class Comparison {
107
97
  * @param {Operand} right Right operand.
108
98
  */
109
99
  constructor(operator, operatorSymbol, left, right) {
100
+ _defineProperty(this, "type", EvaluableType.Expression);
101
+
110
102
  this.operator = operator;
111
103
  this.operatorSymbol = operatorSymbol;
112
104
  this.left = left;
113
105
  this.right = right;
114
-
115
- _defineProperty(this, "type", EvaluableType.Expression);
116
106
  }
117
107
  /**
118
108
  * {@link Evaluable.evaluate}
@@ -142,9 +132,9 @@ class Comparison {
142
132
  /**
143
133
  * {@link Evaluable.simplify}
144
134
  */
145
- simplify(...args) {
146
- const left = this.left.simplify(...args);
147
- const right = this.right.simplify(...args);
135
+ simplify() {
136
+ const left = this.left.simplify(...arguments);
137
+ const right = this.right.simplify(...arguments);
148
138
 
149
139
  if (!isEvaluable(left) && !isEvaluable(right)) {
150
140
  return this.comparison(left, right);
@@ -172,11 +162,6 @@ class Comparison {
172
162
 
173
163
  }
174
164
 
175
- /**
176
- * Comparison expression module.
177
- * @module illogical/expression/comparison
178
- */
179
-
180
165
  const OPERATOR$h = Symbol('EQ');
181
166
  /**
182
167
  * Equal comparison expression
@@ -206,11 +191,6 @@ class Equal extends Comparison {
206
191
 
207
192
  }
208
193
 
209
- /**
210
- * Comparison expression module.
211
- * @module illogical/expression/comparison
212
- */
213
-
214
194
  const OPERATOR$g = Symbol('GE');
215
195
  /**
216
196
  * Greater than or equal comparison expression
@@ -244,11 +224,6 @@ class GreaterThanOrEqual extends Comparison {
244
224
 
245
225
  }
246
226
 
247
- /**
248
- * Comparison expression module.
249
- * @module illogical/expression/comparison
250
- */
251
-
252
227
  const OPERATOR$f = Symbol('GT');
253
228
  /**
254
229
  * Greater than comparison expression
@@ -282,11 +257,6 @@ class GreaterThan extends Comparison {
282
257
 
283
258
  }
284
259
 
285
- /**
286
- * Comparison expression module.
287
- * @module illogical/expression/comparison
288
- */
289
-
290
260
  const OPERATOR$e = Symbol('IN');
291
261
  /**
292
262
  * In comparison expression
@@ -351,11 +321,6 @@ class In extends Comparison {
351
321
 
352
322
  }
353
323
 
354
- /**
355
- * Comparison expression module.
356
- * @module illogical/expression/comparison
357
- */
358
-
359
324
  const OPERATOR$d = Symbol('LE');
360
325
  /**
361
326
  * Less than or equal comparison expression
@@ -389,11 +354,6 @@ class LessThanOrEqual extends Comparison {
389
354
 
390
355
  }
391
356
 
392
- /**
393
- * Comparison expression module.
394
- * @module illogical/expression/comparison
395
- */
396
-
397
357
  const OPERATOR$c = Symbol('LT');
398
358
  /**
399
359
  * Less than comparison expression
@@ -427,11 +387,6 @@ class LessThan extends Comparison {
427
387
 
428
388
  }
429
389
 
430
- /**
431
- * Comparison expression module.
432
- * @module illogical/expression/comparison
433
- */
434
-
435
390
  const OPERATOR$b = Symbol('NE');
436
391
  /**
437
392
  * Not equal comparison expression
@@ -461,11 +416,6 @@ class NotEqual extends Comparison {
461
416
 
462
417
  }
463
418
 
464
- /**
465
- * Comparison expression module.
466
- * @module illogical/expression/comparison
467
- */
468
-
469
419
  const OPERATOR$a = Symbol('NOT IN');
470
420
  /**
471
421
  * Not in comparison expression
@@ -530,11 +480,6 @@ class NotIn extends Comparison {
530
480
 
531
481
  }
532
482
 
533
- /**
534
- * Comparison expression module.
535
- * @module illogical/expression/comparison
536
- */
537
-
538
483
  const OPERATOR$9 = Symbol('OVERLAP');
539
484
  /**
540
485
  * Overlap comparison expression
@@ -585,11 +530,6 @@ class Overlap extends Comparison {
585
530
 
586
531
  }
587
532
 
588
- /**
589
- * Prefix expression module.
590
- * @module illogical/expression/prefix
591
- */
592
-
593
533
  const OPERATOR$8 = Symbol('PREFIX');
594
534
  /**
595
535
  * Prefix comparison expression
@@ -680,9 +620,6 @@ class Value extends Operand {
680
620
  }
681
621
 
682
622
  super();
683
-
684
- _defineProperty(this, "value", void 0);
685
-
686
623
  this.value = value;
687
624
  }
688
625
  /**
@@ -721,11 +658,6 @@ class Value extends Operand {
721
658
 
722
659
  }
723
660
 
724
- /**
725
- * Present expression module.
726
- * @module illogical/expression/comparison
727
- */
728
-
729
661
  const OPERATOR$7 = Symbol('PRESENT');
730
662
  /**
731
663
  * Present comparison expression
@@ -776,11 +708,6 @@ class Present extends Comparison {
776
708
 
777
709
  }
778
710
 
779
- /**
780
- * Suffix expression module.
781
- * @module illogical/expression/suffix
782
- */
783
-
784
711
  const OPERATOR$6 = Symbol('PREFIX');
785
712
  /**
786
713
  * Suffix comparison expression
@@ -825,11 +752,6 @@ class Suffix extends Comparison {
825
752
 
826
753
  }
827
754
 
828
- /**
829
- * Undefined expression module.
830
- * @module illogical/expression/comparison
831
- */
832
-
833
755
  const OPERATOR$5 = Symbol('UNDEFINED');
834
756
  /**
835
757
  * Undefined comparison expression
@@ -894,11 +816,11 @@ class Logical {
894
816
  * @param {Evaluable[]} operands Collection of operands.
895
817
  */
896
818
  constructor(operator, operatorSymbol, operands) {
819
+ _defineProperty(this, "type", EvaluableType.Expression);
820
+
897
821
  this.operator = operator;
898
822
  this.operatorSymbol = operatorSymbol;
899
823
  this.operands = operands;
900
-
901
- _defineProperty(this, "type", EvaluableType.Expression);
902
824
  }
903
825
  /**
904
826
  * {@link Evaluable.evaluate}
@@ -928,11 +850,6 @@ class Logical {
928
850
 
929
851
  }
930
852
 
931
- /**
932
- * Logical expression module.
933
- * @module illogical/expression/logical
934
- */
935
-
936
853
  const OPERATOR$4 = Symbol('AND');
937
854
  /**
938
855
  * And logical expression
@@ -971,17 +888,21 @@ class And extends Logical {
971
888
  */
972
889
 
973
890
 
974
- simplify(...args) {
891
+ simplify() {
892
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
893
+ args[_key] = arguments[_key];
894
+ }
895
+
975
896
  const simplified = this.operands.reduce((result, child) => {
976
897
  if (result !== false) {
977
898
  const childResult = child.simplify(...args);
978
899
 
979
- if (!isBoolean(childResult)) {
900
+ if (isEvaluable(childResult)) {
980
901
  if (isBoolean(result)) {
981
- return [child];
902
+ return [childResult];
982
903
  }
983
904
 
984
- return [...result, child];
905
+ return [...result, childResult];
985
906
  }
986
907
 
987
908
  if (!childResult) {
@@ -1005,11 +926,6 @@ class And extends Logical {
1005
926
 
1006
927
  }
1007
928
 
1008
- /**
1009
- * Logical expression module.
1010
- * @module illogical/expression/logical
1011
- */
1012
-
1013
929
  const OPERATOR$3 = Symbol('NOT');
1014
930
  /**
1015
931
  * Not logical expression
@@ -1048,8 +964,8 @@ class Not extends Logical {
1048
964
  */
1049
965
 
1050
966
 
1051
- simplify(...args) {
1052
- const simplified = this.operands[0].simplify(...args);
967
+ simplify() {
968
+ const simplified = this.operands[0].simplify(...arguments);
1053
969
 
1054
970
  if (isBoolean(simplified)) {
1055
971
  return !simplified;
@@ -1064,11 +980,6 @@ class Not extends Logical {
1064
980
 
1065
981
  }
1066
982
 
1067
- /**
1068
- * Logical expression module.
1069
- * @module illogical/expression/logical
1070
- */
1071
-
1072
983
  const OPERATOR$2 = Symbol('NOR');
1073
984
  /**
1074
985
  * Nor logical expression
@@ -1107,17 +1018,21 @@ class Nor extends Logical {
1107
1018
  */
1108
1019
 
1109
1020
 
1110
- simplify(...args) {
1021
+ simplify() {
1022
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
1023
+ args[_key] = arguments[_key];
1024
+ }
1025
+
1111
1026
  const simplified = this.operands.reduce((result, child) => {
1112
1027
  if (result !== false) {
1113
1028
  const childResult = child.simplify(...args);
1114
1029
 
1115
1030
  if (isEvaluable(childResult)) {
1116
1031
  if (isBoolean(result)) {
1117
- return [child];
1032
+ return [childResult];
1118
1033
  }
1119
1034
 
1120
- return [...result, child];
1035
+ return [...result, childResult];
1121
1036
  }
1122
1037
 
1123
1038
  if (childResult) {
@@ -1141,11 +1056,6 @@ class Nor extends Logical {
1141
1056
 
1142
1057
  }
1143
1058
 
1144
- /**
1145
- * Logical expression module.
1146
- * @module illogical/expression/logical
1147
- */
1148
-
1149
1059
  const OPERATOR$1 = Symbol('OR');
1150
1060
  /**
1151
1061
  * Or logical expression
@@ -1184,17 +1094,21 @@ class Or extends Logical {
1184
1094
  */
1185
1095
 
1186
1096
 
1187
- simplify(...args) {
1097
+ simplify() {
1098
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
1099
+ args[_key] = arguments[_key];
1100
+ }
1101
+
1188
1102
  const simplified = this.operands.reduce((result, child) => {
1189
1103
  if (result !== true) {
1190
1104
  const childResult = child.simplify(...args);
1191
1105
 
1192
- if (!isBoolean(childResult)) {
1106
+ if (isEvaluable(childResult)) {
1193
1107
  if (isBoolean(result)) {
1194
- return [child];
1108
+ return [childResult];
1195
1109
  }
1196
1110
 
1197
- return [...result, child];
1111
+ return [...result, childResult];
1198
1112
  }
1199
1113
 
1200
1114
  if (childResult) {
@@ -1218,11 +1132,6 @@ class Or extends Logical {
1218
1132
 
1219
1133
  }
1220
1134
 
1221
- /**
1222
- * Logical expression module.
1223
- * @module illogical/expression/logical
1224
- */
1225
-
1226
1135
  const OPERATOR = Symbol('XOR');
1227
1136
  /**
1228
1137
  * Logical xor
@@ -1276,16 +1185,22 @@ class Xor extends Logical {
1276
1185
  */
1277
1186
 
1278
1187
 
1279
- simplify(...args) {
1280
- const [evaluablesLeft, trueCount] = this.operands.reduce(([notSimplifiedConditions, trueCount], child) => {
1188
+ simplify() {
1189
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
1190
+ args[_key] = arguments[_key];
1191
+ }
1192
+
1193
+ const [evaluablesLeft, trueCount] = this.operands.reduce((_ref, child) => {
1194
+ let [notSimplifiedConditions, trueCount] = _ref;
1195
+
1281
1196
  if (trueCount > 1) {
1282
1197
  return [notSimplifiedConditions, trueCount];
1283
1198
  }
1284
1199
 
1285
1200
  const childResult = child.simplify(...args);
1286
1201
 
1287
- if (!isBoolean(childResult)) {
1288
- return [[...notSimplifiedConditions, child], trueCount];
1202
+ if (isEvaluable(childResult)) {
1203
+ return [[...notSimplifiedConditions, childResult], trueCount];
1289
1204
  }
1290
1205
 
1291
1206
  if (childResult) {
@@ -1330,9 +1245,6 @@ class Collection extends Operand {
1330
1245
  */
1331
1246
  constructor(items) {
1332
1247
  super();
1333
-
1334
- _defineProperty(this, "items", void 0);
1335
-
1336
1248
  this.items = items;
1337
1249
  }
1338
1250
  /**
@@ -1350,11 +1262,11 @@ class Collection extends Operand {
1350
1262
  */
1351
1263
 
1352
1264
 
1353
- simplify(...args) {
1265
+ simplify() {
1354
1266
  const values = [];
1355
1267
 
1356
1268
  for (const item of this.items) {
1357
- const simplifiedItem = item.simplify(...args);
1269
+ const simplifiedItem = item.simplify(...arguments);
1358
1270
 
1359
1271
  if (isEvaluable(simplifiedItem)) {
1360
1272
  return this;
@@ -1515,11 +1427,6 @@ class Reference extends Operand {
1515
1427
  }
1516
1428
 
1517
1429
  super();
1518
-
1519
- _defineProperty(this, "key", void 0);
1520
-
1521
- _defineProperty(this, "dataType", void 0);
1522
-
1523
1430
  this.key = key;
1524
1431
  const dataTypeMatch = dataTypeRegex.exec(this.key);
1525
1432
 
@@ -1546,7 +1453,7 @@ class Reference extends Operand {
1546
1453
  */
1547
1454
 
1548
1455
 
1549
- simplify(ctx, ignoreKeys) {
1456
+ simplify(ctx, strictKeys, optionalKeys) {
1550
1457
  const keys = extractKeys(ctx, this.key);
1551
1458
 
1552
1459
  if (!keys) {
@@ -1555,20 +1462,21 @@ class Reference extends Operand {
1555
1462
 
1556
1463
  const key = keys[0].replace(/\[.+$/, '');
1557
1464
 
1558
- if (ctx[key] !== undefined || ignoreKeys.includes(key)) {
1465
+ if (ctx[key] !== undefined) {
1559
1466
  return this.evaluate(ctx);
1560
1467
  }
1561
1468
 
1562
- return this;
1469
+ return strictKeys && strictKeys.includes(key) || optionalKeys && !optionalKeys.includes(key) ? undefined : this;
1563
1470
  }
1564
1471
  /**
1565
1472
  * {@link Evaluable.serialize}
1566
1473
  */
1567
1474
 
1568
1475
 
1569
- serialize({
1570
- referenceSerialization
1571
- }) {
1476
+ serialize(_ref) {
1477
+ let {
1478
+ referenceSerialization
1479
+ } = _ref;
1572
1480
  const key = this.dataType ? `${this.key}.(${this.dataType})` : this.key;
1573
1481
  return referenceSerialization(key);
1574
1482
  }
@@ -1610,11 +1518,6 @@ class Reference extends Operand {
1610
1518
 
1611
1519
  }
1612
1520
 
1613
- /**
1614
- * Parser module.
1615
- * @module illogical/parser
1616
- */
1617
-
1618
1521
  /**
1619
1522
  * Default reference predicate.
1620
1523
  * The "$" symbol at the begging of the operand is used
@@ -1664,10 +1567,6 @@ class Parser {
1664
1567
  * @param {Options?} options Parser options.
1665
1568
  */
1666
1569
  constructor(options) {
1667
- _defineProperty(this, "opts", void 0);
1668
-
1669
- _defineProperty(this, "expectedOperators", void 0);
1670
-
1671
1570
  this.opts = { ...defaultOptions
1672
1571
  }; // Apply exclusive options overrides
1673
1572
 
@@ -1716,6 +1615,8 @@ class Parser {
1716
1615
 
1717
1616
 
1718
1617
  parseRawExp(raw) {
1618
+ var _this = this;
1619
+
1719
1620
  // Value / Reference
1720
1621
  if (!Array.isArray(raw)) {
1721
1622
  return this.getOperand(raw);
@@ -1737,9 +1638,11 @@ class Parser {
1737
1638
  * @param collapsible
1738
1639
  */
1739
1640
 
1740
- const logicalExpressionReducer = (operands, collapsible = false) => {
1641
+ const logicalExpressionReducer = function (operands) {
1642
+ let collapsible = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1643
+
1741
1644
  if (operands.length === 0 || operands.filter(operand => operand.type === EvaluableType.Expression).length === 0) {
1742
- return this.getOperand(raw);
1645
+ return _this.getOperand(raw);
1743
1646
  }
1744
1647
 
1745
1648
  return collapsible && operands.length === 1 ? operands[0] : undefined;
@@ -1873,6 +1776,10 @@ class Parser {
1873
1776
 
1874
1777
  }
1875
1778
 
1779
+ /**
1780
+ * Main module.
1781
+ * @module illogical
1782
+ */
1876
1783
  /**
1877
1784
  * Condition engine
1878
1785
  */
@@ -1883,8 +1790,6 @@ class Engine {
1883
1790
  * @param {Options?} options Parser options.
1884
1791
  */
1885
1792
  constructor(options) {
1886
- _defineProperty(this, "parser", void 0);
1887
-
1888
1793
  this.parser = new Parser(options);
1889
1794
  }
1890
1795
  /**
@@ -1927,14 +1832,16 @@ class Engine {
1927
1832
  *
1928
1833
  * @param {ExpressionInput} exp Raw expression.
1929
1834
  * @param {Context} context Evaluation data context.
1930
- * @param {string[]} ignoreKeys keys to be considered present even if their not present in the context.
1931
- * Default to empty array
1835
+ * @param {string[]} strictKeys keys to be considered present even if they are not present in the context
1836
+ * @param {string[]} optionalKeys keys to be considered not present unless they are in the context or in
1837
+ * `strictKeys`; when `strictKeys` is `undefined` and `optionalKeys` is an array, every key that is not in
1838
+ * `optionalKeys` is considered to be present and thus will be evaluated
1932
1839
  * @returns {Inpunt | boolean}
1933
1840
  */
1934
1841
 
1935
1842
 
1936
- simplify(exp, context, ignoreKeys = []) {
1937
- const result = this.parse(exp).simplify(context, ignoreKeys);
1843
+ simplify(exp, context, strictKeys, optionalKeys) {
1844
+ const result = this.parse(exp).simplify(context, strictKeys, optionalKeys);
1938
1845
 
1939
1846
  if (isEvaluable(result)) {
1940
1847
  return result.serialize(this.parser.options);
@@ -1949,5 +1856,4 @@ class Engine {
1949
1856
 
1950
1857
  }
1951
1858
 
1952
- export default Engine;
1953
- export { OPERATOR$4 as OPERATOR_AND, OPERATOR$h as OPERATOR_EQ, OPERATOR$g as OPERATOR_GE, OPERATOR$f as OPERATOR_GT, OPERATOR$e as OPERATOR_IN, OPERATOR$d as OPERATOR_LE, OPERATOR$c as OPERATOR_LT, OPERATOR$b as OPERATOR_NE, OPERATOR$2 as OPERATOR_NOR, OPERATOR$3 as OPERATOR_NOT, OPERATOR$a as OPERATOR_NOT_IN, OPERATOR$1 as OPERATOR_OR, OPERATOR$9 as OPERATOR_OVERLAP, OPERATOR$8 as OPERATOR_PREFIX, OPERATOR$7 as OPERATOR_PRESENT, OPERATOR$6 as OPERATOR_SUFFIX, OPERATOR$5 as OPERATOR_UNDEFINED, OPERATOR as OPERATOR_XOR };
1859
+ export { OPERATOR$4 as OPERATOR_AND, OPERATOR$h as OPERATOR_EQ, OPERATOR$g as OPERATOR_GE, OPERATOR$f as OPERATOR_GT, OPERATOR$e as OPERATOR_IN, OPERATOR$d as OPERATOR_LE, OPERATOR$c as OPERATOR_LT, OPERATOR$b as OPERATOR_NE, OPERATOR$2 as OPERATOR_NOR, OPERATOR$3 as OPERATOR_NOT, OPERATOR$a as OPERATOR_NOT_IN, OPERATOR$1 as OPERATOR_OR, OPERATOR$9 as OPERATOR_OVERLAP, OPERATOR$8 as OPERATOR_PREFIX, OPERATOR$7 as OPERATOR_PRESENT, OPERATOR$6 as OPERATOR_SUFFIX, OPERATOR$5 as OPERATOR_UNDEFINED, OPERATOR as OPERATOR_XOR, Engine as default };