@the-trybe/formula-engine 1.0.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.
- package/.claude/settings.local.json +6 -0
- package/PRD_FORMULA_ENGINE.md +1863 -0
- package/README.md +382 -0
- package/dist/decimal-utils.d.ts +180 -0
- package/dist/decimal-utils.js +355 -0
- package/dist/dependency-extractor.d.ts +20 -0
- package/dist/dependency-extractor.js +103 -0
- package/dist/dependency-graph.d.ts +60 -0
- package/dist/dependency-graph.js +252 -0
- package/dist/errors.d.ts +161 -0
- package/dist/errors.js +260 -0
- package/dist/evaluator.d.ts +51 -0
- package/dist/evaluator.js +494 -0
- package/dist/formula-engine.d.ts +79 -0
- package/dist/formula-engine.js +355 -0
- package/dist/functions.d.ts +3 -0
- package/dist/functions.js +720 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +61 -0
- package/dist/lexer.d.ts +25 -0
- package/dist/lexer.js +357 -0
- package/dist/parser.d.ts +32 -0
- package/dist/parser.js +372 -0
- package/dist/types.d.ts +228 -0
- package/dist/types.js +62 -0
- package/jest.config.js +23 -0
- package/package.json +35 -0
- package/src/decimal-utils.ts +408 -0
- package/src/dependency-extractor.ts +117 -0
- package/src/dependency-graph.test.ts +238 -0
- package/src/dependency-graph.ts +288 -0
- package/src/errors.ts +296 -0
- package/src/evaluator.ts +604 -0
- package/src/formula-engine.test.ts +660 -0
- package/src/formula-engine.ts +430 -0
- package/src/functions.ts +770 -0
- package/src/index.ts +103 -0
- package/src/lexer.test.ts +288 -0
- package/src/lexer.ts +394 -0
- package/src/parser.test.ts +349 -0
- package/src/parser.ts +449 -0
- package/src/types.ts +347 -0
- package/tsconfig.json +29 -0
package/dist/parser.js
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Parser = void 0;
|
|
4
|
+
const lexer_1 = require("./lexer");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
const errors_1 = require("./errors");
|
|
7
|
+
// Operator precedence levels (higher = tighter binding)
|
|
8
|
+
const PRECEDENCE = {
|
|
9
|
+
LOWEST: 1,
|
|
10
|
+
TERNARY: 2, // ? :
|
|
11
|
+
OR: 3, // || OR
|
|
12
|
+
AND: 4, // && AND
|
|
13
|
+
EQUALITY: 5, // == !=
|
|
14
|
+
COMPARISON: 6, // < > <= >=
|
|
15
|
+
TERM: 7, // + -
|
|
16
|
+
FACTOR: 8, // * / %
|
|
17
|
+
POWER: 9, // ^
|
|
18
|
+
UNARY: 10, // - ! NOT
|
|
19
|
+
CALL: 11, // function calls
|
|
20
|
+
MEMBER: 12, // . []
|
|
21
|
+
};
|
|
22
|
+
class Parser {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.tokens = [];
|
|
25
|
+
this.current = 0;
|
|
26
|
+
this.expression = '';
|
|
27
|
+
}
|
|
28
|
+
parse(expression) {
|
|
29
|
+
this.expression = expression;
|
|
30
|
+
const lexer = new lexer_1.Lexer(expression);
|
|
31
|
+
this.tokens = lexer.tokenize();
|
|
32
|
+
this.current = 0;
|
|
33
|
+
const ast = this.parseExpression(PRECEDENCE.LOWEST);
|
|
34
|
+
if (!this.isAtEnd()) {
|
|
35
|
+
const token = this.peek();
|
|
36
|
+
throw new errors_1.UnexpectedTokenError(String(token.value), ['end of expression'], token.position);
|
|
37
|
+
}
|
|
38
|
+
return ast;
|
|
39
|
+
}
|
|
40
|
+
parseExpression(precedence) {
|
|
41
|
+
let left = this.parsePrefixExpression();
|
|
42
|
+
while (!this.isAtEnd() && precedence < this.getPrecedence()) {
|
|
43
|
+
left = this.parseInfixExpression(left);
|
|
44
|
+
}
|
|
45
|
+
return left;
|
|
46
|
+
}
|
|
47
|
+
parsePrefixExpression() {
|
|
48
|
+
const token = this.peek();
|
|
49
|
+
switch (token.type) {
|
|
50
|
+
case types_1.TokenType.NUMBER:
|
|
51
|
+
return this.parseNumber();
|
|
52
|
+
case types_1.TokenType.STRING:
|
|
53
|
+
return this.parseString();
|
|
54
|
+
case types_1.TokenType.BOOLEAN:
|
|
55
|
+
return this.parseBoolean();
|
|
56
|
+
case types_1.TokenType.NULL:
|
|
57
|
+
return this.parseNull();
|
|
58
|
+
case types_1.TokenType.VARIABLE:
|
|
59
|
+
return this.parseVariable();
|
|
60
|
+
case types_1.TokenType.CONTEXT_VAR:
|
|
61
|
+
return this.parseContextVariable();
|
|
62
|
+
case types_1.TokenType.IDENTIFIER:
|
|
63
|
+
return this.parseIdentifierOrFunctionCall();
|
|
64
|
+
case types_1.TokenType.LPAREN:
|
|
65
|
+
return this.parseGroupedExpression();
|
|
66
|
+
case types_1.TokenType.LBRACKET:
|
|
67
|
+
return this.parseArrayLiteral();
|
|
68
|
+
case types_1.TokenType.MINUS:
|
|
69
|
+
case types_1.TokenType.NOT:
|
|
70
|
+
return this.parseUnaryExpression();
|
|
71
|
+
default:
|
|
72
|
+
throw new errors_1.UnexpectedTokenError(String(token.value), ['number', 'string', 'boolean', 'null', 'variable', 'identifier', '(', '[', '-', '!'], token.position);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
parseInfixExpression(left) {
|
|
76
|
+
const token = this.peek();
|
|
77
|
+
switch (token.type) {
|
|
78
|
+
case types_1.TokenType.PLUS:
|
|
79
|
+
case types_1.TokenType.MINUS:
|
|
80
|
+
case types_1.TokenType.MULTIPLY:
|
|
81
|
+
case types_1.TokenType.DIVIDE:
|
|
82
|
+
case types_1.TokenType.MODULO:
|
|
83
|
+
case types_1.TokenType.POWER:
|
|
84
|
+
case types_1.TokenType.EQ:
|
|
85
|
+
case types_1.TokenType.NEQ:
|
|
86
|
+
case types_1.TokenType.LT:
|
|
87
|
+
case types_1.TokenType.GT:
|
|
88
|
+
case types_1.TokenType.LTE:
|
|
89
|
+
case types_1.TokenType.GTE:
|
|
90
|
+
case types_1.TokenType.AND:
|
|
91
|
+
case types_1.TokenType.OR:
|
|
92
|
+
return this.parseBinaryExpression(left);
|
|
93
|
+
case types_1.TokenType.QUESTION:
|
|
94
|
+
return this.parseTernaryExpression(left);
|
|
95
|
+
case types_1.TokenType.DOT:
|
|
96
|
+
return this.parseMemberAccess(left);
|
|
97
|
+
case types_1.TokenType.LBRACKET:
|
|
98
|
+
return this.parseIndexAccess(left);
|
|
99
|
+
case types_1.TokenType.LPAREN:
|
|
100
|
+
// This handles the case where we have an identifier followed by (
|
|
101
|
+
// But actually this should be handled in parseIdentifierOrFunctionCall
|
|
102
|
+
return left;
|
|
103
|
+
default:
|
|
104
|
+
return left;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
parseNumber() {
|
|
108
|
+
const token = this.advance();
|
|
109
|
+
const value = token.value;
|
|
110
|
+
if (typeof value === 'number') {
|
|
111
|
+
// It's a float
|
|
112
|
+
return {
|
|
113
|
+
type: 'NumberLiteral',
|
|
114
|
+
value: value,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// It's a decimal (stored as string)
|
|
119
|
+
return {
|
|
120
|
+
type: 'DecimalLiteral',
|
|
121
|
+
value: String(value),
|
|
122
|
+
raw: String(value),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
parseString() {
|
|
127
|
+
const token = this.advance();
|
|
128
|
+
return {
|
|
129
|
+
type: 'StringLiteral',
|
|
130
|
+
value: String(token.value),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
parseBoolean() {
|
|
134
|
+
const token = this.advance();
|
|
135
|
+
return {
|
|
136
|
+
type: 'BooleanLiteral',
|
|
137
|
+
value: token.value === true,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
parseNull() {
|
|
141
|
+
this.advance();
|
|
142
|
+
return {
|
|
143
|
+
type: 'NullLiteral',
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
parseVariable() {
|
|
147
|
+
const token = this.advance();
|
|
148
|
+
return {
|
|
149
|
+
type: 'VariableReference',
|
|
150
|
+
prefix: '$',
|
|
151
|
+
name: String(token.value),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
parseContextVariable() {
|
|
155
|
+
const token = this.advance();
|
|
156
|
+
return {
|
|
157
|
+
type: 'VariableReference',
|
|
158
|
+
prefix: '@',
|
|
159
|
+
name: String(token.value),
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
parseIdentifierOrFunctionCall() {
|
|
163
|
+
const token = this.advance();
|
|
164
|
+
const name = String(token.value);
|
|
165
|
+
// Check if it's a function call
|
|
166
|
+
if (this.peek().type === types_1.TokenType.LPAREN) {
|
|
167
|
+
return this.parseFunctionCall(name);
|
|
168
|
+
}
|
|
169
|
+
// Otherwise, check for keywords AND/OR/NOT used as standalone identifiers
|
|
170
|
+
const upperName = name.toUpperCase();
|
|
171
|
+
if (upperName === 'AND' || upperName === 'OR') {
|
|
172
|
+
// These should be handled as operators, but if we reach here,
|
|
173
|
+
// it means they were used in an invalid context
|
|
174
|
+
throw new errors_1.SyntaxError(`'${name}' cannot be used as an identifier`, token.position, token.line, token.column, this.expression);
|
|
175
|
+
}
|
|
176
|
+
// It's a bare identifier - could be a variable without prefix
|
|
177
|
+
// For now, treat it as an error - require explicit prefix
|
|
178
|
+
throw new errors_1.SyntaxError(`Unknown identifier '${name}'. Variables must be prefixed with $ or @`, token.position, token.line, token.column, this.expression);
|
|
179
|
+
}
|
|
180
|
+
parseFunctionCall(name) {
|
|
181
|
+
this.advance(); // consume '('
|
|
182
|
+
const args = [];
|
|
183
|
+
if (this.peek().type !== types_1.TokenType.RPAREN) {
|
|
184
|
+
do {
|
|
185
|
+
if (this.peek().type === types_1.TokenType.COMMA) {
|
|
186
|
+
this.advance();
|
|
187
|
+
}
|
|
188
|
+
args.push(this.parseExpression(PRECEDENCE.LOWEST));
|
|
189
|
+
} while (this.peek().type === types_1.TokenType.COMMA);
|
|
190
|
+
}
|
|
191
|
+
this.expect(types_1.TokenType.RPAREN, ')');
|
|
192
|
+
return {
|
|
193
|
+
type: 'FunctionCall',
|
|
194
|
+
name: name.toUpperCase(), // Functions are case-insensitive
|
|
195
|
+
arguments: args,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
parseGroupedExpression() {
|
|
199
|
+
this.advance(); // consume '('
|
|
200
|
+
const expr = this.parseExpression(PRECEDENCE.LOWEST);
|
|
201
|
+
this.expect(types_1.TokenType.RPAREN, ')');
|
|
202
|
+
return expr;
|
|
203
|
+
}
|
|
204
|
+
parseArrayLiteral() {
|
|
205
|
+
this.advance(); // consume '['
|
|
206
|
+
const elements = [];
|
|
207
|
+
if (this.peek().type !== types_1.TokenType.RBRACKET) {
|
|
208
|
+
do {
|
|
209
|
+
if (this.peek().type === types_1.TokenType.COMMA) {
|
|
210
|
+
this.advance();
|
|
211
|
+
}
|
|
212
|
+
elements.push(this.parseExpression(PRECEDENCE.LOWEST));
|
|
213
|
+
} while (this.peek().type === types_1.TokenType.COMMA);
|
|
214
|
+
}
|
|
215
|
+
this.expect(types_1.TokenType.RBRACKET, ']');
|
|
216
|
+
return {
|
|
217
|
+
type: 'ArrayLiteral',
|
|
218
|
+
elements,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
parseUnaryExpression() {
|
|
222
|
+
const token = this.advance();
|
|
223
|
+
const operator = this.getOperatorSymbol(token.type);
|
|
224
|
+
const operand = this.parseExpression(PRECEDENCE.UNARY);
|
|
225
|
+
return {
|
|
226
|
+
type: 'UnaryOperation',
|
|
227
|
+
operator,
|
|
228
|
+
operand,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
parseBinaryExpression(left) {
|
|
232
|
+
const token = this.advance();
|
|
233
|
+
const operator = this.getOperatorSymbol(token.type);
|
|
234
|
+
const precedence = this.getTokenPrecedence(token.type);
|
|
235
|
+
// Right associativity for power operator
|
|
236
|
+
const nextPrecedence = token.type === types_1.TokenType.POWER ? precedence - 1 : precedence;
|
|
237
|
+
const right = this.parseExpression(nextPrecedence);
|
|
238
|
+
return {
|
|
239
|
+
type: 'BinaryOperation',
|
|
240
|
+
operator,
|
|
241
|
+
left,
|
|
242
|
+
right,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
parseTernaryExpression(condition) {
|
|
246
|
+
this.advance(); // consume '?'
|
|
247
|
+
const consequent = this.parseExpression(PRECEDENCE.LOWEST);
|
|
248
|
+
this.expect(types_1.TokenType.COLON, ':');
|
|
249
|
+
const alternate = this.parseExpression(PRECEDENCE.TERNARY - 1);
|
|
250
|
+
return {
|
|
251
|
+
type: 'ConditionalExpression',
|
|
252
|
+
condition,
|
|
253
|
+
consequent,
|
|
254
|
+
alternate,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
parseMemberAccess(object) {
|
|
258
|
+
this.advance(); // consume '.'
|
|
259
|
+
const token = this.peek();
|
|
260
|
+
if (token.type !== types_1.TokenType.IDENTIFIER && token.type !== types_1.TokenType.VARIABLE) {
|
|
261
|
+
throw new errors_1.UnexpectedTokenError(String(token.value), ['identifier'], token.position);
|
|
262
|
+
}
|
|
263
|
+
this.advance();
|
|
264
|
+
const property = String(token.value);
|
|
265
|
+
const node = {
|
|
266
|
+
type: 'MemberAccess',
|
|
267
|
+
object,
|
|
268
|
+
property,
|
|
269
|
+
};
|
|
270
|
+
// Check for chained access
|
|
271
|
+
if (this.peek().type === types_1.TokenType.DOT) {
|
|
272
|
+
return this.parseMemberAccess(node);
|
|
273
|
+
}
|
|
274
|
+
if (this.peek().type === types_1.TokenType.LBRACKET) {
|
|
275
|
+
return this.parseIndexAccess(node);
|
|
276
|
+
}
|
|
277
|
+
return node;
|
|
278
|
+
}
|
|
279
|
+
parseIndexAccess(object) {
|
|
280
|
+
this.advance(); // consume '['
|
|
281
|
+
const index = this.parseExpression(PRECEDENCE.LOWEST);
|
|
282
|
+
this.expect(types_1.TokenType.RBRACKET, ']');
|
|
283
|
+
const node = {
|
|
284
|
+
type: 'IndexAccess',
|
|
285
|
+
object,
|
|
286
|
+
index,
|
|
287
|
+
};
|
|
288
|
+
// Check for chained access
|
|
289
|
+
if (this.peek().type === types_1.TokenType.DOT) {
|
|
290
|
+
return this.parseMemberAccess(node);
|
|
291
|
+
}
|
|
292
|
+
if (this.peek().type === types_1.TokenType.LBRACKET) {
|
|
293
|
+
return this.parseIndexAccess(node);
|
|
294
|
+
}
|
|
295
|
+
return node;
|
|
296
|
+
}
|
|
297
|
+
getPrecedence() {
|
|
298
|
+
return this.getTokenPrecedence(this.peek().type);
|
|
299
|
+
}
|
|
300
|
+
getTokenPrecedence(type) {
|
|
301
|
+
switch (type) {
|
|
302
|
+
case types_1.TokenType.OR:
|
|
303
|
+
return PRECEDENCE.OR;
|
|
304
|
+
case types_1.TokenType.AND:
|
|
305
|
+
return PRECEDENCE.AND;
|
|
306
|
+
case types_1.TokenType.EQ:
|
|
307
|
+
case types_1.TokenType.NEQ:
|
|
308
|
+
return PRECEDENCE.EQUALITY;
|
|
309
|
+
case types_1.TokenType.LT:
|
|
310
|
+
case types_1.TokenType.GT:
|
|
311
|
+
case types_1.TokenType.LTE:
|
|
312
|
+
case types_1.TokenType.GTE:
|
|
313
|
+
return PRECEDENCE.COMPARISON;
|
|
314
|
+
case types_1.TokenType.PLUS:
|
|
315
|
+
case types_1.TokenType.MINUS:
|
|
316
|
+
return PRECEDENCE.TERM;
|
|
317
|
+
case types_1.TokenType.MULTIPLY:
|
|
318
|
+
case types_1.TokenType.DIVIDE:
|
|
319
|
+
case types_1.TokenType.MODULO:
|
|
320
|
+
return PRECEDENCE.FACTOR;
|
|
321
|
+
case types_1.TokenType.POWER:
|
|
322
|
+
return PRECEDENCE.POWER;
|
|
323
|
+
case types_1.TokenType.DOT:
|
|
324
|
+
case types_1.TokenType.LBRACKET:
|
|
325
|
+
return PRECEDENCE.MEMBER;
|
|
326
|
+
case types_1.TokenType.QUESTION:
|
|
327
|
+
return PRECEDENCE.TERNARY;
|
|
328
|
+
default:
|
|
329
|
+
return PRECEDENCE.LOWEST;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
getOperatorSymbol(type) {
|
|
333
|
+
switch (type) {
|
|
334
|
+
case types_1.TokenType.PLUS: return '+';
|
|
335
|
+
case types_1.TokenType.MINUS: return '-';
|
|
336
|
+
case types_1.TokenType.MULTIPLY: return '*';
|
|
337
|
+
case types_1.TokenType.DIVIDE: return '/';
|
|
338
|
+
case types_1.TokenType.MODULO: return '%';
|
|
339
|
+
case types_1.TokenType.POWER: return '^';
|
|
340
|
+
case types_1.TokenType.EQ: return '==';
|
|
341
|
+
case types_1.TokenType.NEQ: return '!=';
|
|
342
|
+
case types_1.TokenType.LT: return '<';
|
|
343
|
+
case types_1.TokenType.GT: return '>';
|
|
344
|
+
case types_1.TokenType.LTE: return '<=';
|
|
345
|
+
case types_1.TokenType.GTE: return '>=';
|
|
346
|
+
case types_1.TokenType.AND: return '&&';
|
|
347
|
+
case types_1.TokenType.OR: return '||';
|
|
348
|
+
case types_1.TokenType.NOT: return '!';
|
|
349
|
+
default: return '';
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
peek() {
|
|
353
|
+
return this.tokens[this.current];
|
|
354
|
+
}
|
|
355
|
+
advance() {
|
|
356
|
+
if (!this.isAtEnd()) {
|
|
357
|
+
this.current++;
|
|
358
|
+
}
|
|
359
|
+
return this.tokens[this.current - 1];
|
|
360
|
+
}
|
|
361
|
+
isAtEnd() {
|
|
362
|
+
return this.peek().type === types_1.TokenType.EOF;
|
|
363
|
+
}
|
|
364
|
+
expect(type, expected) {
|
|
365
|
+
if (this.peek().type === type) {
|
|
366
|
+
return this.advance();
|
|
367
|
+
}
|
|
368
|
+
throw new errors_1.UnexpectedTokenError(String(this.peek().value), [expected], this.peek().position);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
exports.Parser = Parser;
|
|
372
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3BhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBZ0M7QUFDaEMsbUNBQW9EO0FBQ3BELHFDQUE2RDtBQUU3RCx3REFBd0Q7QUFDeEQsTUFBTSxVQUFVLEdBQUc7SUFDakIsTUFBTSxFQUFFLENBQUM7SUFDVCxPQUFPLEVBQUUsQ0FBQyxFQUFNLE1BQU07SUFDdEIsRUFBRSxFQUFFLENBQUMsRUFBVyxRQUFRO0lBQ3hCLEdBQUcsRUFBRSxDQUFDLEVBQVUsU0FBUztJQUN6QixRQUFRLEVBQUUsQ0FBQyxFQUFLLFFBQVE7SUFDeEIsVUFBVSxFQUFFLENBQUMsRUFBRyxZQUFZO0lBQzVCLElBQUksRUFBRSxDQUFDLEVBQVMsTUFBTTtJQUN0QixNQUFNLEVBQUUsQ0FBQyxFQUFPLFFBQVE7SUFDeEIsS0FBSyxFQUFFLENBQUMsRUFBUSxJQUFJO0lBQ3BCLEtBQUssRUFBRSxFQUFFLEVBQU8sVUFBVTtJQUMxQixJQUFJLEVBQUUsRUFBRSxFQUFRLGlCQUFpQjtJQUNqQyxNQUFNLEVBQUUsRUFBRSxFQUFNLE9BQU87Q0FDeEIsQ0FBQztBQUVGLE1BQWEsTUFBTTtJQUFuQjtRQUNVLFdBQU0sR0FBWSxFQUFFLENBQUM7UUFDckIsWUFBTyxHQUFXLENBQUMsQ0FBQztRQUNwQixlQUFVLEdBQVcsRUFBRSxDQUFDO0lBeWFsQyxDQUFDO0lBdmFDLEtBQUssQ0FBQyxVQUFrQjtRQUN0QixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixNQUFNLEtBQUssR0FBRyxJQUFJLGFBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztRQUVqQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFVB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UyxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDO1lBQy9CLEtBQUssaUJBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEdBQUcsQ0FBQztZQUMvQixPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNyQixDQUFDO0lBQ0gsQ0FBQztJQUVPLElBQUk7UUFDVixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFTyxPQUFPO1FBQ2IsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNqQixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVPLE9BQU87UUFDYixPQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEtBQUssaUJBQVMsQ0FBQyxHQUFHLENBQUM7SUFDNUMsQ0FBQztJQUVPLE1BQU0sQ0FBQyxJQUFlLEVBQUUsUUFBZ0I7UUFDOUMsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxLQUFLLElBQUksRUFBRSxDQUFDO1lBQzlCLE9BQU8sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3hCLENBQUM7UUFDRCxNQUFNLElBQUksNkJBQW9CLENBQzVCLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQ3pCLENBQUMsUUFBUSxDQUFDLEVBQ1YsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FDckIsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQTVhRCx3QkE0YUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMZXhlciB9IGZyb20gJy4vbGV4ZXInO1xuaW1wb3J0IHsgVG9rZW4sIFRva2VuVHlwZSwgQVNUTm9kZSB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgU3ludGF4RXJyb3IsIFVuZXhwZWN0ZWRUb2tlbkVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xuXG4vLyBPcGVyYXRvciBwcmVjZWRlbmNlIGxldmVscyAoaGlnaGVyID0gdGlnaHRlciBiaW5kaW5nKVxuY29uc3QgUFJFQ0VERU5DRSA9IHtcbiAgTE9XRVNUOiAxLFxuICBURVJOQVJZOiAyLCAgICAgLy8gPyA6XG4gIE9SOiAzLCAgICAgICAgICAvLyB8fCBPUlxuICBBTkQ6IDQsICAgICAgICAgLy8gJiYgQU5EXG4gIEVRVUFMSVRZOiA1LCAgICAvLyA9PSAhPVxuICBDT01QQVJJU09OOiA2LCAgLy8gPCA+IDw9ID49XG4gIFRFUk06IDcsICAgICAgICAvLyArIC1cbiAgRkFDVE9SOiA4LCAgICAgIC8vICogLyAlXG4gIFBPV0VSOiA5LCAgICAgICAvLyBeXG4gIFVOQVJZOiAxMCwgICAgICAvLyAtICEgTk9UXG4gIENBTEw6IDExLCAgICAgICAvLyBmdW5jdGlvbiBjYWxsc1xuICBNRU1CRVI6IDEyLCAgICAgLy8gLiBbXVxufTtcblxuZXhwb3J0IGNsYXNzIFBhcnNlciB7XG4gIHByaXZhdGUgdG9rZW5zOiBUb2tlbltdID0gW107XG4gIHByaXZhdGUgY3VycmVudDogbnVtYmVyID0gMDtcbiAgcHJpdmF0ZSBleHByZXNzaW9uOiBzdHJpbmcgPSAnJztcblxuICBwYXJzZShleHByZXNzaW9uOiBzdHJpbmcpOiBBU1ROb2RlIHtcbiAgICB0aGlzLmV4cHJlc3Npb24gPSBleHByZXNzaW9uO1xuICAgIGNvbnN0IGxleGVyID0gbmV3IExleGVyKGV4cHJlc3Npb24pO1xuICAgIHRoaXMudG9rZW5zID0gbGV4ZXIudG9rZW5pemUoKTtcbiAgICB0aGlzLmN1cnJlbnQgPSAwO1xuXG4gICAgY29uc3QgYXN0ID0gdGhpcy5wYXJzZUV4cHJlc3Npb24oUFJFQ0VERU5DRS5MT1dFU1QpO1xuXG4gICAgaWYgKCF0aGlzLmlzQXRFbmQoKSkge1xuICAgICAgY29uc3QgdG9rZW4gPSB0aGlzLnBlZWsoKTtcbiAgICAgIHRocm93IG5ldyBVbmV4cGVjdGVkVG9rZW5FcnJvcihcbiAgICAgICAgU3RyaW5nKHRva2VuLnZhbHVlKSxcbiAgICAgICAgWydlbmQgb2YgZXhwcmVzc2lvbiddLFxuICAgICAgICB0b2tlbi5wb3NpdGlvblxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXN0O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUV4cHJlc3Npb24ocHJlY2VkZW5jZTogbnVtYmVyKTogQVNUTm9kZSB7XG4gICAgbGV0IGxlZnQgPSB0aGlzLnBhcnNlUHJlZml4RXhwcmVzc2lvbigpO1xuXG4gICAgd2hpbGUgKCF0aGlzLmlzQXRFbmQoKSAmJiBwcmVjZWRlbmNlIDwgdGhpcy5nZXRQcmVjZWRlbmNlKCkpIHtcbiAgICAgIGxlZnQgPSB0aGlzLnBhcnNlSW5maXhFeHByZXNzaW9uKGxlZnQpO1xuICAgIH1cblxuICAgIHJldHVybiBsZWZ0O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVByZWZpeEV4cHJlc3Npb24oKTogQVNUTm9kZSB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnBlZWsoKTtcblxuICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgY2FzZSBUb2tlblR5cGUuTlVNQkVSOlxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZU51bWJlcigpO1xuICAgICAgY2FzZSBUb2tlblR5cGUuU1RSSU5HOlxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZVN0cmluZygpO1xuICAgICAgY2FzZSBUb2tlblR5cGUuQk9PTEVBTjpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VCb29sZWFuKCk7XG4gICAgICBjYXNlIFRva2VuVHlwZS5OVUxMOlxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZU51bGwoKTtcbiAgICAgIGNhc2UgVG9rZW5UeXBlLlZBUklBQkxFOlxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZVZhcmlhYmxlKCk7XG4gICAgICBjYXNlIFRva2VuVHlwZS5DT05URVhUX1ZBUjpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VDb250ZXh0VmFyaWFibGUoKTtcbiAgICAgIGNhc2UgVG9rZW5UeXBlLklERU5USUZJRVI6XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlSWRlbnRpZmllck9yRnVuY3Rpb25DYWxsKCk7XG4gICAgICBjYXNlIFRva2VuVHlwZS5MUEFSRU46XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlR3JvdXBlZEV4cHJlc3Npb24oKTtcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkxCUkFDS0VUOlxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZUFycmF5TGl0ZXJhbCgpO1xuICAgICAgY2FzZSBUb2tlblR5cGUuTUlOVVM6XG4gICAgICBjYXNlIFRva2VuVHlwZS5OT1Q6XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlVW5hcnlFeHByZXNzaW9uKCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IoXG4gICAgICAgICAgU3RyaW5nKHRva2VuLnZhbHVlKSxcbiAgICAgICAgICBbJ251bWJlcicsICdzdHJpbmcnLCAnYm9vbGVhbicsICdudWxsJywgJ3ZhcmlhYmxlJywgJ2lkZW50aWZpZXInLCAnKCcsICdbJywgJy0nLCAnISddLFxuICAgICAgICAgIHRva2VuLnBvc2l0aW9uXG4gICAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUluZml4RXhwcmVzc2lvbihsZWZ0OiBBU1ROb2RlKTogQVNUTm9kZSB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnBlZWsoKTtcblxuICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgY2FzZSBUb2tlblR5cGUuUExVUzpcbiAgICAgIGNhc2UgVG9rZW5UeXBlLk1JTlVTOlxuICAgICAgY2FzZSBUb2tlblR5cGUuTVVMVElQTFk6XG4gICAgICBjYXNlIFRva2VuVHlwZS5ESVZJREU6XG4gICAgICBjYXNlIFRva2VuVHlwZS5NT0RVTE86XG4gICAgICBjYXNlIFRva2VuVHlwZS5QT1dFUjpcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkVROlxuICAgICAgY2FzZSBUb2tlblR5cGUuTkVROlxuICAgICAgY2FzZSBUb2tlblR5cGUuTFQ6XG4gICAgICBjYXNlIFRva2VuVHlwZS5HVDpcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkxURTpcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkdURTpcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkFORDpcbiAgICAgIGNhc2UgVG9rZW5UeXBlLk9SOlxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZUJpbmFyeUV4cHJlc3Npb24obGVmdCk7XG4gICAgICBjYXNlIFRva2VuVHlwZS5RVUVTVElPTjpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VUZXJuYXJ5RXhwcmVzc2lvbihsZWZ0KTtcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkRPVDpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VNZW1iZXJBY2Nlc3MobGVmdCk7XG4gICAgICBjYXNlIFRva2VuVHlwZS5MQlJBQ0tFVDpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VJbmRleEFjY2VzcyhsZWZ0KTtcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkxQQVJFTjpcbiAgICAgICAgLy8gVGhpcyBoYW5kbGVzIHRoZSBjYXNlIHdoZXJlIHdlIGhhdmUgYW4gaWRlbnRpZmllciBmb2xsb3dlZCBieSAoXG4gICAgICAgIC8vIEJ1dCBhY3R1YWxseSB0aGlzIHNob3VsZCBiZSBoYW5kbGVkIGluIHBhcnNlSWRlbnRpZmllck9yRnVuY3Rpb25DYWxsXG4gICAgICAgIHJldHVybiBsZWZ0O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGxlZnQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZU51bWJlcigpOiBBU1ROb2RlIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMuYWR2YW5jZSgpO1xuICAgIGNvbnN0IHZhbHVlID0gdG9rZW4udmFsdWU7XG5cbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgLy8gSXQncyBhIGZsb2F0XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnTnVtYmVyTGl0ZXJhbCcsXG4gICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEl0J3MgYSBkZWNpbWFsIChzdG9yZWQgYXMgc3RyaW5nKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ0RlY2ltYWxMaXRlcmFsJyxcbiAgICAgICAgdmFsdWU6IFN0cmluZyh2YWx1ZSksXG4gICAgICAgIHJhdzogU3RyaW5nKHZhbHVlKSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVN0cmluZygpOiBBU1ROb2RlIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMuYWR2YW5jZSgpO1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnU3RyaW5nTGl0ZXJhbCcsXG4gICAgICB2YWx1ZTogU3RyaW5nKHRva2VuLnZhbHVlKSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUJvb2xlYW4oKTogQVNUTm9kZSB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLmFkdmFuY2UoKTtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ0Jvb2xlYW5MaXRlcmFsJyxcbiAgICAgIHZhbHVlOiB0b2tlbi52YWx1ZSA9PT0gdHJ1ZSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZU51bGwoKTogQVNUTm9kZSB7XG4gICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdOdWxsTGl0ZXJhbCcsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VWYXJpYWJsZSgpOiBBU1ROb2RlIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMuYWR2YW5jZSgpO1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnVmFyaWFibGVSZWZlcmVuY2UnLFxuICAgICAgcHJlZml4OiAnJCcsXG4gICAgICBuYW1lOiBTdHJpbmcodG9rZW4udmFsdWUpLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHBhcnNlQ29udGV4dFZhcmlhYmxlKCk6IEFTVE5vZGUge1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy5hZHZhbmNlKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdWYXJpYWJsZVJlZmVyZW5jZScsXG4gICAgICBwcmVmaXg6ICdAJyxcbiAgICAgIG5hbWU6IFN0cmluZyh0b2tlbi52YWx1ZSksXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VJZGVudGlmaWVyT3JGdW5jdGlvbkNhbGwoKTogQVNUTm9kZSB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLmFkdmFuY2UoKTtcbiAgICBjb25zdCBuYW1lID0gU3RyaW5nKHRva2VuLnZhbHVlKTtcblxuICAgIC8vIENoZWNrIGlmIGl0J3MgYSBmdW5jdGlvbiBjYWxsXG4gICAgaWYgKHRoaXMucGVlaygpLnR5cGUgPT09IFRva2VuVHlwZS5MUEFSRU4pIHtcbiAgICAgIHJldHVybiB0aGlzLnBhcnNlRnVuY3Rpb25DYWxsKG5hbWUpO1xuICAgIH1cblxuICAgIC8vIE90aGVyd2lzZSwgY2hlY2sgZm9yIGtleXdvcmRzIEFORC9PUi9OT1QgdXNlZCBhcyBzdGFuZGFsb25lIGlkZW50aWZpZXJzXG4gICAgY29uc3QgdXBwZXJOYW1lID0gbmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgIGlmICh1cHBlck5hbWUgPT09ICdBTkQnIHx8IHVwcGVyTmFtZSA9PT0gJ09SJykge1xuICAgICAgLy8gVGhlc2Ugc2hvdWxkIGJlIGhhbmRsZWQgYXMgb3BlcmF0b3JzLCBidXQgaWYgd2UgcmVhY2ggaGVyZSxcbiAgICAgIC8vIGl0IG1lYW5zIHRoZXkgd2VyZSB1c2VkIGluIGFuIGludmFsaWQgY29udGV4dFxuICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFxuICAgICAgICBgJyR7bmFtZX0nIGNhbm5vdCBiZSB1c2VkIGFzIGFuIGlkZW50aWZpZXJgLFxuICAgICAgICB0b2tlbi5wb3NpdGlvbixcbiAgICAgICAgdG9rZW4ubGluZSxcbiAgICAgICAgdG9rZW4uY29sdW1uLFxuICAgICAgICB0aGlzLmV4cHJlc3Npb25cbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gSXQncyBhIGJhcmUgaWRlbnRpZmllciAtIGNvdWxkIGJlIGEgdmFyaWFibGUgd2l0aG91dCBwcmVmaXhcbiAgICAvLyBGb3Igbm93LCB0cmVhdCBpdCBhcyBhbiBlcnJvciAtIHJlcXVpcmUgZXhwbGljaXQgcHJlZml4XG4gICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKFxuICAgICAgYFVua25vd24gaWRlbnRpZmllciAnJHtuYW1lfScuIFZhcmlhYmxlcyBtdXN0IGJlIHByZWZpeGVkIHdpdGggJCBvciBAYCxcbiAgICAgIHRva2VuLnBvc2l0aW9uLFxuICAgICAgdG9rZW4ubGluZSxcbiAgICAgIHRva2VuLmNvbHVtbixcbiAgICAgIHRoaXMuZXhwcmVzc2lvblxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlRnVuY3Rpb25DYWxsKG5hbWU6IHN0cmluZyk6IEFTVE5vZGUge1xuICAgIHRoaXMuYWR2YW5jZSgpOyAvLyBjb25zdW1lICcoJ1xuICAgIGNvbnN0IGFyZ3M6IEFTVE5vZGVbXSA9IFtdO1xuXG4gICAgaWYgKHRoaXMucGVlaygpLnR5cGUgIT09IFRva2VuVHlwZS5SUEFSRU4pIHtcbiAgICAgIGRvIHtcbiAgICAgICAgaWYgKHRoaXMucGVlaygpLnR5cGUgPT09IFRva2VuVHlwZS5DT01NQSkge1xuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICB9XG4gICAgICAgIGFyZ3MucHVzaCh0aGlzLnBhcnNlRXhwcmVzc2lvbihQUkVDRURFTkNFLkxPV0VTVCkpO1xuICAgICAgfSB3aGlsZSAodGhpcy5wZWVrKCkudHlwZSA9PT0gVG9rZW5UeXBlLkNPTU1BKTtcbiAgICB9XG5cbiAgICB0aGlzLmV4cGVjdChUb2tlblR5cGUuUlBBUkVOLCAnKScpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdGdW5jdGlvbkNhbGwnLFxuICAgICAgbmFtZTogbmFtZS50b1VwcGVyQ2FzZSgpLCAvLyBGdW5jdGlvbnMgYXJlIGNhc2UtaW5zZW5zaXRpdmVcbiAgICAgIGFyZ3VtZW50czogYXJncyxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUdyb3VwZWRFeHByZXNzaW9uKCk6IEFTVE5vZGUge1xuICAgIHRoaXMuYWR2YW5jZSgpOyAvLyBjb25zdW1lICcoJ1xuICAgIGNvbnN0IGV4cHIgPSB0aGlzLnBhcnNlRXhwcmVzc2lvbihQUkVDRURFTkNFLkxPV0VTVCk7XG4gICAgdGhpcy5leHBlY3QoVG9rZW5UeXBlLlJQQVJFTiwgJyknKTtcbiAgICByZXR1cm4gZXhwcjtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VBcnJheUxpdGVyYWwoKTogQVNUTm9kZSB7XG4gICAgdGhpcy5hZHZhbmNlKCk7IC8vIGNvbnN1bWUgJ1snXG4gICAgY29uc3QgZWxlbWVudHM6IEFTVE5vZGVbXSA9IFtdO1xuXG4gICAgaWYgKHRoaXMucGVlaygpLnR5cGUgIT09IFRva2VuVHlwZS5SQlJBQ0tFVCkge1xuICAgICAgZG8ge1xuICAgICAgICBpZiAodGhpcy5wZWVrKCkudHlwZSA9PT0gVG9rZW5UeXBlLkNPTU1BKSB7XG4gICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxlbWVudHMucHVzaCh0aGlzLnBhcnNlRXhwcmVzc2lvbihQUkVDRURFTkNFLkxPV0VTVCkpO1xuICAgICAgfSB3aGlsZSAodGhpcy5wZWVrKCkudHlwZSA9PT0gVG9rZW5UeXBlLkNPTU1BKTtcbiAgICB9XG5cbiAgICB0aGlzLmV4cGVjdChUb2tlblR5cGUuUkJSQUNLRVQsICddJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ0FycmF5TGl0ZXJhbCcsXG4gICAgICBlbGVtZW50cyxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVVuYXJ5RXhwcmVzc2lvbigpOiBBU1ROb2RlIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMuYWR2YW5jZSgpO1xuICAgIGNvbnN0IG9wZXJhdG9yID0gdGhpcy5nZXRPcGVyYXRvclN5bWJvbCh0b2tlbi50eXBlKTtcbiAgICBjb25zdCBvcGVyYW5kID0gdGhpcy5wYXJzZUV4cHJlc3Npb24oUFJFQ0VERU5DRS5VTkFSWSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ1VuYXJ5T3BlcmF0aW9uJyxcbiAgICAgIG9wZXJhdG9yLFxuICAgICAgb3BlcmFuZCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUJpbmFyeUV4cHJlc3Npb24obGVmdDogQVNUTm9kZSk6IEFTVE5vZGUge1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy5hZHZhbmNlKCk7XG4gICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLmdldE9wZXJhdG9yU3ltYm9sKHRva2VuLnR5cGUpO1xuICAgIGNvbnN0IHByZWNlZGVuY2UgPSB0aGlzLmdldFRva2VuUHJlY2VkZW5jZSh0b2tlbi50eXBlKTtcblxuICAgIC8vIFJpZ2h0IGFzc29jaWF0aXZpdHkgZm9yIHBvd2VyIG9wZXJhdG9yXG4gICAgY29uc3QgbmV4dFByZWNlZGVuY2UgPSB0b2tlbi50eXBlID09PSBUb2tlblR5cGUuUE9XRVIgPyBwcmVjZWRlbmNlIC0gMSA6IHByZWNlZGVuY2U7XG4gICAgY29uc3QgcmlnaHQgPSB0aGlzLnBhcnNlRXhwcmVzc2lvbihuZXh0UHJlY2VkZW5jZSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ0JpbmFyeU9wZXJhdGlvbicsXG4gICAgICBvcGVyYXRvcixcbiAgICAgIGxlZnQsXG4gICAgICByaWdodCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVRlcm5hcnlFeHByZXNzaW9uKGNvbmRpdGlvbjogQVNUTm9kZSk6IEFTVE5vZGUge1xuICAgIHRoaXMuYWR2YW5jZSgpOyAvLyBjb25zdW1lICc/J1xuICAgIGNvbnN0IGNvbnNlcXVlbnQgPSB0aGlzLnBhcnNlRXhwcmVzc2lvbihQUkVDRURFTkNFLkxPV0VTVCk7XG4gICAgdGhpcy5leHBlY3QoVG9rZW5UeXBlLkNPTE9OLCAnOicpO1xuICAgIGNvbnN0IGFsdGVybmF0ZSA9IHRoaXMucGFyc2VFeHByZXNzaW9uKFBSRUNFREVOQ0UuVEVSTkFSWSAtIDEpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdDb25kaXRpb25hbEV4cHJlc3Npb24nLFxuICAgICAgY29uZGl0aW9uLFxuICAgICAgY29uc2VxdWVudCxcbiAgICAgIGFsdGVybmF0ZSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZU1lbWJlckFjY2VzcyhvYmplY3Q6IEFTVE5vZGUpOiBBU1ROb2RlIHtcbiAgICB0aGlzLmFkdmFuY2UoKTsgLy8gY29uc3VtZSAnLidcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMucGVlaygpO1xuXG4gICAgaWYgKHRva2VuLnR5cGUgIT09IFRva2VuVHlwZS5JREVOVElGSUVSICYmIHRva2VuLnR5cGUgIT09IFRva2VuVHlwZS5WQVJJQUJMRSkge1xuICAgICAgdGhyb3cgbmV3IFVuZXhwZWN0ZWRUb2tlbkVycm9yKFxuICAgICAgICBTdHJpbmcodG9rZW4udmFsdWUpLFxuICAgICAgICBbJ2lkZW50aWZpZXInXSxcbiAgICAgICAgdG9rZW4ucG9zaXRpb25cbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgY29uc3QgcHJvcGVydHkgPSBTdHJpbmcodG9rZW4udmFsdWUpO1xuXG4gICAgY29uc3Qgbm9kZTogQVNUTm9kZSA9IHtcbiAgICAgIHR5cGU6ICdNZW1iZXJBY2Nlc3MnLFxuICAgICAgb2JqZWN0LFxuICAgICAgcHJvcGVydHksXG4gICAgfTtcblxuICAgIC8vIENoZWNrIGZvciBjaGFpbmVkIGFjY2Vzc1xuICAgIGlmICh0aGlzLnBlZWsoKS50eXBlID09PSBUb2tlblR5cGUuRE9UKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYXJzZU1lbWJlckFjY2Vzcyhub2RlKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucGVlaygpLnR5cGUgPT09IFRva2VuVHlwZS5MQlJBQ0tFVCkge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VJbmRleEFjY2Vzcyhub2RlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbm9kZTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VJbmRleEFjY2VzcyhvYmplY3Q6IEFTVE5vZGUpOiBBU1ROb2RlIHtcbiAgICB0aGlzLmFkdmFuY2UoKTsgLy8gY29uc3VtZSAnWydcbiAgICBjb25zdCBpbmRleCA9IHRoaXMucGFyc2VFeHByZXNzaW9uKFBSRUNFREVOQ0UuTE9XRVNUKTtcbiAgICB0aGlzLmV4cGVjdChUb2tlblR5cGUuUkJSQUNLRVQsICddJyk7XG5cbiAgICBjb25zdCBub2RlOiBBU1ROb2RlID0ge1xuICAgICAgdHlwZTogJ0luZGV4QWNjZXNzJyxcbiAgICAgIG9iamVjdCxcbiAgICAgIGluZGV4LFxuICAgIH07XG5cbiAgICAvLyBDaGVjayBmb3IgY2hhaW5lZCBhY2Nlc3NcbiAgICBpZiAodGhpcy5wZWVrKCkudHlwZSA9PT0gVG9rZW5UeXBlLkRPVCkge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VNZW1iZXJBY2Nlc3Mobm9kZSk7XG4gICAgfVxuICAgIGlmICh0aGlzLnBlZWsoKS50eXBlID09PSBUb2tlblR5cGUuTEJSQUNLRVQpIHtcbiAgICAgIHJldHVybiB0aGlzLnBhcnNlSW5kZXhBY2Nlc3Mobm9kZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICBwcml2YXRlIGdldFByZWNlZGVuY2UoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5nZXRUb2tlblByZWNlZGVuY2UodGhpcy5wZWVrKCkudHlwZSk7XG4gIH1cblxuICBwcml2YXRlIGdldFRva2VuUHJlY2VkZW5jZSh0eXBlOiBUb2tlblR5cGUpOiBudW1iZXIge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBUb2tlblR5cGUuT1I6XG4gICAgICAgIHJldHVybiBQUkVDRURFTkNFLk9SO1xuICAgICAgY2FzZSBUb2tlblR5cGUuQU5EOlxuICAgICAgICByZXR1cm4gUFJFQ0VERU5DRS5BTkQ7XG4gICAgICBjYXNlIFRva2VuVHlwZS5FUTpcbiAgICAgIGNhc2UgVG9rZW5UeXBlLk5FUTpcbiAgICAgICAgcmV0dXJuIFBSRUNFREVOQ0UuRVFVQUxJVFk7XG4gICAgICBjYXNlIFRva2VuVHlwZS5MVDpcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkdUOlxuICAgICAgY2FzZSBUb2tlblR5cGUuTFRFOlxuICAgICAgY2FzZSBUb2tlblR5cGUuR1RFOlxuICAgICAgICByZXR1cm4gUFJFQ0VERU5DRS5DT01QQVJJU09OO1xuICAgICAgY2FzZSBUb2tlblR5cGUuUExVUzpcbiAgICAgIGNhc2UgVG9rZW5UeXBlLk1JTlVTOlxuICAgICAgICByZXR1cm4gUFJFQ0VERU5DRS5URVJNO1xuICAgICAgY2FzZSBUb2tlblR5cGUuTVVMVElQTFk6XG4gICAgICBjYXNlIFRva2VuVHlwZS5ESVZJREU6XG4gICAgICBjYXNlIFRva2VuVHlwZS5NT0RVTE86XG4gICAgICAgIHJldHVybiBQUkVDRURFTkNFLkZBQ1RPUjtcbiAgICAgIGNhc2UgVG9rZW5UeXBlLlBPV0VSOlxuICAgICAgICByZXR1cm4gUFJFQ0VERU5DRS5QT1dFUjtcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkRPVDpcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkxCUkFDS0VUOlxuICAgICAgICByZXR1cm4gUFJFQ0VERU5DRS5NRU1CRVI7XG4gICAgICBjYXNlIFRva2VuVHlwZS5RVUVTVElPTjpcbiAgICAgICAgcmV0dXJuIFBSRUNFREVOQ0UuVEVSTkFSWTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBQUkVDRURFTkNFLkxPV0VTVDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldE9wZXJhdG9yU3ltYm9sKHR5cGU6IFRva2VuVHlwZSk6IHN0cmluZyB7XG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlIFRva2VuVHlwZS5QTFVTOiByZXR1cm4gJysnO1xuICAgICAgY2FzZSBUb2tlblR5cGUuTUlOVVM6IHJldHVybiAnLSc7XG4gICAgICBjYXNlIFRva2VuVHlwZS5NVUxUSVBMWTogcmV0dXJuICcqJztcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkRJVklERTogcmV0dXJuICcvJztcbiAgICAgIGNhc2UgVG9rZW5UeXBlLk1PRFVMTzogcmV0dXJuICclJztcbiAgICAgIGNhc2UgVG9rZW5UeXBlLlBPV0VSOiByZXR1cm4gJ14nO1xuICAgICAgY2FzZSBUb2tlblR5cGUuRVE6IHJldHVybiAnPT0nO1xuICAgICAgY2FzZSBUb2tlblR5cGUuTkVROiByZXR1cm4gJyE9JztcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkxUOiByZXR1cm4gJzwnO1xuICAgICAgY2FzZSBUb2tlblR5cGUuR1Q6IHJldHVybiAnPic7XG4gICAgICBjYXNlIFRva2VuVHlwZS5MVEU6IHJldHVybiAnPD0nO1xuICAgICAgY2FzZSBUb2tlblR5cGUuR1RFOiByZXR1cm4gJz49JztcbiAgICAgIGNhc2UgVG9rZW5UeXBlLkFORDogcmV0dXJuICcmJic7XG4gICAgICBjYXNlIFRva2VuVHlwZS5PUjogcmV0dXJuICd8fCc7XG4gICAgICBjYXNlIFRva2VuVHlwZS5OT1Q6IHJldHVybiAnISc7XG4gICAgICBkZWZhdWx0OiByZXR1cm4gJyc7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwZWVrKCk6IFRva2VuIHtcbiAgICByZXR1cm4gdGhpcy50b2tlbnNbdGhpcy5jdXJyZW50XTtcbiAgfVxuXG4gIHByaXZhdGUgYWR2YW5jZSgpOiBUb2tlbiB7XG4gICAgaWYgKCF0aGlzLmlzQXRFbmQoKSkge1xuICAgICAgdGhpcy5jdXJyZW50Kys7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRva2Vuc1t0aGlzLmN1cnJlbnQgLSAxXTtcbiAgfVxuXG4gIHByaXZhdGUgaXNBdEVuZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5wZWVrKCkudHlwZSA9PT0gVG9rZW5UeXBlLkVPRjtcbiAgfVxuXG4gIHByaXZhdGUgZXhwZWN0KHR5cGU6IFRva2VuVHlwZSwgZXhwZWN0ZWQ6IHN0cmluZyk6IFRva2VuIHtcbiAgICBpZiAodGhpcy5wZWVrKCkudHlwZSA9PT0gdHlwZSkge1xuICAgICAgcmV0dXJuIHRoaXMuYWR2YW5jZSgpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgVW5leHBlY3RlZFRva2VuRXJyb3IoXG4gICAgICBTdHJpbmcodGhpcy5wZWVrKCkudmFsdWUpLFxuICAgICAgW2V4cGVjdGVkXSxcbiAgICAgIHRoaXMucGVlaygpLnBvc2l0aW9uXG4gICAgKTtcbiAgfVxufVxuIl19
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { Decimal } from 'decimal.js';
|
|
2
|
+
export type ValueType = 'number' | 'decimal' | 'string' | 'boolean' | 'array' | 'object' | 'null' | 'any';
|
|
3
|
+
export type FormulaValue = Decimal | number | string | boolean | null | FormulaValue[] | {
|
|
4
|
+
[key: string]: FormulaValue;
|
|
5
|
+
};
|
|
6
|
+
export declare enum DecimalRoundingMode {
|
|
7
|
+
CEIL = "CEIL",
|
|
8
|
+
FLOOR = "FLOOR",
|
|
9
|
+
DOWN = "DOWN",
|
|
10
|
+
UP = "UP",
|
|
11
|
+
HALF_UP = "HALF_UP",
|
|
12
|
+
HALF_DOWN = "HALF_DOWN",
|
|
13
|
+
HALF_EVEN = "HALF_EVEN",
|
|
14
|
+
HALF_ODD = "HALF_ODD"
|
|
15
|
+
}
|
|
16
|
+
export interface DecimalConfig {
|
|
17
|
+
precision?: number;
|
|
18
|
+
roundingMode?: DecimalRoundingMode;
|
|
19
|
+
divisionScale?: number;
|
|
20
|
+
preserveTrailingZeros?: boolean;
|
|
21
|
+
autoConvertFloats?: boolean;
|
|
22
|
+
maxExponent?: number;
|
|
23
|
+
minExponent?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface RoundingConfig {
|
|
26
|
+
mode: 'HALF_UP' | 'HALF_DOWN' | 'FLOOR' | 'CEIL' | 'NONE';
|
|
27
|
+
precision: number;
|
|
28
|
+
}
|
|
29
|
+
export interface ErrorBehavior {
|
|
30
|
+
type: 'THROW' | 'NULL' | 'ZERO' | 'DEFAULT' | 'SKIP';
|
|
31
|
+
defaultValue?: unknown;
|
|
32
|
+
}
|
|
33
|
+
export interface FormulaDefinition {
|
|
34
|
+
id: string;
|
|
35
|
+
expression: string;
|
|
36
|
+
dependencies?: string[];
|
|
37
|
+
onError?: ErrorBehavior;
|
|
38
|
+
defaultValue?: unknown;
|
|
39
|
+
rounding?: RoundingConfig;
|
|
40
|
+
metadata?: Record<string, unknown>;
|
|
41
|
+
}
|
|
42
|
+
export interface EvaluationContext {
|
|
43
|
+
variables: Record<string, unknown>;
|
|
44
|
+
collections?: Record<string, unknown[]>;
|
|
45
|
+
extra?: Record<string, unknown>;
|
|
46
|
+
}
|
|
47
|
+
export interface OperatorDefinition {
|
|
48
|
+
symbol: string;
|
|
49
|
+
precedence: number;
|
|
50
|
+
associativity: 'left' | 'right';
|
|
51
|
+
handler: (left: unknown, right: unknown) => unknown;
|
|
52
|
+
}
|
|
53
|
+
export interface SecurityConfig {
|
|
54
|
+
maxExpressionLength?: number;
|
|
55
|
+
maxRecursionDepth?: number;
|
|
56
|
+
maxIterations?: number;
|
|
57
|
+
maxExecutionTime?: number;
|
|
58
|
+
allowedFunctions?: string[];
|
|
59
|
+
blockedFunctions?: string[];
|
|
60
|
+
}
|
|
61
|
+
export interface FormulaEngineConfig {
|
|
62
|
+
enableCache?: boolean;
|
|
63
|
+
maxCacheSize?: number;
|
|
64
|
+
defaultErrorBehavior?: ErrorBehavior;
|
|
65
|
+
defaultRounding?: RoundingConfig;
|
|
66
|
+
variablePrefix?: string;
|
|
67
|
+
contextPrefix?: string;
|
|
68
|
+
strictMode?: boolean;
|
|
69
|
+
operators?: OperatorDefinition[];
|
|
70
|
+
functions?: FunctionDefinition[];
|
|
71
|
+
decimal?: DecimalConfig;
|
|
72
|
+
security?: SecurityConfig;
|
|
73
|
+
}
|
|
74
|
+
export interface DecimalLiteral {
|
|
75
|
+
type: 'DecimalLiteral';
|
|
76
|
+
value: string;
|
|
77
|
+
raw: string;
|
|
78
|
+
}
|
|
79
|
+
export interface NumberLiteral {
|
|
80
|
+
type: 'NumberLiteral';
|
|
81
|
+
value: number;
|
|
82
|
+
}
|
|
83
|
+
export interface StringLiteral {
|
|
84
|
+
type: 'StringLiteral';
|
|
85
|
+
value: string;
|
|
86
|
+
}
|
|
87
|
+
export interface BooleanLiteral {
|
|
88
|
+
type: 'BooleanLiteral';
|
|
89
|
+
value: boolean;
|
|
90
|
+
}
|
|
91
|
+
export interface NullLiteral {
|
|
92
|
+
type: 'NullLiteral';
|
|
93
|
+
}
|
|
94
|
+
export interface ArrayLiteral {
|
|
95
|
+
type: 'ArrayLiteral';
|
|
96
|
+
elements: ASTNode[];
|
|
97
|
+
}
|
|
98
|
+
export interface VariableReference {
|
|
99
|
+
type: 'VariableReference';
|
|
100
|
+
prefix: '$' | '@';
|
|
101
|
+
name: string;
|
|
102
|
+
}
|
|
103
|
+
export interface BinaryOperation {
|
|
104
|
+
type: 'BinaryOperation';
|
|
105
|
+
operator: string;
|
|
106
|
+
left: ASTNode;
|
|
107
|
+
right: ASTNode;
|
|
108
|
+
}
|
|
109
|
+
export interface UnaryOperation {
|
|
110
|
+
type: 'UnaryOperation';
|
|
111
|
+
operator: string;
|
|
112
|
+
operand: ASTNode;
|
|
113
|
+
}
|
|
114
|
+
export interface ConditionalExpression {
|
|
115
|
+
type: 'ConditionalExpression';
|
|
116
|
+
condition: ASTNode;
|
|
117
|
+
consequent: ASTNode;
|
|
118
|
+
alternate: ASTNode;
|
|
119
|
+
}
|
|
120
|
+
export interface FunctionCall {
|
|
121
|
+
type: 'FunctionCall';
|
|
122
|
+
name: string;
|
|
123
|
+
arguments: ASTNode[];
|
|
124
|
+
}
|
|
125
|
+
export interface MemberAccess {
|
|
126
|
+
type: 'MemberAccess';
|
|
127
|
+
object: ASTNode;
|
|
128
|
+
property: string;
|
|
129
|
+
}
|
|
130
|
+
export interface IndexAccess {
|
|
131
|
+
type: 'IndexAccess';
|
|
132
|
+
object: ASTNode;
|
|
133
|
+
index: ASTNode;
|
|
134
|
+
}
|
|
135
|
+
export type ASTNode = DecimalLiteral | NumberLiteral | StringLiteral | BooleanLiteral | NullLiteral | ArrayLiteral | VariableReference | BinaryOperation | UnaryOperation | ConditionalExpression | FunctionCall | MemberAccess | IndexAccess;
|
|
136
|
+
export interface ArgumentType {
|
|
137
|
+
name: string;
|
|
138
|
+
type: ValueType;
|
|
139
|
+
required: boolean;
|
|
140
|
+
default?: unknown;
|
|
141
|
+
}
|
|
142
|
+
export type FunctionImplementation = (args: unknown[], context: EvaluationContext, engine: unknown) => unknown;
|
|
143
|
+
export interface FunctionDefinition {
|
|
144
|
+
name: string;
|
|
145
|
+
minArgs: number;
|
|
146
|
+
maxArgs: number;
|
|
147
|
+
argTypes?: ArgumentType[];
|
|
148
|
+
returnType: ValueType;
|
|
149
|
+
implementation: FunctionImplementation;
|
|
150
|
+
description?: string;
|
|
151
|
+
}
|
|
152
|
+
export interface DependencyGraph {
|
|
153
|
+
nodes: Set<string>;
|
|
154
|
+
edges: Map<string, Set<string>>;
|
|
155
|
+
hasCycles(): boolean;
|
|
156
|
+
getRoots(): Set<string>;
|
|
157
|
+
getDependents(nodeId: string): Set<string>;
|
|
158
|
+
getDependencies(nodeId: string): Set<string>;
|
|
159
|
+
getTransitiveDependencies(nodeId: string): Set<string>;
|
|
160
|
+
topologicalSort(): string[];
|
|
161
|
+
}
|
|
162
|
+
export interface EvaluationResult {
|
|
163
|
+
value: unknown;
|
|
164
|
+
success: boolean;
|
|
165
|
+
error?: Error;
|
|
166
|
+
executionTimeMs: number;
|
|
167
|
+
accessedVariables: Set<string>;
|
|
168
|
+
}
|
|
169
|
+
export interface EvaluationResultSet {
|
|
170
|
+
results: Map<string, EvaluationResult>;
|
|
171
|
+
success: boolean;
|
|
172
|
+
errors: Error[];
|
|
173
|
+
totalExecutionTimeMs: number;
|
|
174
|
+
evaluationOrder: string[];
|
|
175
|
+
}
|
|
176
|
+
export interface ValidationResult {
|
|
177
|
+
valid: boolean;
|
|
178
|
+
errors: Error[];
|
|
179
|
+
warnings: string[];
|
|
180
|
+
dependencyGraph: DependencyGraph;
|
|
181
|
+
evaluationOrder: string[];
|
|
182
|
+
}
|
|
183
|
+
export interface CacheStats {
|
|
184
|
+
size: number;
|
|
185
|
+
hits: number;
|
|
186
|
+
misses: number;
|
|
187
|
+
hitRate: number;
|
|
188
|
+
}
|
|
189
|
+
export declare enum TokenType {
|
|
190
|
+
NUMBER = "NUMBER",
|
|
191
|
+
STRING = "STRING",
|
|
192
|
+
BOOLEAN = "BOOLEAN",
|
|
193
|
+
NULL = "NULL",
|
|
194
|
+
IDENTIFIER = "IDENTIFIER",
|
|
195
|
+
VARIABLE = "VARIABLE",
|
|
196
|
+
CONTEXT_VAR = "CONTEXT_VAR",
|
|
197
|
+
PLUS = "PLUS",
|
|
198
|
+
MINUS = "MINUS",
|
|
199
|
+
MULTIPLY = "MULTIPLY",
|
|
200
|
+
DIVIDE = "DIVIDE",
|
|
201
|
+
MODULO = "MODULO",
|
|
202
|
+
POWER = "POWER",
|
|
203
|
+
EQ = "EQ",
|
|
204
|
+
NEQ = "NEQ",
|
|
205
|
+
LT = "LT",
|
|
206
|
+
GT = "GT",
|
|
207
|
+
LTE = "LTE",
|
|
208
|
+
GTE = "GTE",
|
|
209
|
+
AND = "AND",
|
|
210
|
+
OR = "OR",
|
|
211
|
+
NOT = "NOT",
|
|
212
|
+
LPAREN = "LPAREN",
|
|
213
|
+
RPAREN = "RPAREN",
|
|
214
|
+
LBRACKET = "LBRACKET",
|
|
215
|
+
RBRACKET = "RBRACKET",
|
|
216
|
+
COMMA = "COMMA",
|
|
217
|
+
DOT = "DOT",
|
|
218
|
+
QUESTION = "QUESTION",
|
|
219
|
+
COLON = "COLON",
|
|
220
|
+
EOF = "EOF"
|
|
221
|
+
}
|
|
222
|
+
export interface Token {
|
|
223
|
+
type: TokenType;
|
|
224
|
+
value: string | number | boolean | null;
|
|
225
|
+
position: number;
|
|
226
|
+
line: number;
|
|
227
|
+
column: number;
|
|
228
|
+
}
|