@briza/illogical 1.5.9 → 1.6.1

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,3 +1,11 @@
1
+ function _defineProperty(e, r, t) {
2
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
3
+ value: t,
4
+ enumerable: !0,
5
+ configurable: !0,
6
+ writable: !0
7
+ }) : e[r] = t, e;
8
+ }
1
9
  function _toPrimitive(t, r) {
2
10
  if ("object" != typeof t || !t) return t;
3
11
  var e = t[Symbol.toPrimitive];
@@ -10,21 +18,7 @@ function _toPrimitive(t, r) {
10
18
  }
11
19
  function _toPropertyKey(t) {
12
20
  var i = _toPrimitive(t, "string");
13
- return "symbol" == typeof i ? i : String(i);
14
- }
15
- function _defineProperty(obj, key, value) {
16
- key = _toPropertyKey(key);
17
- if (key in obj) {
18
- Object.defineProperty(obj, key, {
19
- value: value,
20
- enumerable: true,
21
- configurable: true,
22
- writable: true
23
- });
24
- } else {
25
- obj[key] = value;
26
- }
27
- return obj;
21
+ return "symbol" == typeof i ? i : i + "";
28
22
  }
29
23
 
30
24
  /**
@@ -32,7 +26,14 @@ function _defineProperty(obj, key, value) {
32
26
  * @param value Tested value.
33
27
  */
34
28
  function isNumber(value) {
35
- return typeof value === 'number' && isFinite(value);
29
+ return typeof value === 'number';
30
+ }
31
+ /**
32
+ * Is number predicate.
33
+ * @param value Tested value.
34
+ */
35
+ function isInfinite(value) {
36
+ return typeof value === 'number' && !isFinite(value);
36
37
  }
37
38
 
38
39
  /**
@@ -54,50 +55,597 @@ function isObject(value) {
54
55
  if (typeof value !== 'object' || (value === null || value === void 0 ? void 0 : value.constructor) !== Object) {
55
56
  return false;
56
57
  }
57
- return true;
58
- }
59
-
60
- /**
61
- * Is Boolean predicate.
62
- * @param value tested value.
63
- * @return result of the test
64
- */
65
- function isBoolean(value) {
66
- return typeof value === 'boolean';
67
- }
58
+ return true;
59
+ }
60
+
61
+ /**
62
+ * Is Boolean predicate.
63
+ * @param value tested value.
64
+ * @return result of the test
65
+ */
66
+ function isBoolean(value) {
67
+ return typeof value === 'boolean';
68
+ }
69
+
70
+ /**
71
+ * Check if a value is a an Evaluable
72
+ * @param {Result | Evaluable} value value to check if is Evaluable
73
+ * @returns {Evaluable}
74
+ */
75
+ function isEvaluable(value) {
76
+ return typeof value === 'object' && value !== null && !Array.isArray(value) && typeof value.evaluate === 'function' && typeof value.simplify === 'function' && typeof value.serialize === 'function' && typeof value.toString === 'function';
77
+ }
78
+
79
+ /**
80
+ * Ensures all values are results.
81
+ * @param {(Result | Evaluable)[]} values results or evaluables
82
+ * @returns {boolean} type guard
83
+ */
84
+ function areAllResults(values) {
85
+ return values.every(value => !isEvaluable(value));
86
+ }
87
+
88
+ /**
89
+ * Ensures all values are numbers.
90
+ * @param {Result[]} results results or evaluables
91
+ * @returns {boolean} type guard
92
+ */
93
+ function areAllNumbers(results) {
94
+ return results.every(isNumber);
95
+ }
96
+
97
+ /**
98
+ * Valid types for context members
99
+ */
100
+
101
+ /**
102
+ * Evaluation Context
103
+ * Holds references used during the evaluation process.
104
+ * Format: key: value.
105
+ */
106
+
107
+ /**
108
+ * Evaluation result
109
+ */
110
+
111
+ let EvaluableType = /*#__PURE__*/function (EvaluableType) {
112
+ EvaluableType["Operand"] = "Operand";
113
+ EvaluableType["Expression"] = "Expression";
114
+ return EvaluableType;
115
+ }({});
116
+
117
+ /**
118
+ * Evaluable
119
+ */
120
+
121
+ /**
122
+ * Abstract arithmetic expression
123
+ */
124
+ class Arithmetic {
125
+ /**
126
+ * @constructor
127
+ * @param {string} operator String representation of the operator.
128
+ * @param {symbol} operatorSymbol Operator symbol.
129
+ * @param {Operand[]} operands Operands.
130
+ */
131
+ constructor(operator, operatorSymbol, operands) {
132
+ this.operator = operator;
133
+ this.operatorSymbol = operatorSymbol;
134
+ this.operands = operands;
135
+ _defineProperty(this, "type", EvaluableType.Expression);
136
+ }
137
+
138
+ /**
139
+ * Helper function to assist with arithmetic evaluation. Ensures that all
140
+ * operands are present and are numbers. Throws error if any operand is not a
141
+ * number.
142
+ *
143
+ * @param {Result[]} results
144
+ * @returns {number[] | false} false if any operand is missing, otherwise the
145
+ * array of numbers
146
+ */
147
+ getResultValues(results) {
148
+ const presentValues = results.filter(result => result !== null && result !== undefined);
149
+ // If we have missing context values the result must be false
150
+ if (presentValues.length !== results.length) {
151
+ return false;
152
+ }
153
+ if (!areAllNumbers(presentValues)) {
154
+ throw new Error(`operands must be numbers for ${this.constructor.name}`);
155
+ }
156
+ return presentValues;
157
+ }
158
+
159
+ /**
160
+ * Performs the arithmetic operation on the operands evaluated values.
161
+ * @param {Result[]} results Operand result values.
162
+ * @returns {Result}
163
+ */
164
+
165
+ /**
166
+ * {@link Evaluable.evaluate}
167
+ */
168
+ evaluate(ctx) {
169
+ return this.operate(this.operands.map(operand => operand.evaluate(ctx)));
170
+ }
171
+
172
+ /**
173
+ * {@link Evaluable.toString}
174
+ */
175
+ toString() {
176
+ return `(${this.operands.map(operand => operand.toString()).join(` ${this.operator} `)})`;
177
+ }
178
+
179
+ /**
180
+ * {@link Evaluable.simplify}
181
+ */
182
+ simplify(...args) {
183
+ const results = this.operands.map(operand => operand.simplify(...args));
184
+ if (areAllResults(results)) {
185
+ return this.operate(results);
186
+ }
187
+ return this;
188
+ }
189
+
190
+ /**
191
+ * {@link Evaluable.serialize}
192
+ */
193
+ serialize(options) {
194
+ const {
195
+ operatorMapping
196
+ } = options;
197
+ const operator = operatorMapping.get(this.operatorSymbol);
198
+ if (operator === undefined) {
199
+ throw new Error(`missing operator ${this.operatorSymbol.toString()}`);
200
+ }
201
+ return [operator, ...this.operands.map(operand => operand.serialize(options))];
202
+ }
203
+ }
204
+
205
+ // Operator key
206
+ const OPERATOR$l = Symbol('DIVIDE');
207
+
208
+ /**
209
+ * Divide operation expression
210
+ */
211
+ class Divide extends Arithmetic {
212
+ /**
213
+ * @constructor Generic constructor
214
+ * @param {Evaluable[]} args
215
+ */
216
+
217
+ /**
218
+ * @constructor
219
+ * @param {Operand[]} operands Operands.
220
+ */
221
+ constructor(...operands) {
222
+ if (operands.length < 2) {
223
+ throw new Error('divide expression requires at least 2 operands');
224
+ }
225
+ super('/', OPERATOR$l, operands);
226
+ }
227
+ operate(results) {
228
+ const presentResults = this.getResultValues(results);
229
+ if (presentResults === false) {
230
+ return false;
231
+ }
232
+ return presentResults.reduce((acc, result) => acc / result);
233
+ }
234
+ }
235
+
236
+ const getNumDecimals = num => {
237
+ const numberSplit = num.toString().split('.');
238
+ return numberSplit.length == 2 ? numberSplit[1].length : 0;
239
+ };
240
+ const operateWithExpectedDecimals = operation => (first, second) => {
241
+ const numDecimals1 = getNumDecimals(first);
242
+ const numDecimals2 = getNumDecimals(second);
243
+ const maxDecimals = operation === 'multiply' ? numDecimals1 + numDecimals2 : numDecimals1 > numDecimals2 ? numDecimals1 : numDecimals2;
244
+ return operation === 'sum' ? Number((first + second).toFixed(maxDecimals)) : operation === 'subtract' ? Number((first - second).toFixed(maxDecimals)) : Number((first * second).toFixed(maxDecimals));
245
+ };
246
+
247
+ // Operator key
248
+ const OPERATOR$k = Symbol('MULTIPLY');
249
+ const multiplyWithExpectedDecimals = operateWithExpectedDecimals('multiply');
250
+
251
+ /**
252
+ * Multiply operation expression
253
+ */
254
+ class Multiply extends Arithmetic {
255
+ /**
256
+ * @constructor Generic constructor
257
+ * @param {Evaluable[]} args
258
+ */
259
+
260
+ /**
261
+ * @constructor
262
+ * @param {Operand[]} operands Operands.
263
+ */
264
+ constructor(...operands) {
265
+ if (operands.length < 2) {
266
+ throw new Error('multiply expression requires at least 2 operands');
267
+ }
268
+ super('*', OPERATOR$k, operands);
269
+ }
270
+ operate(results) {
271
+ const presentResults = this.getResultValues(results);
272
+ if (presentResults === false) {
273
+ return false;
274
+ }
275
+ return presentResults.reduce((acc, result) => multiplyWithExpectedDecimals(acc, result));
276
+ }
277
+ }
278
+
279
+ // Operator key
280
+ const OPERATOR$j = Symbol('SUBTRACT');
281
+ const subtractWithExpectedDecimals = operateWithExpectedDecimals('subtract');
282
+
283
+ /**
284
+ * Subtract operation expression
285
+ */
286
+ class Subtract extends Arithmetic {
287
+ /**
288
+ * @constructor Generic constructor
289
+ * @param {Evaluable[]} args
290
+ */
291
+
292
+ /**
293
+ * @constructor
294
+ * @param {Operand[]} operands Operands.
295
+ */
296
+ constructor(...operands) {
297
+ if (operands.length < 2) {
298
+ throw new Error('subtract expression requires at least 2 operands');
299
+ }
300
+ super('-', OPERATOR$j, operands);
301
+ }
302
+ operate(results) {
303
+ const presentResults = this.getResultValues(results);
304
+ if (presentResults === false) {
305
+ return false;
306
+ }
307
+ return presentResults.reduce((acc, result) => subtractWithExpectedDecimals(acc, result));
308
+ }
309
+ }
310
+
311
+ // Operator key
312
+ const OPERATOR$i = Symbol('SUM');
313
+ const addWithExpectedDecimals = operateWithExpectedDecimals('sum');
314
+
315
+ /**
316
+ * Sum operation expression
317
+ */
318
+ class Sum extends Arithmetic {
319
+ /**
320
+ * @constructor Generic constructor
321
+ * @param {Evaluable[]} args
322
+ */
323
+
324
+ /**
325
+ * @constructor
326
+ * @param {Operand[]} operands Operands.
327
+ */
328
+ constructor(...operands) {
329
+ if (operands.length < 2) {
330
+ throw new Error('sum expression requires at least 2 operands');
331
+ }
332
+ super('+', OPERATOR$i, operands);
333
+ }
334
+ operate(results) {
335
+ const presentResults = this.getResultValues(results);
336
+ if (presentResults === false) {
337
+ return false;
338
+ }
339
+ return presentResults.reduce((acc, result) => addWithExpectedDecimals(acc, result));
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Abstract operand
345
+ */
346
+ class Operand {
347
+ constructor() {
348
+ _defineProperty(this, "type", EvaluableType.Operand);
349
+ }
350
+ /**
351
+ * {@link Evaluable.evaluate}
352
+ */
353
+ /**
354
+ * {@link Evaluable.simplify}
355
+ */
356
+ /**
357
+ * {@link Evaluable.serialize}
358
+ */
359
+ /**
360
+ * Get the strict representation.
361
+ */
362
+ toString() {
363
+ throw new Error('not implemented exception');
364
+ }
365
+ }
366
+
367
+ /**
368
+ * Print value as string
369
+ * @param {Result} value
370
+ * @return {string}
371
+ */
372
+ function printValue(value) {
373
+ if (isString(value)) {
374
+ return `"${value}"`;
375
+ }
376
+ return `${value}`;
377
+ }
378
+
379
+ /**
380
+ * Static value operand
381
+ */
382
+ class Value extends Operand {
383
+ /**
384
+ * @constructor
385
+ * @param {Result} value Constant value.
386
+ */
387
+ constructor(value) {
388
+ if (Array.isArray(value)) {
389
+ throw new Error('deprecated direct usage of array, please use Collection operand');
390
+ }
391
+ super();
392
+ _defineProperty(this, "value", void 0);
393
+ this.value = value;
394
+ }
395
+
396
+ /**
397
+ * {@link Evaluable.evaluate}
398
+ */
399
+ evaluate() {
400
+ return this.value;
401
+ }
402
+
403
+ /**
404
+ * {@link Evaluable.simplify}
405
+ */
406
+ simplify() {
407
+ return this.value;
408
+ }
409
+
410
+ /**
411
+ * {@link Evaluable.serialize}
412
+ */
413
+ serialize() {
414
+ return this.value;
415
+ }
416
+
417
+ /**
418
+ * Get the strict representation of the operand.
419
+ * @return {string}
420
+ */
421
+ toString() {
422
+ return printValue(this.value);
423
+ }
424
+ }
425
+
426
+ /**
427
+ * Convert a value to number if possible, otherwise return undefined
428
+ * @param value value to be converted to number
429
+ */
430
+ const toNumber = value => {
431
+ const isValueNumber = isNumber(value);
432
+ if (isValueNumber) {
433
+ return value;
434
+ } else if (isString(value)) {
435
+ if (value.match(/^\d+\.\d+$/)) {
436
+ return parseFloat(value);
437
+ } else if (value.match(/^0$|^[1-9]\d*$/)) {
438
+ return parseInt(value);
439
+ }
440
+ }
441
+ return undefined;
442
+ };
443
+
444
+ /**
445
+ * Convert a value to string if possible, otherwise return undefined
446
+ * @param value value to be converted to string
447
+ */
448
+ const toString = value => {
449
+ if (isNumber(value)) {
450
+ return `${value}`;
451
+ } else if (isString(value)) {
452
+ return value;
453
+ }
454
+ return undefined;
455
+ };
456
+ /**
457
+ * Convert a value to number if it's type is string, otherwise return NaN
458
+ * @param value value to be converted to number
459
+ */
460
+ const toDateNumber = value => {
461
+ if (isString(value)) {
462
+ return Date.parse(value);
463
+ }
464
+ return NaN;
465
+ };
466
+
467
+ const keyWithArrayIndexRegex = /^(?<currentKey>[^[\]]+?)(?<indexes>(?:\[\d+])+)?$/;
468
+ const arrayIndexRegex = /\[(\d+)]/g;
469
+ const parseBacktickWrappedKey = key => key.startsWith('`') && key.endsWith('`') ? key.slice(1, -1) : key;
470
+ const parseKey = key => {
471
+ const keys = key.match(/(`[^[\]]+`(\[\d+\])*|[^`.]+)/g);
472
+ return !keys ? [] : keys.flatMap(key => {
473
+ const unwrappedKey = parseBacktickWrappedKey(key);
474
+ const keys = [];
475
+ const parseResult = keyWithArrayIndexRegex.exec(unwrappedKey);
476
+ if (parseResult) {
477
+ var _parseResult$groups$c, _parseResult$groups, _parseResult$groups2;
478
+ const extractedKey = parseBacktickWrappedKey((_parseResult$groups$c = parseResult === null || parseResult === void 0 || (_parseResult$groups = parseResult.groups) === null || _parseResult$groups === void 0 ? void 0 : _parseResult$groups.currentKey) !== null && _parseResult$groups$c !== void 0 ? _parseResult$groups$c : unwrappedKey);
479
+ keys.push(extractedKey);
480
+ const rawIndexes = parseResult === null || parseResult === void 0 || (_parseResult$groups2 = parseResult.groups) === null || _parseResult$groups2 === void 0 ? void 0 : _parseResult$groups2.indexes;
481
+ if (rawIndexes) {
482
+ for (const indexResult of rawIndexes.matchAll(arrayIndexRegex)) {
483
+ keys.push(parseInt(indexResult[1]));
484
+ }
485
+ }
486
+ } else {
487
+ keys.push(unwrappedKey);
488
+ }
489
+ return keys;
490
+ });
491
+ };
492
+ const complexKeyExpression = /{([^{}]+)}/;
493
+ function extractComplexKeys(ctx, key) {
494
+ // Resolve complex keys
495
+ let complexKeyMatches = complexKeyExpression.exec(key);
496
+ while (complexKeyMatches) {
497
+ const resolvedValue = complexValueLookup(ctx, complexKeyMatches[1]);
498
+ if (resolvedValue === undefined) {
499
+ return undefined;
500
+ }
501
+ key = key.replace(complexKeyExpression, `${resolvedValue}`);
502
+ complexKeyMatches = complexKeyExpression.exec(key);
503
+ }
504
+ return parseKey(key);
505
+ }
506
+ const isContext = value => isObject(value);
507
+ const simpleValueLookup = keys => ctx => {
508
+ let pointer = ctx;
509
+ for (const key of keys) {
510
+ if (typeof key === 'number') {
511
+ if (!Array.isArray(pointer)) {
512
+ return undefined;
513
+ }
514
+ pointer = pointer[key];
515
+ } else if (!isContext(pointer)) {
516
+ return undefined;
517
+ } else {
518
+ pointer = pointer[key];
519
+ }
520
+ }
521
+ return pointer;
522
+ };
523
+
524
+ /**
525
+ * Lookup for the reference in the context.
526
+ * The nested context value is annotated with "." delimiter.
527
+ * @example address.city
528
+ * @param {Context} ctx
529
+ * @param {string} key Context lookup key.
530
+ * @return {Result}
531
+ */
532
+ function complexValueLookup(ctx, key) {
533
+ const keys = extractComplexKeys(ctx, key);
534
+ if (!keys) {
535
+ return undefined;
536
+ }
537
+ return simpleValueLookup(keys !== null && keys !== void 0 ? keys : [])(ctx);
538
+ }
539
+ let DataType = /*#__PURE__*/function (DataType) {
540
+ DataType["Number"] = "Number";
541
+ DataType["String"] = "String";
542
+ return DataType;
543
+ }({});
544
+
545
+ // Equivalent to /^.+\.\((Number|String)\)$/
546
+ const dataTypeRegex = new RegExp(`^.+\\.\\((${Object.keys(DataType).join('|')})\\)$`);
547
+ const isComplexKey = key => key.indexOf('{') > -1;
548
+
549
+ /**
550
+ * Reference operand resolved within the context
551
+ */
552
+ class Reference extends Operand {
553
+ /**
554
+ * @constructor
555
+ * @param {string} key Context key.
556
+ */
557
+ constructor(key) {
558
+ if (key.trim() === '') {
559
+ throw new Error('invalid reference key');
560
+ }
561
+ super();
562
+ _defineProperty(this, "key", void 0);
563
+ _defineProperty(this, "dataType", void 0);
564
+ _defineProperty(this, "valueLookup", void 0);
565
+ _defineProperty(this, "getKeys", void 0);
566
+ this.key = key;
567
+ const dataTypeMatch = dataTypeRegex.exec(this.key);
568
+ if (dataTypeMatch) {
569
+ this.dataType = DataType[dataTypeMatch[1]];
570
+ }
571
+ if (this.key.match(/.\(.+\)$/)) {
572
+ this.key = this.key.replace(/.\(.+\)$/, '');
573
+ }
574
+ if (isComplexKey(this.key)) {
575
+ this.valueLookup = context => complexValueLookup(context, this.key);
576
+ this.getKeys = context => extractComplexKeys(context, this.key);
577
+ } else {
578
+ const keys = parseKey(this.key);
579
+ this.valueLookup = simpleValueLookup(keys);
580
+ this.getKeys = () => keys;
581
+ }
582
+ }
68
583
 
69
- /**
70
- * Check if a value is a an Evaluable
71
- * @param {Result | Evaluable} value value to check if is Evaluable
72
- * @returns {Evaluable}
73
- */
74
- function isEvaluable(value) {
75
- return typeof value === 'object' && value !== null && !Array.isArray(value) && typeof value.evaluate === 'function' && typeof value.simplify === 'function' && typeof value.serialize === 'function' && typeof value.toString === 'function';
76
- }
584
+ /**
585
+ * Evaluate in the given context.
586
+ * @param {Context} ctx
587
+ * @return {boolean}
588
+ */
589
+ evaluate(ctx) {
590
+ return this.toDataType(this.valueLookup(ctx));
591
+ }
77
592
 
78
- /**
79
- * Valid types for context members
80
- */
593
+ /**
594
+ * {@link Evaluable.simplify}
595
+ */
596
+ simplify(ctx, strictKeys, optionalKeys) {
597
+ var _this$getKeys;
598
+ const [key] = (_this$getKeys = this.getKeys(ctx)) !== null && _this$getKeys !== void 0 ? _this$getKeys : [];
599
+ if (ctx[key] !== undefined) {
600
+ return this.evaluate(ctx);
601
+ }
602
+ if (!key || typeof key === 'number') {
603
+ return this;
604
+ }
605
+ return strictKeys && strictKeys.includes(key) || optionalKeys && !optionalKeys.includes(key) ? undefined : this;
606
+ }
81
607
 
82
- /**
83
- * Evaluation Context
84
- * Holds references used during the evaluation process.
85
- * Format: key: value.
86
- */
608
+ /**
609
+ * {@link Evaluable.serialize}
610
+ */
611
+ serialize({
612
+ referenceSerialization
613
+ }) {
614
+ const key = this.dataType ? `${this.key}.(${this.dataType})` : this.key;
615
+ return referenceSerialization(key);
616
+ }
87
617
 
88
- /**
89
- * Evaluation result
90
- */
618
+ /**
619
+ * Get the strict representation of the operand.
620
+ * @return {string}
621
+ */
622
+ toString() {
623
+ return `{${this.key}}`;
624
+ }
91
625
 
92
- let EvaluableType = /*#__PURE__*/function (EvaluableType) {
93
- EvaluableType["Operand"] = "Operand";
94
- EvaluableType["Expression"] = "Expression";
95
- return EvaluableType;
96
- }({});
626
+ /**
627
+ * Converts a value to a specified data type
628
+ * Silently returns original value if data type conversion has not been implemented.
629
+ * @param value value to cast as data type
630
+ */
631
+ toDataType(value) {
632
+ let result = value;
633
+ switch (this.dataType) {
634
+ case DataType.Number:
635
+ result = toNumber(value);
636
+ break;
637
+ case DataType.String:
638
+ result = toString(value);
639
+ break;
640
+ }
641
+ if (value && result === undefined) {
642
+ console.warn(`Casting ${value} to ${this.dataType} resulted in ${result}`);
643
+ }
644
+ return result;
645
+ }
646
+ }
97
647
 
98
- /**
99
- * Evaluable
100
- */
648
+ const isSimplifiedArithmeticExpression = (operand, result) => operand instanceof Arithmetic && !isEvaluable(result) && !isInfinite(result) && !(operand instanceof Reference);
101
649
 
102
650
  /**
103
651
  * Abstract comparison expression
@@ -148,6 +696,12 @@ class Comparison {
148
696
  if (!isEvaluable(left) && !isEvaluable(right)) {
149
697
  return this.comparison(left, right);
150
698
  }
699
+ if (isEvaluable(left) && isSimplifiedArithmeticExpression(this.right, right)) {
700
+ return Reflect.construct(this.constructor, [left, new Value(right)]);
701
+ }
702
+ if (isEvaluable(right) && isSimplifiedArithmeticExpression(this.left, left)) {
703
+ return Reflect.construct(this.constructor, [new Value(left), right]);
704
+ }
151
705
  return this;
152
706
  }
153
707
 
@@ -194,47 +748,6 @@ class Equal extends Comparison {
194
748
  }
195
749
  }
196
750
 
197
- /**
198
- * Convert a value to number if possible, otherwise return undefined
199
- * @param value value to be converted to number
200
- */
201
- const toNumber = value => {
202
- const isValueNumber = isNumber(value);
203
- if (isValueNumber) {
204
- return value;
205
- } else if (isString(value)) {
206
- if (value.match(/^\d+\.\d+$/)) {
207
- return parseFloat(value);
208
- } else if (value.match(/^0$|^[1-9]\d*$/)) {
209
- return parseInt(value);
210
- }
211
- }
212
- return undefined;
213
- };
214
-
215
- /**
216
- * Convert a value to string if possible, otherwise return undefined
217
- * @param value value to be converted to string
218
- */
219
- const toString = value => {
220
- if (isNumber(value)) {
221
- return `${value}`;
222
- } else if (isString(value)) {
223
- return value;
224
- }
225
- return undefined;
226
- };
227
- /**
228
- * Convert a value to number if it's type is string, otherwise return NaN
229
- * @param value value to be converted to number
230
- */
231
- const toDateNumber = value => {
232
- if (isString(value)) {
233
- return Date.parse(value);
234
- }
235
- return NaN;
236
- };
237
-
238
751
  // Operator key
239
752
  const OPERATOR$g = Symbol('GE');
240
753
 
@@ -551,142 +1064,59 @@ class Overlap extends Comparison {
551
1064
  const rightArray = right;
552
1065
  if (leftArray.length === 0 && rightArray.length === 0) {
553
1066
  return true;
554
- }
555
- return leftArray.some(element => rightArray.includes(element));
556
- }
557
-
558
- /**
559
- * Get the strict representation of the expression.
560
- * @return {string}
561
- */
562
- toString() {
563
- const left = this.left.toString();
564
- const right = this.right.toString();
565
- return `(${left} ${this.operator} ${right})`;
566
- }
567
- }
568
-
569
- // Operator key
570
- const OPERATOR$8 = Symbol('PREFIX');
571
-
572
- /**
573
- * Prefix comparison expression
574
- */
575
- class Prefix extends Comparison {
576
- /**
577
- * @constructor
578
- * @param {Evaluable} left Left operand.
579
- * @param {Evaluable} right Right operand.
580
- */
581
-
582
- constructor(left, right) {
583
- if (arguments.length !== 2) {
584
- throw new Error('comparison expression expects left and right operands');
585
- }
586
- super('prefix', OPERATOR$8, left, right);
587
- }
588
-
589
- /**
590
- * {@link Comparison.comparison}
591
- */
592
- comparison(left, right) {
593
- if (isString(left) === false || isString(right) === false) {
594
- return false;
595
- }
596
- return right.startsWith(left);
597
- }
598
-
599
- /**
600
- * Get the strict representation of the expression.
601
- * @return {string}
602
- */
603
- toString() {
604
- const left = this.left.toString();
605
- const right = this.right.toString();
606
- return `(<${left}>${right})`;
607
- }
608
- }
609
-
610
- /**
611
- * Abstract operand
612
- */
613
- class Operand {
614
- constructor() {
615
- _defineProperty(this, "type", EvaluableType.Operand);
616
- }
617
- /**
618
- * {@link Evaluable.evaluate}
619
- */
620
- /**
621
- * {@link Evaluable.simplify}
622
- */
623
- /**
624
- * {@link Evaluable.serialize}
625
- */
626
- /**
627
- * Get the strict representation.
628
- */
629
- toString() {
630
- throw new Error('not implemented exception');
631
- }
632
- }
633
-
634
- /**
635
- * Print value as string
636
- * @param {Result} value
637
- * @return {string}
638
- */
639
- function printValue(value) {
640
- if (isString(value)) {
641
- return `"${value}"`;
642
- }
643
- return `${value}`;
644
- }
645
-
646
- /**
647
- * Static value operand
648
- */
649
- class Value extends Operand {
650
- /**
651
- * @constructor
652
- * @param {Result} value Constant value.
653
- */
654
- constructor(value) {
655
- if (Array.isArray(value)) {
656
- throw new Error('deprecated direct usage of array, please use Collection operand');
657
- }
658
- super();
659
- _defineProperty(this, "value", void 0);
660
- this.value = value;
1067
+ }
1068
+ return leftArray.some(element => rightArray.includes(element));
661
1069
  }
662
1070
 
663
1071
  /**
664
- * {@link Evaluable.evaluate}
1072
+ * Get the strict representation of the expression.
1073
+ * @return {string}
665
1074
  */
666
- evaluate() {
667
- return this.value;
1075
+ toString() {
1076
+ const left = this.left.toString();
1077
+ const right = this.right.toString();
1078
+ return `(${left} ${this.operator} ${right})`;
668
1079
  }
1080
+ }
669
1081
 
1082
+ // Operator key
1083
+ const OPERATOR$8 = Symbol('PREFIX');
1084
+
1085
+ /**
1086
+ * Prefix comparison expression
1087
+ */
1088
+ class Prefix extends Comparison {
670
1089
  /**
671
- * {@link Evaluable.simplify}
1090
+ * @constructor
1091
+ * @param {Evaluable} left Left operand.
1092
+ * @param {Evaluable} right Right operand.
672
1093
  */
673
- simplify() {
674
- return this.value;
1094
+
1095
+ constructor(left, right) {
1096
+ if (arguments.length !== 2) {
1097
+ throw new Error('comparison expression expects left and right operands');
1098
+ }
1099
+ super('prefix', OPERATOR$8, left, right);
675
1100
  }
676
1101
 
677
1102
  /**
678
- * {@link Evaluable.serialize}
1103
+ * {@link Comparison.comparison}
679
1104
  */
680
- serialize() {
681
- return this.value;
1105
+ comparison(left, right) {
1106
+ if (isString(left) === false || isString(right) === false) {
1107
+ return false;
1108
+ }
1109
+ return right.startsWith(left);
682
1110
  }
683
1111
 
684
1112
  /**
685
- * Get the strict representation of the operand.
1113
+ * Get the strict representation of the expression.
686
1114
  * @return {string}
687
1115
  */
688
1116
  toString() {
689
- return printValue(this.value);
1117
+ const left = this.left.toString();
1118
+ const right = this.right.toString();
1119
+ return `(<${left}>${right})`;
690
1120
  }
691
1121
  }
692
1122
 
@@ -1233,187 +1663,6 @@ class Collection extends Operand {
1233
1663
  }
1234
1664
  }
1235
1665
 
1236
- const keyWithArrayIndexRegex = /^(?<currentKey>[^[\]]+?)(?<indexes>(?:\[\d+])+)?$/;
1237
- const arrayIndexRegex = /\[(\d+)]/g;
1238
- const parseBacktickWrappedKey = key => key.startsWith('`') && key.endsWith('`') ? key.slice(1, -1) : key;
1239
- const parseKey = key => {
1240
- const keys = key.match(/(`[^[\]]+`(\[\d+\])*|[^`.]+)/g);
1241
- return !keys ? [] : keys.flatMap(key => {
1242
- const unwrappedKey = parseBacktickWrappedKey(key);
1243
- const keys = [];
1244
- const parseResult = keyWithArrayIndexRegex.exec(unwrappedKey);
1245
- if (parseResult) {
1246
- var _parseResult$groups$c, _parseResult$groups, _parseResult$groups2;
1247
- const extractedKey = parseBacktickWrappedKey((_parseResult$groups$c = parseResult === null || parseResult === void 0 || (_parseResult$groups = parseResult.groups) === null || _parseResult$groups === void 0 ? void 0 : _parseResult$groups.currentKey) !== null && _parseResult$groups$c !== void 0 ? _parseResult$groups$c : unwrappedKey);
1248
- keys.push(extractedKey);
1249
- const rawIndexes = parseResult === null || parseResult === void 0 || (_parseResult$groups2 = parseResult.groups) === null || _parseResult$groups2 === void 0 ? void 0 : _parseResult$groups2.indexes;
1250
- if (rawIndexes) {
1251
- for (const indexResult of rawIndexes.matchAll(arrayIndexRegex)) {
1252
- keys.push(parseInt(indexResult[1]));
1253
- }
1254
- }
1255
- } else {
1256
- keys.push(unwrappedKey);
1257
- }
1258
- return keys;
1259
- });
1260
- };
1261
- const complexKeyExpression = /{([^{}]+)}/;
1262
- function extractComplexKeys(ctx, key) {
1263
- // Resolve complex keys
1264
- let complexKeyMatches = complexKeyExpression.exec(key);
1265
- while (complexKeyMatches) {
1266
- const resolvedValue = complexValueLookup(ctx, complexKeyMatches[1]);
1267
- if (resolvedValue === undefined) {
1268
- return undefined;
1269
- }
1270
- key = key.replace(complexKeyExpression, `${resolvedValue}`);
1271
- complexKeyMatches = complexKeyExpression.exec(key);
1272
- }
1273
- return parseKey(key);
1274
- }
1275
- const isContext = value => isObject(value);
1276
- const simpleValueLookup = keys => ctx => {
1277
- let pointer = ctx;
1278
- for (const key of keys) {
1279
- if (typeof key === 'number') {
1280
- if (!Array.isArray(pointer)) {
1281
- return undefined;
1282
- }
1283
- pointer = pointer[key];
1284
- } else if (!isContext(pointer)) {
1285
- return undefined;
1286
- } else {
1287
- pointer = pointer[key];
1288
- }
1289
- }
1290
- return pointer;
1291
- };
1292
-
1293
- /**
1294
- * Lookup for the reference in the context.
1295
- * The nested context value is annotated with "." delimiter.
1296
- * @example address.city
1297
- * @param {Context} ctx
1298
- * @param {string} key Context lookup key.
1299
- * @return {Result}
1300
- */
1301
- function complexValueLookup(ctx, key) {
1302
- const keys = extractComplexKeys(ctx, key);
1303
- if (!keys) {
1304
- return undefined;
1305
- }
1306
- return simpleValueLookup(keys !== null && keys !== void 0 ? keys : [])(ctx);
1307
- }
1308
- let DataType = /*#__PURE__*/function (DataType) {
1309
- DataType["Number"] = "Number";
1310
- DataType["String"] = "String";
1311
- return DataType;
1312
- }({});
1313
-
1314
- // Equivalent to /^.+\.\((Number|String)\)$/
1315
- const dataTypeRegex = new RegExp(`^.+\\.\\((${Object.keys(DataType).join('|')})\\)$`);
1316
- const isComplexKey = key => key.indexOf('{') > -1;
1317
-
1318
- /**
1319
- * Reference operand resolved within the context
1320
- */
1321
- class Reference extends Operand {
1322
- /**
1323
- * @constructor
1324
- * @param {string} key Context key.
1325
- */
1326
- constructor(key) {
1327
- if (key.trim() === '') {
1328
- throw new Error('invalid reference key');
1329
- }
1330
- super();
1331
- _defineProperty(this, "key", void 0);
1332
- _defineProperty(this, "dataType", void 0);
1333
- _defineProperty(this, "valueLookup", void 0);
1334
- _defineProperty(this, "getKeys", void 0);
1335
- this.key = key;
1336
- const dataTypeMatch = dataTypeRegex.exec(this.key);
1337
- if (dataTypeMatch) {
1338
- this.dataType = DataType[dataTypeMatch[1]];
1339
- }
1340
- if (this.key.match(/.\(.+\)$/)) {
1341
- this.key = this.key.replace(/.\(.+\)$/, '');
1342
- }
1343
- if (isComplexKey(this.key)) {
1344
- this.valueLookup = context => complexValueLookup(context, this.key);
1345
- this.getKeys = context => extractComplexKeys(context, this.key);
1346
- } else {
1347
- const keys = parseKey(this.key);
1348
- this.valueLookup = simpleValueLookup(keys);
1349
- this.getKeys = () => keys;
1350
- }
1351
- }
1352
-
1353
- /**
1354
- * Evaluate in the given context.
1355
- * @param {Context} ctx
1356
- * @return {boolean}
1357
- */
1358
- evaluate(ctx) {
1359
- return this.toDataType(this.valueLookup(ctx));
1360
- }
1361
-
1362
- /**
1363
- * {@link Evaluable.simplify}
1364
- */
1365
- simplify(ctx, strictKeys, optionalKeys) {
1366
- var _this$getKeys;
1367
- const [key] = (_this$getKeys = this.getKeys(ctx)) !== null && _this$getKeys !== void 0 ? _this$getKeys : [];
1368
- if (ctx[key] !== undefined) {
1369
- return this.evaluate(ctx);
1370
- }
1371
- if (!key || typeof key === 'number') {
1372
- return this;
1373
- }
1374
- return strictKeys && strictKeys.includes(key) || optionalKeys && !optionalKeys.includes(key) ? undefined : this;
1375
- }
1376
-
1377
- /**
1378
- * {@link Evaluable.serialize}
1379
- */
1380
- serialize({
1381
- referenceSerialization
1382
- }) {
1383
- const key = this.dataType ? `${this.key}.(${this.dataType})` : this.key;
1384
- return referenceSerialization(key);
1385
- }
1386
-
1387
- /**
1388
- * Get the strict representation of the operand.
1389
- * @return {string}
1390
- */
1391
- toString() {
1392
- return `{${this.key}}`;
1393
- }
1394
-
1395
- /**
1396
- * Converts a value to a specified data type
1397
- * Silently returns original value if data type conversion has not been implemented.
1398
- * @param value value to cast as data type
1399
- */
1400
- toDataType(value) {
1401
- let result = value;
1402
- switch (this.dataType) {
1403
- case DataType.Number:
1404
- result = toNumber(value);
1405
- break;
1406
- case DataType.String:
1407
- result = toString(value);
1408
- break;
1409
- }
1410
- if (value && result === undefined) {
1411
- console.warn(`Casting ${value} to ${this.dataType} resulted in ${result}`);
1412
- }
1413
- return result;
1414
- }
1415
- }
1416
-
1417
1666
  // Option value whitelist
1418
1667
 
1419
1668
  // Parser options
@@ -1449,7 +1698,9 @@ const defaultOperatorMapping = new Map([
1449
1698
  // Comparison
1450
1699
  [OPERATOR$h, '=='], [OPERATOR$b, '!='], [OPERATOR$f, '>'], [OPERATOR$g, '>='], [OPERATOR$c, '<'], [OPERATOR$d, '<='], [OPERATOR$e, 'IN'], [OPERATOR$a, 'NOT IN'], [OPERATOR$8, 'PREFIX'], [OPERATOR$6, 'SUFFIX'], [OPERATOR$9, 'OVERLAP'], [OPERATOR$5, 'UNDEFINED'], [OPERATOR$7, 'PRESENT'],
1451
1700
  // Logical
1452
- [OPERATOR$4, 'AND'], [OPERATOR$1, 'OR'], [OPERATOR$2, 'NOR'], [OPERATOR, 'XOR'], [OPERATOR$3, 'NOT']]);
1701
+ [OPERATOR$4, 'AND'], [OPERATOR$1, 'OR'], [OPERATOR$2, 'NOR'], [OPERATOR, 'XOR'], [OPERATOR$3, 'NOT'],
1702
+ // Arithmetic
1703
+ [OPERATOR$i, '+'], [OPERATOR$j, '-'], [OPERATOR$k, '*'], [OPERATOR$l, '/']]);
1453
1704
 
1454
1705
  /**
1455
1706
  * Default parser options
@@ -1463,6 +1714,14 @@ const defaultOptions = {
1463
1714
 
1464
1715
  // Input types
1465
1716
 
1717
+ const invalidExpression = 'invalid expression';
1718
+ const logicalIfValidOperands = (operands, logical) => {
1719
+ if (operands.every(operand => operand instanceof Logical || operand instanceof Comparison)) {
1720
+ return logical;
1721
+ }
1722
+ throw new Error(invalidExpression);
1723
+ };
1724
+
1466
1725
  /**
1467
1726
  * Parser of raw expressions into Evaluable expression
1468
1727
  */
@@ -1473,7 +1732,8 @@ class Parser {
1473
1732
  */
1474
1733
  constructor(options) {
1475
1734
  _defineProperty(this, "opts", void 0);
1476
- _defineProperty(this, "expectedOperators", void 0);
1735
+ _defineProperty(this, "expectedRootOperators", void 0);
1736
+ _defineProperty(this, "unexpectedRootSymbols", new Set([OPERATOR$i, OPERATOR$j, OPERATOR$k, OPERATOR$l]));
1477
1737
  this.opts = {
1478
1738
  ...defaultOptions
1479
1739
  };
@@ -1485,7 +1745,7 @@ class Parser {
1485
1745
  }
1486
1746
  }
1487
1747
  }
1488
- this.expectedOperators = new Set(this.opts.operatorMapping.values());
1748
+ this.expectedRootOperators = new Set(Array.from(this.opts.operatorMapping.entries()).filter(([symbol]) => !this.unexpectedRootSymbols.has(symbol)).map(([, operator]) => operator));
1489
1749
  }
1490
1750
 
1491
1751
  /**
@@ -1503,10 +1763,10 @@ class Parser {
1503
1763
  */
1504
1764
  parse(raw) {
1505
1765
  if (raw === undefined || raw === null || Array.isArray(raw) === false) {
1506
- throw new Error('invalid expression');
1766
+ throw new Error(invalidExpression);
1507
1767
  }
1508
- if (raw.length === 0 || !this.expectedOperators.has(`${raw[0]}`)) {
1509
- throw new Error('invalid expression');
1768
+ if (raw.length === 0 || !this.expectedRootOperators.has(`${raw[0]}`)) {
1769
+ throw new Error(invalidExpression);
1510
1770
  }
1511
1771
  return this.parseRawExp(raw);
1512
1772
  }
@@ -1544,71 +1804,103 @@ class Parser {
1544
1804
  return collapsible && operands.length === 1 ? operands[0] : undefined;
1545
1805
  };
1546
1806
  switch (operator) {
1547
- /**
1548
- * Logical
1549
- */
1807
+ // Logical
1550
1808
  case this.opts.operatorMapping.get(OPERATOR$4):
1551
- expression = operands => logicalExpressionReducer(operands, true) || new And(operands);
1809
+ expression = operands => logicalExpressionReducer(operands, true) || logicalIfValidOperands(operands, new And(operands));
1552
1810
  operandParser = this.parseRawExp;
1553
1811
  break;
1554
1812
  case this.opts.operatorMapping.get(OPERATOR$1):
1555
- expression = operands => logicalExpressionReducer(operands, true) || new Or(operands);
1813
+ expression = operands => logicalExpressionReducer(operands, true) || logicalIfValidOperands(operands, new Or(operands));
1556
1814
  operandParser = this.parseRawExp;
1557
1815
  break;
1558
1816
  case this.opts.operatorMapping.get(OPERATOR$2):
1559
- expression = operands => logicalExpressionReducer(operands) || new Nor(operands);
1817
+ expression = operands => logicalExpressionReducer(operands) || logicalIfValidOperands(operands, new Nor(operands));
1560
1818
  operandParser = this.parseRawExp;
1561
1819
  break;
1562
1820
  case this.opts.operatorMapping.get(OPERATOR):
1563
- expression = operands => logicalExpressionReducer(operands) || new Xor(operands);
1821
+ expression = operands => logicalExpressionReducer(operands) || logicalIfValidOperands(operands, new Xor(operands));
1564
1822
  operandParser = this.parseRawExp;
1565
1823
  break;
1566
1824
  case this.opts.operatorMapping.get(OPERATOR$3):
1567
- expression = operands => logicalExpressionReducer(operands) || new Not(...operands);
1825
+ expression = operands => logicalExpressionReducer(operands) || logicalIfValidOperands(operands, new Not(...operands));
1568
1826
  operandParser = this.parseRawExp;
1569
1827
  break;
1570
- /**
1571
- * Comparison
1572
- */
1828
+
1829
+ // Comparison
1573
1830
  case this.opts.operatorMapping.get(OPERATOR$h):
1574
1831
  expression = operands => new Equal(...operands);
1832
+ operandParser = this.parseRawExp;
1575
1833
  break;
1576
1834
  case this.opts.operatorMapping.get(OPERATOR$b):
1577
1835
  expression = operands => new NotEqual(...operands);
1836
+ operandParser = this.parseRawExp;
1578
1837
  break;
1579
1838
  case this.opts.operatorMapping.get(OPERATOR$f):
1580
1839
  expression = operands => new GreaterThan(...operands);
1840
+ operandParser = this.parseRawExp;
1581
1841
  break;
1582
1842
  case this.opts.operatorMapping.get(OPERATOR$g):
1583
1843
  expression = operands => new GreaterThanOrEqual(...operands);
1844
+ operandParser = this.parseRawExp;
1584
1845
  break;
1585
1846
  case this.opts.operatorMapping.get(OPERATOR$c):
1586
1847
  expression = operands => new LessThan(...operands);
1848
+ operandParser = this.parseRawExp;
1587
1849
  break;
1588
1850
  case this.opts.operatorMapping.get(OPERATOR$d):
1589
1851
  expression = operands => new LessThanOrEqual(...operands);
1852
+ operandParser = this.parseRawExp;
1590
1853
  break;
1854
+
1855
+ // Containment
1591
1856
  case this.opts.operatorMapping.get(OPERATOR$e):
1592
1857
  expression = operands => new In(...operands);
1593
1858
  break;
1594
1859
  case this.opts.operatorMapping.get(OPERATOR$a):
1595
1860
  expression = operands => new NotIn(...operands);
1596
1861
  break;
1862
+
1863
+ // Prefix
1597
1864
  case this.opts.operatorMapping.get(OPERATOR$8):
1598
1865
  expression = operands => new Prefix(...operands);
1599
1866
  break;
1867
+
1868
+ // Suffix
1600
1869
  case this.opts.operatorMapping.get(OPERATOR$6):
1601
1870
  expression = operands => new Suffix(...operands);
1602
1871
  break;
1872
+
1873
+ // Overlap
1603
1874
  case this.opts.operatorMapping.get(OPERATOR$9):
1604
1875
  expression = operands => new Overlap(...operands);
1605
1876
  break;
1877
+
1878
+ // Presence
1606
1879
  case this.opts.operatorMapping.get(OPERATOR$5):
1607
1880
  expression = operands => new Undefined(...operands);
1608
1881
  break;
1609
1882
  case this.opts.operatorMapping.get(OPERATOR$7):
1610
1883
  expression = operands => new Present(...operands);
1611
1884
  break;
1885
+
1886
+ // Arithmetic
1887
+ case this.opts.operatorMapping.get(OPERATOR$i):
1888
+ expression = operands => new Sum(...operands);
1889
+ operandParser = this.parseRawExp;
1890
+ break;
1891
+ case this.opts.operatorMapping.get(OPERATOR$j):
1892
+ expression = operands => new Subtract(...operands);
1893
+ operandParser = this.parseRawExp;
1894
+ break;
1895
+ case this.opts.operatorMapping.get(OPERATOR$k):
1896
+ expression = operands => new Multiply(...operands);
1897
+ operandParser = this.parseRawExp;
1898
+ break;
1899
+ case this.opts.operatorMapping.get(OPERATOR$l):
1900
+ expression = operands => new Divide(...operands);
1901
+ operandParser = this.parseRawExp;
1902
+ break;
1903
+
1612
1904
  // Collection
1613
1905
  default:
1614
1906
  return this.getOperand(raw);
@@ -1629,6 +1921,8 @@ class Parser {
1629
1921
  }
1630
1922
  }
1631
1923
 
1924
+ const unexpectedResultError = 'non expression or boolean result should be returned';
1925
+
1632
1926
  /**
1633
1927
  * Condition engine
1634
1928
  */
@@ -1649,7 +1943,11 @@ class Engine {
1649
1943
  * @return {boolean}
1650
1944
  */
1651
1945
  evaluate(exp, ctx) {
1652
- return this.parse(exp).evaluate(ctx);
1946
+ const result = this.parse(exp).evaluate(ctx);
1947
+ if (isBoolean(result)) {
1948
+ return result;
1949
+ }
1950
+ throw new Error(unexpectedResultError);
1653
1951
  }
1654
1952
 
1655
1953
  /**
@@ -1693,8 +1991,8 @@ class Engine {
1693
1991
  if (isBoolean(result)) {
1694
1992
  return result;
1695
1993
  }
1696
- throw new Error('non expression or boolean result should be returned');
1994
+ throw new Error(unexpectedResultError);
1697
1995
  }
1698
1996
  }
1699
1997
 
1700
- 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, defaultOptions, isEvaluable };
1998
+ export { OPERATOR$4 as OPERATOR_AND, OPERATOR$l as OPERATOR_DIVIDE, 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$k as OPERATOR_MULTIPLY, 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$j as OPERATOR_SUBTRACT, OPERATOR$6 as OPERATOR_SUFFIX, OPERATOR$i as OPERATOR_SUM, OPERATOR$5 as OPERATOR_UNDEFINED, OPERATOR as OPERATOR_XOR, Engine as default, defaultOptions, isEvaluable };