@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
|
@@ -0,0 +1,720 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createBuiltInFunctions = createBuiltInFunctions;
|
|
4
|
+
const decimal_utils_1 = require("./decimal-utils");
|
|
5
|
+
const errors_1 = require("./errors");
|
|
6
|
+
// Helper to check if value is numeric (Decimal or number)
|
|
7
|
+
function isNumeric(value) {
|
|
8
|
+
return value instanceof decimal_utils_1.Decimal || typeof value === 'number';
|
|
9
|
+
}
|
|
10
|
+
// Helper to convert to Decimal
|
|
11
|
+
function toDecimal(value, utils) {
|
|
12
|
+
if (value instanceof decimal_utils_1.Decimal)
|
|
13
|
+
return value;
|
|
14
|
+
if (typeof value === 'number')
|
|
15
|
+
return utils.from(value);
|
|
16
|
+
if (typeof value === 'string')
|
|
17
|
+
return utils.from(value);
|
|
18
|
+
throw new errors_1.TypeMismatchError('number', typeof value, 'numeric conversion');
|
|
19
|
+
}
|
|
20
|
+
// Helper to convert value to number (for functions that return native numbers)
|
|
21
|
+
function toNumber(value) {
|
|
22
|
+
if (value instanceof decimal_utils_1.Decimal)
|
|
23
|
+
return value.toNumber();
|
|
24
|
+
if (typeof value === 'number')
|
|
25
|
+
return value;
|
|
26
|
+
if (typeof value === 'string')
|
|
27
|
+
return parseFloat(value);
|
|
28
|
+
throw new errors_1.TypeMismatchError('number', typeof value, 'numeric conversion');
|
|
29
|
+
}
|
|
30
|
+
function createBuiltInFunctions(decimalUtils) {
|
|
31
|
+
const functions = new Map();
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// Math Functions
|
|
34
|
+
// ============================================================================
|
|
35
|
+
const ABS = {
|
|
36
|
+
name: 'ABS',
|
|
37
|
+
minArgs: 1,
|
|
38
|
+
maxArgs: 1,
|
|
39
|
+
returnType: 'decimal',
|
|
40
|
+
description: 'Absolute value',
|
|
41
|
+
implementation: (args) => {
|
|
42
|
+
return decimalUtils.abs(toDecimal(args[0], decimalUtils));
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
const ROUND = {
|
|
46
|
+
name: 'ROUND',
|
|
47
|
+
minArgs: 1,
|
|
48
|
+
maxArgs: 3,
|
|
49
|
+
returnType: 'decimal',
|
|
50
|
+
description: 'Round to precision',
|
|
51
|
+
implementation: (args) => {
|
|
52
|
+
const value = toDecimal(args[0], decimalUtils);
|
|
53
|
+
const precision = args.length > 1 ? toNumber(args[1]) : 0;
|
|
54
|
+
const mode = args.length > 2 ? String(args[2]) : undefined;
|
|
55
|
+
return decimalUtils.round(value, precision, mode);
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
const FLOOR = {
|
|
59
|
+
name: 'FLOOR',
|
|
60
|
+
minArgs: 1,
|
|
61
|
+
maxArgs: 2,
|
|
62
|
+
returnType: 'decimal',
|
|
63
|
+
description: 'Round down',
|
|
64
|
+
implementation: (args) => {
|
|
65
|
+
const value = toDecimal(args[0], decimalUtils);
|
|
66
|
+
const scale = args.length > 1 ? toNumber(args[1]) : 0;
|
|
67
|
+
return decimalUtils.floor(value, scale);
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
const CEIL = {
|
|
71
|
+
name: 'CEIL',
|
|
72
|
+
minArgs: 1,
|
|
73
|
+
maxArgs: 2,
|
|
74
|
+
returnType: 'decimal',
|
|
75
|
+
description: 'Round up',
|
|
76
|
+
implementation: (args) => {
|
|
77
|
+
const value = toDecimal(args[0], decimalUtils);
|
|
78
|
+
const scale = args.length > 1 ? toNumber(args[1]) : 0;
|
|
79
|
+
return decimalUtils.ceil(value, scale);
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
const TRUNCATE = {
|
|
83
|
+
name: 'TRUNCATE',
|
|
84
|
+
minArgs: 1,
|
|
85
|
+
maxArgs: 2,
|
|
86
|
+
returnType: 'decimal',
|
|
87
|
+
description: 'Truncate to precision',
|
|
88
|
+
implementation: (args) => {
|
|
89
|
+
const value = toDecimal(args[0], decimalUtils);
|
|
90
|
+
const scale = args.length > 1 ? toNumber(args[1]) : 0;
|
|
91
|
+
return decimalUtils.truncate(value, scale);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
const MIN = {
|
|
95
|
+
name: 'MIN',
|
|
96
|
+
minArgs: 1,
|
|
97
|
+
maxArgs: -1,
|
|
98
|
+
returnType: 'decimal',
|
|
99
|
+
description: 'Minimum value',
|
|
100
|
+
implementation: (args) => {
|
|
101
|
+
if (args.length === 1 && Array.isArray(args[0])) {
|
|
102
|
+
return decimalUtils.min(...args[0].map(v => toDecimal(v, decimalUtils)));
|
|
103
|
+
}
|
|
104
|
+
return decimalUtils.min(...args.map(v => toDecimal(v, decimalUtils)));
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
const MAX = {
|
|
108
|
+
name: 'MAX',
|
|
109
|
+
minArgs: 1,
|
|
110
|
+
maxArgs: -1,
|
|
111
|
+
returnType: 'decimal',
|
|
112
|
+
description: 'Maximum value',
|
|
113
|
+
implementation: (args) => {
|
|
114
|
+
if (args.length === 1 && Array.isArray(args[0])) {
|
|
115
|
+
return decimalUtils.max(...args[0].map(v => toDecimal(v, decimalUtils)));
|
|
116
|
+
}
|
|
117
|
+
return decimalUtils.max(...args.map(v => toDecimal(v, decimalUtils)));
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
const POW = {
|
|
121
|
+
name: 'POW',
|
|
122
|
+
minArgs: 2,
|
|
123
|
+
maxArgs: 2,
|
|
124
|
+
returnType: 'decimal',
|
|
125
|
+
description: 'Power',
|
|
126
|
+
implementation: (args) => {
|
|
127
|
+
const base = toDecimal(args[0], decimalUtils);
|
|
128
|
+
const exp = toNumber(args[1]);
|
|
129
|
+
return decimalUtils.power(base, exp);
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
const SQRT = {
|
|
133
|
+
name: 'SQRT',
|
|
134
|
+
minArgs: 1,
|
|
135
|
+
maxArgs: 1,
|
|
136
|
+
returnType: 'decimal',
|
|
137
|
+
description: 'Square root',
|
|
138
|
+
implementation: (args) => {
|
|
139
|
+
return decimalUtils.sqrt(toDecimal(args[0], decimalUtils));
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
const LOG = {
|
|
143
|
+
name: 'LOG',
|
|
144
|
+
minArgs: 1,
|
|
145
|
+
maxArgs: 1,
|
|
146
|
+
returnType: 'decimal',
|
|
147
|
+
description: 'Natural logarithm',
|
|
148
|
+
implementation: (args) => {
|
|
149
|
+
return decimalUtils.ln(toDecimal(args[0], decimalUtils));
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
const LOG10 = {
|
|
153
|
+
name: 'LOG10',
|
|
154
|
+
minArgs: 1,
|
|
155
|
+
maxArgs: 1,
|
|
156
|
+
returnType: 'decimal',
|
|
157
|
+
description: 'Base-10 logarithm',
|
|
158
|
+
implementation: (args) => {
|
|
159
|
+
return decimalUtils.log10(toDecimal(args[0], decimalUtils));
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
const SIGN = {
|
|
163
|
+
name: 'SIGN',
|
|
164
|
+
minArgs: 1,
|
|
165
|
+
maxArgs: 1,
|
|
166
|
+
returnType: 'number',
|
|
167
|
+
description: 'Sign of number (-1, 0, or 1)',
|
|
168
|
+
implementation: (args) => {
|
|
169
|
+
return decimalUtils.sign(toDecimal(args[0], decimalUtils));
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
const DECIMAL = {
|
|
173
|
+
name: 'DECIMAL',
|
|
174
|
+
minArgs: 1,
|
|
175
|
+
maxArgs: 2,
|
|
176
|
+
returnType: 'decimal',
|
|
177
|
+
description: 'Convert to Decimal',
|
|
178
|
+
implementation: (args) => {
|
|
179
|
+
const value = toDecimal(args[0], decimalUtils);
|
|
180
|
+
if (args.length > 1) {
|
|
181
|
+
const scale = toNumber(args[1]);
|
|
182
|
+
return decimalUtils.round(value, scale);
|
|
183
|
+
}
|
|
184
|
+
return value;
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
const SCALE = {
|
|
188
|
+
name: 'SCALE',
|
|
189
|
+
minArgs: 1,
|
|
190
|
+
maxArgs: 1,
|
|
191
|
+
returnType: 'number',
|
|
192
|
+
description: 'Get scale (decimal places)',
|
|
193
|
+
implementation: (args) => {
|
|
194
|
+
return decimalUtils.scale(toDecimal(args[0], decimalUtils));
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
const PRECISION = {
|
|
198
|
+
name: 'PRECISION',
|
|
199
|
+
minArgs: 1,
|
|
200
|
+
maxArgs: 1,
|
|
201
|
+
returnType: 'number',
|
|
202
|
+
description: 'Get precision (significant digits)',
|
|
203
|
+
implementation: (args) => {
|
|
204
|
+
return decimalUtils.precision(toDecimal(args[0], decimalUtils));
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
const DIVIDE = {
|
|
208
|
+
name: 'DIVIDE',
|
|
209
|
+
minArgs: 2,
|
|
210
|
+
maxArgs: 4,
|
|
211
|
+
returnType: 'decimal',
|
|
212
|
+
description: 'Division with scale and rounding',
|
|
213
|
+
implementation: (args) => {
|
|
214
|
+
const a = toDecimal(args[0], decimalUtils);
|
|
215
|
+
const b = toDecimal(args[1], decimalUtils);
|
|
216
|
+
const scale = args.length > 2 ? toNumber(args[2]) : undefined;
|
|
217
|
+
const mode = args.length > 3 ? String(args[3]) : undefined;
|
|
218
|
+
return decimalUtils.divide(a, b, scale, mode);
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
// ============================================================================
|
|
222
|
+
// Aggregation Functions
|
|
223
|
+
// ============================================================================
|
|
224
|
+
const SUM = {
|
|
225
|
+
name: 'SUM',
|
|
226
|
+
minArgs: 1,
|
|
227
|
+
maxArgs: 2,
|
|
228
|
+
returnType: 'decimal',
|
|
229
|
+
description: 'Sum of array values',
|
|
230
|
+
implementation: (args, context, engine) => {
|
|
231
|
+
const arr = args[0];
|
|
232
|
+
if (!Array.isArray(arr)) {
|
|
233
|
+
throw new errors_1.TypeMismatchError('array', typeof arr, 'SUM');
|
|
234
|
+
}
|
|
235
|
+
if (args.length === 1) {
|
|
236
|
+
// Simple sum
|
|
237
|
+
return decimalUtils.sum(arr.map(v => toDecimal(v, decimalUtils)));
|
|
238
|
+
}
|
|
239
|
+
// Sum with expression - args[1] should be evaluated for each item
|
|
240
|
+
// This is handled specially by the evaluator
|
|
241
|
+
throw new Error('SUM with expression must be handled by evaluator');
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
const AVG = {
|
|
245
|
+
name: 'AVG',
|
|
246
|
+
minArgs: 1,
|
|
247
|
+
maxArgs: 1,
|
|
248
|
+
returnType: 'decimal',
|
|
249
|
+
description: 'Average of array values',
|
|
250
|
+
implementation: (args) => {
|
|
251
|
+
const arr = args[0];
|
|
252
|
+
if (!Array.isArray(arr)) {
|
|
253
|
+
throw new errors_1.TypeMismatchError('array', typeof arr, 'AVG');
|
|
254
|
+
}
|
|
255
|
+
return decimalUtils.avg(arr.map(v => toDecimal(v, decimalUtils)));
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
const COUNT = {
|
|
259
|
+
name: 'COUNT',
|
|
260
|
+
minArgs: 1,
|
|
261
|
+
maxArgs: 1,
|
|
262
|
+
returnType: 'number',
|
|
263
|
+
description: 'Count of array elements',
|
|
264
|
+
implementation: (args) => {
|
|
265
|
+
const arr = args[0];
|
|
266
|
+
if (!Array.isArray(arr)) {
|
|
267
|
+
throw new errors_1.TypeMismatchError('array', typeof arr, 'COUNT');
|
|
268
|
+
}
|
|
269
|
+
return arr.length;
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
const PRODUCT = {
|
|
273
|
+
name: 'PRODUCT',
|
|
274
|
+
minArgs: 1,
|
|
275
|
+
maxArgs: 1,
|
|
276
|
+
returnType: 'decimal',
|
|
277
|
+
description: 'Product of array values',
|
|
278
|
+
implementation: (args) => {
|
|
279
|
+
const arr = args[0];
|
|
280
|
+
if (!Array.isArray(arr)) {
|
|
281
|
+
throw new errors_1.TypeMismatchError('array', typeof arr, 'PRODUCT');
|
|
282
|
+
}
|
|
283
|
+
return decimalUtils.product(arr.map(v => toDecimal(v, decimalUtils)));
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
const FILTER = {
|
|
287
|
+
name: 'FILTER',
|
|
288
|
+
minArgs: 2,
|
|
289
|
+
maxArgs: 2,
|
|
290
|
+
returnType: 'array',
|
|
291
|
+
description: 'Filter array by condition',
|
|
292
|
+
implementation: () => {
|
|
293
|
+
// This must be handled by the evaluator to evaluate the condition expression
|
|
294
|
+
throw new Error('FILTER must be handled by evaluator');
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
const MAP = {
|
|
298
|
+
name: 'MAP',
|
|
299
|
+
minArgs: 2,
|
|
300
|
+
maxArgs: 2,
|
|
301
|
+
returnType: 'array',
|
|
302
|
+
description: 'Transform array elements',
|
|
303
|
+
implementation: () => {
|
|
304
|
+
// This must be handled by the evaluator to evaluate the transform expression
|
|
305
|
+
throw new Error('MAP must be handled by evaluator');
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
// ============================================================================
|
|
309
|
+
// String Functions
|
|
310
|
+
// ============================================================================
|
|
311
|
+
const LEN = {
|
|
312
|
+
name: 'LEN',
|
|
313
|
+
minArgs: 1,
|
|
314
|
+
maxArgs: 1,
|
|
315
|
+
returnType: 'number',
|
|
316
|
+
description: 'String length',
|
|
317
|
+
implementation: (args) => {
|
|
318
|
+
const str = String(args[0]);
|
|
319
|
+
return str.length;
|
|
320
|
+
},
|
|
321
|
+
};
|
|
322
|
+
const UPPER = {
|
|
323
|
+
name: 'UPPER',
|
|
324
|
+
minArgs: 1,
|
|
325
|
+
maxArgs: 1,
|
|
326
|
+
returnType: 'string',
|
|
327
|
+
description: 'Uppercase string',
|
|
328
|
+
implementation: (args) => {
|
|
329
|
+
return String(args[0]).toUpperCase();
|
|
330
|
+
},
|
|
331
|
+
};
|
|
332
|
+
const LOWER = {
|
|
333
|
+
name: 'LOWER',
|
|
334
|
+
minArgs: 1,
|
|
335
|
+
maxArgs: 1,
|
|
336
|
+
returnType: 'string',
|
|
337
|
+
description: 'Lowercase string',
|
|
338
|
+
implementation: (args) => {
|
|
339
|
+
return String(args[0]).toLowerCase();
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
const TRIM = {
|
|
343
|
+
name: 'TRIM',
|
|
344
|
+
minArgs: 1,
|
|
345
|
+
maxArgs: 1,
|
|
346
|
+
returnType: 'string',
|
|
347
|
+
description: 'Trim whitespace',
|
|
348
|
+
implementation: (args) => {
|
|
349
|
+
return String(args[0]).trim();
|
|
350
|
+
},
|
|
351
|
+
};
|
|
352
|
+
const CONCAT = {
|
|
353
|
+
name: 'CONCAT',
|
|
354
|
+
minArgs: 1,
|
|
355
|
+
maxArgs: -1,
|
|
356
|
+
returnType: 'string',
|
|
357
|
+
description: 'Concatenate strings',
|
|
358
|
+
implementation: (args) => {
|
|
359
|
+
return args.map(a => String(a)).join('');
|
|
360
|
+
},
|
|
361
|
+
};
|
|
362
|
+
const SUBSTR = {
|
|
363
|
+
name: 'SUBSTR',
|
|
364
|
+
minArgs: 2,
|
|
365
|
+
maxArgs: 3,
|
|
366
|
+
returnType: 'string',
|
|
367
|
+
description: 'Substring',
|
|
368
|
+
implementation: (args) => {
|
|
369
|
+
const str = String(args[0]);
|
|
370
|
+
const start = toNumber(args[1]);
|
|
371
|
+
const len = args.length > 2 ? toNumber(args[2]) : undefined;
|
|
372
|
+
return len !== undefined ? str.substr(start, len) : str.substr(start);
|
|
373
|
+
},
|
|
374
|
+
};
|
|
375
|
+
const REPLACE = {
|
|
376
|
+
name: 'REPLACE',
|
|
377
|
+
minArgs: 3,
|
|
378
|
+
maxArgs: 3,
|
|
379
|
+
returnType: 'string',
|
|
380
|
+
description: 'Replace substring',
|
|
381
|
+
implementation: (args) => {
|
|
382
|
+
const str = String(args[0]);
|
|
383
|
+
const search = String(args[1]);
|
|
384
|
+
const replacement = String(args[2]);
|
|
385
|
+
return str.split(search).join(replacement);
|
|
386
|
+
},
|
|
387
|
+
};
|
|
388
|
+
const CONTAINS = {
|
|
389
|
+
name: 'CONTAINS',
|
|
390
|
+
minArgs: 2,
|
|
391
|
+
maxArgs: 2,
|
|
392
|
+
returnType: 'boolean',
|
|
393
|
+
description: 'Check if string contains substring',
|
|
394
|
+
implementation: (args) => {
|
|
395
|
+
const str = String(args[0]);
|
|
396
|
+
const search = String(args[1]);
|
|
397
|
+
return str.includes(search);
|
|
398
|
+
},
|
|
399
|
+
};
|
|
400
|
+
const STARTSWITH = {
|
|
401
|
+
name: 'STARTSWITH',
|
|
402
|
+
minArgs: 2,
|
|
403
|
+
maxArgs: 2,
|
|
404
|
+
returnType: 'boolean',
|
|
405
|
+
description: 'Check if string starts with prefix',
|
|
406
|
+
implementation: (args) => {
|
|
407
|
+
return String(args[0]).startsWith(String(args[1]));
|
|
408
|
+
},
|
|
409
|
+
};
|
|
410
|
+
const ENDSWITH = {
|
|
411
|
+
name: 'ENDSWITH',
|
|
412
|
+
minArgs: 2,
|
|
413
|
+
maxArgs: 2,
|
|
414
|
+
returnType: 'boolean',
|
|
415
|
+
description: 'Check if string ends with suffix',
|
|
416
|
+
implementation: (args) => {
|
|
417
|
+
return String(args[0]).endsWith(String(args[1]));
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
// ============================================================================
|
|
421
|
+
// Logical Functions
|
|
422
|
+
// ============================================================================
|
|
423
|
+
const IF = {
|
|
424
|
+
name: 'IF',
|
|
425
|
+
minArgs: 3,
|
|
426
|
+
maxArgs: 3,
|
|
427
|
+
returnType: 'any',
|
|
428
|
+
description: 'Conditional expression',
|
|
429
|
+
implementation: (args) => {
|
|
430
|
+
const condition = args[0];
|
|
431
|
+
return condition ? args[1] : args[2];
|
|
432
|
+
},
|
|
433
|
+
};
|
|
434
|
+
const COALESCE = {
|
|
435
|
+
name: 'COALESCE',
|
|
436
|
+
minArgs: 1,
|
|
437
|
+
maxArgs: -1,
|
|
438
|
+
returnType: 'any',
|
|
439
|
+
description: 'First non-null value',
|
|
440
|
+
implementation: (args) => {
|
|
441
|
+
for (const arg of args) {
|
|
442
|
+
if (arg !== null && arg !== undefined) {
|
|
443
|
+
return arg;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return null;
|
|
447
|
+
},
|
|
448
|
+
};
|
|
449
|
+
const ISNULL = {
|
|
450
|
+
name: 'ISNULL',
|
|
451
|
+
minArgs: 1,
|
|
452
|
+
maxArgs: 1,
|
|
453
|
+
returnType: 'boolean',
|
|
454
|
+
description: 'Check if null',
|
|
455
|
+
implementation: (args) => {
|
|
456
|
+
return args[0] === null || args[0] === undefined;
|
|
457
|
+
},
|
|
458
|
+
};
|
|
459
|
+
const ISEMPTY = {
|
|
460
|
+
name: 'ISEMPTY',
|
|
461
|
+
minArgs: 1,
|
|
462
|
+
maxArgs: 1,
|
|
463
|
+
returnType: 'boolean',
|
|
464
|
+
description: 'Check if empty',
|
|
465
|
+
implementation: (args) => {
|
|
466
|
+
const val = args[0];
|
|
467
|
+
if (val === null || val === undefined)
|
|
468
|
+
return true;
|
|
469
|
+
if (typeof val === 'string')
|
|
470
|
+
return val.length === 0;
|
|
471
|
+
if (Array.isArray(val))
|
|
472
|
+
return val.length === 0;
|
|
473
|
+
if (typeof val === 'object')
|
|
474
|
+
return Object.keys(val).length === 0;
|
|
475
|
+
return false;
|
|
476
|
+
},
|
|
477
|
+
};
|
|
478
|
+
const DEFAULT = {
|
|
479
|
+
name: 'DEFAULT',
|
|
480
|
+
minArgs: 2,
|
|
481
|
+
maxArgs: 2,
|
|
482
|
+
returnType: 'any',
|
|
483
|
+
description: 'Default value if null',
|
|
484
|
+
implementation: (args) => {
|
|
485
|
+
return args[0] !== null && args[0] !== undefined ? args[0] : args[1];
|
|
486
|
+
},
|
|
487
|
+
};
|
|
488
|
+
const AND = {
|
|
489
|
+
name: 'AND',
|
|
490
|
+
minArgs: 2,
|
|
491
|
+
maxArgs: -1,
|
|
492
|
+
returnType: 'boolean',
|
|
493
|
+
description: 'Logical AND of all arguments',
|
|
494
|
+
implementation: (args) => {
|
|
495
|
+
return args.every(a => Boolean(a));
|
|
496
|
+
},
|
|
497
|
+
};
|
|
498
|
+
const OR = {
|
|
499
|
+
name: 'OR',
|
|
500
|
+
minArgs: 2,
|
|
501
|
+
maxArgs: -1,
|
|
502
|
+
returnType: 'boolean',
|
|
503
|
+
description: 'Logical OR of all arguments',
|
|
504
|
+
implementation: (args) => {
|
|
505
|
+
return args.some(a => Boolean(a));
|
|
506
|
+
},
|
|
507
|
+
};
|
|
508
|
+
const NOT = {
|
|
509
|
+
name: 'NOT',
|
|
510
|
+
minArgs: 1,
|
|
511
|
+
maxArgs: 1,
|
|
512
|
+
returnType: 'boolean',
|
|
513
|
+
description: 'Logical NOT',
|
|
514
|
+
implementation: (args) => {
|
|
515
|
+
return !Boolean(args[0]);
|
|
516
|
+
},
|
|
517
|
+
};
|
|
518
|
+
// ============================================================================
|
|
519
|
+
// Type Functions
|
|
520
|
+
// ============================================================================
|
|
521
|
+
const NUMBER = {
|
|
522
|
+
name: 'NUMBER',
|
|
523
|
+
minArgs: 1,
|
|
524
|
+
maxArgs: 1,
|
|
525
|
+
returnType: 'decimal',
|
|
526
|
+
description: 'Convert to number',
|
|
527
|
+
implementation: (args) => {
|
|
528
|
+
return toDecimal(args[0], decimalUtils);
|
|
529
|
+
},
|
|
530
|
+
};
|
|
531
|
+
const STRING = {
|
|
532
|
+
name: 'STRING',
|
|
533
|
+
minArgs: 1,
|
|
534
|
+
maxArgs: 1,
|
|
535
|
+
returnType: 'string',
|
|
536
|
+
description: 'Convert to string',
|
|
537
|
+
implementation: (args) => {
|
|
538
|
+
const val = args[0];
|
|
539
|
+
if (val instanceof decimal_utils_1.Decimal) {
|
|
540
|
+
return val.toString();
|
|
541
|
+
}
|
|
542
|
+
return String(val);
|
|
543
|
+
},
|
|
544
|
+
};
|
|
545
|
+
const BOOLEAN = {
|
|
546
|
+
name: 'BOOLEAN',
|
|
547
|
+
minArgs: 1,
|
|
548
|
+
maxArgs: 1,
|
|
549
|
+
returnType: 'boolean',
|
|
550
|
+
description: 'Convert to boolean',
|
|
551
|
+
implementation: (args) => {
|
|
552
|
+
const val = args[0];
|
|
553
|
+
if (typeof val === 'string') {
|
|
554
|
+
return val.toLowerCase() === 'true' || val === '1';
|
|
555
|
+
}
|
|
556
|
+
if (val instanceof decimal_utils_1.Decimal) {
|
|
557
|
+
return !val.isZero();
|
|
558
|
+
}
|
|
559
|
+
return Boolean(val);
|
|
560
|
+
},
|
|
561
|
+
};
|
|
562
|
+
const TYPEOF = {
|
|
563
|
+
name: 'TYPEOF',
|
|
564
|
+
minArgs: 1,
|
|
565
|
+
maxArgs: 1,
|
|
566
|
+
returnType: 'string',
|
|
567
|
+
description: 'Get type name',
|
|
568
|
+
implementation: (args) => {
|
|
569
|
+
const val = args[0];
|
|
570
|
+
if (val === null)
|
|
571
|
+
return 'null';
|
|
572
|
+
if (val instanceof decimal_utils_1.Decimal)
|
|
573
|
+
return 'decimal';
|
|
574
|
+
if (Array.isArray(val))
|
|
575
|
+
return 'array';
|
|
576
|
+
return typeof val;
|
|
577
|
+
},
|
|
578
|
+
};
|
|
579
|
+
// ============================================================================
|
|
580
|
+
// Array Functions
|
|
581
|
+
// ============================================================================
|
|
582
|
+
const FIRST = {
|
|
583
|
+
name: 'FIRST',
|
|
584
|
+
minArgs: 1,
|
|
585
|
+
maxArgs: 1,
|
|
586
|
+
returnType: 'any',
|
|
587
|
+
description: 'First element of array',
|
|
588
|
+
implementation: (args) => {
|
|
589
|
+
const arr = args[0];
|
|
590
|
+
if (!Array.isArray(arr)) {
|
|
591
|
+
throw new errors_1.TypeMismatchError('array', typeof arr, 'FIRST');
|
|
592
|
+
}
|
|
593
|
+
return arr.length > 0 ? arr[0] : null;
|
|
594
|
+
},
|
|
595
|
+
};
|
|
596
|
+
const LAST = {
|
|
597
|
+
name: 'LAST',
|
|
598
|
+
minArgs: 1,
|
|
599
|
+
maxArgs: 1,
|
|
600
|
+
returnType: 'any',
|
|
601
|
+
description: 'Last element of array',
|
|
602
|
+
implementation: (args) => {
|
|
603
|
+
const arr = args[0];
|
|
604
|
+
if (!Array.isArray(arr)) {
|
|
605
|
+
throw new errors_1.TypeMismatchError('array', typeof arr, 'LAST');
|
|
606
|
+
}
|
|
607
|
+
return arr.length > 0 ? arr[arr.length - 1] : null;
|
|
608
|
+
},
|
|
609
|
+
};
|
|
610
|
+
const REVERSE = {
|
|
611
|
+
name: 'REVERSE',
|
|
612
|
+
minArgs: 1,
|
|
613
|
+
maxArgs: 1,
|
|
614
|
+
returnType: 'array',
|
|
615
|
+
description: 'Reverse array',
|
|
616
|
+
implementation: (args) => {
|
|
617
|
+
const arr = args[0];
|
|
618
|
+
if (!Array.isArray(arr)) {
|
|
619
|
+
throw new errors_1.TypeMismatchError('array', typeof arr, 'REVERSE');
|
|
620
|
+
}
|
|
621
|
+
return [...arr].reverse();
|
|
622
|
+
},
|
|
623
|
+
};
|
|
624
|
+
const SLICE = {
|
|
625
|
+
name: 'SLICE',
|
|
626
|
+
minArgs: 2,
|
|
627
|
+
maxArgs: 3,
|
|
628
|
+
returnType: 'array',
|
|
629
|
+
description: 'Slice array',
|
|
630
|
+
implementation: (args) => {
|
|
631
|
+
const arr = args[0];
|
|
632
|
+
if (!Array.isArray(arr)) {
|
|
633
|
+
throw new errors_1.TypeMismatchError('array', typeof arr, 'SLICE');
|
|
634
|
+
}
|
|
635
|
+
const start = toNumber(args[1]);
|
|
636
|
+
const end = args.length > 2 ? toNumber(args[2]) : undefined;
|
|
637
|
+
return arr.slice(start, end);
|
|
638
|
+
},
|
|
639
|
+
};
|
|
640
|
+
const INCLUDES = {
|
|
641
|
+
name: 'INCLUDES',
|
|
642
|
+
minArgs: 2,
|
|
643
|
+
maxArgs: 2,
|
|
644
|
+
returnType: 'boolean',
|
|
645
|
+
description: 'Check if array includes value',
|
|
646
|
+
implementation: (args) => {
|
|
647
|
+
const arr = args[0];
|
|
648
|
+
if (!Array.isArray(arr)) {
|
|
649
|
+
throw new errors_1.TypeMismatchError('array', typeof arr, 'INCLUDES');
|
|
650
|
+
}
|
|
651
|
+
const value = args[1];
|
|
652
|
+
return arr.some(item => {
|
|
653
|
+
if (item instanceof decimal_utils_1.Decimal && value instanceof decimal_utils_1.Decimal) {
|
|
654
|
+
return item.equals(value);
|
|
655
|
+
}
|
|
656
|
+
return item === value;
|
|
657
|
+
});
|
|
658
|
+
},
|
|
659
|
+
};
|
|
660
|
+
const INDEXOF = {
|
|
661
|
+
name: 'INDEXOF',
|
|
662
|
+
minArgs: 2,
|
|
663
|
+
maxArgs: 2,
|
|
664
|
+
returnType: 'number',
|
|
665
|
+
description: 'Find index of value in array',
|
|
666
|
+
implementation: (args) => {
|
|
667
|
+
const arr = args[0];
|
|
668
|
+
if (!Array.isArray(arr)) {
|
|
669
|
+
throw new errors_1.TypeMismatchError('array', typeof arr, 'INDEXOF');
|
|
670
|
+
}
|
|
671
|
+
const value = args[1];
|
|
672
|
+
for (let i = 0; i < arr.length; i++) {
|
|
673
|
+
const item = arr[i];
|
|
674
|
+
if (item instanceof decimal_utils_1.Decimal && value instanceof decimal_utils_1.Decimal) {
|
|
675
|
+
if (item.equals(value))
|
|
676
|
+
return i;
|
|
677
|
+
}
|
|
678
|
+
else if (item === value) {
|
|
679
|
+
return i;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return -1;
|
|
683
|
+
},
|
|
684
|
+
};
|
|
685
|
+
const FLATTEN = {
|
|
686
|
+
name: 'FLATTEN',
|
|
687
|
+
minArgs: 1,
|
|
688
|
+
maxArgs: 2,
|
|
689
|
+
returnType: 'array',
|
|
690
|
+
description: 'Flatten nested array',
|
|
691
|
+
implementation: (args) => {
|
|
692
|
+
const arr = args[0];
|
|
693
|
+
if (!Array.isArray(arr)) {
|
|
694
|
+
throw new errors_1.TypeMismatchError('array', typeof arr, 'FLATTEN');
|
|
695
|
+
}
|
|
696
|
+
const depth = args.length > 1 ? toNumber(args[1]) : 1;
|
|
697
|
+
return arr.flat(depth);
|
|
698
|
+
},
|
|
699
|
+
};
|
|
700
|
+
// Register all functions
|
|
701
|
+
const allFunctions = [
|
|
702
|
+
// Math
|
|
703
|
+
ABS, ROUND, FLOOR, CEIL, TRUNCATE, MIN, MAX, POW, SQRT, LOG, LOG10, SIGN, DECIMAL, SCALE, PRECISION, DIVIDE,
|
|
704
|
+
// Aggregation
|
|
705
|
+
SUM, AVG, COUNT, PRODUCT, FILTER, MAP,
|
|
706
|
+
// String
|
|
707
|
+
LEN, UPPER, LOWER, TRIM, CONCAT, SUBSTR, REPLACE, CONTAINS, STARTSWITH, ENDSWITH,
|
|
708
|
+
// Logical
|
|
709
|
+
IF, COALESCE, ISNULL, ISEMPTY, DEFAULT, AND, OR, NOT,
|
|
710
|
+
// Type
|
|
711
|
+
NUMBER, STRING, BOOLEAN, TYPEOF,
|
|
712
|
+
// Array
|
|
713
|
+
FIRST, LAST, REVERSE, SLICE, INCLUDES, INDEXOF, FLATTEN,
|
|
714
|
+
];
|
|
715
|
+
for (const fn of allFunctions) {
|
|
716
|
+
functions.set(fn.name, fn);
|
|
717
|
+
}
|
|
718
|
+
return functions;
|
|
719
|
+
}
|
|
720
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuY3Rpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Z1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTJCQSx3REFzdUJDO0FBaHdCRCxtREFBd0Q7QUFDeEQscUNBQWlFO0FBSWpFLDBEQUEwRDtBQUMxRCxTQUFTLFNBQVMsQ0FBQyxLQUFjO0lBQy9CLE9BQU8sS0FBSyxZQUFZLHVCQUFPLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxDQUFDO0FBQy9ELENBQUM7QUFFRCwrQkFBK0I7QUFDL0IsU0FBUyxTQUFTLENBQUMsS0FBYyxFQUFFLEtBQW1CO0lBQ3BELElBQUksS0FBSyxZQUFZLHVCQUFPO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDM0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3hELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUTtRQUFFLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN4RCxNQUFNLElBQUksMEJBQWlCLENBQUMsUUFBUSxFQUFFLE9BQU8sS0FBSyxFQUFFLG9CQUFvQixDQUFDLENBQUM7QUFDNUUsQ0FBQztBQUVELCtFQUErRTtBQUMvRSxTQUFTLFFBQVEsQ0FBQyxLQUFjO0lBQzlCLElBQUksS0FBSyxZQUFZLHVCQUFPO1FBQUUsT0FBTyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDdEQsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDNUMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDeEQsTUFBTSxJQUFJLDBCQUFpQixDQUFDLFFBQVEsRUFBRSxPQUFPLEtBQUssRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0FBQzVFLENBQUM7QUFFRCxTQUFnQixzQkFB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QU0sRUFBRSxPQUFPLEVBQUUsTUFBTTtRQUMvQixRQUFRO1FBQ1IsS0FBSyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTztLQUN4RCxDQUFDO0lBRUYsS0FBSyxNQUFNLEVBQUUsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUM5QixTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGdW5jdGlvbkRlZmluaXRpb24sIEV2YWx1YXRpb25Db250ZXh0IH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBEZWNpbWFsVXRpbHMsIERlY2ltYWwgfSBmcm9tICcuL2RlY2ltYWwtdXRpbHMnO1xuaW1wb3J0IHsgQXJndW1lbnRDb3VudEVycm9yLCBUeXBlTWlzbWF0Y2hFcnJvciB9IGZyb20gJy4vZXJyb3JzJztcblxudHlwZSBGbkltcGwgPSBGdW5jdGlvbkRlZmluaXRpb25bJ2ltcGxlbWVudGF0aW9uJ107XG5cbi8vIEhlbHBlciB0byBjaGVjayBpZiB2YWx1ZSBpcyBudW1lcmljIChEZWNpbWFsIG9yIG51bWJlcilcbmZ1bmN0aW9uIGlzTnVtZXJpYyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIERlY2ltYWwgfCBudW1iZXIge1xuICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBEZWNpbWFsIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcic7XG59XG5cbi8vIEhlbHBlciB0byBjb252ZXJ0IHRvIERlY2ltYWxcbmZ1bmN0aW9uIHRvRGVjaW1hbCh2YWx1ZTogdW5rbm93biwgdXRpbHM6IERlY2ltYWxVdGlscyk6IERlY2ltYWwge1xuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEZWNpbWFsKSByZXR1cm4gdmFsdWU7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSByZXR1cm4gdXRpbHMuZnJvbSh2YWx1ZSk7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSByZXR1cm4gdXRpbHMuZnJvbSh2YWx1ZSk7XG4gIHRocm93IG5ldyBUeXBlTWlzbWF0Y2hFcnJvcignbnVtYmVyJywgdHlwZW9mIHZhbHVlLCAnbnVtZXJpYyBjb252ZXJzaW9uJyk7XG59XG5cbi8vIEhlbHBlciB0byBjb252ZXJ0IHZhbHVlIHRvIG51bWJlciAoZm9yIGZ1bmN0aW9ucyB0aGF0IHJldHVybiBuYXRpdmUgbnVtYmVycylcbmZ1bmN0aW9uIHRvTnVtYmVyKHZhbHVlOiB1bmtub3duKTogbnVtYmVyIHtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGVjaW1hbCkgcmV0dXJuIHZhbHVlLnRvTnVtYmVyKCk7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSByZXR1cm4gdmFsdWU7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSByZXR1cm4gcGFyc2VGbG9hdCh2YWx1ZSk7XG4gIHRocm93IG5ldyBUeXBlTWlzbWF0Y2hFcnJvcignbnVtYmVyJywgdHlwZW9mIHZhbHVlLCAnbnVtZXJpYyBjb252ZXJzaW9uJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVCdWlsdEluRnVuY3Rpb25zKGRlY2ltYWxVdGlsczogRGVjaW1hbFV0aWxzKTogTWFwPHN0cmluZywgRnVuY3Rpb25EZWZpbml0aW9uPiB7XG4gIGNvbnN0IGZ1bmN0aW9ucyA9IG5ldyBNYXA8c3RyaW5nLCBGdW5jdGlvbkRlZmluaXRpb24+KCk7XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBNYXRoIEZ1bmN0aW9uc1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgY29uc3QgQUJTOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ0FCUycsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAxLFxuICAgIHJldHVyblR5cGU6ICdkZWNpbWFsJyxcbiAgICBkZXNjcmlwdGlvbjogJ0Fic29sdXRlIHZhbHVlJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIHJldHVybiBkZWNpbWFsVXRpbHMuYWJzKHRvRGVjaW1hbChhcmdzWzBdLCBkZWNpbWFsVXRpbHMpKTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IFJPVU5EOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ1JPVU5EJyxcbiAgICBtaW5BcmdzOiAxLFxuICAgIG1heEFyZ3M6IDMsXG4gICAgcmV0dXJuVHlwZTogJ2RlY2ltYWwnLFxuICAgIGRlc2NyaXB0aW9uOiAnUm91bmQgdG8gcHJlY2lzaW9uJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdG9EZWNpbWFsKGFyZ3NbMF0sIGRlY2ltYWxVdGlscyk7XG4gICAgICBjb25zdCBwcmVjaXNpb24gPSBhcmdzLmxlbmd0aCA+IDEgPyB0b051bWJlcihhcmdzWzFdKSA6IDA7XG4gICAgICBjb25zdCBtb2RlID0gYXJncy5sZW5ndGggPiAyID8gU3RyaW5nKGFyZ3NbMl0pIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIGRlY2ltYWxVdGlscy5yb3VuZCh2YWx1ZSwgcHJlY2lzaW9uLCBtb2RlIGFzIGFueSk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBGTE9PUjogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdGTE9PUicsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAyLFxuICAgIHJldHVyblR5cGU6ICdkZWNpbWFsJyxcbiAgICBkZXNjcmlwdGlvbjogJ1JvdW5kIGRvd24nLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSB0b0RlY2ltYWwoYXJnc1swXSwgZGVjaW1hbFV0aWxzKTtcbiAgICAgIGNvbnN0IHNjYWxlID0gYXJncy5sZW5ndGggPiAxID8gdG9OdW1iZXIoYXJnc1sxXSkgOiAwO1xuICAgICAgcmV0dXJuIGRlY2ltYWxVdGlscy5mbG9vcih2YWx1ZSwgc2NhbGUpO1xuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgQ0VJTDogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdDRUlMJyxcbiAgICBtaW5BcmdzOiAxLFxuICAgIG1heEFyZ3M6IDIsXG4gICAgcmV0dXJuVHlwZTogJ2RlY2ltYWwnLFxuICAgIGRlc2NyaXB0aW9uOiAnUm91bmQgdXAnLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSB0b0RlY2ltYWwoYXJnc1swXSwgZGVjaW1hbFV0aWxzKTtcbiAgICAgIGNvbnN0IHNjYWxlID0gYXJncy5sZW5ndGggPiAxID8gdG9OdW1iZXIoYXJnc1sxXSkgOiAwO1xuICAgICAgcmV0dXJuIGRlY2ltYWxVdGlscy5jZWlsKHZhbHVlLCBzY2FsZSk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBUUlVOQ0FURTogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdUUlVOQ0FURScsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAyLFxuICAgIHJldHVyblR5cGU6ICdkZWNpbWFsJyxcbiAgICBkZXNjcmlwdGlvbjogJ1RydW5jYXRlIHRvIHByZWNpc2lvbicsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRvRGVjaW1hbChhcmdzWzBdLCBkZWNpbWFsVXRpbHMpO1xuICAgICAgY29uc3Qgc2NhbGUgPSBhcmdzLmxlbmd0aCA+IDEgPyB0b051bWJlcihhcmdzWzFdKSA6IDA7XG4gICAgICByZXR1cm4gZGVjaW1hbFV0aWxzLnRydW5jYXRlKHZhbHVlLCBzY2FsZSk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBNSU46IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnTUlOJyxcbiAgICBtaW5BcmdzOiAxLFxuICAgIG1heEFyZ3M6IC0xLFxuICAgIHJldHVyblR5cGU6ICdkZWNpbWFsJyxcbiAgICBkZXNjcmlwdGlvbjogJ01pbmltdW0gdmFsdWUnLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgaWYgKGFyZ3MubGVuZ3RoID09PSAxICYmIEFycmF5LmlzQXJyYXkoYXJnc1swXSkpIHtcbiAgICAgICAgcmV0dXJuIGRlY2ltYWxVdGlscy5taW4oLi4uYXJnc1swXS5tYXAodiA9PiB0b0RlY2ltYWwodiwgZGVjaW1hbFV0aWxzKSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRlY2ltYWxVdGlscy5taW4oLi4uYXJncy5tYXAodiA9PiB0b0RlY2ltYWwodiwgZGVjaW1hbFV0aWxzKSkpO1xuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgTUFYOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ01BWCcsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAtMSxcbiAgICByZXR1cm5UeXBlOiAnZGVjaW1hbCcsXG4gICAgZGVzY3JpcHRpb246ICdNYXhpbXVtIHZhbHVlJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMSAmJiBBcnJheS5pc0FycmF5KGFyZ3NbMF0pKSB7XG4gICAgICAgIHJldHVybiBkZWNpbWFsVXRpbHMubWF4KC4uLmFyZ3NbMF0ubWFwKHYgPT4gdG9EZWNpbWFsKHYsIGRlY2ltYWxVdGlscykpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZWNpbWFsVXRpbHMubWF4KC4uLmFyZ3MubWFwKHYgPT4gdG9EZWNpbWFsKHYsIGRlY2ltYWxVdGlscykpKTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IFBPVzogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdQT1cnLFxuICAgIG1pbkFyZ3M6IDIsXG4gICAgbWF4QXJnczogMixcbiAgICByZXR1cm5UeXBlOiAnZGVjaW1hbCcsXG4gICAgZGVzY3JpcHRpb246ICdQb3dlcicsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICBjb25zdCBiYXNlID0gdG9EZWNpbWFsKGFyZ3NbMF0sIGRlY2ltYWxVdGlscyk7XG4gICAgICBjb25zdCBleHAgPSB0b051bWJlcihhcmdzWzFdKTtcbiAgICAgIHJldHVybiBkZWNpbWFsVXRpbHMucG93ZXIoYmFzZSwgZXhwKTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IFNRUlQ6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnU1FSVCcsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAxLFxuICAgIHJldHVyblR5cGU6ICdkZWNpbWFsJyxcbiAgICBkZXNjcmlwdGlvbjogJ1NxdWFyZSByb290JyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIHJldHVybiBkZWNpbWFsVXRpbHMuc3FydCh0b0RlY2ltYWwoYXJnc1swXSwgZGVjaW1hbFV0aWxzKSk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBMT0c6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnTE9HJyxcbiAgICBtaW5BcmdzOiAxLFxuICAgIG1heEFyZ3M6IDEsXG4gICAgcmV0dXJuVHlwZTogJ2RlY2ltYWwnLFxuICAgIGRlc2NyaXB0aW9uOiAnTmF0dXJhbCBsb2dhcml0aG0nLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgcmV0dXJuIGRlY2ltYWxVdGlscy5sbih0b0RlY2ltYWwoYXJnc1swXSwgZGVjaW1hbFV0aWxzKSk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBMT0cxMDogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdMT0cxMCcsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAxLFxuICAgIHJldHVyblR5cGU6ICdkZWNpbWFsJyxcbiAgICBkZXNjcmlwdGlvbjogJ0Jhc2UtMTAgbG9nYXJpdGhtJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIHJldHVybiBkZWNpbWFsVXRpbHMubG9nMTAodG9EZWNpbWFsKGFyZ3NbMF0sIGRlY2ltYWxVdGlscykpO1xuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgU0lHTjogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdTSUdOJyxcbiAgICBtaW5BcmdzOiAxLFxuICAgIG1heEFyZ3M6IDEsXG4gICAgcmV0dXJuVHlwZTogJ251bWJlcicsXG4gICAgZGVzY3JpcHRpb246ICdTaWduIG9mIG51bWJlciAoLTEsIDAsIG9yIDEpJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIHJldHVybiBkZWNpbWFsVXRpbHMuc2lnbih0b0RlY2ltYWwoYXJnc1swXSwgZGVjaW1hbFV0aWxzKSk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBERUNJTUFMOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ0RFQ0lNQUwnLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMixcbiAgICByZXR1cm5UeXBlOiAnZGVjaW1hbCcsXG4gICAgZGVzY3JpcHRpb246ICdDb252ZXJ0IHRvIERlY2ltYWwnLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSB0b0RlY2ltYWwoYXJnc1swXSwgZGVjaW1hbFV0aWxzKTtcbiAgICAgIGlmIChhcmdzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgY29uc3Qgc2NhbGUgPSB0b051bWJlcihhcmdzWzFdKTtcbiAgICAgICAgcmV0dXJuIGRlY2ltYWxVdGlscy5yb3VuZCh2YWx1ZSwgc2NhbGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgU0NBTEU6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnU0NBTEUnLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMSxcbiAgICByZXR1cm5UeXBlOiAnbnVtYmVyJyxcbiAgICBkZXNjcmlwdGlvbjogJ0dldCBzY2FsZSAoZGVjaW1hbCBwbGFjZXMpJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIHJldHVybiBkZWNpbWFsVXRpbHMuc2NhbGUodG9EZWNpbWFsKGFyZ3NbMF0sIGRlY2ltYWxVdGlscykpO1xuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgUFJFQ0lTSU9OOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ1BSRUNJU0lPTicsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAxLFxuICAgIHJldHVyblR5cGU6ICdudW1iZXInLFxuICAgIGRlc2NyaXB0aW9uOiAnR2V0IHByZWNpc2lvbiAoc2lnbmlmaWNhbnQgZGlnaXRzKScsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICByZXR1cm4gZGVjaW1hbFV0aWxzLnByZWNpc2lvbih0b0RlY2ltYWwoYXJnc1swXSwgZGVjaW1hbFV0aWxzKSk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBESVZJREU6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnRElWSURFJyxcbiAgICBtaW5BcmdzOiAyLFxuICAgIG1heEFyZ3M6IDQsXG4gICAgcmV0dXJuVHlwZTogJ2RlY2ltYWwnLFxuICAgIGRlc2NyaXB0aW9uOiAnRGl2aXNpb24gd2l0aCBzY2FsZSBhbmQgcm91bmRpbmcnLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgY29uc3QgYSA9IHRvRGVjaW1hbChhcmdzWzBdLCBkZWNpbWFsVXRpbHMpO1xuICAgICAgY29uc3QgYiA9IHRvRGVjaW1hbChhcmdzWzFdLCBkZWNpbWFsVXRpbHMpO1xuICAgICAgY29uc3Qgc2NhbGUgPSBhcmdzLmxlbmd0aCA+IDIgPyB0b051bWJlcihhcmdzWzJdKSA6IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IG1vZGUgPSBhcmdzLmxlbmd0aCA+IDMgPyBTdHJpbmcoYXJnc1szXSkgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gZGVjaW1hbFV0aWxzLmRpdmlkZShhLCBiLCBzY2FsZSwgbW9kZSBhcyBhbnkpO1xuICAgIH0sXG4gIH07XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBBZ2dyZWdhdGlvbiBGdW5jdGlvbnNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGNvbnN0IFNVTTogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdTVU0nLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMixcbiAgICByZXR1cm5UeXBlOiAnZGVjaW1hbCcsXG4gICAgZGVzY3JpcHRpb246ICdTdW0gb2YgYXJyYXkgdmFsdWVzJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MsIGNvbnRleHQsIGVuZ2luZSkgPT4ge1xuICAgICAgY29uc3QgYXJyID0gYXJnc1swXTtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcnIpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlTWlzbWF0Y2hFcnJvcignYXJyYXknLCB0eXBlb2YgYXJyLCAnU1VNJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAvLyBTaW1wbGUgc3VtXG4gICAgICAgIHJldHVybiBkZWNpbWFsVXRpbHMuc3VtKGFyci5tYXAodiA9PiB0b0RlY2ltYWwodiwgZGVjaW1hbFV0aWxzKSkpO1xuICAgICAgfVxuXG4gICAgICAvLyBTdW0gd2l0aCBleHByZXNzaW9uIC0gYXJnc1sxXSBzaG91bGQgYmUgZXZhbHVhdGVkIGZvciBlYWNoIGl0ZW1cbiAgICAgIC8vIFRoaXMgaXMgaGFuZGxlZCBzcGVjaWFsbHkgYnkgdGhlIGV2YWx1YXRvclxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdTVU0gd2l0aCBleHByZXNzaW9uIG11c3QgYmUgaGFuZGxlZCBieSBldmFsdWF0b3InKTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IEFWRzogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdBVkcnLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMSxcbiAgICByZXR1cm5UeXBlOiAnZGVjaW1hbCcsXG4gICAgZGVzY3JpcHRpb246ICdBdmVyYWdlIG9mIGFycmF5IHZhbHVlcycsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICBjb25zdCBhcnIgPSBhcmdzWzBdO1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFycikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVNaXNtYXRjaEVycm9yKCdhcnJheScsIHR5cGVvZiBhcnIsICdBVkcnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZWNpbWFsVXRpbHMuYXZnKGFyci5tYXAodiA9PiB0b0RlY2ltYWwodiwgZGVjaW1hbFV0aWxzKSkpO1xuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgQ09VTlQ6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnQ09VTlQnLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMSxcbiAgICByZXR1cm5UeXBlOiAnbnVtYmVyJyxcbiAgICBkZXNjcmlwdGlvbjogJ0NvdW50IG9mIGFycmF5IGVsZW1lbnRzJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIGNvbnN0IGFyciA9IGFyZ3NbMF07XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZU1pc21hdGNoRXJyb3IoJ2FycmF5JywgdHlwZW9mIGFyciwgJ0NPVU5UJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyLmxlbmd0aDtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IFBST0RVQ1Q6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnUFJPRFVDVCcsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAxLFxuICAgIHJldHVyblR5cGU6ICdkZWNpbWFsJyxcbiAgICBkZXNjcmlwdGlvbjogJ1Byb2R1Y3Qgb2YgYXJyYXkgdmFsdWVzJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIGNvbnN0IGFyciA9IGFyZ3NbMF07XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZU1pc21hdGNoRXJyb3IoJ2FycmF5JywgdHlwZW9mIGFyciwgJ1BST0RVQ1QnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZWNpbWFsVXRpbHMucHJvZHVjdChhcnIubWFwKHYgPT4gdG9EZWNpbWFsKHYsIGRlY2ltYWxVdGlscykpKTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IEZJTFRFUjogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdGSUxURVInLFxuICAgIG1pbkFyZ3M6IDIsXG4gICAgbWF4QXJnczogMixcbiAgICByZXR1cm5UeXBlOiAnYXJyYXknLFxuICAgIGRlc2NyaXB0aW9uOiAnRmlsdGVyIGFycmF5IGJ5IGNvbmRpdGlvbicsXG4gICAgaW1wbGVtZW50YXRpb246ICgpID0+IHtcbiAgICAgIC8vIFRoaXMgbXVzdCBiZSBoYW5kbGVkIGJ5IHRoZSBldmFsdWF0b3IgdG8gZXZhbHVhdGUgdGhlIGNvbmRpdGlvbiBleHByZXNzaW9uXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZJTFRFUiBtdXN0IGJlIGhhbmRsZWQgYnkgZXZhbHVhdG9yJyk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBNQVA6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnTUFQJyxcbiAgICBtaW5BcmdzOiAyLFxuICAgIG1heEFyZ3M6IDIsXG4gICAgcmV0dXJuVHlwZTogJ2FycmF5JyxcbiAgICBkZXNjcmlwdGlvbjogJ1RyYW5zZm9ybSBhcnJheSBlbGVtZW50cycsXG4gICAgaW1wbGVtZW50YXRpb246ICgpID0+IHtcbiAgICAgIC8vIFRoaXMgbXVzdCBiZSBoYW5kbGVkIGJ5IHRoZSBldmFsdWF0b3IgdG8gZXZhbHVhdGUgdGhlIHRyYW5zZm9ybSBleHByZXNzaW9uXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01BUCBtdXN0IGJlIGhhbmRsZWQgYnkgZXZhbHVhdG9yJyk7XG4gICAgfSxcbiAgfTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIFN0cmluZyBGdW5jdGlvbnNcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGNvbnN0IExFTjogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdMRU4nLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMSxcbiAgICByZXR1cm5UeXBlOiAnbnVtYmVyJyxcbiAgICBkZXNjcmlwdGlvbjogJ1N0cmluZyBsZW5ndGgnLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgY29uc3Qgc3RyID0gU3RyaW5nKGFyZ3NbMF0pO1xuICAgICAgcmV0dXJuIHN0ci5sZW5ndGg7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBVUFBFUjogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdVUFBFUicsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAxLFxuICAgIHJldHVyblR5cGU6ICdzdHJpbmcnLFxuICAgIGRlc2NyaXB0aW9uOiAnVXBwZXJjYXNlIHN0cmluZycsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICByZXR1cm4gU3RyaW5nKGFyZ3NbMF0pLnRvVXBwZXJDYXNlKCk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBMT1dFUjogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdMT1dFUicsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAxLFxuICAgIHJldHVyblR5cGU6ICdzdHJpbmcnLFxuICAgIGRlc2NyaXB0aW9uOiAnTG93ZXJjYXNlIHN0cmluZycsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICByZXR1cm4gU3RyaW5nKGFyZ3NbMF0pLnRvTG93ZXJDYXNlKCk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBUUklNOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ1RSSU0nLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMSxcbiAgICByZXR1cm5UeXBlOiAnc3RyaW5nJyxcbiAgICBkZXNjcmlwdGlvbjogJ1RyaW0gd2hpdGVzcGFjZScsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICByZXR1cm4gU3RyaW5nKGFyZ3NbMF0pLnRyaW0oKTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IENPTkNBVDogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdDT05DQVQnLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogLTEsXG4gICAgcmV0dXJuVHlwZTogJ3N0cmluZycsXG4gICAgZGVzY3JpcHRpb246ICdDb25jYXRlbmF0ZSBzdHJpbmdzJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIHJldHVybiBhcmdzLm1hcChhID0+IFN0cmluZyhhKSkuam9pbignJyk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBTVUJTVFI6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnU1VCU1RSJyxcbiAgICBtaW5BcmdzOiAyLFxuICAgIG1heEFyZ3M6IDMsXG4gICAgcmV0dXJuVHlwZTogJ3N0cmluZycsXG4gICAgZGVzY3JpcHRpb246ICdTdWJzdHJpbmcnLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgY29uc3Qgc3RyID0gU3RyaW5nKGFyZ3NbMF0pO1xuICAgICAgY29uc3Qgc3RhcnQgPSB0b051bWJlcihhcmdzWzFdKTtcbiAgICAgIGNvbnN0IGxlbiA9IGFyZ3MubGVuZ3RoID4gMiA/IHRvTnVtYmVyKGFyZ3NbMl0pIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIGxlbiAhPT0gdW5kZWZpbmVkID8gc3RyLnN1YnN0cihzdGFydCwgbGVuKSA6IHN0ci5zdWJzdHIoc3RhcnQpO1xuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgUkVQTEFDRTogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdSRVBMQUNFJyxcbiAgICBtaW5BcmdzOiAzLFxuICAgIG1heEFyZ3M6IDMsXG4gICAgcmV0dXJuVHlwZTogJ3N0cmluZycsXG4gICAgZGVzY3JpcHRpb246ICdSZXBsYWNlIHN1YnN0cmluZycsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICBjb25zdCBzdHIgPSBTdHJpbmcoYXJnc1swXSk7XG4gICAgICBjb25zdCBzZWFyY2ggPSBTdHJpbmcoYXJnc1sxXSk7XG4gICAgICBjb25zdCByZXBsYWNlbWVudCA9IFN0cmluZyhhcmdzWzJdKTtcbiAgICAgIHJldHVybiBzdHIuc3BsaXQoc2VhcmNoKS5qb2luKHJlcGxhY2VtZW50KTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IENPTlRBSU5TOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ0NPTlRBSU5TJyxcbiAgICBtaW5BcmdzOiAyLFxuICAgIG1heEFyZ3M6IDIsXG4gICAgcmV0dXJuVHlwZTogJ2Jvb2xlYW4nLFxuICAgIGRlc2NyaXB0aW9uOiAnQ2hlY2sgaWYgc3RyaW5nIGNvbnRhaW5zIHN1YnN0cmluZycsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICBjb25zdCBzdHIgPSBTdHJpbmcoYXJnc1swXSk7XG4gICAgICBjb25zdCBzZWFyY2ggPSBTdHJpbmcoYXJnc1sxXSk7XG4gICAgICByZXR1cm4gc3RyLmluY2x1ZGVzKHNlYXJjaCk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBTVEFSVFNXSVRIOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ1NUQVJUU1dJVEgnLFxuICAgIG1pbkFyZ3M6IDIsXG4gICAgbWF4QXJnczogMixcbiAgICByZXR1cm5UeXBlOiAnYm9vbGVhbicsXG4gICAgZGVzY3JpcHRpb246ICdDaGVjayBpZiBzdHJpbmcgc3RhcnRzIHdpdGggcHJlZml4JyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIHJldHVybiBTdHJpbmcoYXJnc1swXSkuc3RhcnRzV2l0aChTdHJpbmcoYXJnc1sxXSkpO1xuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgRU5EU1dJVEg6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnRU5EU1dJVEgnLFxuICAgIG1pbkFyZ3M6IDIsXG4gICAgbWF4QXJnczogMixcbiAgICByZXR1cm5UeXBlOiAnYm9vbGVhbicsXG4gICAgZGVzY3JpcHRpb246ICdDaGVjayBpZiBzdHJpbmcgZW5kcyB3aXRoIHN1ZmZpeCcsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICByZXR1cm4gU3RyaW5nKGFyZ3NbMF0pLmVuZHNXaXRoKFN0cmluZyhhcmdzWzFdKSk7XG4gICAgfSxcbiAgfTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIExvZ2ljYWwgRnVuY3Rpb25zXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBjb25zdCBJRjogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdJRicsXG4gICAgbWluQXJnczogMyxcbiAgICBtYXhBcmdzOiAzLFxuICAgIHJldHVyblR5cGU6ICdhbnknLFxuICAgIGRlc2NyaXB0aW9uOiAnQ29uZGl0aW9uYWwgZXhwcmVzc2lvbicsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICBjb25zdCBjb25kaXRpb24gPSBhcmdzWzBdO1xuICAgICAgcmV0dXJuIGNvbmRpdGlvbiA/IGFyZ3NbMV0gOiBhcmdzWzJdO1xuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgQ09BTEVTQ0U6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnQ09BTEVTQ0UnLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogLTEsXG4gICAgcmV0dXJuVHlwZTogJ2FueScsXG4gICAgZGVzY3JpcHRpb246ICdGaXJzdCBub24tbnVsbCB2YWx1ZScsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGFyZyBvZiBhcmdzKSB7XG4gICAgICAgIGlmIChhcmcgIT09IG51bGwgJiYgYXJnICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4gYXJnO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IElTTlVMTDogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdJU05VTEwnLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMSxcbiAgICByZXR1cm5UeXBlOiAnYm9vbGVhbicsXG4gICAgZGVzY3JpcHRpb246ICdDaGVjayBpZiBudWxsJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIHJldHVybiBhcmdzWzBdID09PSBudWxsIHx8IGFyZ3NbMF0gPT09IHVuZGVmaW5lZDtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IElTRU1QVFk6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnSVNFTVBUWScsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAxLFxuICAgIHJldHVyblR5cGU6ICdib29sZWFuJyxcbiAgICBkZXNjcmlwdGlvbjogJ0NoZWNrIGlmIGVtcHR5JyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIGNvbnN0IHZhbCA9IGFyZ3NbMF07XG4gICAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykgcmV0dXJuIHZhbC5sZW5ndGggPT09IDA7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSByZXR1cm4gdmFsLmxlbmd0aCA9PT0gMDtcbiAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnb2JqZWN0JykgcmV0dXJuIE9iamVjdC5rZXlzKHZhbCkubGVuZ3RoID09PSAwO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG4gIH07XG5cbiAgY29uc3QgREVGQVVMVDogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdERUZBVUxUJyxcbiAgICBtaW5BcmdzOiAyLFxuICAgIG1heEFyZ3M6IDIsXG4gICAgcmV0dXJuVHlwZTogJ2FueScsXG4gICAgZGVzY3JpcHRpb246ICdEZWZhdWx0IHZhbHVlIGlmIG51bGwnLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgcmV0dXJuIGFyZ3NbMF0gIT09IG51bGwgJiYgYXJnc1swXSAhPT0gdW5kZWZpbmVkID8gYXJnc1swXSA6IGFyZ3NbMV07XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBBTkQ6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnQU5EJyxcbiAgICBtaW5BcmdzOiAyLFxuICAgIG1heEFyZ3M6IC0xLFxuICAgIHJldHVyblR5cGU6ICdib29sZWFuJyxcbiAgICBkZXNjcmlwdGlvbjogJ0xvZ2ljYWwgQU5EIG9mIGFsbCBhcmd1bWVudHMnLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgcmV0dXJuIGFyZ3MuZXZlcnkoYSA9PiBCb29sZWFuKGEpKTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IE9SOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ09SJyxcbiAgICBtaW5BcmdzOiAyLFxuICAgIG1heEFyZ3M6IC0xLFxuICAgIHJldHVyblR5cGU6ICdib29sZWFuJyxcbiAgICBkZXNjcmlwdGlvbjogJ0xvZ2ljYWwgT1Igb2YgYWxsIGFyZ3VtZW50cycsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICByZXR1cm4gYXJncy5zb21lKGEgPT4gQm9vbGVhbihhKSk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBOT1Q6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnTk9UJyxcbiAgICBtaW5BcmdzOiAxLFxuICAgIG1heEFyZ3M6IDEsXG4gICAgcmV0dXJuVHlwZTogJ2Jvb2xlYW4nLFxuICAgIGRlc2NyaXB0aW9uOiAnTG9naWNhbCBOT1QnLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgcmV0dXJuICFCb29sZWFuKGFyZ3NbMF0pO1xuICAgIH0sXG4gIH07XG5cbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAvLyBUeXBlIEZ1bmN0aW9uc1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgY29uc3QgTlVNQkVSOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ05VTUJFUicsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAxLFxuICAgIHJldHVyblR5cGU6ICdkZWNpbWFsJyxcbiAgICBkZXNjcmlwdGlvbjogJ0NvbnZlcnQgdG8gbnVtYmVyJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIHJldHVybiB0b0RlY2ltYWwoYXJnc1swXSwgZGVjaW1hbFV0aWxzKTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IFNUUklORzogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdTVFJJTkcnLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMSxcbiAgICByZXR1cm5UeXBlOiAnc3RyaW5nJyxcbiAgICBkZXNjcmlwdGlvbjogJ0NvbnZlcnQgdG8gc3RyaW5nJyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIGNvbnN0IHZhbCA9IGFyZ3NbMF07XG4gICAgICBpZiAodmFsIGluc3RhbmNlb2YgRGVjaW1hbCkge1xuICAgICAgICByZXR1cm4gdmFsLnRvU3RyaW5nKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gU3RyaW5nKHZhbCk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBCT09MRUFOOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ0JPT0xFQU4nLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMSxcbiAgICByZXR1cm5UeXBlOiAnYm9vbGVhbicsXG4gICAgZGVzY3JpcHRpb246ICdDb252ZXJ0IHRvIGJvb2xlYW4nLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgY29uc3QgdmFsID0gYXJnc1swXTtcbiAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gdmFsLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJyB8fCB2YWwgPT09ICcxJztcbiAgICAgIH1cbiAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBEZWNpbWFsKSB7XG4gICAgICAgIHJldHVybiAhdmFsLmlzWmVybygpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIEJvb2xlYW4odmFsKTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IFRZUEVPRjogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdUWVBFT0YnLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMSxcbiAgICByZXR1cm5UeXBlOiAnc3RyaW5nJyxcbiAgICBkZXNjcmlwdGlvbjogJ0dldCB0eXBlIG5hbWUnLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgY29uc3QgdmFsID0gYXJnc1swXTtcbiAgICAgIGlmICh2YWwgPT09IG51bGwpIHJldHVybiAnbnVsbCc7XG4gICAgICBpZiAodmFsIGluc3RhbmNlb2YgRGVjaW1hbCkgcmV0dXJuICdkZWNpbWFsJztcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbCkpIHJldHVybiAnYXJyYXknO1xuICAgICAgcmV0dXJuIHR5cGVvZiB2YWw7XG4gICAgfSxcbiAgfTtcblxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gIC8vIEFycmF5IEZ1bmN0aW9uc1xuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgY29uc3QgRklSU1Q6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnRklSU1QnLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMSxcbiAgICByZXR1cm5UeXBlOiAnYW55JyxcbiAgICBkZXNjcmlwdGlvbjogJ0ZpcnN0IGVsZW1lbnQgb2YgYXJyYXknLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgY29uc3QgYXJyID0gYXJnc1swXTtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcnIpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlTWlzbWF0Y2hFcnJvcignYXJyYXknLCB0eXBlb2YgYXJyLCAnRklSU1QnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnIubGVuZ3RoID4gMCA/IGFyclswXSA6IG51bGw7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBMQVNUOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ0xBU1QnLFxuICAgIG1pbkFyZ3M6IDEsXG4gICAgbWF4QXJnczogMSxcbiAgICByZXR1cm5UeXBlOiAnYW55JyxcbiAgICBkZXNjcmlwdGlvbjogJ0xhc3QgZWxlbWVudCBvZiBhcnJheScsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICBjb25zdCBhcnIgPSBhcmdzWzBdO1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFycikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVNaXNtYXRjaEVycm9yKCdhcnJheScsIHR5cGVvZiBhcnIsICdMQVNUJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXJyLmxlbmd0aCA+IDAgPyBhcnJbYXJyLmxlbmd0aCAtIDFdIDogbnVsbDtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IFJFVkVSU0U6IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnUkVWRVJTRScsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAxLFxuICAgIHJldHVyblR5cGU6ICdhcnJheScsXG4gICAgZGVzY3JpcHRpb246ICdSZXZlcnNlIGFycmF5JyxcbiAgICBpbXBsZW1lbnRhdGlvbjogKGFyZ3MpID0+IHtcbiAgICAgIGNvbnN0IGFyciA9IGFyZ3NbMF07XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoYXJyKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZU1pc21hdGNoRXJyb3IoJ2FycmF5JywgdHlwZW9mIGFyciwgJ1JFVkVSU0UnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbLi4uYXJyXS5yZXZlcnNlKCk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBTTElDRTogRnVuY3Rpb25EZWZpbml0aW9uID0ge1xuICAgIG5hbWU6ICdTTElDRScsXG4gICAgbWluQXJnczogMixcbiAgICBtYXhBcmdzOiAzLFxuICAgIHJldHVyblR5cGU6ICdhcnJheScsXG4gICAgZGVzY3JpcHRpb246ICdTbGljZSBhcnJheScsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICBjb25zdCBhcnIgPSBhcmdzWzBdO1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFycikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVNaXNtYXRjaEVycm9yKCdhcnJheScsIHR5cGVvZiBhcnIsICdTTElDRScpO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhcnQgPSB0b051bWJlcihhcmdzWzFdKTtcbiAgICAgIGNvbnN0IGVuZCA9IGFyZ3MubGVuZ3RoID4gMiA/IHRvTnVtYmVyKGFyZ3NbMl0pIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIGFyci5zbGljZShzdGFydCwgZW5kKTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IElOQ0xVREVTOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ0lOQ0xVREVTJyxcbiAgICBtaW5BcmdzOiAyLFxuICAgIG1heEFyZ3M6IDIsXG4gICAgcmV0dXJuVHlwZTogJ2Jvb2xlYW4nLFxuICAgIGRlc2NyaXB0aW9uOiAnQ2hlY2sgaWYgYXJyYXkgaW5jbHVkZXMgdmFsdWUnLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgY29uc3QgYXJyID0gYXJnc1swXTtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcnIpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlTWlzbWF0Y2hFcnJvcignYXJyYXknLCB0eXBlb2YgYXJyLCAnSU5DTFVERVMnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZhbHVlID0gYXJnc1sxXTtcbiAgICAgIHJldHVybiBhcnIuc29tZShpdGVtID0+IHtcbiAgICAgICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBEZWNpbWFsICYmIHZhbHVlIGluc3RhbmNlb2YgRGVjaW1hbCkge1xuICAgICAgICAgIHJldHVybiBpdGVtLmVxdWFscyh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGl0ZW0gPT09IHZhbHVlO1xuICAgICAgfSk7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBJTkRFWE9GOiBGdW5jdGlvbkRlZmluaXRpb24gPSB7XG4gICAgbmFtZTogJ0lOREVYT0YnLFxuICAgIG1pbkFyZ3M6IDIsXG4gICAgbWF4QXJnczogMixcbiAgICByZXR1cm5UeXBlOiAnbnVtYmVyJyxcbiAgICBkZXNjcmlwdGlvbjogJ0ZpbmQgaW5kZXggb2YgdmFsdWUgaW4gYXJyYXknLFxuICAgIGltcGxlbWVudGF0aW9uOiAoYXJncykgPT4ge1xuICAgICAgY29uc3QgYXJyID0gYXJnc1swXTtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShhcnIpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlTWlzbWF0Y2hFcnJvcignYXJyYXknLCB0eXBlb2YgYXJyLCAnSU5ERVhPRicpO1xuICAgICAgfVxuICAgICAgY29uc3QgdmFsdWUgPSBhcmdzWzFdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgaXRlbSA9IGFycltpXTtcbiAgICAgICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBEZWNpbWFsICYmIHZhbHVlIGluc3RhbmNlb2YgRGVjaW1hbCkge1xuICAgICAgICAgIGlmIChpdGVtLmVxdWFscyh2YWx1ZSkpIHJldHVybiBpO1xuICAgICAgICB9IGVsc2UgaWYgKGl0ZW0gPT09IHZhbHVlKSB7XG4gICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAtMTtcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IEZMQVRURU46IEZ1bmN0aW9uRGVmaW5pdGlvbiA9IHtcbiAgICBuYW1lOiAnRkxBVFRFTicsXG4gICAgbWluQXJnczogMSxcbiAgICBtYXhBcmdzOiAyLFxuICAgIHJldHVyblR5cGU6ICdhcnJheScsXG4gICAgZGVzY3JpcHRpb246ICdGbGF0dGVuIG5lc3RlZCBhcnJheScsXG4gICAgaW1wbGVtZW50YXRpb246IChhcmdzKSA9PiB7XG4gICAgICBjb25zdCBhcnIgPSBhcmdzWzBdO1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGFycikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVNaXNtYXRjaEVycm9yKCdhcnJheScsIHR5cGVvZiBhcnIsICdGTEFUVEVOJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBkZXB0aCA9IGFyZ3MubGVuZ3RoID4gMSA/IHRvTnVtYmVyKGFyZ3NbMV0pIDogMTtcbiAgICAgIHJldHVybiBhcnIuZmxhdChkZXB0aCk7XG4gICAgfSxcbiAgfTtcblxuICAvLyBSZWdpc3RlciBhbGwgZnVuY3Rpb25zXG4gIGNvbnN0IGFsbEZ1bmN0aW9ucyA9IFtcbiAgICAvLyBNYXRoXG4gICAgQUJTLCBST1VORCwgRkxPT1IsIENFSUwsIFRSVU5DQVRFLCBNSU4sIE1BWCwgUE9XLCBTUVJULCBMT0csIExPRzEwLCBTSUdOLCBERUNJTUFMLCBTQ0FMRSwgUFJFQ0lTSU9OLCBESVZJREUsXG4gICAgLy8gQWdncmVnYXRpb25cbiAgICBTVU0sIEFWRywgQ09VTlQsIFBST0RVQ1QsIEZJTFRFUiwgTUFQLFxuICAgIC8vIFN0cmluZ1xuICAgIExFTiwgVVBQRVIsIExPV0VSLCBUUklNLCBDT05DQVQsIFNVQlNUUiwgUkVQTEFDRSwgQ09OVEFJTlMsIFNUQVJUU1dJVEgsIEVORFNXSVRILFxuICAgIC8vIExvZ2ljYWxcbiAgICBJRiwgQ09BTEVTQ0UsIElTTlVMTCwgSVNFTVBUWSwgREVGQVVMVCwgQU5ELCBPUiwgTk9ULFxuICAgIC8vIFR5cGVcbiAgICBOVU1CRVIsIFNUUklORywgQk9PTEVBTiwgVFlQRU9GLFxuICAgIC8vIEFycmF5XG4gICAgRklSU1QsIExBU1QsIFJFVkVSU0UsIFNMSUNFLCBJTkNMVURFUywgSU5ERVhPRiwgRkxBVFRFTixcbiAgXTtcblxuICBmb3IgKGNvbnN0IGZuIG9mIGFsbEZ1bmN0aW9ucykge1xuICAgIGZ1bmN0aW9ucy5zZXQoZm4ubmFtZSwgZm4pO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9ucztcbn1cbiJdfQ==
|