@sapui5/sap.fe.base 1.125.0 → 1.126.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1822 @@
1
+ /*!
2
+ * SAP UI development toolkit for HTML5 (SAPUI5)
3
+ * (c) Copyright 2009-2024 SAP SE. All rights reserved
4
+ */
5
+ sap.ui.define(["sap/fe/base/AnnotationEnum"], function (AnnotationEnum) {
6
+ "use strict";
7
+
8
+ var _exports = {};
9
+ var resolveEnumValue = AnnotationEnum.resolveEnumValue;
10
+ function isProperty(serviceObject) {
11
+ return (serviceObject === null || serviceObject === void 0 ? void 0 : serviceObject._type) === "Property";
12
+ }
13
+
14
+ /**
15
+ * An expression that evaluates to type T.
16
+ *
17
+ * @typedef BindingToolkitExpression
18
+ */
19
+ _exports.isProperty = isProperty;
20
+ const EDM_TYPE_MAPPING = {
21
+ "Edm.Boolean": {
22
+ type: "sap.ui.model.odata.type.Boolean"
23
+ },
24
+ "Edm.Byte": {
25
+ type: "sap.ui.model.odata.type.Byte"
26
+ },
27
+ "Edm.Date": {
28
+ type: "sap.ui.model.odata.type.Date"
29
+ },
30
+ "Edm.DateTimeOffset": {
31
+ constraints: {
32
+ $Precision: "precision",
33
+ $V4: "V4"
34
+ },
35
+ type: "sap.ui.model.odata.type.DateTimeOffset"
36
+ },
37
+ "Edm.Decimal": {
38
+ constraints: {
39
+ "@Org.OData.Validation.V1.Minimum/$Decimal": "minimum",
40
+ "@Org.OData.Validation.V1.Minimum@Org.OData.Validation.V1.Exclusive": "minimumExclusive",
41
+ "@Org.OData.Validation.V1.Maximum/$Decimal": "maximum",
42
+ "@Org.OData.Validation.V1.Maximum@Org.OData.Validation.V1.Exclusive": "maximumExclusive",
43
+ $Precision: "precision",
44
+ $Scale: "scale"
45
+ },
46
+ type: "sap.ui.model.odata.type.Decimal"
47
+ },
48
+ "Edm.Double": {
49
+ type: "sap.ui.model.odata.type.Double"
50
+ },
51
+ "Edm.Guid": {
52
+ type: "sap.ui.model.odata.type.Guid"
53
+ },
54
+ "Edm.Int16": {
55
+ type: "sap.ui.model.odata.type.Int16"
56
+ },
57
+ "Edm.Int32": {
58
+ type: "sap.ui.model.odata.type.Int32"
59
+ },
60
+ "Edm.Int64": {
61
+ type: "sap.ui.model.odata.type.Int64"
62
+ },
63
+ "Edm.SByte": {
64
+ type: "sap.ui.model.odata.type.SByte"
65
+ },
66
+ "Edm.Single": {
67
+ type: "sap.ui.model.odata.type.Single"
68
+ },
69
+ "Edm.Stream": {
70
+ type: "sap.ui.model.odata.type.Stream"
71
+ },
72
+ "Edm.Binary": {
73
+ type: "sap.ui.model.odata.type.Stream"
74
+ },
75
+ "Edm.String": {
76
+ constraints: {
77
+ "@com.sap.vocabularies.Common.v1.IsDigitSequence": "isDigitSequence",
78
+ $MaxLength: "maxLength",
79
+ $Nullable: "nullable"
80
+ },
81
+ type: "sap.ui.model.odata.type.String"
82
+ },
83
+ "Edm.TimeOfDay": {
84
+ constraints: {
85
+ $Precision: "precision"
86
+ },
87
+ type: "sap.ui.model.odata.type.TimeOfDay"
88
+ }
89
+ };
90
+
91
+ /**
92
+ * An expression that evaluates to type T, or a constant value of type T
93
+ */
94
+ _exports.EDM_TYPE_MAPPING = EDM_TYPE_MAPPING;
95
+ const unresolvableExpression = {
96
+ _type: "Unresolvable"
97
+ };
98
+ _exports.unresolvableExpression = unresolvableExpression;
99
+ function escapeXmlAttribute(inputString) {
100
+ return inputString.replace(/'/g, "\\'");
101
+ }
102
+ _exports.escapeXmlAttribute = escapeXmlAttribute;
103
+ function hasUnresolvableExpression() {
104
+ for (var _len = arguments.length, expressions = new Array(_len), _key = 0; _key < _len; _key++) {
105
+ expressions[_key] = arguments[_key];
106
+ }
107
+ return expressions.find(expr => expr._type === "Unresolvable") !== undefined;
108
+ }
109
+ /**
110
+ * Check two expressions for (deep) equality.
111
+ *
112
+ * @param a
113
+ * @param b
114
+ * @returns `true` if the two expressions are equal
115
+ */
116
+ _exports.hasUnresolvableExpression = hasUnresolvableExpression;
117
+ function _checkExpressionsAreEqual(a, b) {
118
+ if (a._type !== b._type) {
119
+ return false;
120
+ }
121
+ switch (a._type) {
122
+ case "Unresolvable":
123
+ return false;
124
+ // Unresolvable is never equal to anything even itself
125
+ case "Constant":
126
+ case "EmbeddedBinding":
127
+ case "EmbeddedExpressionBinding":
128
+ return a.value === b.value;
129
+ case "Not":
130
+ return _checkExpressionsAreEqual(a.operand, b.operand);
131
+ case "Truthy":
132
+ return _checkExpressionsAreEqual(a.operand, b.operand);
133
+ case "Set":
134
+ return a.operator === b.operator && a.operands.length === b.operands.length && a.operands.every(expression => b.operands.some(otherExpression => _checkExpressionsAreEqual(expression, otherExpression)));
135
+ case "IfElse":
136
+ return _checkExpressionsAreEqual(a.condition, b.condition) && _checkExpressionsAreEqual(a.onTrue, b.onTrue) && _checkExpressionsAreEqual(a.onFalse, b.onFalse);
137
+ case "Comparison":
138
+ return a.operator === b.operator && _checkExpressionsAreEqual(a.operand1, b.operand1) && _checkExpressionsAreEqual(a.operand2, b.operand2);
139
+ case "Concat":
140
+ const aExpressions = a.expressions;
141
+ const bExpressions = b.expressions;
142
+ if (aExpressions.length !== bExpressions.length) {
143
+ return false;
144
+ }
145
+ return aExpressions.every((expression, index) => {
146
+ return _checkExpressionsAreEqual(expression, bExpressions[index]);
147
+ });
148
+ case "Length":
149
+ return _checkExpressionsAreEqual(a.pathInModel, b.pathInModel);
150
+ case "PathInModel":
151
+ return a.modelName === b.modelName && a.path === b.path && a.targetEntitySet === b.targetEntitySet;
152
+ case "Formatter":
153
+ return a.fn === b.fn && a.parameters.length === b.parameters.length && a.parameters.every((value, index) => _checkExpressionsAreEqual(b.parameters[index], value));
154
+ case "ComplexType":
155
+ return a.type === b.type && a.bindingParameters.length === b.bindingParameters.length && a.bindingParameters.every((value, index) => _checkExpressionsAreEqual(b.bindingParameters[index], value));
156
+ case "Function":
157
+ const otherFunction = b;
158
+ if (a.obj === undefined || otherFunction.obj === undefined) {
159
+ return a.obj === otherFunction;
160
+ }
161
+ return a.fn === otherFunction.fn && _checkExpressionsAreEqual(a.obj, otherFunction.obj) && a.parameters.length === otherFunction.parameters.length && a.parameters.every((value, index) => _checkExpressionsAreEqual(otherFunction.parameters[index], value));
162
+ case "Ref":
163
+ return a.ref === b.ref;
164
+ }
165
+ return false;
166
+ }
167
+
168
+ /**
169
+ * Converts a nested SetExpression by inlining operands of type SetExpression with the same operator.
170
+ *
171
+ * @param expression The expression to flatten
172
+ * @returns A new SetExpression with the same operator
173
+ */
174
+ _exports._checkExpressionsAreEqual = _checkExpressionsAreEqual;
175
+ function flattenSetExpression(expression) {
176
+ return expression.operands.reduce((result, operand) => {
177
+ const candidatesForFlattening = operand._type === "Set" && operand.operator === expression.operator ? operand.operands : [operand];
178
+ candidatesForFlattening.forEach(candidate => {
179
+ if (result.operands.every(e => !_checkExpressionsAreEqual(e, candidate))) {
180
+ result.operands.push(candidate);
181
+ }
182
+ });
183
+ return result;
184
+ }, {
185
+ _type: "Set",
186
+ operator: expression.operator,
187
+ operands: []
188
+ });
189
+ }
190
+
191
+ /**
192
+ * Detects whether an array of boolean expressions contains an expression and its negation.
193
+ *
194
+ * @param expressions Array of expressions
195
+ * @returns `true` if the set of expressions contains an expression and its negation
196
+ */
197
+ function hasOppositeExpressions(expressions) {
198
+ const negatedExpressions = expressions.map(not);
199
+ return expressions.some((expression, index) => {
200
+ for (let i = index + 1; i < negatedExpressions.length; i++) {
201
+ if (_checkExpressionsAreEqual(expression, negatedExpressions[i])) {
202
+ return true;
203
+ }
204
+ }
205
+ return false;
206
+ });
207
+ }
208
+
209
+ /**
210
+ * Logical `and` expression.
211
+ *
212
+ * The expression is simplified to false if this can be decided statically (that is, if one operand is a constant
213
+ * false or if the expression contains an operand and its negation).
214
+ *
215
+ * @param operands Expressions to connect by `and`
216
+ * @returns Expression evaluating to boolean
217
+ */
218
+ function and() {
219
+ for (var _len2 = arguments.length, operands = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
220
+ operands[_key2] = arguments[_key2];
221
+ }
222
+ const expressions = flattenSetExpression({
223
+ _type: "Set",
224
+ operator: "&&",
225
+ operands: operands.map(wrapPrimitive)
226
+ }).operands;
227
+ if (hasUnresolvableExpression(...expressions)) {
228
+ return unresolvableExpression;
229
+ }
230
+ let isStaticFalse = false;
231
+ const nonTrivialExpression = expressions.filter(expression => {
232
+ if (isFalse(expression)) {
233
+ isStaticFalse = true;
234
+ }
235
+ return !isConstant(expression);
236
+ });
237
+ if (isStaticFalse) {
238
+ return constant(false);
239
+ } else if (nonTrivialExpression.length === 0) {
240
+ // Resolve the constant then
241
+ const isValid = expressions.reduce((result, expression) => result && isTrue(expression), true);
242
+ return constant(isValid);
243
+ } else if (nonTrivialExpression.length === 1) {
244
+ return nonTrivialExpression[0];
245
+ } else if (hasOppositeExpressions(nonTrivialExpression)) {
246
+ return constant(false);
247
+ } else {
248
+ return {
249
+ _type: "Set",
250
+ operator: "&&",
251
+ operands: nonTrivialExpression
252
+ };
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Logical `or` expression.
258
+ *
259
+ * The expression is simplified to true if this can be decided statically (that is, if one operand is a constant
260
+ * true or if the expression contains an operand and its negation).
261
+ *
262
+ * @param operands Expressions to connect by `or`
263
+ * @returns Expression evaluating to boolean
264
+ */
265
+ _exports.and = and;
266
+ function or() {
267
+ for (var _len3 = arguments.length, operands = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
268
+ operands[_key3] = arguments[_key3];
269
+ }
270
+ const expressions = flattenSetExpression({
271
+ _type: "Set",
272
+ operator: "||",
273
+ operands: operands.map(wrapPrimitive)
274
+ }).operands;
275
+ if (hasUnresolvableExpression(...expressions)) {
276
+ return unresolvableExpression;
277
+ }
278
+ let isStaticTrue = false;
279
+ const nonTrivialExpression = expressions.filter(expression => {
280
+ if (isTrue(expression)) {
281
+ isStaticTrue = true;
282
+ }
283
+ return !isConstant(expression) || expression.value;
284
+ });
285
+ if (isStaticTrue) {
286
+ return constant(true);
287
+ } else if (nonTrivialExpression.length === 0) {
288
+ // Resolve the constant then
289
+ const isValid = expressions.reduce((result, expression) => result && isTrue(expression), true);
290
+ return constant(isValid);
291
+ } else if (nonTrivialExpression.length === 1) {
292
+ return nonTrivialExpression[0];
293
+ } else if (hasOppositeExpressions(nonTrivialExpression)) {
294
+ return constant(true);
295
+ } else {
296
+ return {
297
+ _type: "Set",
298
+ operator: "||",
299
+ operands: nonTrivialExpression
300
+ };
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Logical `not` operator.
306
+ *
307
+ * @param operand The expression to reverse
308
+ * @returns The resulting expression that evaluates to boolean
309
+ */
310
+ _exports.or = or;
311
+ function not(operand) {
312
+ operand = wrapPrimitive(operand);
313
+ if (hasUnresolvableExpression(operand)) {
314
+ return unresolvableExpression;
315
+ } else if (isConstant(operand)) {
316
+ return constant(!operand.value);
317
+ } else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "||" && operand.operands.every(expression => isConstant(expression) || isComparison(expression))) {
318
+ return and(...operand.operands.map(expression => not(expression)));
319
+ } else if (typeof operand === "object" && operand._type === "Set" && operand.operator === "&&" && operand.operands.every(expression => isConstant(expression) || isComparison(expression))) {
320
+ return or(...operand.operands.map(expression => not(expression)));
321
+ } else if (isComparison(operand)) {
322
+ // Create the reverse comparison
323
+ switch (operand.operator) {
324
+ case "!==":
325
+ return {
326
+ ...operand,
327
+ operator: "==="
328
+ };
329
+ case "<":
330
+ return {
331
+ ...operand,
332
+ operator: ">="
333
+ };
334
+ case "<=":
335
+ return {
336
+ ...operand,
337
+ operator: ">"
338
+ };
339
+ case "===":
340
+ return {
341
+ ...operand,
342
+ operator: "!=="
343
+ };
344
+ case ">":
345
+ return {
346
+ ...operand,
347
+ operator: "<="
348
+ };
349
+ case ">=":
350
+ return {
351
+ ...operand,
352
+ operator: "<"
353
+ };
354
+ }
355
+ } else if (operand._type === "Not") {
356
+ return operand.operand;
357
+ }
358
+ return {
359
+ _type: "Not",
360
+ operand: operand
361
+ };
362
+ }
363
+
364
+ /**
365
+ * Evaluates whether a binding expression is equal to true with a loose equality.
366
+ *
367
+ * @param operand The expression to check
368
+ * @returns The resulting expression that evaluates to boolean
369
+ */
370
+ _exports.not = not;
371
+ function isTruthy(operand) {
372
+ if (isConstant(operand)) {
373
+ return constant(!!operand.value);
374
+ } else {
375
+ return {
376
+ _type: "Truthy",
377
+ operand: operand
378
+ };
379
+ }
380
+ }
381
+
382
+ /**
383
+ * Creates a binding expression that will be evaluated by the corresponding model.
384
+ *
385
+ * @param path
386
+ * @param modelName
387
+ * @param visitedNavigationPaths
388
+ * @param pathVisitor
389
+ * @returns An expression representating that path in the model
390
+ * @deprecated use pathInModel instead
391
+ */
392
+ _exports.isTruthy = isTruthy;
393
+ function bindingExpression(path, modelName) {
394
+ let visitedNavigationPaths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
395
+ let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
396
+ return pathInModel(path, modelName, visitedNavigationPaths, pathVisitor);
397
+ }
398
+
399
+ /**
400
+ * Creates a binding expression that will be evaluated by the corresponding model.
401
+ *
402
+ * @template TargetType
403
+ * @param path The path on the model
404
+ * @param [modelName] The name of the model
405
+ * @param [visitedNavigationPaths] The paths from the root entitySet
406
+ * @param [pathVisitor] A function to modify the resulting path
407
+ * @returns An expression representating that path in the model
408
+ */
409
+ _exports.bindingExpression = bindingExpression;
410
+ function pathInModel(path, modelName) {
411
+ let visitedNavigationPaths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
412
+ let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
413
+ if (path === undefined) {
414
+ return unresolvableExpression;
415
+ }
416
+ let targetPath;
417
+ if (pathVisitor) {
418
+ targetPath = pathVisitor(path);
419
+ if (targetPath === undefined) {
420
+ return unresolvableExpression;
421
+ }
422
+ } else {
423
+ const localPath = visitedNavigationPaths.concat();
424
+ localPath.push(path);
425
+ targetPath = localPath.join("/");
426
+ }
427
+ return {
428
+ _type: "PathInModel",
429
+ modelName: modelName,
430
+ path: targetPath
431
+ };
432
+ }
433
+ _exports.pathInModel = pathInModel;
434
+ /**
435
+ * Creates a constant expression based on a primitive value.
436
+ *
437
+ * @template T
438
+ * @param value The constant to wrap in an expression
439
+ * @returns The constant expression
440
+ */
441
+ function constant(value) {
442
+ let constantValue;
443
+ if (typeof value === "object" && value !== null && value !== undefined) {
444
+ if (Array.isArray(value)) {
445
+ constantValue = value.map(wrapPrimitive);
446
+ } else if (isPrimitiveObject(value)) {
447
+ constantValue = value.valueOf();
448
+ } else {
449
+ constantValue = Object.entries(value).reduce((plainExpression, _ref) => {
450
+ let [key, val] = _ref;
451
+ const wrappedValue = wrapPrimitive(val);
452
+ if (wrappedValue._type !== "Constant" || wrappedValue.value !== undefined) {
453
+ plainExpression[key] = wrappedValue;
454
+ }
455
+ return plainExpression;
456
+ }, {});
457
+ }
458
+ } else {
459
+ constantValue = value;
460
+ }
461
+ return {
462
+ _type: "Constant",
463
+ value: constantValue
464
+ };
465
+ }
466
+ _exports.constant = constant;
467
+ function resolveBindingString(value, targetType) {
468
+ if (value !== undefined && typeof value === "string" && value.startsWith("{")) {
469
+ const pathInModelRegex = /^{(.*)>(.+)}$/; // Matches model paths like "model>path" or ">path" (default model)
470
+ const pathInModelRegexMatch = pathInModelRegex.exec(value);
471
+ if (value.startsWith("{=")) {
472
+ // Expression binding, we can just remove the outer binding things
473
+ return {
474
+ _type: "EmbeddedExpressionBinding",
475
+ value: value
476
+ };
477
+ } else if (pathInModelRegexMatch) {
478
+ return pathInModel(pathInModelRegexMatch[2] || "", pathInModelRegexMatch[1] || undefined);
479
+ } else {
480
+ return {
481
+ _type: "EmbeddedBinding",
482
+ value: value
483
+ };
484
+ }
485
+ } else if (targetType === "boolean" && typeof value === "string" && (value === "true" || value === "false")) {
486
+ return constant(value === "true");
487
+ } else if (targetType === "number" && typeof value === "string" && (!isNaN(Number(value)) || value === "NaN")) {
488
+ return constant(Number(value));
489
+ } else {
490
+ return constant(value);
491
+ }
492
+ }
493
+
494
+ /**
495
+ * A named reference.
496
+ *
497
+ * @see fn
498
+ * @param reference Reference
499
+ * @returns The object reference binding part
500
+ */
501
+ _exports.resolveBindingString = resolveBindingString;
502
+ function ref(reference) {
503
+ return {
504
+ _type: "Ref",
505
+ ref: reference
506
+ };
507
+ }
508
+
509
+ /**
510
+ * Wrap a primitive into a constant expression if it is not already an expression.
511
+ *
512
+ * @template T
513
+ * @param something The object to wrap in a Constant expression
514
+ * @returns Either the original object or the wrapped one depending on the case
515
+ */
516
+ _exports.ref = ref;
517
+ function wrapPrimitive(something) {
518
+ if (isBindingToolkitExpression(something)) {
519
+ return something;
520
+ }
521
+ return constant(something);
522
+ }
523
+
524
+ /**
525
+ * Checks if the expression or value provided is a binding tooling expression or not.
526
+ *
527
+ * Every object having a property named `_type` of some value is considered an expression, even if there is actually
528
+ * no such expression type supported.
529
+ *
530
+ * @param expression
531
+ * @returns `true` if the expression is a binding toolkit expression
532
+ */
533
+ _exports.wrapPrimitive = wrapPrimitive;
534
+ function isBindingToolkitExpression(expression) {
535
+ return (expression === null || expression === void 0 ? void 0 : expression._type) !== undefined;
536
+ }
537
+
538
+ /**
539
+ * Checks if the expression or value provided is constant or not.
540
+ *
541
+ * @template T The target type
542
+ * @param maybeConstant The expression or primitive value that is to be checked
543
+ * @returns `true` if it is constant
544
+ */
545
+ _exports.isBindingToolkitExpression = isBindingToolkitExpression;
546
+ function isConstant(maybeConstant) {
547
+ return typeof maybeConstant !== "object" || maybeConstant._type === "Constant";
548
+ }
549
+ _exports.isConstant = isConstant;
550
+ function isTrue(expression) {
551
+ return isConstant(expression) && expression.value === true;
552
+ }
553
+ function isFalse(expression) {
554
+ return isConstant(expression) && expression.value === false;
555
+ }
556
+
557
+ /**
558
+ * Checks if the expression or value provided is a path in model expression or not.
559
+ *
560
+ * @template T The target type
561
+ * @param maybeBinding The expression or primitive value that is to be checked
562
+ * @returns `true` if it is a path in model expression
563
+ */
564
+ function isPathInModelExpression(maybeBinding) {
565
+ return (maybeBinding === null || maybeBinding === void 0 ? void 0 : maybeBinding._type) === "PathInModel";
566
+ }
567
+
568
+ /**
569
+ * Checks if the expression or value provided is a complex type expression.
570
+ *
571
+ * @template T The target type
572
+ * @param maybeBinding The expression or primitive value that is to be checked
573
+ * @returns `true` if it is a path in model expression
574
+ */
575
+ _exports.isPathInModelExpression = isPathInModelExpression;
576
+ function isComplexTypeExpression(maybeBinding) {
577
+ return (maybeBinding === null || maybeBinding === void 0 ? void 0 : maybeBinding._type) === "ComplexType";
578
+ }
579
+
580
+ /**
581
+ * Checks if the expression or value provided is a concat expression or not.
582
+ *
583
+ * @param expression
584
+ * @returns `true` if the expression is a ConcatExpression
585
+ */
586
+ _exports.isComplexTypeExpression = isComplexTypeExpression;
587
+ function isConcatExpression(expression) {
588
+ return (expression === null || expression === void 0 ? void 0 : expression._type) === "Concat";
589
+ }
590
+
591
+ /**
592
+ * Checks if the expression or value provided is a IfElse expression or not.
593
+ *
594
+ * @param expression
595
+ * @returns `true` if the expression is a IfElseExpression
596
+ */
597
+ function isIfElseExpression(expression) {
598
+ return (expression === null || expression === void 0 ? void 0 : expression._type) === "IfElse";
599
+ }
600
+
601
+ /**
602
+ * Checks if the expression provided is a comparison or not.
603
+ *
604
+ * @template T The target type
605
+ * @param expression The expression
606
+ * @returns `true` if the expression is a ComparisonExpression
607
+ */
608
+ function isComparison(expression) {
609
+ return expression._type === "Comparison";
610
+ }
611
+
612
+ /**
613
+ * Checks whether the input parameter is a constant expression of type undefined.
614
+ *
615
+ * @param expression The input expression or object in general
616
+ * @returns `true` if the input is constant which has undefined for value
617
+ */
618
+ function isUndefinedExpression(expression) {
619
+ const expressionAsExpression = expression;
620
+ return (expressionAsExpression === null || expressionAsExpression === void 0 ? void 0 : expressionAsExpression._type) === "Constant" && (expressionAsExpression === null || expressionAsExpression === void 0 ? void 0 : expressionAsExpression.value) === undefined;
621
+ }
622
+ _exports.isUndefinedExpression = isUndefinedExpression;
623
+ function isPrimitiveObject(objectType) {
624
+ switch (objectType.constructor.name) {
625
+ case "String":
626
+ case "Number":
627
+ case "Boolean":
628
+ return true;
629
+ default:
630
+ return false;
631
+ }
632
+ }
633
+ /**
634
+ * Check if the passed annotation annotationValue is a ComplexAnnotationExpression.
635
+ *
636
+ * @template T The target type
637
+ * @param annotationValue The annotation annotationValue to evaluate
638
+ * @returns `true` if the object is a {ComplexAnnotationExpression}
639
+ */
640
+ function isComplexAnnotationExpression(annotationValue) {
641
+ return typeof annotationValue === "object" && !isPrimitiveObject(annotationValue);
642
+ }
643
+
644
+ /**
645
+ * Generate the corresponding annotationValue for a given annotation annotationValue.
646
+ *
647
+ * @template T The target type
648
+ * @param annotationValue The source annotation annotationValue
649
+ * @param visitedNavigationPaths The path from the root entity set
650
+ * @param defaultValue Default value if the annotationValue is undefined
651
+ * @param pathVisitor A function to modify the resulting path
652
+ * @returns The annotationValue equivalent to that annotation annotationValue
653
+ */
654
+ function getExpressionFromAnnotation(annotationValue) {
655
+ var _annotationValue;
656
+ let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
657
+ let defaultValue = arguments.length > 2 ? arguments[2] : undefined;
658
+ let pathVisitor = arguments.length > 3 ? arguments[3] : undefined;
659
+ if (annotationValue === undefined) {
660
+ return wrapPrimitive(defaultValue);
661
+ }
662
+ annotationValue = (_annotationValue = annotationValue) === null || _annotationValue === void 0 ? void 0 : _annotationValue.valueOf();
663
+ if (!isComplexAnnotationExpression(annotationValue)) {
664
+ return constant(annotationValue);
665
+ }
666
+ switch (annotationValue.type) {
667
+ case "Path":
668
+ return pathInModel(annotationValue.path, undefined, visitedNavigationPaths, pathVisitor);
669
+ case "If":
670
+ return annotationIfExpression(annotationValue.If, visitedNavigationPaths, pathVisitor);
671
+ case "Not":
672
+ return not(parseAnnotationCondition(annotationValue.Not, visitedNavigationPaths, pathVisitor));
673
+ case "Eq":
674
+ return equal(parseAnnotationCondition(annotationValue.Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Eq[1], visitedNavigationPaths, pathVisitor));
675
+ case "Ne":
676
+ return notEqual(parseAnnotationCondition(annotationValue.Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Ne[1], visitedNavigationPaths, pathVisitor));
677
+ case "Gt":
678
+ return greaterThan(parseAnnotationCondition(annotationValue.Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Gt[1], visitedNavigationPaths, pathVisitor));
679
+ case "Ge":
680
+ return greaterOrEqual(parseAnnotationCondition(annotationValue.Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Ge[1], visitedNavigationPaths, pathVisitor));
681
+ case "Lt":
682
+ return lessThan(parseAnnotationCondition(annotationValue.Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Lt[1], visitedNavigationPaths, pathVisitor));
683
+ case "Le":
684
+ return lessOrEqual(parseAnnotationCondition(annotationValue.Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.Le[1], visitedNavigationPaths, pathVisitor));
685
+ case "Or":
686
+ return or(...annotationValue.Or.map(function (orCondition) {
687
+ return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
688
+ }));
689
+ case "And":
690
+ return and(...annotationValue.And.map(function (andCondition) {
691
+ return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
692
+ }));
693
+ case "Apply":
694
+ return annotationApplyExpression(annotationValue, visitedNavigationPaths, pathVisitor);
695
+ }
696
+ return unresolvableExpression;
697
+ }
698
+
699
+ /**
700
+ * Parse the annotation condition into an expression.
701
+ *
702
+ * @template T The target type
703
+ * @param annotationValue The condition or value from the annotation
704
+ * @param visitedNavigationPaths The path from the root entity set
705
+ * @param pathVisitor A function to modify the resulting path
706
+ * @returns An equivalent expression
707
+ */
708
+ _exports.getExpressionFromAnnotation = getExpressionFromAnnotation;
709
+ function parseAnnotationCondition(annotationValue) {
710
+ let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
711
+ let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
712
+ if (annotationValue === null || typeof annotationValue !== "object") {
713
+ return constant(annotationValue);
714
+ } else if (annotationValue.hasOwnProperty("$Or")) {
715
+ return or(...annotationValue.$Or.map(function (orCondition) {
716
+ return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
717
+ }));
718
+ } else if (annotationValue.hasOwnProperty("$And")) {
719
+ return and(...annotationValue.$And.map(function (andCondition) {
720
+ return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
721
+ }));
722
+ } else if (annotationValue.hasOwnProperty("$Not")) {
723
+ return not(parseAnnotationCondition(annotationValue.$Not, visitedNavigationPaths, pathVisitor));
724
+ } else if (annotationValue.hasOwnProperty("$Eq")) {
725
+ return equal(parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor));
726
+ } else if (annotationValue.hasOwnProperty("$Ne")) {
727
+ return notEqual(parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor));
728
+ } else if (annotationValue.hasOwnProperty("$Gt")) {
729
+ return greaterThan(parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor));
730
+ } else if (annotationValue.hasOwnProperty("$Ge")) {
731
+ return greaterOrEqual(parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor));
732
+ } else if (annotationValue.hasOwnProperty("$Lt")) {
733
+ return lessThan(parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor));
734
+ } else if (annotationValue.hasOwnProperty("$Le")) {
735
+ return lessOrEqual(parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor));
736
+ } else if (annotationValue.hasOwnProperty("$Path")) {
737
+ return pathInModel(annotationValue.$Path, undefined, visitedNavigationPaths, pathVisitor);
738
+ } else if (annotationValue.hasOwnProperty("$Apply")) {
739
+ return getExpressionFromAnnotation({
740
+ type: "Apply",
741
+ Function: annotationValue.$Function,
742
+ Apply: annotationValue.$Apply
743
+ }, visitedNavigationPaths, undefined, pathVisitor);
744
+ } else if (annotationValue.hasOwnProperty("$If")) {
745
+ return getExpressionFromAnnotation({
746
+ type: "If",
747
+ If: annotationValue.$If
748
+ }, visitedNavigationPaths, undefined, pathVisitor);
749
+ } else if (annotationValue.hasOwnProperty("$EnumMember")) {
750
+ return constant(resolveEnumValue(annotationValue.$EnumMember));
751
+ }
752
+ return constant(false);
753
+ }
754
+
755
+ /**
756
+ * Process the {IfAnnotationExpressionValue} into an expression.
757
+ *
758
+ * @template T The target type
759
+ * @param annotationValue An If expression returning the type T
760
+ * @param visitedNavigationPaths The path from the root entity set
761
+ * @param pathVisitor A function to modify the resulting path
762
+ * @returns The equivalent ifElse expression
763
+ */
764
+ function annotationIfExpression(annotationValue) {
765
+ let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
766
+ let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
767
+ return ifElse(parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[1], visitedNavigationPaths, pathVisitor), parseAnnotationCondition(annotationValue[2], visitedNavigationPaths, pathVisitor));
768
+ }
769
+ // This type is not recursively transformed from the metamodel content, as such we have some ugly things there
770
+ _exports.annotationIfExpression = annotationIfExpression;
771
+ function convertSubApplyParameters(applyParam) {
772
+ let applyParamConverted = applyParam;
773
+ if (applyParam.hasOwnProperty("$Path")) {
774
+ applyParamConverted = {
775
+ type: "Path",
776
+ path: applyParam.$Path
777
+ };
778
+ } else if (applyParam.hasOwnProperty("$If")) {
779
+ applyParamConverted = {
780
+ type: "If",
781
+ If: applyParam.$If
782
+ };
783
+ } else if (applyParam.hasOwnProperty("$Apply")) {
784
+ applyParamConverted = {
785
+ type: "Apply",
786
+ Function: applyParam.$Function,
787
+ Apply: applyParam.$Apply
788
+ };
789
+ }
790
+ return applyParamConverted;
791
+ }
792
+ function annotationApplyExpression(applyExpression) {
793
+ let visitedNavigationPaths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
794
+ let pathVisitor = arguments.length > 2 ? arguments[2] : undefined;
795
+ switch (applyExpression.Function) {
796
+ case "odata.concat":
797
+ return concat(...applyExpression.Apply.map(applyParam => {
798
+ return getExpressionFromAnnotation(convertSubApplyParameters(applyParam), visitedNavigationPaths, undefined, pathVisitor);
799
+ }));
800
+ case "odata.uriEncode":
801
+ const parameter = getExpressionFromAnnotation(convertSubApplyParameters(applyExpression.Apply[0]), visitedNavigationPaths, undefined, pathVisitor);
802
+ // The second parameter for uriEncode is always a string since the target evaluation is against a formatValue call in ODataUtils which expect the target type as second parameter
803
+ return fn("odata.uriEncode", [parameter, "Edm.String"], undefined, true);
804
+ case "odata.fillUriTemplate":
805
+ const template = applyExpression.Apply[0];
806
+ const templateParams = applyExpression.Apply.slice(1);
807
+ const targetObject = {};
808
+ templateParams.forEach(applyParam => {
809
+ targetObject[applyParam.$Name] = getExpressionFromAnnotation(convertSubApplyParameters(applyParam.$LabeledElement), visitedNavigationPaths, undefined, pathVisitor);
810
+ });
811
+ return fn("odata.fillUriTemplate", [template, targetObject], undefined, true);
812
+ }
813
+ return unresolvableExpression;
814
+ }
815
+
816
+ /**
817
+ * Generic helper for the comparison operations (equal, notEqual, ...).
818
+ *
819
+ * @template T The target type
820
+ * @param operator The operator to apply
821
+ * @param leftOperand The operand on the left side of the operator
822
+ * @param rightOperand The operand on the right side of the operator
823
+ * @returns An expression representing the comparison
824
+ */
825
+ _exports.annotationApplyExpression = annotationApplyExpression;
826
+ function comparison(operator, leftOperand, rightOperand) {
827
+ const leftExpression = wrapPrimitive(leftOperand);
828
+ const rightExpression = wrapPrimitive(rightOperand);
829
+ if (hasUnresolvableExpression(leftExpression, rightExpression)) {
830
+ return unresolvableExpression;
831
+ }
832
+ if (isConstant(leftExpression) && isConstant(rightExpression)) {
833
+ switch (operator) {
834
+ case "!==":
835
+ return constant(leftExpression.value !== rightExpression.value);
836
+ case "===":
837
+ return constant(leftExpression.value === rightExpression.value);
838
+ case "<":
839
+ if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
840
+ return constant(false);
841
+ }
842
+ return constant(leftExpression.value < rightExpression.value);
843
+ case "<=":
844
+ if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
845
+ return constant(false);
846
+ }
847
+ return constant(leftExpression.value <= rightExpression.value);
848
+ case ">":
849
+ if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
850
+ return constant(false);
851
+ }
852
+ return constant(leftExpression.value > rightExpression.value);
853
+ case ">=":
854
+ if (leftExpression.value === null || leftExpression.value === undefined || rightExpression.value === null || rightExpression.value === undefined) {
855
+ return constant(false);
856
+ }
857
+ return constant(leftExpression.value >= rightExpression.value);
858
+ }
859
+ } else {
860
+ return {
861
+ _type: "Comparison",
862
+ operator: operator,
863
+ operand1: leftExpression,
864
+ operand2: rightExpression
865
+ };
866
+ }
867
+ }
868
+
869
+ /**
870
+ * Generic helper for the length of an expression.
871
+ *
872
+ * @param expression The input expression pointing to an array
873
+ * @param checkUndefined Is the array potentially undefined
874
+ * @returns An expression representing the length
875
+ */
876
+ function length(expression) {
877
+ let checkUndefined = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
878
+ if (expression._type === "Unresolvable") {
879
+ return expression;
880
+ }
881
+ if (!checkUndefined) {
882
+ return {
883
+ _type: "Length",
884
+ pathInModel: expression
885
+ };
886
+ }
887
+ return ifElse(equal(expression, undefined), -1, length(expression));
888
+ }
889
+
890
+ /**
891
+ * Comparison: "equal" (===).
892
+ *
893
+ * @template T The target type
894
+ * @param leftOperand The operand on the left side
895
+ * @param rightOperand The operand on the right side of the comparison
896
+ * @returns An expression representing the comparison
897
+ */
898
+ _exports.length = length;
899
+ function equal(leftOperand, rightOperand) {
900
+ const leftExpression = wrapPrimitive(leftOperand);
901
+ const rightExpression = wrapPrimitive(rightOperand);
902
+ if (hasUnresolvableExpression(leftExpression, rightExpression)) {
903
+ return unresolvableExpression;
904
+ }
905
+ if (_checkExpressionsAreEqual(leftExpression, rightExpression)) {
906
+ return constant(true);
907
+ }
908
+ function reduce(left, right) {
909
+ if (left._type === "Comparison" && isTrue(right)) {
910
+ // compare(a, b) === true ~~> compare(a, b)
911
+ return left;
912
+ } else if (left._type === "Comparison" && isFalse(right)) {
913
+ // compare(a, b) === false ~~> !compare(a, b)
914
+ return not(left);
915
+ } else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onTrue, right)) {
916
+ // (if (x) { a } else { b }) === a ~~> x || (b === a)
917
+ return or(left.condition, equal(left.onFalse, right));
918
+ } else if (left._type === "IfElse" && _checkExpressionsAreEqual(left.onFalse, right)) {
919
+ // (if (x) { a } else { b }) === b ~~> !x || (a === b)
920
+ return or(not(left.condition), equal(left.onTrue, right));
921
+ } else if (left._type === "IfElse" && isConstant(left.onTrue) && isConstant(left.onFalse) && isConstant(right) && !_checkExpressionsAreEqual(left.onTrue, right) && !_checkExpressionsAreEqual(left.onFalse, right)) {
922
+ return constant(false);
923
+ }
924
+ return undefined;
925
+ }
926
+
927
+ // exploit symmetry: a === b <~> b === a
928
+ const reduced = reduce(leftExpression, rightExpression) ?? reduce(rightExpression, leftExpression);
929
+ return reduced ?? comparison("===", leftExpression, rightExpression);
930
+ }
931
+
932
+ /**
933
+ * Comparison: "not equal" (!==).
934
+ *
935
+ * @template T The target type
936
+ * @param leftOperand The operand on the left side
937
+ * @param rightOperand The operand on the right side of the comparison
938
+ * @returns An expression representing the comparison
939
+ */
940
+ _exports.equal = equal;
941
+ function notEqual(leftOperand, rightOperand) {
942
+ return not(equal(leftOperand, rightOperand));
943
+ }
944
+
945
+ /**
946
+ * Comparison: "greater or equal" (>=).
947
+ *
948
+ * @template T The target type
949
+ * @param leftOperand The operand on the left side
950
+ * @param rightOperand The operand on the right side of the comparison
951
+ * @returns An expression representing the comparison
952
+ */
953
+ _exports.notEqual = notEqual;
954
+ function greaterOrEqual(leftOperand, rightOperand) {
955
+ return comparison(">=", leftOperand, rightOperand);
956
+ }
957
+
958
+ /**
959
+ * Comparison: "greater than" (>).
960
+ *
961
+ * @template T The target type
962
+ * @param leftOperand The operand on the left side
963
+ * @param rightOperand The operand on the right side of the comparison
964
+ * @returns An expression representing the comparison
965
+ */
966
+ _exports.greaterOrEqual = greaterOrEqual;
967
+ function greaterThan(leftOperand, rightOperand) {
968
+ return comparison(">", leftOperand, rightOperand);
969
+ }
970
+
971
+ /**
972
+ * Comparison: "less or equal" (<=).
973
+ *
974
+ * @template T The target type
975
+ * @param leftOperand The operand on the left side
976
+ * @param rightOperand The operand on the right side of the comparison
977
+ * @returns An expression representing the comparison
978
+ */
979
+ _exports.greaterThan = greaterThan;
980
+ function lessOrEqual(leftOperand, rightOperand) {
981
+ return comparison("<=", leftOperand, rightOperand);
982
+ }
983
+
984
+ /**
985
+ * Comparison: "less than" (<).
986
+ *
987
+ * @template T The target type
988
+ * @param leftOperand The operand on the left side
989
+ * @param rightOperand The operand on the right side of the comparison
990
+ * @returns An expression representing the comparison
991
+ */
992
+ _exports.lessOrEqual = lessOrEqual;
993
+ function lessThan(leftOperand, rightOperand) {
994
+ return comparison("<", leftOperand, rightOperand);
995
+ }
996
+
997
+ /**
998
+ * If-then-else expression.
999
+ *
1000
+ * Evaluates to onTrue if the condition evaluates to true, else evaluates to onFalse.
1001
+ *
1002
+ * @template T The target type
1003
+ * @param condition The condition to evaluate
1004
+ * @param onTrue Expression result if the condition evaluates to true
1005
+ * @param onFalse Expression result if the condition evaluates to false
1006
+ * @returns The expression that represents this conditional check
1007
+ */
1008
+ _exports.lessThan = lessThan;
1009
+ function ifElse(condition, onTrue, onFalse) {
1010
+ let conditionExpression = wrapPrimitive(condition);
1011
+ let onTrueExpression = wrapPrimitive(onTrue);
1012
+ let onFalseExpression = wrapPrimitive(onFalse);
1013
+
1014
+ // swap branches if the condition is a negation
1015
+ if (conditionExpression._type === "Not") {
1016
+ // ifElse(not(X), a, b) --> ifElse(X, b, a)
1017
+ [onTrueExpression, onFalseExpression] = [onFalseExpression, onTrueExpression];
1018
+ conditionExpression = not(conditionExpression);
1019
+ }
1020
+
1021
+ // inline nested if-else expressions: onTrue branch
1022
+ // ifElse(X, ifElse(X, a, b), c) ==> ifElse(X, a, c)
1023
+ if (onTrueExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onTrueExpression.condition)) {
1024
+ onTrueExpression = onTrueExpression.onTrue;
1025
+ }
1026
+
1027
+ // inline nested if-else expressions: onFalse branch
1028
+ // ifElse(X, a, ifElse(X, b, c)) ==> ifElse(X, a, c)
1029
+ if (onFalseExpression._type === "IfElse" && _checkExpressionsAreEqual(conditionExpression, onFalseExpression.condition)) {
1030
+ onFalseExpression = onFalseExpression.onFalse;
1031
+ }
1032
+
1033
+ // (if true then a else b) ~~> a
1034
+ // (if false then a else b) ~~> b
1035
+ if (isConstant(conditionExpression)) {
1036
+ return conditionExpression.value ? onTrueExpression : onFalseExpression;
1037
+ }
1038
+
1039
+ // if (isConstantBoolean(onTrueExpression) || isConstantBoolean(onFalseExpression)) {
1040
+ // return or(and(condition, onTrueExpression as Expression<boolean>), and(not(condition), onFalseExpression as Expression<boolean>)) as Expression<T>
1041
+ // }
1042
+
1043
+ // (if X then a else a) ~~> a
1044
+ if (_checkExpressionsAreEqual(onTrueExpression, onFalseExpression)) {
1045
+ return onTrueExpression;
1046
+ }
1047
+
1048
+ // if X then a else false ~~> X && a
1049
+ if (isFalse(onFalseExpression)) {
1050
+ return and(conditionExpression, onTrueExpression);
1051
+ }
1052
+
1053
+ // if X then a else true ~~> !X || a
1054
+ if (isTrue(onFalseExpression)) {
1055
+ return or(not(conditionExpression), onTrueExpression);
1056
+ }
1057
+
1058
+ // if X then false else a ~~> !X && a
1059
+ if (isFalse(onTrueExpression)) {
1060
+ return and(not(conditionExpression), onFalseExpression);
1061
+ }
1062
+
1063
+ // if X then true else a ~~> X || a
1064
+ if (isTrue(onTrueExpression)) {
1065
+ return or(conditionExpression, onFalseExpression);
1066
+ }
1067
+ if (hasUnresolvableExpression(conditionExpression, onTrueExpression, onFalseExpression)) {
1068
+ return unresolvableExpression;
1069
+ }
1070
+ if (isComplexTypeExpression(condition) || isComplexTypeExpression(onTrue) || isComplexTypeExpression(onFalse)) {
1071
+ let pathIdx = 0;
1072
+ const myIfElseExpression = formatResult([condition, onTrue, onFalse], "sap.fe.core.formatters.StandardFormatter#ifElse");
1073
+ const allParts = [];
1074
+ transformRecursively(myIfElseExpression, "PathInModel", constantPath => {
1075
+ allParts.push(constantPath);
1076
+ return pathInModel(`$${pathIdx++}`, "$");
1077
+ }, true);
1078
+ allParts.unshift(constant(JSON.stringify(myIfElseExpression)));
1079
+ return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
1080
+ }
1081
+ return {
1082
+ _type: "IfElse",
1083
+ condition: conditionExpression,
1084
+ onTrue: onTrueExpression,
1085
+ onFalse: onFalseExpression
1086
+ };
1087
+ }
1088
+
1089
+ /**
1090
+ * Checks whether the current expression has a reference to the default model (undefined).
1091
+ *
1092
+ * @param expression The expression to evaluate
1093
+ * @returns `true` if there is a reference to the default context
1094
+ */
1095
+ _exports.ifElse = ifElse;
1096
+ function hasReferenceToDefaultContext(expression) {
1097
+ switch (expression._type) {
1098
+ case "Constant":
1099
+ case "Formatter":
1100
+ case "ComplexType":
1101
+ return false;
1102
+ case "Set":
1103
+ return expression.operands.some(hasReferenceToDefaultContext);
1104
+ case "PathInModel":
1105
+ return expression.modelName === undefined;
1106
+ case "Comparison":
1107
+ return hasReferenceToDefaultContext(expression.operand1) || hasReferenceToDefaultContext(expression.operand2);
1108
+ case "IfElse":
1109
+ return hasReferenceToDefaultContext(expression.condition) || hasReferenceToDefaultContext(expression.onTrue) || hasReferenceToDefaultContext(expression.onFalse);
1110
+ case "Not":
1111
+ case "Truthy":
1112
+ return hasReferenceToDefaultContext(expression.operand);
1113
+ default:
1114
+ return false;
1115
+ }
1116
+ }
1117
+
1118
+ // This is one case where any does make sense...
1119
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1120
+
1121
+ /**
1122
+ * Calls a formatter function to process the parameters.
1123
+ * If requireContext is set to true and no context is passed a default context will be added automatically.
1124
+ *
1125
+ * @template T
1126
+ * @template U
1127
+ * @param parameters The list of parameter that should match the type and number of the formatter function
1128
+ * @param formatterFunction The function to call
1129
+ * @param [contextEntityType] If no parameter refers to the context then we use this information to add a reference to the keys from the entity type.
1130
+ * @param [ignoreComplexType] Whether to ignore the transgformation to the StandardFormatter or not
1131
+ * @returns The corresponding expression
1132
+ */
1133
+ function formatResult(parameters, formatterFunction, contextEntityType) {
1134
+ let ignoreComplexType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1135
+ const parameterExpressions = parameters.map(wrapPrimitive);
1136
+ if (hasUnresolvableExpression(...parameterExpressions)) {
1137
+ return unresolvableExpression;
1138
+ }
1139
+ if (contextEntityType) {
1140
+ // Otherwise, if the context is required and no context is provided make sure to add the default binding
1141
+ if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
1142
+ contextEntityType.keys.forEach(key => parameterExpressions.push(pathInModel(key.name, "")));
1143
+ }
1144
+ }
1145
+ let functionName = "";
1146
+ if (typeof formatterFunction === "string") {
1147
+ functionName = formatterFunction;
1148
+ } else {
1149
+ functionName = formatterFunction.__functionName;
1150
+ }
1151
+ // FormatterName can be of format sap.fe.core.xxx#methodName to have multiple formatter in one class
1152
+ const [formatterClass, formatterName] = functionName.split("#");
1153
+
1154
+ // In some case we also cannot call directly a function because of too complex input, in that case we need to convert to a simpler function call
1155
+ if (!ignoreComplexType && (parameterExpressions.some(isComplexTypeExpression) || parameterExpressions.some(isConcatExpression) || parameterExpressions.some(isIfElseExpression))) {
1156
+ let pathIdx = 0;
1157
+ const myFormatExpression = formatResult(parameterExpressions, functionName, undefined, true);
1158
+ const allParts = [];
1159
+ transformRecursively(myFormatExpression, "PathInModel", constantPath => {
1160
+ allParts.push(constantPath);
1161
+ return pathInModel(`$${pathIdx++}`, "$");
1162
+ }, true);
1163
+ allParts.unshift(constant(JSON.stringify(myFormatExpression)));
1164
+ return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
1165
+ } else if (!!formatterName && formatterName.length > 0) {
1166
+ parameterExpressions.unshift(constant(formatterName));
1167
+ }
1168
+ return {
1169
+ _type: "Formatter",
1170
+ fn: formatterClass,
1171
+ parameters: parameterExpressions
1172
+ };
1173
+ }
1174
+ _exports.formatResult = formatResult;
1175
+ function setUpConstraints(targetMapping, property) {
1176
+ var _targetMapping$constr, _targetMapping$constr2, _targetMapping$constr3, _targetMapping$constr4, _property$annotations, _property$annotations2, _targetMapping$constr5, _property$annotations5, _property$annotations6, _property$annotations9, _property$annotations10, _targetMapping$constr6, _targetMapping$constr7;
1177
+ const constraints = {};
1178
+ if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr = targetMapping.constraints) !== null && _targetMapping$constr !== void 0 && _targetMapping$constr.$Scale && property.scale !== undefined) {
1179
+ constraints.scale = property.scale;
1180
+ }
1181
+ if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr2 = targetMapping.constraints) !== null && _targetMapping$constr2 !== void 0 && _targetMapping$constr2.$Precision && property.precision !== undefined) {
1182
+ constraints.precision = property.precision;
1183
+ }
1184
+ if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr3 = targetMapping.constraints) !== null && _targetMapping$constr3 !== void 0 && _targetMapping$constr3.$MaxLength && property.maxLength !== undefined) {
1185
+ constraints.maxLength = property.maxLength;
1186
+ }
1187
+ if (property.nullable === false) {
1188
+ constraints.nullable = false;
1189
+ }
1190
+ if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr4 = targetMapping.constraints) !== null && _targetMapping$constr4 !== void 0 && _targetMapping$constr4["@Org.OData.Validation.V1.Minimum/$Decimal"] && !isNaN((_property$annotations = property.annotations) === null || _property$annotations === void 0 ? void 0 : (_property$annotations2 = _property$annotations.Validation) === null || _property$annotations2 === void 0 ? void 0 : _property$annotations2.Minimum)) {
1191
+ var _property$annotations3, _property$annotations4;
1192
+ constraints.minimum = `${(_property$annotations3 = property.annotations) === null || _property$annotations3 === void 0 ? void 0 : (_property$annotations4 = _property$annotations3.Validation) === null || _property$annotations4 === void 0 ? void 0 : _property$annotations4.Minimum}`;
1193
+ }
1194
+ if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr5 = targetMapping.constraints) !== null && _targetMapping$constr5 !== void 0 && _targetMapping$constr5["@Org.OData.Validation.V1.Maximum/$Decimal"] && !isNaN((_property$annotations5 = property.annotations) === null || _property$annotations5 === void 0 ? void 0 : (_property$annotations6 = _property$annotations5.Validation) === null || _property$annotations6 === void 0 ? void 0 : _property$annotations6.Maximum)) {
1195
+ var _property$annotations7, _property$annotations8;
1196
+ constraints.maximum = `${(_property$annotations7 = property.annotations) === null || _property$annotations7 === void 0 ? void 0 : (_property$annotations8 = _property$annotations7.Validation) === null || _property$annotations8 === void 0 ? void 0 : _property$annotations8.Maximum}`;
1197
+ }
1198
+ if ((_property$annotations9 = property.annotations) !== null && _property$annotations9 !== void 0 && (_property$annotations10 = _property$annotations9.Common) !== null && _property$annotations10 !== void 0 && _property$annotations10.IsDigitSequence && targetMapping.type === "sap.ui.model.odata.type.String" && targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr6 = targetMapping.constraints) !== null && _targetMapping$constr6 !== void 0 && _targetMapping$constr6["@com.sap.vocabularies.Common.v1.IsDigitSequence"]) {
1199
+ constraints.isDigitSequence = true;
1200
+ }
1201
+ if (targetMapping !== null && targetMapping !== void 0 && (_targetMapping$constr7 = targetMapping.constraints) !== null && _targetMapping$constr7 !== void 0 && _targetMapping$constr7.$V4) {
1202
+ constraints.V4 = true;
1203
+ }
1204
+ return constraints;
1205
+ }
1206
+
1207
+ /**
1208
+ * Generates the binding expression for the property, and sets up the formatOptions and constraints.
1209
+ *
1210
+ * @param property The Property for which we are setting up the binding
1211
+ * @param propertyBindingExpression The BindingExpression of the property above. Serves as the basis to which information can be added
1212
+ * @param ignoreConstraints Ignore constraints of the property
1213
+ * @returns The binding expression for the property with formatOptions and constraints
1214
+ */
1215
+ _exports.setUpConstraints = setUpConstraints;
1216
+ function formatWithTypeInformation(property, propertyBindingExpression) {
1217
+ var _outExpression$type, _outExpression$constr3, _outExpression$constr4;
1218
+ let ignoreConstraints = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1219
+ const outExpression = propertyBindingExpression;
1220
+ if (property._type !== "Property" && property._type !== "ActionParameter") {
1221
+ return outExpression;
1222
+ }
1223
+ const targetMapping = EDM_TYPE_MAPPING[property.type];
1224
+ if (!targetMapping) {
1225
+ return outExpression;
1226
+ }
1227
+ if (!outExpression.formatOptions) {
1228
+ outExpression.formatOptions = {};
1229
+ }
1230
+ outExpression.constraints = {};
1231
+ outExpression.type = targetMapping.type;
1232
+ if (!ignoreConstraints) {
1233
+ outExpression.constraints = setUpConstraints(targetMapping, property);
1234
+ }
1235
+ if ((outExpression === null || outExpression === void 0 ? void 0 : (_outExpression$type = outExpression.type) === null || _outExpression$type === void 0 ? void 0 : _outExpression$type.indexOf("sap.ui.model.odata.type.Int")) === 0 && (outExpression === null || outExpression === void 0 ? void 0 : outExpression.type) !== "sap.ui.model.odata.type.Int64" || (outExpression === null || outExpression === void 0 ? void 0 : outExpression.type) === "sap.ui.model.odata.type.Double") {
1236
+ outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
1237
+ parseAsString: false
1238
+ });
1239
+ }
1240
+ if (outExpression.type === "sap.ui.model.odata.type.String" && isProperty(property)) {
1241
+ var _outExpression$constr, _outExpression$constr2;
1242
+ if (!((_outExpression$constr = outExpression.constraints) !== null && _outExpression$constr !== void 0 && _outExpression$constr.isDigitSequence) || ((_outExpression$constr2 = outExpression.constraints) === null || _outExpression$constr2 === void 0 ? void 0 : _outExpression$constr2.nullable) === false) {
1243
+ outExpression.formatOptions.parseKeepsEmptyString = true;
1244
+ }
1245
+ const fiscalType = getFiscalType(property);
1246
+ if (fiscalType) {
1247
+ outExpression.formatOptions.fiscalType = fiscalType;
1248
+ outExpression.type = "sap.fe.core.type.FiscalDate";
1249
+ }
1250
+ }
1251
+ const typesSupportingParseEmptyValueToZero = ["sap.ui.model.odata.type.Int16", "sap.ui.model.odata.type.Int32", "sap.ui.model.odata.type.Int64", "sap.ui.model.odata.type.Single", "sap.ui.model.odata.type.Double", "sap.ui.model.odata.type.Decimal", "sap.ui.model.odata.type.Byte", "sap.ui.model.odata.type.SByte"];
1252
+ if (((_outExpression$constr3 = outExpression.constraints) === null || _outExpression$constr3 === void 0 ? void 0 : _outExpression$constr3.nullable) === false && outExpression.type && typesSupportingParseEmptyValueToZero.includes(outExpression.type)) {
1253
+ outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
1254
+ parseEmptyValueToZero: true
1255
+ });
1256
+ }
1257
+ if (((_outExpression$constr4 = outExpression.constraints) === null || _outExpression$constr4 === void 0 ? void 0 : _outExpression$constr4.nullable) !== false && (outExpression.type === "sap.ui.model.odata.type.Int64" || outExpression.type === "sap.ui.model.odata.type.Decimal")) {
1258
+ outExpression.formatOptions = Object.assign(outExpression.formatOptions, {
1259
+ emptyString: ""
1260
+ });
1261
+ }
1262
+ return outExpression;
1263
+ }
1264
+ _exports.formatWithTypeInformation = formatWithTypeInformation;
1265
+ const getFiscalType = function (property) {
1266
+ var _property$annotations11, _property$annotations12, _property$annotations13, _property$annotations14, _property$annotations15, _property$annotations16, _property$annotations17, _property$annotations18, _property$annotations19, _property$annotations20, _property$annotations21, _property$annotations22, _property$annotations23, _property$annotations24, _property$annotations25, _property$annotations26;
1267
+ if ((_property$annotations11 = property.annotations) !== null && _property$annotations11 !== void 0 && (_property$annotations12 = _property$annotations11.Common) !== null && _property$annotations12 !== void 0 && _property$annotations12.IsFiscalYear) {
1268
+ return "com.sap.vocabularies.Common.v1.IsFiscalYear";
1269
+ }
1270
+ if ((_property$annotations13 = property.annotations) !== null && _property$annotations13 !== void 0 && (_property$annotations14 = _property$annotations13.Common) !== null && _property$annotations14 !== void 0 && _property$annotations14.IsFiscalPeriod) {
1271
+ return "com.sap.vocabularies.Common.v1.IsFiscalPeriod";
1272
+ }
1273
+ if ((_property$annotations15 = property.annotations) !== null && _property$annotations15 !== void 0 && (_property$annotations16 = _property$annotations15.Common) !== null && _property$annotations16 !== void 0 && _property$annotations16.IsFiscalYearPeriod) {
1274
+ return "com.sap.vocabularies.Common.v1.IsFiscalYearPeriod";
1275
+ }
1276
+ if ((_property$annotations17 = property.annotations) !== null && _property$annotations17 !== void 0 && (_property$annotations18 = _property$annotations17.Common) !== null && _property$annotations18 !== void 0 && _property$annotations18.IsFiscalQuarter) {
1277
+ return "com.sap.vocabularies.Common.v1.IsFiscalQuarter";
1278
+ }
1279
+ if ((_property$annotations19 = property.annotations) !== null && _property$annotations19 !== void 0 && (_property$annotations20 = _property$annotations19.Common) !== null && _property$annotations20 !== void 0 && _property$annotations20.IsFiscalYearQuarter) {
1280
+ return "com.sap.vocabularies.Common.v1.IsFiscalYearQuarter";
1281
+ }
1282
+ if ((_property$annotations21 = property.annotations) !== null && _property$annotations21 !== void 0 && (_property$annotations22 = _property$annotations21.Common) !== null && _property$annotations22 !== void 0 && _property$annotations22.IsFiscalWeek) {
1283
+ return "com.sap.vocabularies.Common.v1.IsFiscalWeek";
1284
+ }
1285
+ if ((_property$annotations23 = property.annotations) !== null && _property$annotations23 !== void 0 && (_property$annotations24 = _property$annotations23.Common) !== null && _property$annotations24 !== void 0 && _property$annotations24.IsFiscalYearWeek) {
1286
+ return "com.sap.vocabularies.Common.v1.IsFiscalYearWeek";
1287
+ }
1288
+ if ((_property$annotations25 = property.annotations) !== null && _property$annotations25 !== void 0 && (_property$annotations26 = _property$annotations25.Common) !== null && _property$annotations26 !== void 0 && _property$annotations26.IsDayOfFiscalYear) {
1289
+ return "com.sap.vocabularies.Common.v1.IsDayOfFiscalYear";
1290
+ }
1291
+ };
1292
+
1293
+ /**
1294
+ * Calls a complex type to process the parameters.
1295
+ * If requireContext is set to true and no context is passed, a default context will be added automatically.
1296
+ *
1297
+ * @template T
1298
+ * @template U
1299
+ * @param parameters The list of parameters that should match the type for the complex type=
1300
+ * @param type The complex type to use
1301
+ * @param [contextEntityType] The context entity type to consider
1302
+ * @param oFormatOptions
1303
+ * @returns The corresponding expression
1304
+ */
1305
+ _exports.getFiscalType = getFiscalType;
1306
+ function addTypeInformation(parameters, type, contextEntityType, oFormatOptions) {
1307
+ const parameterExpressions = parameters.map(wrapPrimitive);
1308
+ if (hasUnresolvableExpression(...parameterExpressions)) {
1309
+ return unresolvableExpression;
1310
+ }
1311
+ // If there is only one parameter and it is a constant and we don't expect the context then return the constant
1312
+ if (parameterExpressions.length === 1 && isConstant(parameterExpressions[0]) && !contextEntityType) {
1313
+ return parameterExpressions[0];
1314
+ } else if (contextEntityType) {
1315
+ // Otherwise, if the context is required and no context is provided make sure to add the default binding
1316
+ if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
1317
+ contextEntityType.keys.forEach(key => parameterExpressions.push(pathInModel(key.name, "")));
1318
+ }
1319
+ }
1320
+ oFormatOptions = _getComplexTypeFormatOptionsFromFirstParam(parameters[0], oFormatOptions);
1321
+ if (type === "sap.ui.model.odata.type.Unit") {
1322
+ const uomPath = pathInModel("/##@@requestUnitsOfMeasure");
1323
+ uomPath.targetType = "any";
1324
+ uomPath.mode = "OneTime";
1325
+ parameterExpressions.push(uomPath);
1326
+ } else if (type === "sap.ui.model.odata.type.Currency") {
1327
+ const currencyPath = pathInModel("/##@@requestCurrencyCodes");
1328
+ currencyPath.targetType = "any";
1329
+ currencyPath.mode = "OneTime";
1330
+ parameterExpressions.push(currencyPath);
1331
+ }
1332
+ return {
1333
+ _type: "ComplexType",
1334
+ type: type,
1335
+ formatOptions: oFormatOptions || {},
1336
+ parameters: {},
1337
+ bindingParameters: parameterExpressions
1338
+ };
1339
+ }
1340
+ _exports.addTypeInformation = addTypeInformation;
1341
+ /**
1342
+ * Process the formatOptions for a complexType based on the first parameter.
1343
+ *
1344
+ * @param param The first parameter of the complex type
1345
+ * @param formatOptions Initial formatOptions
1346
+ * @returns The modified formatOptions
1347
+ */
1348
+ function _getComplexTypeFormatOptionsFromFirstParam(param, formatOptions) {
1349
+ var _param$type;
1350
+ // if showMeasure is set to false we want to not parse as string to see the 0
1351
+ // we do that also for all bindings because otherwise the mdc Field isn't editable
1352
+ if (!(formatOptions && formatOptions.showNumber === false) && ((param === null || param === void 0 ? void 0 : (_param$type = param.type) === null || _param$type === void 0 ? void 0 : _param$type.indexOf("sap.ui.model.odata.type.Int")) === 0 || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Decimal" || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Double")) {
1353
+ if ((param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Int64" || (param === null || param === void 0 ? void 0 : param.type) === "sap.ui.model.odata.type.Decimal") {
1354
+ var _formatOptions;
1355
+ //sap.ui.model.odata.type.Int64 do not support parseAsString false
1356
+ formatOptions = ((_formatOptions = formatOptions) === null || _formatOptions === void 0 ? void 0 : _formatOptions.showMeasure) === false ? {
1357
+ showMeasure: false
1358
+ } : {};
1359
+ } else {
1360
+ var _formatOptions2;
1361
+ formatOptions = ((_formatOptions2 = formatOptions) === null || _formatOptions2 === void 0 ? void 0 : _formatOptions2.showMeasure) === false ? {
1362
+ parseAsString: false,
1363
+ showMeasure: false
1364
+ } : {
1365
+ parseAsString: false
1366
+ };
1367
+ }
1368
+ formatOptions.emptyString = null;
1369
+ }
1370
+ return formatOptions;
1371
+ }
1372
+ /**
1373
+ * Function call, optionally with arguments.
1374
+ *
1375
+ * @param func Function name or reference to function
1376
+ * @param parameters Arguments
1377
+ * @param on Object to call the function on
1378
+ * @param isFormattingFn
1379
+ * @returns Expression representing the function call (not the result of the function call!)
1380
+ */
1381
+ function fn(func, parameters, on) {
1382
+ let isFormattingFn = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1383
+ const functionName = typeof func === "string" ? func : func.__functionName;
1384
+ return {
1385
+ _type: "Function",
1386
+ obj: on !== undefined ? wrapPrimitive(on) : undefined,
1387
+ fn: functionName,
1388
+ isFormattingFn: isFormattingFn,
1389
+ parameters: parameters.map(wrapPrimitive)
1390
+ };
1391
+ }
1392
+
1393
+ /**
1394
+ * Shortcut function to determine if a binding value is null, undefined or empty.
1395
+ *
1396
+ * @param expression
1397
+ * @returns A Boolean expression evaluating the fact that the current element is empty
1398
+ */
1399
+ _exports.fn = fn;
1400
+ function isEmpty(expression) {
1401
+ const aBindings = [];
1402
+ transformRecursively(expression, "PathInModel", expr => {
1403
+ aBindings.push(or(equal(expr, ""), equal(expr, undefined), equal(expr, null)));
1404
+ return expr;
1405
+ });
1406
+ return and(...aBindings);
1407
+ }
1408
+ _exports.isEmpty = isEmpty;
1409
+ function concat() {
1410
+ for (var _len4 = arguments.length, inExpressions = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
1411
+ inExpressions[_key4] = arguments[_key4];
1412
+ }
1413
+ const expressions = inExpressions.map(wrapPrimitive);
1414
+ if (hasUnresolvableExpression(...expressions)) {
1415
+ return unresolvableExpression;
1416
+ }
1417
+ if (expressions.every(isConstant)) {
1418
+ return constant(expressions.reduce((concatenated, value) => {
1419
+ if (value.value !== undefined && value.value !== null) {
1420
+ return concatenated + value.value.toString();
1421
+ }
1422
+ return concatenated;
1423
+ }, ""));
1424
+ } else if (expressions.some(isComplexTypeExpression)) {
1425
+ let pathIdx = 0;
1426
+ const myConcatExpression = formatResult(expressions, "sap.fe.core.formatters.StandardFormatter#concat", undefined, true);
1427
+ const allParts = [];
1428
+ transformRecursively(myConcatExpression, "PathInModel", constantPath => {
1429
+ allParts.push(constantPath);
1430
+ return pathInModel(`$${pathIdx++}`, "$");
1431
+ });
1432
+ allParts.unshift(constant(JSON.stringify(myConcatExpression)));
1433
+ return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression", undefined, true);
1434
+ }
1435
+ return {
1436
+ _type: "Concat",
1437
+ expressions: expressions
1438
+ };
1439
+ }
1440
+ _exports.concat = concat;
1441
+ function transformRecursively(inExpression, expressionType, transformFunction) {
1442
+ let includeAllExpression = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1443
+ let expression = inExpression;
1444
+ switch (expression._type) {
1445
+ case "Function":
1446
+ case "Formatter":
1447
+ expression.parameters = expression.parameters.map(parameter => transformRecursively(parameter, expressionType, transformFunction, includeAllExpression));
1448
+ break;
1449
+ case "Concat":
1450
+ expression.expressions = expression.expressions.map(subExpression => transformRecursively(subExpression, expressionType, transformFunction, includeAllExpression));
1451
+ expression = concat(...expression.expressions);
1452
+ break;
1453
+ case "ComplexType":
1454
+ expression.bindingParameters = expression.bindingParameters.map(bindingParameter => transformRecursively(bindingParameter, expressionType, transformFunction, includeAllExpression));
1455
+ break;
1456
+ case "IfElse":
1457
+ const onTrue = transformRecursively(expression.onTrue, expressionType, transformFunction, includeAllExpression);
1458
+ const onFalse = transformRecursively(expression.onFalse, expressionType, transformFunction, includeAllExpression);
1459
+ let condition = expression.condition;
1460
+ if (includeAllExpression) {
1461
+ condition = transformRecursively(expression.condition, expressionType, transformFunction, includeAllExpression);
1462
+ }
1463
+ expression = ifElse(condition, onTrue, onFalse);
1464
+ break;
1465
+ case "Not":
1466
+ if (includeAllExpression) {
1467
+ const operand = transformRecursively(expression.operand, expressionType, transformFunction, includeAllExpression);
1468
+ expression = not(operand);
1469
+ }
1470
+ break;
1471
+ case "Truthy":
1472
+ break;
1473
+ case "Set":
1474
+ if (includeAllExpression) {
1475
+ const operands = expression.operands.map(operand => transformRecursively(operand, expressionType, transformFunction, includeAllExpression));
1476
+ expression = expression.operator === "||" ? or(...operands) : and(...operands);
1477
+ }
1478
+ break;
1479
+ case "Comparison":
1480
+ if (includeAllExpression) {
1481
+ const operand1 = transformRecursively(expression.operand1, expressionType, transformFunction, includeAllExpression);
1482
+ const operand2 = transformRecursively(expression.operand2, expressionType, transformFunction, includeAllExpression);
1483
+ expression = comparison(expression.operator, operand1, operand2);
1484
+ }
1485
+ break;
1486
+ case "Constant":
1487
+ const constantValue = expression.value;
1488
+ if (typeof constantValue === "object" && constantValue) {
1489
+ Object.keys(constantValue).forEach(key => {
1490
+ constantValue[key] = transformRecursively(constantValue[key], expressionType, transformFunction, includeAllExpression);
1491
+ });
1492
+ }
1493
+ break;
1494
+ case "Ref":
1495
+ case "Length":
1496
+ case "PathInModel":
1497
+ case "EmbeddedBinding":
1498
+ case "EmbeddedExpressionBinding":
1499
+ case "Unresolvable":
1500
+ // Do nothing
1501
+ break;
1502
+ }
1503
+ if (expressionType === expression._type) {
1504
+ expression = transformFunction(inExpression);
1505
+ }
1506
+ return expression;
1507
+ }
1508
+ _exports.transformRecursively = transformRecursively;
1509
+ const needParenthesis = function (expr) {
1510
+ return !isConstant(expr) && !isPathInModelExpression(expr) && isBindingToolkitExpression(expr) && expr._type !== "IfElse" && expr._type !== "Function";
1511
+ };
1512
+
1513
+ /**
1514
+ * Compiles a constant object to a string.
1515
+ *
1516
+ * @param expr
1517
+ * @param isNullable
1518
+ * @returns The compiled string
1519
+ */
1520
+ function compileConstantObject(expr) {
1521
+ let isNullable = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1522
+ if (isNullable && Object.keys(expr.value).length === 0) {
1523
+ return "";
1524
+ }
1525
+ const objects = expr.value;
1526
+ const properties = [];
1527
+ Object.keys(objects).forEach(key => {
1528
+ const value = objects[key];
1529
+ const childResult = compileExpression(value, true, false, isNullable);
1530
+ if (childResult && childResult.length > 0) {
1531
+ properties.push(`${key}: ${childResult}`);
1532
+ }
1533
+ });
1534
+ return `{${properties.join(", ")}}`;
1535
+ }
1536
+
1537
+ /**
1538
+ * Compiles a Constant Binding Expression.
1539
+ *
1540
+ * @param expr
1541
+ * @param embeddedInBinding
1542
+ * @param isNullable
1543
+ * @param doNotStringify
1544
+ * @returns The compiled string
1545
+ */
1546
+
1547
+ function compileConstant(expr, embeddedInBinding) {
1548
+ let isNullable = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1549
+ let doNotStringify = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1550
+ if (expr.value === null) {
1551
+ return doNotStringify ? null : "null";
1552
+ }
1553
+ if (expr.value === undefined) {
1554
+ return doNotStringify ? undefined : "undefined";
1555
+ }
1556
+ if (typeof expr.value === "object") {
1557
+ if (Array.isArray(expr.value)) {
1558
+ const entries = expr.value.map(expression => compileExpression(expression, true));
1559
+ return `[${entries.join(", ")}]`;
1560
+ } else {
1561
+ return compileConstantObject(expr, isNullable);
1562
+ }
1563
+ }
1564
+ if (embeddedInBinding) {
1565
+ switch (typeof expr.value) {
1566
+ case "number":
1567
+ case "bigint":
1568
+ case "boolean":
1569
+ return expr.value.toString();
1570
+ case "string":
1571
+ return `'${escapeXmlAttribute(expr.value.toString())}'`;
1572
+ default:
1573
+ return "";
1574
+ }
1575
+ } else {
1576
+ return doNotStringify ? expr.value : expr.value.toString();
1577
+ }
1578
+ }
1579
+
1580
+ /**
1581
+ * Generates the binding string for a Binding expression.
1582
+ *
1583
+ * @param expressionForBinding The expression to compile
1584
+ * @param embeddedInBinding Whether the expression to compile is embedded into another expression
1585
+ * @param embeddedSeparator The binding value evaluator ($ or % depending on whether we want to force the type or not)
1586
+ * @returns The corresponding expression binding
1587
+ */
1588
+ _exports.compileConstant = compileConstant;
1589
+ function compilePathInModelExpression(expressionForBinding, embeddedInBinding, embeddedSeparator) {
1590
+ if (expressionForBinding.type || expressionForBinding.parameters || expressionForBinding.targetType || expressionForBinding.formatOptions || expressionForBinding.constraints) {
1591
+ // This is now a complex binding definition, let's prepare for it
1592
+ const complexBindingDefinition = {
1593
+ path: compilePathInModel(expressionForBinding),
1594
+ type: expressionForBinding.type,
1595
+ targetType: expressionForBinding.targetType,
1596
+ parameters: expressionForBinding.parameters,
1597
+ formatOptions: expressionForBinding.formatOptions,
1598
+ constraints: expressionForBinding.constraints
1599
+ };
1600
+ const outBinding = compileExpression(complexBindingDefinition, false, false, true);
1601
+ if (embeddedInBinding) {
1602
+ return `${embeddedSeparator}${outBinding}`;
1603
+ }
1604
+ return outBinding;
1605
+ } else if (embeddedInBinding) {
1606
+ return `${embeddedSeparator}{${compilePathInModel(expressionForBinding)}}`;
1607
+ } else {
1608
+ return `{${compilePathInModel(expressionForBinding)}}`;
1609
+ }
1610
+ }
1611
+ function compileComplexTypeExpression(expression) {
1612
+ if (expression.bindingParameters.length === 1) {
1613
+ return `{${compilePathParameter(expression.bindingParameters[0], true)}, type: '${expression.type}'}`;
1614
+ }
1615
+ let outputEnd = `], type: '${expression.type}'`;
1616
+ if (hasElements(expression.formatOptions)) {
1617
+ outputEnd += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
1618
+ }
1619
+ if (hasElements(expression.parameters)) {
1620
+ outputEnd += `, parameters: ${compileExpression(expression.parameters)}`;
1621
+ }
1622
+ outputEnd += "}";
1623
+ return `{mode:'TwoWay', parts:[${expression.bindingParameters.map(param => compilePathParameter(param)).join(",")}${outputEnd}`;
1624
+ }
1625
+
1626
+ /**
1627
+ * Wrap the compiled binding string as required depending on its context.
1628
+ *
1629
+ * @param expression The compiled expression
1630
+ * @param embeddedInBinding True if the compiled expression is to be embedded in a binding
1631
+ * @param parenthesisRequired True if the embedded binding needs to be wrapped in parethesis so that it is evaluated as one
1632
+ * @returns Finalized compiled expression
1633
+ */
1634
+ function wrapBindingExpression(expression, embeddedInBinding) {
1635
+ let parenthesisRequired = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1636
+ if (embeddedInBinding) {
1637
+ if (parenthesisRequired) {
1638
+ return `(${expression})`;
1639
+ } else {
1640
+ return expression;
1641
+ }
1642
+ } else {
1643
+ return `{= ${expression}}`;
1644
+ }
1645
+ }
1646
+
1647
+ /**
1648
+ * Compile an expression into an expression binding.
1649
+ *
1650
+ * @template T The target type
1651
+ * @param expression The expression to compile
1652
+ * @param embeddedInBinding Whether the expression to compile is embedded into another expression
1653
+ * @param keepTargetType Keep the target type of the embedded bindings instead of casting them to any
1654
+ * @param isNullable Whether binding expression can resolve to empty string or not
1655
+ * @returns The corresponding expression binding
1656
+ */
1657
+ _exports.wrapBindingExpression = wrapBindingExpression;
1658
+ function compileExpression(expression) {
1659
+ let embeddedInBinding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1660
+ let keepTargetType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1661
+ let isNullable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1662
+ const expr = wrapPrimitive(expression);
1663
+ const embeddedSeparator = keepTargetType ? "$" : "%";
1664
+ switch (expr._type) {
1665
+ case "Unresolvable":
1666
+ return undefined;
1667
+ case "Constant":
1668
+ return compileConstant(expr, embeddedInBinding, isNullable);
1669
+ case "Ref":
1670
+ return expr.ref || "null";
1671
+ case "Function":
1672
+ let hasEmbeddedFunctionCallOrBinding = false;
1673
+ if (expr.isFormattingFn) {
1674
+ transformRecursively(expr, "Function", subFn => {
1675
+ if (subFn !== expr && subFn.obj === undefined) {
1676
+ hasEmbeddedFunctionCallOrBinding = true;
1677
+ }
1678
+ return subFn;
1679
+ }, true);
1680
+ transformRecursively(expr, "Constant", subFn => {
1681
+ if (subFn !== expr && typeof subFn.value === "object") {
1682
+ transformRecursively(subFn, "PathInModel", subSubFn => {
1683
+ hasEmbeddedFunctionCallOrBinding = true;
1684
+ return subSubFn;
1685
+ });
1686
+ }
1687
+ return subFn;
1688
+ }, true);
1689
+ }
1690
+ const argumentString = `${expr.parameters.map(arg => compileExpression(arg, true)).join(", ")}`;
1691
+ let fnCall = expr.obj === undefined ? `${expr.fn}(${argumentString})` : `${compileExpression(expr.obj, true)}.${expr.fn}(${argumentString})`;
1692
+ if (!embeddedInBinding && hasEmbeddedFunctionCallOrBinding) {
1693
+ fnCall = `{= ${fnCall}}`;
1694
+ }
1695
+ return fnCall;
1696
+ case "EmbeddedExpressionBinding":
1697
+ return embeddedInBinding ? `(${expr.value.substring(2, expr.value.length - 1)})` : `${expr.value}`;
1698
+ case "EmbeddedBinding":
1699
+ return embeddedInBinding ? `${embeddedSeparator}${expr.value}` : `${expr.value}`;
1700
+ case "PathInModel":
1701
+ return compilePathInModelExpression(expr, embeddedInBinding, embeddedSeparator);
1702
+ case "Comparison":
1703
+ const comparisonExpression = compileComparisonExpression(expr);
1704
+ return wrapBindingExpression(comparisonExpression, embeddedInBinding);
1705
+ case "IfElse":
1706
+ const ifElseExpression = `${compileExpression(expr.condition, true)} ? ${compileExpression(expr.onTrue, true, keepTargetType)} : ${compileExpression(expr.onFalse, true, keepTargetType)}`;
1707
+ return wrapBindingExpression(ifElseExpression, embeddedInBinding, true);
1708
+ case "Set":
1709
+ const setExpression = expr.operands.map(operand => compileExpression(operand, true)).join(` ${expr.operator} `);
1710
+ return wrapBindingExpression(setExpression, embeddedInBinding, true);
1711
+ case "Concat":
1712
+ const concatExpression = expr.expressions.map(nestedExpression => compileExpression(nestedExpression, true, true)).join(" + ");
1713
+ return wrapBindingExpression(concatExpression, embeddedInBinding);
1714
+ case "Length":
1715
+ const lengthExpression = `${compileExpression(expr.pathInModel, true)}.length`;
1716
+ return wrapBindingExpression(lengthExpression, embeddedInBinding);
1717
+ case "Not":
1718
+ const notExpression = `!${compileExpression(expr.operand, true)}`;
1719
+ return wrapBindingExpression(notExpression, embeddedInBinding);
1720
+ case "Truthy":
1721
+ const truthyExpression = `!!${compileExpression(expr.operand, true)}`;
1722
+ return wrapBindingExpression(truthyExpression, embeddedInBinding);
1723
+ case "Formatter":
1724
+ const formatterExpression = compileFormatterExpression(expr);
1725
+ return embeddedInBinding ? `$${formatterExpression}` : formatterExpression;
1726
+ case "ComplexType":
1727
+ const complexTypeExpression = compileComplexTypeExpression(expr);
1728
+ return embeddedInBinding ? `$${complexTypeExpression}` : complexTypeExpression;
1729
+ default:
1730
+ return "";
1731
+ }
1732
+ }
1733
+
1734
+ /**
1735
+ * Compile a comparison expression.
1736
+ *
1737
+ * @param expression The comparison expression.
1738
+ * @returns The compiled expression. Needs wrapping before it can be used as an expression binding.
1739
+ */
1740
+ _exports.compileExpression = compileExpression;
1741
+ function compileComparisonExpression(expression) {
1742
+ function compileOperand(operand) {
1743
+ const compiledOperand = compileExpression(operand, true) ?? "undefined";
1744
+ return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
1745
+ }
1746
+ return `${compileOperand(expression.operand1)} ${expression.operator} ${compileOperand(expression.operand2)}`;
1747
+ }
1748
+
1749
+ /**
1750
+ * Compile a formatter expression.
1751
+ *
1752
+ * @param expression The formatter expression.
1753
+ * @returns The compiled expression.
1754
+ */
1755
+ function compileFormatterExpression(expression) {
1756
+ if (expression.parameters.length === 1) {
1757
+ return `{${compilePathParameter(expression.parameters[0], true)}, formatter: '${expression.fn}'}`;
1758
+ } else {
1759
+ const parts = expression.parameters.map(param => {
1760
+ if (param._type === "ComplexType") {
1761
+ return compileComplexTypeExpression(param);
1762
+ } else {
1763
+ return compilePathParameter(param);
1764
+ }
1765
+ });
1766
+ return `{parts: [${parts.join(", ")}], formatter: '${expression.fn}'}`;
1767
+ }
1768
+ }
1769
+
1770
+ /**
1771
+ * Compile the path parameter of a formatter call.
1772
+ *
1773
+ * @param expression The binding part to evaluate
1774
+ * @param singlePath Whether there is one or multiple path to consider
1775
+ * @returns The string snippet to include in the overall binding definition
1776
+ */
1777
+ function compilePathParameter(expression) {
1778
+ let singlePath = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1779
+ let outValue = "";
1780
+ if (expression._type === "Constant") {
1781
+ if (expression.value === undefined) {
1782
+ // Special case otherwise the JSTokenizer complains about incorrect content
1783
+ outValue = `value: 'undefined'`;
1784
+ } else {
1785
+ outValue = `value: ${compileConstant(expression, true)}`;
1786
+ }
1787
+ } else if (expression._type === "PathInModel") {
1788
+ outValue = `path: '${compilePathInModel(expression)}'`;
1789
+ outValue += expression.type ? `, type: '${expression.type}'` : `, targetType: 'any'`;
1790
+ if (expression.mode) {
1791
+ outValue += `, mode: '${compileExpression(expression.mode)}'`;
1792
+ }
1793
+ if (hasElements(expression.constraints)) {
1794
+ outValue += `, constraints: ${compileExpression(expression.constraints)}`;
1795
+ }
1796
+ if (hasElements(expression.formatOptions)) {
1797
+ outValue += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
1798
+ }
1799
+ if (hasElements(expression.parameters)) {
1800
+ outValue += `, parameters: ${compileExpression(expression.parameters)}`;
1801
+ }
1802
+ } else {
1803
+ return "";
1804
+ }
1805
+ return singlePath ? outValue : `{${outValue}}`;
1806
+ }
1807
+ function hasElements(obj) {
1808
+ return !!obj && Object.keys(obj).length > 0;
1809
+ }
1810
+
1811
+ /**
1812
+ * Compile a binding expression path.
1813
+ *
1814
+ * @param expression The expression to compile.
1815
+ * @returns The compiled path.
1816
+ */
1817
+ function compilePathInModel(expression) {
1818
+ return `${expression.modelName ? expression.modelName + ">" : ""}${expression.path}`;
1819
+ }
1820
+ return _exports;
1821
+ }, false);
1822
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJpc1Byb3BlcnR5Iiwic2VydmljZU9iamVjdCIsIl90eXBlIiwiRURNX1RZUEVfTUFQUElORyIsInR5cGUiLCJjb25zdHJhaW50cyIsIiRQcmVjaXNpb24iLCIkVjQiLCIkU2NhbGUiLCIkTWF4TGVuZ3RoIiwiJE51bGxhYmxlIiwidW5yZXNvbHZhYmxlRXhwcmVzc2lvbiIsImVzY2FwZVhtbEF0dHJpYnV0ZSIsImlucHV0U3RyaW5nIiwicmVwbGFjZSIsImhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24iLCJleHByZXNzaW9ucyIsImZpbmQiLCJleHByIiwidW5kZWZpbmVkIiwiX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbCIsImEiLCJiIiwidmFsdWUiLCJvcGVyYW5kIiwib3BlcmF0b3IiLCJvcGVyYW5kcyIsImxlbmd0aCIsImV2ZXJ5IiwiZXhwcmVzc2lvbiIsInNvbWUiLCJvdGhlckV4cHJlc3Npb24iLCJjb25kaXRpb24iLCJvblRydWUiLCJvbkZhbHNlIiwib3BlcmFuZDEiLCJvcGVyYW5kMiIsImFFeHByZXNzaW9ucyIsImJFeHByZXNzaW9ucyIsImluZGV4IiwicGF0aEluTW9kZWwiLCJtb2RlbE5hbWUiLCJwYXRoIiwidGFyZ2V0RW50aXR5U2V0IiwiZm4iLCJwYXJhbWV0ZXJzIiwiYmluZGluZ1BhcmFtZXRlcnMiLCJvdGhlckZ1bmN0aW9uIiwib2JqIiwicmVmIiwiZmxhdHRlblNldEV4cHJlc3Npb24iLCJyZWR1Y2UiLCJyZXN1bHQiLCJjYW5kaWRhdGVzRm9yRmxhdHRlbmluZyIsImZvckVhY2giLCJjYW5kaWRhdGUiLCJlIiwicHVzaCIsImhhc09wcG9zaXRlRXhwcmVzc2lvbnMiLCJuZWdhdGVkRXhwcmVzc2lvbnMiLCJtYXAiLCJub3QiLCJpIiwiYW5kIiwid3JhcFByaW1pdGl2ZSIsImlzU3RhdGljRmFsc2UiLCJub25Ucml2aWFsRXhwcmVzc2lvbiIsImZpbHRlciIsImlzRmFsc2UiLCJpc0NvbnN0YW50IiwiY29uc3RhbnQiLCJpc1ZhbGlkIiwiaXNUcnVlIiwib3IiLCJpc1N0YXRpY1RydWUiLCJpc0NvbXBhcmlzb24iLCJpc1RydXRoeSIsImJpbmRpbmdFeHByZXNzaW9uIiwidmlzaXRlZE5hdmlnYXRpb25QYXRocyIsInBhdGhWaXNpdG9yIiwidGFyZ2V0UGF0aCIsImxvY2FsUGF0aCIsImNvbmNhdCIsImpvaW4iLCJjb25zdGFudFZhbHVlIiwiQXJyYXkiLCJpc0FycmF5IiwiaXNQcmltaXRpdmVPYmplY3QiLCJ2YWx1ZU9mIiwiT2JqZWN0IiwiZW50cmllcyIsInBsYWluRXhwcmVzc2lvbiIsImtleSIsInZhbCIsIndyYXBwZWRWYWx1ZSIsInJlc29sdmVCaW5kaW5nU3RyaW5nIiwidGFyZ2V0VHlwZSIsInN0YXJ0c1dpdGgiLCJwYXRoSW5Nb2RlbFJlZ2V4IiwicGF0aEluTW9kZWxSZWdleE1hdGNoIiwiZXhlYyIsImlzTmFOIiwiTnVtYmVyIiwicmVmZXJlbmNlIiwic29tZXRoaW5nIiwiaXNCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24iLCJtYXliZUNvbnN0YW50IiwiaXNQYXRoSW5Nb2RlbEV4cHJlc3Npb24iLCJtYXliZUJpbmRpbmciLCJpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbiIsImlzQ29uY2F0RXhwcmVzc2lvbiIsImlzSWZFbHNlRXhwcmVzc2lvbiIsImlzVW5kZWZpbmVkRXhwcmVzc2lvbiIsImV4cHJlc3Npb25Bc0V4cHJlc3Npb24iLCJvYmplY3RUeXBlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiaXNDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb24iLCJhbm5vdGF0aW9uVmFsdWUiLCJnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24iLCJkZWZhdWx0VmFsdWUiLCJhbm5vdGF0aW9uSWZFeHByZXNzaW9uIiwiSWYiLCJwYXJzZUFubm90YXRpb25Db25kaXRpb24iLCJOb3QiLCJlcXVhbCIsIkVxIiwibm90RXF1YWwiLCJOZSIsImdyZWF0ZXJUaGFuIiwiR3QiLCJncmVhdGVyT3JFcXVhbCIsIkdlIiwibGVzc1RoYW4iLCJMdCIsImxlc3NPckVxdWFsIiwiTGUiLCJPciIsIm9yQ29uZGl0aW9uIiwiQW5kIiwiYW5kQ29uZGl0aW9uIiwiYW5ub3RhdGlvbkFwcGx5RXhwcmVzc2lvbiIsImhhc093blByb3BlcnR5IiwiJE9yIiwiJEFuZCIsIiROb3QiLCIkRXEiLCIkTmUiLCIkR3QiLCIkR2UiLCIkTHQiLCIkTGUiLCIkUGF0aCIsIkZ1bmN0aW9uIiwiJEZ1bmN0aW9uIiwiQXBwbHkiLCIkQXBwbHkiLCIkSWYiLCJyZXNvbHZlRW51bVZhbHVlIiwiJEVudW1NZW1iZXIiLCJpZkVsc2UiLCJjb252ZXJ0U3ViQXBwbHlQYXJhbWV0ZXJzIiwiYXBwbHlQYXJhbSIsImFwcGx5UGFyYW1Db252ZXJ0ZWQiLCJhcHBseUV4cHJlc3Npb24iLCJwYXJhbWV0ZXIiLCJ0ZW1wbGF0ZSIsInRlbXBsYXRlUGFyYW1zIiwic2xpY2UiLCJ0YXJnZXRPYmplY3QiLCIkTmFtZSIsIiRMYWJlbGVkRWxlbWVudCIsImNvbXBhcmlzb24iLCJsZWZ0T3BlcmFuZCIsInJpZ2h0T3BlcmFuZCIsImxlZnRFeHByZXNzaW9uIiwicmlnaHRFeHByZXNzaW9uIiwiY2hlY2tVbmRlZmluZWQiLCJsZWZ0IiwicmlnaHQiLCJyZWR1Y2VkIiwiY29uZGl0aW9uRXhwcmVzc2lvbiIsIm9uVHJ1ZUV4cHJlc3Npb24iLCJvbkZhbHNlRXhwcmVzc2lvbiIsInBhdGhJZHgiLCJteUlmRWxzZUV4cHJlc3Npb24iLCJmb3JtYXRSZXN1bHQiLCJhbGxQYXJ0cyIsInRyYW5zZm9ybVJlY3Vyc2l2ZWx5IiwiY29uc3RhbnRQYXRoIiwidW5zaGlmdCIsIkpTT04iLCJzdHJpbmdpZnkiLCJoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0IiwiZm9ybWF0dGVyRnVuY3Rpb24iLCJjb250ZXh0RW50aXR5VHlwZSIsImlnbm9yZUNvbXBsZXhUeXBlIiwicGFyYW1ldGVyRXhwcmVzc2lvbnMiLCJrZXlzIiwiZnVuY3Rpb25OYW1lIiwiX19mdW5jdGlvbk5hbWUiLCJmb3JtYXR0ZXJDbGFzcyIsImZvcm1hdHRlck5hbWUiLCJzcGxpdCIsIm15Rm9ybWF0RXhwcmVzc2lvbiIsInNldFVwQ29uc3RyYWludHMiLCJ0YXJnZXRNYXBwaW5nIiwicHJvcGVydHkiLCJzY2FsZSIsInByZWNpc2lvbiIsIm1heExlbmd0aCIsIm51bGxhYmxlIiwiYW5ub3RhdGlvbnMiLCJWYWxpZGF0aW9uIiwiTWluaW11bSIsIm1pbmltdW0iLCJNYXhpbXVtIiwibWF4aW11bSIsIkNvbW1vbiIsIklzRGlnaXRTZXF1ZW5jZSIsImlzRGlnaXRTZXF1ZW5jZSIsIlY0IiwiZm9ybWF0V2l0aFR5cGVJbmZvcm1hdGlvbiIsInByb3BlcnR5QmluZGluZ0V4cHJlc3Npb24iLCJpZ25vcmVDb25zdHJhaW50cyIsIm91dEV4cHJlc3Npb24iLCJmb3JtYXRPcHRpb25zIiwiaW5kZXhPZiIsImFzc2lnbiIsInBhcnNlQXNTdHJpbmciLCJwYXJzZUtlZXBzRW1wdHlTdHJpbmciLCJmaXNjYWxUeXBlIiwiZ2V0RmlzY2FsVHlwZSIsInR5cGVzU3VwcG9ydGluZ1BhcnNlRW1wdHlWYWx1ZVRvWmVybyIsImluY2x1ZGVzIiwicGFyc2VFbXB0eVZhbHVlVG9aZXJvIiwiZW1wdHlTdHJpbmciLCJJc0Zpc2NhbFllYXIiLCJJc0Zpc2NhbFBlcmlvZCIsIklzRmlzY2FsWWVhclBlcmlvZCIsIklzRmlzY2FsUXVhcnRlciIsIklzRmlzY2FsWWVhclF1YXJ0ZXIiLCJJc0Zpc2NhbFdlZWsiLCJJc0Zpc2NhbFllYXJXZWVrIiwiSXNEYXlPZkZpc2NhbFllYXIiLCJhZGRUeXBlSW5mb3JtYXRpb24iLCJvRm9ybWF0T3B0aW9ucyIsIl9nZXRDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnNGcm9tRmlyc3RQYXJhbSIsInVvbVBhdGgiLCJtb2RlIiwiY3VycmVuY3lQYXRoIiwicGFyYW0iLCJzaG93TnVtYmVyIiwic2hvd01lYXN1cmUiLCJmdW5jIiwib24iLCJpc0Zvcm1hdHRpbmdGbiIsImlzRW1wdHkiLCJhQmluZGluZ3MiLCJpbkV4cHJlc3Npb25zIiwiY29uY2F0ZW5hdGVkIiwidG9TdHJpbmciLCJteUNvbmNhdEV4cHJlc3Npb24iLCJpbkV4cHJlc3Npb24iLCJleHByZXNzaW9uVHlwZSIsInRyYW5zZm9ybUZ1bmN0aW9uIiwiaW5jbHVkZUFsbEV4cHJlc3Npb24iLCJzdWJFeHByZXNzaW9uIiwiYmluZGluZ1BhcmFtZXRlciIsIm5lZWRQYXJlbnRoZXNpcyIsImNvbXBpbGVDb25zdGFudE9iamVjdCIsImlzTnVsbGFibGUiLCJvYmplY3RzIiwicHJvcGVydGllcyIsImNoaWxkUmVzdWx0IiwiY29tcGlsZUV4cHJlc3Npb24iLCJjb21waWxlQ29uc3RhbnQiLCJlbWJlZGRlZEluQmluZGluZyIsImRvTm90U3RyaW5naWZ5IiwiY29tcGlsZVBhdGhJbk1vZGVsRXhwcmVzc2lvbiIsImV4cHJlc3Npb25Gb3JCaW5kaW5nIiwiZW1iZWRkZWRTZXBhcmF0b3IiLCJjb21wbGV4QmluZGluZ0RlZmluaXRpb24iLCJjb21waWxlUGF0aEluTW9kZWwiLCJvdXRCaW5kaW5nIiwiY29tcGlsZUNvbXBsZXhUeXBlRXhwcmVzc2lvbiIsImNvbXBpbGVQYXRoUGFyYW1ldGVyIiwib3V0cHV0RW5kIiwiaGFzRWxlbWVudHMiLCJ3cmFwQmluZGluZ0V4cHJlc3Npb24iLCJwYXJlbnRoZXNpc1JlcXVpcmVkIiwia2VlcFRhcmdldFR5cGUiLCJoYXNFbWJlZGRlZEZ1bmN0aW9uQ2FsbE9yQmluZGluZyIsInN1YkZuIiwic3ViU3ViRm4iLCJhcmd1bWVudFN0cmluZyIsImFyZyIsImZuQ2FsbCIsInN1YnN0cmluZyIsImNvbXBhcmlzb25FeHByZXNzaW9uIiwiY29tcGlsZUNvbXBhcmlzb25FeHByZXNzaW9uIiwiaWZFbHNlRXhwcmVzc2lvbiIsInNldEV4cHJlc3Npb24iLCJjb25jYXRFeHByZXNzaW9uIiwibmVzdGVkRXhwcmVzc2lvbiIsImxlbmd0aEV4cHJlc3Npb24iLCJub3RFeHByZXNzaW9uIiwidHJ1dGh5RXhwcmVzc2lvbiIsImZvcm1hdHRlckV4cHJlc3Npb24iLCJjb21waWxlRm9ybWF0dGVyRXhwcmVzc2lvbiIsImNvbXBsZXhUeXBlRXhwcmVzc2lvbiIsImNvbXBpbGVPcGVyYW5kIiwiY29tcGlsZWRPcGVyYW5kIiwicGFydHMiLCJzaW5nbGVQYXRoIiwib3V0VmFsdWUiXSwic291cmNlUm9vdCI6Ii4iLCJzb3VyY2VzIjpbIkJpbmRpbmdUb29sa2l0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHtcblx0QWN0aW9uUGFyYW1ldGVyLFxuXHRBbmRBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0QW5kQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRBcHBseUFubm90YXRpb25FeHByZXNzaW9uLFxuXHRCb29sZWFuLFxuXHRDb25kaXRpb25hbENoZWNrT3JWYWx1ZSxcblx0RW50aXR5U2V0LFxuXHRFbnRpdHlUeXBlLFxuXHRFcUFubm90YXRpb25FeHByZXNzaW9uLFxuXHRFcUNvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0R2VBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0R2VDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdEd0QW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdEd0Q29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRJZkFubm90YXRpb25FeHByZXNzaW9uLFxuXHRJZkFubm90YXRpb25FeHByZXNzaW9uVmFsdWUsXG5cdExlQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdExlQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRMdEFubm90YXRpb25FeHByZXNzaW9uLFxuXHRMdENvbmRpdGlvbmFsRXhwcmVzc2lvbixcblx0TmVBbm5vdGF0aW9uRXhwcmVzc2lvbixcblx0TmVDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdE5vdEFubm90YXRpb25FeHByZXNzaW9uLFxuXHROb3RDb25kaXRpb25hbEV4cHJlc3Npb24sXG5cdE9yQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdE9yQ29uZGl0aW9uYWxFeHByZXNzaW9uLFxuXHRQYXRoQW5ub3RhdGlvbkV4cHJlc3Npb24sXG5cdFBhdGhDb25kaXRpb25FeHByZXNzaW9uLFxuXHRQcm9wZXJ0eSxcblx0UHJvcGVydHlBbm5vdGF0aW9uVmFsdWVcbn0gZnJvbSBcIkBzYXAtdXgvdm9jYWJ1bGFyaWVzLXR5cGVzXCI7XG5pbXBvcnQgeyBDb21tb25Bbm5vdGF0aW9uVGVybXMgfSBmcm9tIFwiQHNhcC11eC92b2NhYnVsYXJpZXMtdHlwZXMvdm9jYWJ1bGFyaWVzL0NvbW1vblwiO1xuaW1wb3J0IHsgcmVzb2x2ZUVudW1WYWx1ZSB9IGZyb20gXCJzYXAvZmUvYmFzZS9Bbm5vdGF0aW9uRW51bVwiO1xuXG5leHBvcnQgdHlwZSBQcmltaXRpdmVUeXBlID0gc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHwgYm9vbGVhbiB8IG9iamVjdCB8IG51bGwgfCB1bmRlZmluZWQ7XG50eXBlIERlZmluZWRQcmltaXRpdmVUeXBlID0gc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHwgYm9vbGVhbiB8IG9iamVjdDtcbnR5cGUgUHJpbWl0aXZlVHlwZUNhc3Q8UD4gPSBQIGV4dGVuZHMgU3RyaW5nID8gc3RyaW5nIDogUCBleHRlbmRzIEJvb2xlYW4gPyBib29sZWFuIDogUCBleHRlbmRzIE51bWJlciA/IG51bWJlciA6IFA7XG50eXBlIEJhc2VFeHByZXNzaW9uPF9UPiA9IHtcblx0X3R5cGU6IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIEZvcm1hdE9wdGlvbnMgPSBQYXJ0aWFsPHtcblx0Y3VzdG9tVW5pdHM6IFJlY29yZDxzdHJpbmcsIG9iamVjdD47XG5cdGN1c3RvbUN1cnJlbmNpZXM6IFJlY29yZDxzdHJpbmcsIG9iamVjdD47XG5cdGRlY2ltYWxzOiBudW1iZXI7XG5cdGVtcHR5U3RyaW5nOiBudWxsIHwgbnVtYmVyIHwgc3RyaW5nO1xuXHRmaXNjYWxUeXBlOiBzdHJpbmc7XG5cdGdyb3VwaW5nRW5hYmxlZDogYm9vbGVhbjtcblx0bWF4RnJhY3Rpb25EaWdpdHM6IG51bWJlcjtcblx0bWF4SW50ZWdlckRpZ2l0czogbnVtYmVyO1xuXHRtaW5GcmFjdGlvbkRpZ2l0czogbnVtYmVyO1xuXHRtaW5JbnRlZ2VyRGlnaXRzOiBudW1iZXI7XG5cdHBhcnNlQXNTdHJpbmc6IGJvb2xlYW47XG5cdHBhcnNlS2VlcHNFbXB0eVN0cmluZzogYm9vbGVhbjtcblx0cGF0dGVybjogc3RyaW5nO1xuXHRwcmVjaXNpb246IG51bWJlcjtcblx0cHJlc2VydmVEZWNpbWFsczogYm9vbGVhbjtcblx0c2hvcnREZWNpbWFsczogbnVtYmVyO1xuXHRzaG9ydFJlZk51bWJlcjogbnVtYmVyO1xuXHRzaG93TWVhc3VyZTogYm9vbGVhbjtcblx0c2hvd051bWJlcjogYm9vbGVhbjtcblx0c2hvd1NjYWxlOiBib29sZWFuO1xuXHRzdHlsZTogc3RyaW5nO1xufT47XG5cbmV4cG9ydCB0eXBlIENvbnN0YW50RXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJDb25zdGFudFwiO1xuXHR2YWx1ZTogVDtcbn07XG5cbnR5cGUgU2V0T3BlcmF0b3IgPSBcIiYmXCIgfCBcInx8XCI7XG5leHBvcnQgdHlwZSBTZXRFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248Ym9vbGVhbj4gJiB7XG5cdF90eXBlOiBcIlNldFwiO1xuXHRvcGVyYXRvcjogU2V0T3BlcmF0b3I7XG5cdG9wZXJhbmRzOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIE5vdEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxib29sZWFuPiAmIHtcblx0X3R5cGU6IFwiTm90XCI7XG5cdG9wZXJhbmQ6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPjtcbn07XG5cbmV4cG9ydCB0eXBlIFRydXRoeUV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxib29sZWFuPiAmIHtcblx0X3R5cGU6IFwiVHJ1dGh5XCI7XG5cdG9wZXJhbmQ6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxzdHJpbmc+O1xufTtcblxuZXhwb3J0IHR5cGUgUmVmZXJlbmNlRXhwcmVzc2lvbiA9IEJhc2VFeHByZXNzaW9uPG9iamVjdD4gJiB7XG5cdF90eXBlOiBcIlJlZlwiO1xuXHRyZWY6IHN0cmluZyB8IG51bGw7XG59O1xuXG5leHBvcnQgdHlwZSBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkZvcm1hdHRlclwiO1xuXHRmbjogc3RyaW5nO1xuXHRwYXJhbWV0ZXJzOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj5bXTtcbn07XG5cbnR5cGUgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkNvbXBsZXhUeXBlXCI7XG5cdHR5cGU6IHN0cmluZztcblx0Zm9ybWF0T3B0aW9uczogRm9ybWF0T3B0aW9ucztcblx0cGFyYW1ldGVyczogb2JqZWN0O1xuXHRiaW5kaW5nUGFyYW1ldGVyczogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+W107XG59O1xuXG5leHBvcnQgdHlwZSBGdW5jdGlvbkV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiRnVuY3Rpb25cIjtcblx0b2JqPzogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPG9iamVjdD47XG5cdGZuOiBzdHJpbmc7XG5cdGlzRm9ybWF0dGluZ0ZuOiBib29sZWFuO1xuXHRwYXJhbWV0ZXJzOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj5bXTtcbn07XG5cbmV4cG9ydCB0eXBlIENvbmNhdEV4cHJlc3Npb24gPSBCYXNlRXhwcmVzc2lvbjxzdHJpbmc+ICYge1xuXHRfdHlwZTogXCJDb25jYXRcIjtcblx0ZXhwcmVzc2lvbnM6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxzdHJpbmc+W107XG59O1xuXG5leHBvcnQgdHlwZSBMZW5ndGhFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248c3RyaW5nPiAmIHtcblx0X3R5cGU6IFwiTGVuZ3RoXCI7XG5cdHBhdGhJbk1vZGVsOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248dW5rbm93bj47XG59O1xuXG50eXBlIFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248c3RyaW5nPiAmIHtcblx0X3R5cGU6IFwiVW5yZXNvbHZhYmxlXCI7XG59O1xuXG4vKipcbiAqIEB0eXBlZGVmIFBhdGhJbk1vZGVsRXhwcmVzc2lvblxuICovXG5leHBvcnQgdHlwZSBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiUGF0aEluTW9kZWxcIjtcblx0bW9kZWxOYW1lPzogc3RyaW5nO1xuXHRwYXRoOiBzdHJpbmc7XG5cdHRhcmdldEVudGl0eVNldD86IEVudGl0eVNldDtcblx0dHlwZT86IHN0cmluZztcblx0Y29uc3RyYWludHM/OiBCaW5kaW5nQ29uc3RyYWludHM7XG5cdHBhcmFtZXRlcnM/OiBvYmplY3Q7XG5cdHRhcmdldFR5cGU/OiBzdHJpbmc7XG5cdG1vZGU/OiBzdHJpbmc7XG5cdGZvcm1hdE9wdGlvbnM/OiBGb3JtYXRPcHRpb25zO1xufTtcblxuZXhwb3J0IHR5cGUgRW1iZWRkZWRVSTVCaW5kaW5nRXhwcmVzc2lvbjxUPiA9IEJhc2VFeHByZXNzaW9uPFQ+ICYge1xuXHRfdHlwZTogXCJFbWJlZGRlZEJpbmRpbmdcIjtcblx0dmFsdWU6IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIEVtYmVkZGVkVUk1RXhwcmVzc2lvbkJpbmRpbmdFeHByZXNzaW9uPFQ+ID0gQmFzZUV4cHJlc3Npb248VD4gJiB7XG5cdF90eXBlOiBcIkVtYmVkZGVkRXhwcmVzc2lvbkJpbmRpbmdcIjtcblx0dmFsdWU6IHN0cmluZztcbn07XG5cbmV4cG9ydCB0eXBlIENvbXBhcmlzb25PcGVyYXRvciA9IFwiPT09XCIgfCBcIiE9PVwiIHwgXCI+PVwiIHwgXCI+XCIgfCBcIjw9XCIgfCBcIjxcIjtcbmV4cG9ydCB0eXBlIENvbXBhcmlzb25FeHByZXNzaW9uID0gQmFzZUV4cHJlc3Npb248Ym9vbGVhbj4gJiB7XG5cdF90eXBlOiBcIkNvbXBhcmlzb25cIjtcblx0b3BlcmF0b3I6IENvbXBhcmlzb25PcGVyYXRvcjtcblx0b3BlcmFuZDE6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPjtcblx0b3BlcmFuZDI6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPjtcbn07XG5cbmV4cG9ydCB0eXBlIElmRWxzZUV4cHJlc3Npb248VD4gPSBCYXNlRXhwcmVzc2lvbjxUPiAmIHtcblx0X3R5cGU6IFwiSWZFbHNlXCI7XG5cdGNvbmRpdGlvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+O1xuXHRvblRydWU6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0b25GYWxzZTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xufTtcbmV4cG9ydCBmdW5jdGlvbiBpc1Byb3BlcnR5KHNlcnZpY2VPYmplY3Q6IHVua25vd24pOiBzZXJ2aWNlT2JqZWN0IGlzIFByb3BlcnR5IHtcblx0cmV0dXJuIChzZXJ2aWNlT2JqZWN0IGFzIFByb3BlcnR5KT8uX3R5cGUgPT09IFwiUHJvcGVydHlcIjtcbn1cblxuLyoqXG4gKiBBbiBleHByZXNzaW9uIHRoYXQgZXZhbHVhdGVzIHRvIHR5cGUgVC5cbiAqXG4gKiBAdHlwZWRlZiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IHR5cGUgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+ID1cblx0fCBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvblxuXHR8IENvbnN0YW50RXhwcmVzc2lvbjxUPlxuXHR8IFNldEV4cHJlc3Npb25cblx0fCBOb3RFeHByZXNzaW9uXG5cdHwgVHJ1dGh5RXhwcmVzc2lvblxuXHR8IENvbmNhdEV4cHJlc3Npb25cblx0fCBMZW5ndGhFeHByZXNzaW9uXG5cdHwgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+XG5cdHwgRW1iZWRkZWRVSTVCaW5kaW5nRXhwcmVzc2lvbjxUPlxuXHR8IEVtYmVkZGVkVUk1RXhwcmVzc2lvbkJpbmRpbmdFeHByZXNzaW9uPFQ+XG5cdHwgQ29tcGFyaXNvbkV4cHJlc3Npb25cblx0fCBJZkVsc2VFeHByZXNzaW9uPFQ+XG5cdHwgRm9ybWF0dGVyRXhwcmVzc2lvbjxUPlxuXHR8IENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPlxuXHR8IFJlZmVyZW5jZUV4cHJlc3Npb25cblx0fCBGdW5jdGlvbkV4cHJlc3Npb248VD47XG5cbnR5cGUgVHlwZU1hcHBpbmdEZWZpbml0aW9uID0ge1xuXHR0eXBlOiBzdHJpbmc7XG5cdGNvbnN0cmFpbnRzPzoge1xuXHRcdCRQcmVjaXNpb24/OiBzdHJpbmc7XG5cdFx0JFY0Pzogc3RyaW5nO1xuXHRcdCRTY2FsZT86IHN0cmluZztcblx0XHQkTWF4TGVuZ3RoPzogc3RyaW5nO1xuXHRcdCROdWxsYWJsZT86IHN0cmluZztcblx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NaW5pbXVtLyREZWNpbWFsXCI/OiBzdHJpbmc7XG5cdFx0XCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWluaW11bUBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5FeGNsdXNpdmVcIj86IHN0cmluZztcblx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NYXhpbXVtLyREZWNpbWFsXCI/OiBzdHJpbmc7XG5cdFx0XCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWF4aW11bUBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5FeGNsdXNpdmVcIj86IHN0cmluZztcblx0XHRcIkBjb20uc2FwLnZvY2FidWxhcmllcy5Db21tb24udjEuSXNEaWdpdFNlcXVlbmNlXCI/OiBzdHJpbmc7XG5cdH07XG59O1xuZXhwb3J0IGNvbnN0IEVETV9UWVBFX01BUFBJTkc6IFJlY29yZDxzdHJpbmcsIFR5cGVNYXBwaW5nRGVmaW5pdGlvbj4gPSB7XG5cdFwiRWRtLkJvb2xlYW5cIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkJvb2xlYW5cIiB9LFxuXHRcIkVkbS5CeXRlXCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5CeXRlXCIgfSxcblx0XCJFZG0uRGF0ZVwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRGF0ZVwiIH0sXG5cdFwiRWRtLkRhdGVUaW1lT2Zmc2V0XCI6IHtcblx0XHRjb25zdHJhaW50czoge1xuXHRcdFx0JFByZWNpc2lvbjogXCJwcmVjaXNpb25cIixcblx0XHRcdCRWNDogXCJWNFwiXG5cdFx0fSxcblx0XHR0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRhdGVUaW1lT2Zmc2V0XCJcblx0fSxcblx0XCJFZG0uRGVjaW1hbFwiOiB7XG5cdFx0Y29uc3RyYWludHM6IHtcblx0XHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1pbmltdW0vJERlY2ltYWxcIjogXCJtaW5pbXVtXCIsXG5cdFx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NaW5pbXVtQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLkV4Y2x1c2l2ZVwiOiBcIm1pbmltdW1FeGNsdXNpdmVcIixcblx0XHRcdFwiQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLk1heGltdW0vJERlY2ltYWxcIjogXCJtYXhpbXVtXCIsXG5cdFx0XHRcIkBPcmcuT0RhdGEuVmFsaWRhdGlvbi5WMS5NYXhpbXVtQE9yZy5PRGF0YS5WYWxpZGF0aW9uLlYxLkV4Y2x1c2l2ZVwiOiBcIm1heGltdW1FeGNsdXNpdmVcIixcblx0XHRcdCRQcmVjaXNpb246IFwicHJlY2lzaW9uXCIsXG5cdFx0XHQkU2NhbGU6IFwic2NhbGVcIlxuXHRcdH0sXG5cdFx0dHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5EZWNpbWFsXCJcblx0fSxcblx0XCJFZG0uRG91YmxlXCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5Eb3VibGVcIiB9LFxuXHRcIkVkbS5HdWlkXCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5HdWlkXCIgfSxcblx0XCJFZG0uSW50MTZcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDE2XCIgfSxcblx0XCJFZG0uSW50MzJcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDMyXCIgfSxcblx0XCJFZG0uSW50NjRcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDY0XCIgfSxcblx0XCJFZG0uU0J5dGVcIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlNCeXRlXCIgfSxcblx0XCJFZG0uU2luZ2xlXCI6IHsgdHlwZTogXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5TaW5nbGVcIiB9LFxuXHRcIkVkbS5TdHJlYW1cIjogeyB0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlN0cmVhbVwiIH0sXG5cdFwiRWRtLkJpbmFyeVwiOiB7IHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU3RyZWFtXCIgfSxcblx0XCJFZG0uU3RyaW5nXCI6IHtcblx0XHRjb25zdHJhaW50czoge1xuXHRcdFx0XCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLklzRGlnaXRTZXF1ZW5jZVwiOiBcImlzRGlnaXRTZXF1ZW5jZVwiLFxuXHRcdFx0JE1heExlbmd0aDogXCJtYXhMZW5ndGhcIixcblx0XHRcdCROdWxsYWJsZTogXCJudWxsYWJsZVwiXG5cdFx0fSxcblx0XHR0eXBlOiBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlN0cmluZ1wiXG5cdH0sXG5cdFwiRWRtLlRpbWVPZkRheVwiOiB7XG5cdFx0Y29uc3RyYWludHM6IHtcblx0XHRcdCRQcmVjaXNpb246IFwicHJlY2lzaW9uXCJcblx0XHR9LFxuXHRcdHR5cGU6IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuVGltZU9mRGF5XCJcblx0fVxufTtcblxuLyoqXG4gKiBBbiBleHByZXNzaW9uIHRoYXQgZXZhbHVhdGVzIHRvIHR5cGUgVCwgb3IgYSBjb25zdGFudCB2YWx1ZSBvZiB0eXBlIFRcbiAqL1xuZXhwb3J0IHR5cGUgRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPiA9IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB8IFQ7XG5cbmV4cG9ydCBjb25zdCB1bnJlc29sdmFibGVFeHByZXNzaW9uOiBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbiA9IHtcblx0X3R5cGU6IFwiVW5yZXNvbHZhYmxlXCJcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVYbWxBdHRyaWJ1dGUoaW5wdXRTdHJpbmc6IHN0cmluZyk6IHN0cmluZyB7XG5cdHJldHVybiBpbnB1dFN0cmluZy5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLmV4cHJlc3Npb25zOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj5bXSk6IGJvb2xlYW4ge1xuXHRyZXR1cm4gZXhwcmVzc2lvbnMuZmluZCgoZXhwcikgPT4gZXhwci5fdHlwZSA9PT0gXCJVbnJlc29sdmFibGVcIikgIT09IHVuZGVmaW5lZDtcbn1cbi8qKlxuICogQ2hlY2sgdHdvIGV4cHJlc3Npb25zIGZvciAoZGVlcCkgZXF1YWxpdHkuXG4gKlxuICogQHBhcmFtIGFcbiAqIEBwYXJhbSBiXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHR3byBleHByZXNzaW9ucyBhcmUgZXF1YWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWw8VD4oYTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LCBiOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4pOiBib29sZWFuIHtcblx0aWYgKGEuX3R5cGUgIT09IGIuX3R5cGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRzd2l0Y2ggKGEuX3R5cGUpIHtcblx0XHRjYXNlIFwiVW5yZXNvbHZhYmxlXCI6XG5cdFx0XHRyZXR1cm4gZmFsc2U7IC8vIFVucmVzb2x2YWJsZSBpcyBuZXZlciBlcXVhbCB0byBhbnl0aGluZyBldmVuIGl0c2VsZlxuXHRcdGNhc2UgXCJDb25zdGFudFwiOlxuXHRcdGNhc2UgXCJFbWJlZGRlZEJpbmRpbmdcIjpcblx0XHRjYXNlIFwiRW1iZWRkZWRFeHByZXNzaW9uQmluZGluZ1wiOlxuXHRcdFx0cmV0dXJuIGEudmFsdWUgPT09IChiIGFzIENvbnN0YW50RXhwcmVzc2lvbjxUPikudmFsdWU7XG5cblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0XHRyZXR1cm4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9wZXJhbmQsIChiIGFzIE5vdEV4cHJlc3Npb24pLm9wZXJhbmQpO1xuXHRcdGNhc2UgXCJUcnV0aHlcIjpcblx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub3BlcmFuZCwgKGIgYXMgVHJ1dGh5RXhwcmVzc2lvbikub3BlcmFuZCk7XG5cdFx0Y2FzZSBcIlNldFwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS5vcGVyYXRvciA9PT0gKGIgYXMgU2V0RXhwcmVzc2lvbikub3BlcmF0b3IgJiZcblx0XHRcdFx0YS5vcGVyYW5kcy5sZW5ndGggPT09IChiIGFzIFNldEV4cHJlc3Npb24pLm9wZXJhbmRzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLm9wZXJhbmRzLmV2ZXJ5KChleHByZXNzaW9uKSA9PlxuXHRcdFx0XHRcdChiIGFzIFNldEV4cHJlc3Npb24pLm9wZXJhbmRzLnNvbWUoKG90aGVyRXhwcmVzc2lvbikgPT4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChleHByZXNzaW9uLCBvdGhlckV4cHJlc3Npb24pKVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIklmRWxzZVwiOlxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLmNvbmRpdGlvbiwgKGIgYXMgSWZFbHNlRXhwcmVzc2lvbjxUPikuY29uZGl0aW9uKSAmJlxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub25UcnVlLCAoYiBhcyBJZkVsc2VFeHByZXNzaW9uPFQ+KS5vblRydWUpICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vbkZhbHNlLCAoYiBhcyBJZkVsc2VFeHByZXNzaW9uPFQ+KS5vbkZhbHNlKVxuXHRcdFx0KTtcblxuXHRcdGNhc2UgXCJDb21wYXJpc29uXCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLm9wZXJhdG9yID09PSAoYiBhcyBDb21wYXJpc29uRXhwcmVzc2lvbikub3BlcmF0b3IgJiZcblx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLm9wZXJhbmQxLCAoYiBhcyBDb21wYXJpc29uRXhwcmVzc2lvbikub3BlcmFuZDEpICYmXG5cdFx0XHRcdF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoYS5vcGVyYW5kMiwgKGIgYXMgQ29tcGFyaXNvbkV4cHJlc3Npb24pLm9wZXJhbmQyKVxuXHRcdFx0KTtcblxuXHRcdGNhc2UgXCJDb25jYXRcIjpcblx0XHRcdGNvbnN0IGFFeHByZXNzaW9ucyA9IGEuZXhwcmVzc2lvbnM7XG5cdFx0XHRjb25zdCBiRXhwcmVzc2lvbnMgPSAoYiBhcyBDb25jYXRFeHByZXNzaW9uKS5leHByZXNzaW9ucztcblx0XHRcdGlmIChhRXhwcmVzc2lvbnMubGVuZ3RoICE9PSBiRXhwcmVzc2lvbnMubGVuZ3RoKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBhRXhwcmVzc2lvbnMuZXZlcnkoKGV4cHJlc3Npb24sIGluZGV4KSA9PiB7XG5cdFx0XHRcdHJldHVybiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGV4cHJlc3Npb24sIGJFeHByZXNzaW9uc1tpbmRleF0pO1xuXHRcdFx0fSk7XG5cblx0XHRjYXNlIFwiTGVuZ3RoXCI6XG5cdFx0XHRyZXR1cm4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChhLnBhdGhJbk1vZGVsLCAoYiBhcyBMZW5ndGhFeHByZXNzaW9uKS5wYXRoSW5Nb2RlbCk7XG5cblx0XHRjYXNlIFwiUGF0aEluTW9kZWxcIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEubW9kZWxOYW1lID09PSAoYiBhcyBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4pLm1vZGVsTmFtZSAmJlxuXHRcdFx0XHRhLnBhdGggPT09IChiIGFzIFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPikucGF0aCAmJlxuXHRcdFx0XHRhLnRhcmdldEVudGl0eVNldCA9PT0gKGIgYXMgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+KS50YXJnZXRFbnRpdHlTZXRcblx0XHRcdCk7XG5cblx0XHRjYXNlIFwiRm9ybWF0dGVyXCI6XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHRhLmZuID09PSAoYiBhcyBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+KS5mbiAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMubGVuZ3RoID09PSAoYiBhcyBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+KS5wYXJhbWV0ZXJzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbCgoYiBhcyBGb3JtYXR0ZXJFeHByZXNzaW9uPFQ+KS5wYXJhbWV0ZXJzW2luZGV4XSwgdmFsdWUpKVxuXHRcdFx0KTtcblx0XHRjYXNlIFwiQ29tcGxleFR5cGVcIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGEudHlwZSA9PT0gKGIgYXMgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+KS50eXBlICYmXG5cdFx0XHRcdGEuYmluZGluZ1BhcmFtZXRlcnMubGVuZ3RoID09PSAoYiBhcyBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4pLmJpbmRpbmdQYXJhbWV0ZXJzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLmJpbmRpbmdQYXJhbWV0ZXJzLmV2ZXJ5KCh2YWx1ZSwgaW5kZXgpID0+XG5cdFx0XHRcdFx0X2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbCgoYiBhcyBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4pLmJpbmRpbmdQYXJhbWV0ZXJzW2luZGV4XSwgdmFsdWUpXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cdFx0Y2FzZSBcIkZ1bmN0aW9uXCI6XG5cdFx0XHRjb25zdCBvdGhlckZ1bmN0aW9uID0gYiBhcyBGdW5jdGlvbkV4cHJlc3Npb248VD47XG5cdFx0XHRpZiAoYS5vYmogPT09IHVuZGVmaW5lZCB8fCBvdGhlckZ1bmN0aW9uLm9iaiA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHJldHVybiBhLm9iaiA9PT0gb3RoZXJGdW5jdGlvbjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0YS5mbiA9PT0gb3RoZXJGdW5jdGlvbi5mbiAmJlxuXHRcdFx0XHRfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGEub2JqLCBvdGhlckZ1bmN0aW9uLm9iaikgJiZcblx0XHRcdFx0YS5wYXJhbWV0ZXJzLmxlbmd0aCA9PT0gb3RoZXJGdW5jdGlvbi5wYXJhbWV0ZXJzLmxlbmd0aCAmJlxuXHRcdFx0XHRhLnBhcmFtZXRlcnMuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT4gX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChvdGhlckZ1bmN0aW9uLnBhcmFtZXRlcnNbaW5kZXhdLCB2YWx1ZSkpXG5cdFx0XHQpO1xuXG5cdFx0Y2FzZSBcIlJlZlwiOlxuXHRcdFx0cmV0dXJuIGEucmVmID09PSAoYiBhcyBSZWZlcmVuY2VFeHByZXNzaW9uKS5yZWY7XG5cdH1cblx0cmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgbmVzdGVkIFNldEV4cHJlc3Npb24gYnkgaW5saW5pbmcgb3BlcmFuZHMgb2YgdHlwZSBTZXRFeHByZXNzaW9uIHdpdGggdGhlIHNhbWUgb3BlcmF0b3IuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb24gVGhlIGV4cHJlc3Npb24gdG8gZmxhdHRlblxuICogQHJldHVybnMgQSBuZXcgU2V0RXhwcmVzc2lvbiB3aXRoIHRoZSBzYW1lIG9wZXJhdG9yXG4gKi9cbmZ1bmN0aW9uIGZsYXR0ZW5TZXRFeHByZXNzaW9uKGV4cHJlc3Npb246IFNldEV4cHJlc3Npb24pOiBTZXRFeHByZXNzaW9uIHtcblx0cmV0dXJuIGV4cHJlc3Npb24ub3BlcmFuZHMucmVkdWNlKFxuXHRcdChyZXN1bHQ6IFNldEV4cHJlc3Npb24sIG9wZXJhbmQpID0+IHtcblx0XHRcdGNvbnN0IGNhbmRpZGF0ZXNGb3JGbGF0dGVuaW5nID1cblx0XHRcdFx0b3BlcmFuZC5fdHlwZSA9PT0gXCJTZXRcIiAmJiBvcGVyYW5kLm9wZXJhdG9yID09PSBleHByZXNzaW9uLm9wZXJhdG9yID8gb3BlcmFuZC5vcGVyYW5kcyA6IFtvcGVyYW5kXTtcblx0XHRcdGNhbmRpZGF0ZXNGb3JGbGF0dGVuaW5nLmZvckVhY2goKGNhbmRpZGF0ZSkgPT4ge1xuXHRcdFx0XHRpZiAocmVzdWx0Lm9wZXJhbmRzLmV2ZXJ5KChlKSA9PiAhX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChlLCBjYW5kaWRhdGUpKSkge1xuXHRcdFx0XHRcdHJlc3VsdC5vcGVyYW5kcy5wdXNoKGNhbmRpZGF0ZSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9LFxuXHRcdHsgX3R5cGU6IFwiU2V0XCIsIG9wZXJhdG9yOiBleHByZXNzaW9uLm9wZXJhdG9yLCBvcGVyYW5kczogW10gfVxuXHQpO1xufVxuXG4vKipcbiAqIERldGVjdHMgd2hldGhlciBhbiBhcnJheSBvZiBib29sZWFuIGV4cHJlc3Npb25zIGNvbnRhaW5zIGFuIGV4cHJlc3Npb24gYW5kIGl0cyBuZWdhdGlvbi5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbnMgQXJyYXkgb2YgZXhwcmVzc2lvbnNcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgc2V0IG9mIGV4cHJlc3Npb25zIGNvbnRhaW5zIGFuIGV4cHJlc3Npb24gYW5kIGl0cyBuZWdhdGlvblxuICovXG5mdW5jdGlvbiBoYXNPcHBvc2l0ZUV4cHJlc3Npb25zKGV4cHJlc3Npb25zOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj5bXSk6IGJvb2xlYW4ge1xuXHRjb25zdCBuZWdhdGVkRXhwcmVzc2lvbnMgPSBleHByZXNzaW9ucy5tYXAobm90KTtcblx0cmV0dXJuIGV4cHJlc3Npb25zLnNvbWUoKGV4cHJlc3Npb24sIGluZGV4KSA9PiB7XG5cdFx0Zm9yIChsZXQgaSA9IGluZGV4ICsgMTsgaSA8IG5lZ2F0ZWRFeHByZXNzaW9ucy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoZXhwcmVzc2lvbiwgbmVnYXRlZEV4cHJlc3Npb25zW2ldKSkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9KTtcbn1cblxuLyoqXG4gKiBMb2dpY2FsIGBhbmRgIGV4cHJlc3Npb24uXG4gKlxuICogVGhlIGV4cHJlc3Npb24gaXMgc2ltcGxpZmllZCB0byBmYWxzZSBpZiB0aGlzIGNhbiBiZSBkZWNpZGVkIHN0YXRpY2FsbHkgKHRoYXQgaXMsIGlmIG9uZSBvcGVyYW5kIGlzIGEgY29uc3RhbnRcbiAqIGZhbHNlIG9yIGlmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIGFuIG9wZXJhbmQgYW5kIGl0cyBuZWdhdGlvbikuXG4gKlxuICogQHBhcmFtIG9wZXJhbmRzIEV4cHJlc3Npb25zIHRvIGNvbm5lY3QgYnkgYGFuZGBcbiAqIEByZXR1cm5zIEV4cHJlc3Npb24gZXZhbHVhdGluZyB0byBib29sZWFuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhbmQoLi4ub3BlcmFuZHM6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPltdKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0Y29uc3QgZXhwcmVzc2lvbnMgPSBmbGF0dGVuU2V0RXhwcmVzc2lvbih7XG5cdFx0X3R5cGU6IFwiU2V0XCIsXG5cdFx0b3BlcmF0b3I6IFwiJiZcIixcblx0XHRvcGVyYW5kczogb3BlcmFuZHMubWFwKHdyYXBQcmltaXRpdmUpXG5cdH0pLm9wZXJhbmRzO1xuXG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKC4uLmV4cHJlc3Npb25zKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdGxldCBpc1N0YXRpY0ZhbHNlID0gZmFsc2U7XG5cdGNvbnN0IG5vblRyaXZpYWxFeHByZXNzaW9uID0gZXhwcmVzc2lvbnMuZmlsdGVyKChleHByZXNzaW9uKSA9PiB7XG5cdFx0aWYgKGlzRmFsc2UoZXhwcmVzc2lvbikpIHtcblx0XHRcdGlzU3RhdGljRmFsc2UgPSB0cnVlO1xuXHRcdH1cblx0XHRyZXR1cm4gIWlzQ29uc3RhbnQoZXhwcmVzc2lvbik7XG5cdH0pO1xuXHRpZiAoaXNTdGF0aWNGYWxzZSkge1xuXHRcdHJldHVybiBjb25zdGFudChmYWxzZSk7XG5cdH0gZWxzZSBpZiAobm9uVHJpdmlhbEV4cHJlc3Npb24ubGVuZ3RoID09PSAwKSB7XG5cdFx0Ly8gUmVzb2x2ZSB0aGUgY29uc3RhbnQgdGhlblxuXHRcdGNvbnN0IGlzVmFsaWQgPSBleHByZXNzaW9ucy5yZWR1Y2UoKHJlc3VsdCwgZXhwcmVzc2lvbikgPT4gcmVzdWx0ICYmIGlzVHJ1ZShleHByZXNzaW9uKSwgdHJ1ZSk7XG5cdFx0cmV0dXJuIGNvbnN0YW50KGlzVmFsaWQpO1xuXHR9IGVsc2UgaWYgKG5vblRyaXZpYWxFeHByZXNzaW9uLmxlbmd0aCA9PT0gMSkge1xuXHRcdHJldHVybiBub25Ucml2aWFsRXhwcmVzc2lvblswXTtcblx0fSBlbHNlIGlmIChoYXNPcHBvc2l0ZUV4cHJlc3Npb25zKG5vblRyaXZpYWxFeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiBjb25zdGFudChmYWxzZSk7XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIlNldFwiLFxuXHRcdFx0b3BlcmF0b3I6IFwiJiZcIixcblx0XHRcdG9wZXJhbmRzOiBub25Ucml2aWFsRXhwcmVzc2lvblxuXHRcdH07XG5cdH1cbn1cblxuLyoqXG4gKiBMb2dpY2FsIGBvcmAgZXhwcmVzc2lvbi5cbiAqXG4gKiBUaGUgZXhwcmVzc2lvbiBpcyBzaW1wbGlmaWVkIHRvIHRydWUgaWYgdGhpcyBjYW4gYmUgZGVjaWRlZCBzdGF0aWNhbGx5ICh0aGF0IGlzLCBpZiBvbmUgb3BlcmFuZCBpcyBhIGNvbnN0YW50XG4gKiB0cnVlIG9yIGlmIHRoZSBleHByZXNzaW9uIGNvbnRhaW5zIGFuIG9wZXJhbmQgYW5kIGl0cyBuZWdhdGlvbikuXG4gKlxuICogQHBhcmFtIG9wZXJhbmRzIEV4cHJlc3Npb25zIHRvIGNvbm5lY3QgYnkgYG9yYFxuICogQHJldHVybnMgRXhwcmVzc2lvbiBldmFsdWF0aW5nIHRvIGJvb2xlYW5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9yKC4uLm9wZXJhbmRzOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8Ym9vbGVhbj5bXSk6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdGNvbnN0IGV4cHJlc3Npb25zID0gZmxhdHRlblNldEV4cHJlc3Npb24oe1xuXHRcdF90eXBlOiBcIlNldFwiLFxuXHRcdG9wZXJhdG9yOiBcInx8XCIsXG5cdFx0b3BlcmFuZHM6IG9wZXJhbmRzLm1hcCh3cmFwUHJpbWl0aXZlKVxuXHR9KS5vcGVyYW5kcztcblx0aWYgKGhhc1VucmVzb2x2YWJsZUV4cHJlc3Npb24oLi4uZXhwcmVzc2lvbnMpKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0bGV0IGlzU3RhdGljVHJ1ZSA9IGZhbHNlO1xuXHRjb25zdCBub25Ucml2aWFsRXhwcmVzc2lvbiA9IGV4cHJlc3Npb25zLmZpbHRlcigoZXhwcmVzc2lvbikgPT4ge1xuXHRcdGlmIChpc1RydWUoZXhwcmVzc2lvbikpIHtcblx0XHRcdGlzU3RhdGljVHJ1ZSA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiAhaXNDb25zdGFudChleHByZXNzaW9uKSB8fCBleHByZXNzaW9uLnZhbHVlO1xuXHR9KTtcblx0aWYgKGlzU3RhdGljVHJ1ZSkge1xuXHRcdHJldHVybiBjb25zdGFudCh0cnVlKTtcblx0fSBlbHNlIGlmIChub25Ucml2aWFsRXhwcmVzc2lvbi5sZW5ndGggPT09IDApIHtcblx0XHQvLyBSZXNvbHZlIHRoZSBjb25zdGFudCB0aGVuXG5cdFx0Y29uc3QgaXNWYWxpZCA9IGV4cHJlc3Npb25zLnJlZHVjZSgocmVzdWx0LCBleHByZXNzaW9uKSA9PiByZXN1bHQgJiYgaXNUcnVlKGV4cHJlc3Npb24pLCB0cnVlKTtcblx0XHRyZXR1cm4gY29uc3RhbnQoaXNWYWxpZCk7XG5cdH0gZWxzZSBpZiAobm9uVHJpdmlhbEV4cHJlc3Npb24ubGVuZ3RoID09PSAxKSB7XG5cdFx0cmV0dXJuIG5vblRyaXZpYWxFeHByZXNzaW9uWzBdO1xuXHR9IGVsc2UgaWYgKGhhc09wcG9zaXRlRXhwcmVzc2lvbnMobm9uVHJpdmlhbEV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIGNvbnN0YW50KHRydWUpO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiB7XG5cdFx0XHRfdHlwZTogXCJTZXRcIixcblx0XHRcdG9wZXJhdG9yOiBcInx8XCIsXG5cdFx0XHRvcGVyYW5kczogbm9uVHJpdmlhbEV4cHJlc3Npb25cblx0XHR9O1xuXHR9XG59XG5cbi8qKlxuICogTG9naWNhbCBgbm90YCBvcGVyYXRvci5cbiAqXG4gKiBAcGFyYW0gb3BlcmFuZCBUaGUgZXhwcmVzc2lvbiB0byByZXZlcnNlXG4gKiBAcmV0dXJucyBUaGUgcmVzdWx0aW5nIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gbm90KG9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdG9wZXJhbmQgPSB3cmFwUHJpbWl0aXZlKG9wZXJhbmQpO1xuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbihvcGVyYW5kKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9IGVsc2UgaWYgKGlzQ29uc3RhbnQob3BlcmFuZCkpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoIW9wZXJhbmQudmFsdWUpO1xuXHR9IGVsc2UgaWYgKFxuXHRcdHR5cGVvZiBvcGVyYW5kID09PSBcIm9iamVjdFwiICYmXG5cdFx0b3BlcmFuZC5fdHlwZSA9PT0gXCJTZXRcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmF0b3IgPT09IFwifHxcIiAmJlxuXHRcdG9wZXJhbmQub3BlcmFuZHMuZXZlcnkoKGV4cHJlc3Npb24pID0+IGlzQ29uc3RhbnQoZXhwcmVzc2lvbikgfHwgaXNDb21wYXJpc29uKGV4cHJlc3Npb24pKVxuXHQpIHtcblx0XHRyZXR1cm4gYW5kKC4uLm9wZXJhbmQub3BlcmFuZHMubWFwKChleHByZXNzaW9uKSA9PiBub3QoZXhwcmVzc2lvbikpKTtcblx0fSBlbHNlIGlmIChcblx0XHR0eXBlb2Ygb3BlcmFuZCA9PT0gXCJvYmplY3RcIiAmJlxuXHRcdG9wZXJhbmQuX3R5cGUgPT09IFwiU2V0XCIgJiZcblx0XHRvcGVyYW5kLm9wZXJhdG9yID09PSBcIiYmXCIgJiZcblx0XHRvcGVyYW5kLm9wZXJhbmRzLmV2ZXJ5KChleHByZXNzaW9uKSA9PiBpc0NvbnN0YW50KGV4cHJlc3Npb24pIHx8IGlzQ29tcGFyaXNvbihleHByZXNzaW9uKSlcblx0KSB7XG5cdFx0cmV0dXJuIG9yKC4uLm9wZXJhbmQub3BlcmFuZHMubWFwKChleHByZXNzaW9uKSA9PiBub3QoZXhwcmVzc2lvbikpKTtcblx0fSBlbHNlIGlmIChpc0NvbXBhcmlzb24ob3BlcmFuZCkpIHtcblx0XHQvLyBDcmVhdGUgdGhlIHJldmVyc2UgY29tcGFyaXNvblxuXHRcdHN3aXRjaCAob3BlcmFuZC5vcGVyYXRvcikge1xuXHRcdFx0Y2FzZSBcIiE9PVwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCI9PT1cIiB9O1xuXHRcdFx0Y2FzZSBcIjxcIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPj1cIiB9O1xuXHRcdFx0Y2FzZSBcIjw9XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIj5cIiB9O1xuXHRcdFx0Y2FzZSBcIj09PVwiOlxuXHRcdFx0XHRyZXR1cm4geyAuLi5vcGVyYW5kLCBvcGVyYXRvcjogXCIhPT1cIiB9O1xuXHRcdFx0Y2FzZSBcIj5cIjpcblx0XHRcdFx0cmV0dXJuIHsgLi4ub3BlcmFuZCwgb3BlcmF0b3I6IFwiPD1cIiB9O1xuXHRcdFx0Y2FzZSBcIj49XCI6XG5cdFx0XHRcdHJldHVybiB7IC4uLm9wZXJhbmQsIG9wZXJhdG9yOiBcIjxcIiB9O1xuXHRcdH1cblx0fSBlbHNlIGlmIChvcGVyYW5kLl90eXBlID09PSBcIk5vdFwiKSB7XG5cdFx0cmV0dXJuIG9wZXJhbmQub3BlcmFuZDtcblx0fVxuXG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiTm90XCIsXG5cdFx0b3BlcmFuZDogb3BlcmFuZFxuXHR9O1xufVxuXG4vKipcbiAqIEV2YWx1YXRlcyB3aGV0aGVyIGEgYmluZGluZyBleHByZXNzaW9uIGlzIGVxdWFsIHRvIHRydWUgd2l0aCBhIGxvb3NlIGVxdWFsaXR5LlxuICpcbiAqIEBwYXJhbSBvcGVyYW5kIFRoZSBleHByZXNzaW9uIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBUaGUgcmVzdWx0aW5nIGV4cHJlc3Npb24gdGhhdCBldmFsdWF0ZXMgdG8gYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNUcnV0aHkob3BlcmFuZDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRpZiAoaXNDb25zdGFudChvcGVyYW5kKSkge1xuXHRcdHJldHVybiBjb25zdGFudCghIW9wZXJhbmQudmFsdWUpO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiB7XG5cdFx0XHRfdHlwZTogXCJUcnV0aHlcIixcblx0XHRcdG9wZXJhbmQ6IG9wZXJhbmRcblx0XHR9O1xuXHR9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGJpbmRpbmcgZXhwcmVzc2lvbiB0aGF0IHdpbGwgYmUgZXZhbHVhdGVkIGJ5IHRoZSBjb3JyZXNwb25kaW5nIG1vZGVsLlxuICpcbiAqIEBwYXJhbSBwYXRoXG4gKiBAcGFyYW0gbW9kZWxOYW1lXG4gKiBAcGFyYW0gdmlzaXRlZE5hdmlnYXRpb25QYXRoc1xuICogQHBhcmFtIHBhdGhWaXNpdG9yXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGF0aW5nIHRoYXQgcGF0aCBpbiB0aGUgbW9kZWxcbiAqIEBkZXByZWNhdGVkIHVzZSBwYXRoSW5Nb2RlbCBpbnN0ZWFkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiaW5kaW5nRXhwcmVzc2lvbjxUYXJnZXRUeXBlIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdHBhdGg6IHN0cmluZyxcblx0bW9kZWxOYW1lPzogc3RyaW5nLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT4gfCBVbnJlc29sdmFibGVQYXRoRXhwcmVzc2lvbiB7XG5cdHJldHVybiBwYXRoSW5Nb2RlbChwYXRoLCBtb2RlbE5hbWUsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgYmluZGluZyBleHByZXNzaW9uIHRoYXQgd2lsbCBiZSBldmFsdWF0ZWQgYnkgdGhlIGNvcnJlc3BvbmRpbmcgbW9kZWwuXG4gKlxuICogQHRlbXBsYXRlIFRhcmdldFR5cGVcbiAqIEBwYXJhbSBwYXRoIFRoZSBwYXRoIG9uIHRoZSBtb2RlbFxuICogQHBhcmFtIFttb2RlbE5hbWVdIFRoZSBuYW1lIG9mIHRoZSBtb2RlbFxuICogQHBhcmFtIFt2aXNpdGVkTmF2aWdhdGlvblBhdGhzXSBUaGUgcGF0aHMgZnJvbSB0aGUgcm9vdCBlbnRpdHlTZXRcbiAqIEBwYXJhbSBbcGF0aFZpc2l0b3JdIEEgZnVuY3Rpb24gdG8gbW9kaWZ5IHRoZSByZXN1bHRpbmcgcGF0aFxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRhdGluZyB0aGF0IHBhdGggaW4gdGhlIG1vZGVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXRoSW5Nb2RlbChcblx0cGF0aDogdW5kZWZpbmVkLFxuXHRtb2RlbE5hbWU/OiBzdHJpbmcsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM/OiBzdHJpbmdbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb247XG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWw8VGFyZ2V0VHlwZSBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRwYXRoOiBzdHJpbmcsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRocz86IHN0cmluZ1tdLFxuXHRwYXRoVmlzaXRvcj86IHVuZGVmaW5lZFxuKTogUGF0aEluTW9kZWxFeHByZXNzaW9uPFRhcmdldFR5cGU+O1xuZXhwb3J0IGZ1bmN0aW9uIHBhdGhJbk1vZGVsPFRhcmdldFR5cGUgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0cGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuXHRtb2RlbE5hbWU/OiBzdHJpbmcsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM/OiBzdHJpbmdbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24gfCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT47XG5leHBvcnQgZnVuY3Rpb24gcGF0aEluTW9kZWw8VGFyZ2V0VHlwZSBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRwYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQsXG5cdG1vZGVsTmFtZT86IHN0cmluZyxcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRoczogc3RyaW5nW10gPSBbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24gfCBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VGFyZ2V0VHlwZT4ge1xuXHRpZiAocGF0aCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0bGV0IHRhcmdldFBhdGg7XG5cdGlmIChwYXRoVmlzaXRvcikge1xuXHRcdHRhcmdldFBhdGggPSBwYXRoVmlzaXRvcihwYXRoKTtcblx0XHRpZiAodGFyZ2V0UGF0aCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0Y29uc3QgbG9jYWxQYXRoID0gdmlzaXRlZE5hdmlnYXRpb25QYXRocy5jb25jYXQoKTtcblx0XHRsb2NhbFBhdGgucHVzaChwYXRoKTtcblx0XHR0YXJnZXRQYXRoID0gbG9jYWxQYXRoLmpvaW4oXCIvXCIpO1xuXHR9XG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiUGF0aEluTW9kZWxcIixcblx0XHRtb2RlbE5hbWU6IG1vZGVsTmFtZSxcblx0XHRwYXRoOiB0YXJnZXRQYXRoXG5cdH07XG59XG5cbnR5cGUgUGxhaW5FeHByZXNzaW9uT2JqZWN0ID0geyBbaW5kZXg6IHN0cmluZ106IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPiB9O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjb25zdGFudCBleHByZXNzaW9uIGJhc2VkIG9uIGEgcHJpbWl0aXZlIHZhbHVlLlxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0gdmFsdWUgVGhlIGNvbnN0YW50IHRvIHdyYXAgaW4gYW4gZXhwcmVzc2lvblxuICogQHJldHVybnMgVGhlIGNvbnN0YW50IGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnN0YW50PFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPih2YWx1ZTogVCk6IENvbnN0YW50RXhwcmVzc2lvbjxUPiB7XG5cdGxldCBjb25zdGFudFZhbHVlOiBUO1xuXG5cdGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCkge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuXHRcdFx0Y29uc3RhbnRWYWx1ZSA9IHZhbHVlLm1hcCh3cmFwUHJpbWl0aXZlKSBhcyBUO1xuXHRcdH0gZWxzZSBpZiAoaXNQcmltaXRpdmVPYmplY3QodmFsdWUpKSB7XG5cdFx0XHRjb25zdGFudFZhbHVlID0gdmFsdWUudmFsdWVPZigpIGFzIFQ7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0YW50VmFsdWUgPSBPYmplY3QuZW50cmllcyh2YWx1ZSkucmVkdWNlKChwbGFpbkV4cHJlc3Npb24sIFtrZXksIHZhbF0pID0+IHtcblx0XHRcdFx0Y29uc3Qgd3JhcHBlZFZhbHVlID0gd3JhcFByaW1pdGl2ZSh2YWwpO1xuXHRcdFx0XHRpZiAod3JhcHBlZFZhbHVlLl90eXBlICE9PSBcIkNvbnN0YW50XCIgfHwgd3JhcHBlZFZhbHVlLnZhbHVlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRwbGFpbkV4cHJlc3Npb25ba2V5XSA9IHdyYXBwZWRWYWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gcGxhaW5FeHByZXNzaW9uO1xuXHRcdFx0fSwge30gYXMgUGxhaW5FeHByZXNzaW9uT2JqZWN0KSBhcyBUO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRjb25zdGFudFZhbHVlID0gdmFsdWU7XG5cdH1cblxuXHRyZXR1cm4geyBfdHlwZTogXCJDb25zdGFudFwiLCB2YWx1ZTogY29uc3RhbnRWYWx1ZSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUJpbmRpbmdTdHJpbmc8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHR2YWx1ZTogc3RyaW5nIHwgYm9vbGVhbiB8IG51bWJlcixcblx0dGFyZ2V0VHlwZT86IHN0cmluZ1xuKTogQ29uc3RhbnRFeHByZXNzaW9uPFQ+IHwgUGF0aEluTW9kZWxFeHByZXNzaW9uPFQ+IHwgRW1iZWRkZWRVSTVCaW5kaW5nRXhwcmVzc2lvbjxUPiB8IEVtYmVkZGVkVUk1RXhwcmVzc2lvbkJpbmRpbmdFeHByZXNzaW9uPFQ+IHtcblx0aWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIHZhbHVlLnN0YXJ0c1dpdGgoXCJ7XCIpKSB7XG5cdFx0Y29uc3QgcGF0aEluTW9kZWxSZWdleCA9IC9eeyguKik+KC4rKX0kLzsgLy8gTWF0Y2hlcyBtb2RlbCBwYXRocyBsaWtlIFwibW9kZWw+cGF0aFwiIG9yIFwiPnBhdGhcIiAoZGVmYXVsdCBtb2RlbClcblx0XHRjb25zdCBwYXRoSW5Nb2RlbFJlZ2V4TWF0Y2ggPSBwYXRoSW5Nb2RlbFJlZ2V4LmV4ZWModmFsdWUpO1xuXG5cdFx0aWYgKHZhbHVlLnN0YXJ0c1dpdGgoXCJ7PVwiKSkge1xuXHRcdFx0Ly8gRXhwcmVzc2lvbiBiaW5kaW5nLCB3ZSBjYW4ganVzdCByZW1vdmUgdGhlIG91dGVyIGJpbmRpbmcgdGhpbmdzXG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRfdHlwZTogXCJFbWJlZGRlZEV4cHJlc3Npb25CaW5kaW5nXCIsXG5cdFx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdFx0fTtcblx0XHR9IGVsc2UgaWYgKHBhdGhJbk1vZGVsUmVnZXhNYXRjaCkge1xuXHRcdFx0cmV0dXJuIHBhdGhJbk1vZGVsKHBhdGhJbk1vZGVsUmVnZXhNYXRjaFsyXSB8fCBcIlwiLCBwYXRoSW5Nb2RlbFJlZ2V4TWF0Y2hbMV0gfHwgdW5kZWZpbmVkKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0X3R5cGU6IFwiRW1iZWRkZWRCaW5kaW5nXCIsXG5cdFx0XHRcdHZhbHVlOiB2YWx1ZVxuXHRcdFx0fTtcblx0XHR9XG5cdH0gZWxzZSBpZiAodGFyZ2V0VHlwZSA9PT0gXCJib29sZWFuXCIgJiYgdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmICh2YWx1ZSA9PT0gXCJ0cnVlXCIgfHwgdmFsdWUgPT09IFwiZmFsc2VcIikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQodmFsdWUgPT09IFwidHJ1ZVwiKSBhcyBDb25zdGFudEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAodGFyZ2V0VHlwZSA9PT0gXCJudW1iZXJcIiAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgKCFpc05hTihOdW1iZXIodmFsdWUpKSB8fCB2YWx1ZSA9PT0gXCJOYU5cIikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoTnVtYmVyKHZhbHVlKSkgYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBjb25zdGFudCh2YWx1ZSkgYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+O1xuXHR9XG59XG5cbi8qKlxuICogQSBuYW1lZCByZWZlcmVuY2UuXG4gKlxuICogQHNlZSBmblxuICogQHBhcmFtIHJlZmVyZW5jZSBSZWZlcmVuY2VcbiAqIEByZXR1cm5zIFRoZSBvYmplY3QgcmVmZXJlbmNlIGJpbmRpbmcgcGFydFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVmKHJlZmVyZW5jZTogc3RyaW5nIHwgbnVsbCk6IFJlZmVyZW5jZUV4cHJlc3Npb24ge1xuXHRyZXR1cm4geyBfdHlwZTogXCJSZWZcIiwgcmVmOiByZWZlcmVuY2UgfTtcbn1cblxuLyoqXG4gKiBXcmFwIGEgcHJpbWl0aXZlIGludG8gYSBjb25zdGFudCBleHByZXNzaW9uIGlmIGl0IGlzIG5vdCBhbHJlYWR5IGFuIGV4cHJlc3Npb24uXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSBzb21ldGhpbmcgVGhlIG9iamVjdCB0byB3cmFwIGluIGEgQ29uc3RhbnQgZXhwcmVzc2lvblxuICogQHJldHVybnMgRWl0aGVyIHRoZSBvcmlnaW5hbCBvYmplY3Qgb3IgdGhlIHdyYXBwZWQgb25lIGRlcGVuZGluZyBvbiB0aGUgY2FzZVxuICovXG5leHBvcnQgZnVuY3Rpb24gd3JhcFByaW1pdGl2ZTxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oc29tZXRoaW5nOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4ge1xuXHRpZiAoaXNCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24oc29tZXRoaW5nKSkge1xuXHRcdHJldHVybiBzb21ldGhpbmcgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9XG5cblx0cmV0dXJuIGNvbnN0YW50KHNvbWV0aGluZyk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBleHByZXNzaW9uIG9yIHZhbHVlIHByb3ZpZGVkIGlzIGEgYmluZGluZyB0b29saW5nIGV4cHJlc3Npb24gb3Igbm90LlxuICpcbiAqIEV2ZXJ5IG9iamVjdCBoYXZpbmcgYSBwcm9wZXJ0eSBuYW1lZCBgX3R5cGVgIG9mIHNvbWUgdmFsdWUgaXMgY29uc2lkZXJlZCBhbiBleHByZXNzaW9uLCBldmVuIGlmIHRoZXJlIGlzIGFjdHVhbGx5XG4gKiBubyBzdWNoIGV4cHJlc3Npb24gdHlwZSBzdXBwb3J0ZWQuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb25cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgZXhwcmVzc2lvbiBpcyBhIGJpbmRpbmcgdG9vbGtpdCBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0JpbmRpbmdUb29sa2l0RXhwcmVzc2lvbihcblx0ZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+IHwgdW5rbm93blxuKTogZXhwcmVzc2lvbiBpcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj4ge1xuXHRyZXR1cm4gKGV4cHJlc3Npb24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+KT8uX3R5cGUgIT09IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgY29uc3RhbnQgb3Igbm90LlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtICBtYXliZUNvbnN0YW50IFRoZSBleHByZXNzaW9uIG9yIHByaW1pdGl2ZSB2YWx1ZSB0aGF0IGlzIHRvIGJlIGNoZWNrZWRcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiBpdCBpcyBjb25zdGFudFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb25zdGFudDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4obWF5YmVDb25zdGFudDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+KTogbWF5YmVDb25zdGFudCBpcyBDb25zdGFudEV4cHJlc3Npb248VD4ge1xuXHRyZXR1cm4gdHlwZW9mIG1heWJlQ29uc3RhbnQgIT09IFwib2JqZWN0XCIgfHwgKG1heWJlQ29uc3RhbnQgYXMgQmFzZUV4cHJlc3Npb248VD4pLl90eXBlID09PSBcIkNvbnN0YW50XCI7XG59XG5cbmZ1bmN0aW9uIGlzVHJ1ZShleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pOiBib29sZWFuIHtcblx0cmV0dXJuIGlzQ29uc3RhbnQoZXhwcmVzc2lvbikgJiYgZXhwcmVzc2lvbi52YWx1ZSA9PT0gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaXNGYWxzZShleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pOiBib29sZWFuIHtcblx0cmV0dXJuIGlzQ29uc3RhbnQoZXhwcmVzc2lvbikgJiYgZXhwcmVzc2lvbi52YWx1ZSA9PT0gZmFsc2U7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBleHByZXNzaW9uIG9yIHZhbHVlIHByb3ZpZGVkIGlzIGEgcGF0aCBpbiBtb2RlbCBleHByZXNzaW9uIG9yIG5vdC5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSAgbWF5YmVCaW5kaW5nIFRoZSBleHByZXNzaW9uIG9yIHByaW1pdGl2ZSB2YWx1ZSB0aGF0IGlzIHRvIGJlIGNoZWNrZWRcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiBpdCBpcyBhIHBhdGggaW4gbW9kZWwgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQYXRoSW5Nb2RlbEV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRtYXliZUJpbmRpbmc6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogbWF5YmVCaW5kaW5nIGlzIFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPiB7XG5cdHJldHVybiAobWF5YmVCaW5kaW5nIGFzIEJhc2VFeHByZXNzaW9uPFQ+KT8uX3R5cGUgPT09IFwiUGF0aEluTW9kZWxcIjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgYSBjb21wbGV4IHR5cGUgZXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSAgbWF5YmVCaW5kaW5nIFRoZSBleHByZXNzaW9uIG9yIHByaW1pdGl2ZSB2YWx1ZSB0aGF0IGlzIHRvIGJlIGNoZWNrZWRcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiBpdCBpcyBhIHBhdGggaW4gbW9kZWwgZXhwcmVzc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb21wbGV4VHlwZUV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRtYXliZUJpbmRpbmc6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogbWF5YmVCaW5kaW5nIGlzIENvbXBsZXhUeXBlRXhwcmVzc2lvbjxUPiB7XG5cdHJldHVybiAobWF5YmVCaW5kaW5nIGFzIEJhc2VFeHByZXNzaW9uPFQ+KT8uX3R5cGUgPT09IFwiQ29tcGxleFR5cGVcIjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGV4cHJlc3Npb24gb3IgdmFsdWUgcHJvdmlkZWQgaXMgYSBjb25jYXQgZXhwcmVzc2lvbiBvciBub3QuXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb25cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgZXhwcmVzc2lvbiBpcyBhIENvbmNhdEV4cHJlc3Npb25cbiAqL1xuZnVuY3Rpb24gaXNDb25jYXRFeHByZXNzaW9uKGV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik6IGV4cHJlc3Npb24gaXMgQ29uY2F0RXhwcmVzc2lvbiB7XG5cdHJldHVybiAoZXhwcmVzc2lvbiBhcyBCYXNlRXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik/Ll90eXBlID09PSBcIkNvbmNhdFwiO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZXhwcmVzc2lvbiBvciB2YWx1ZSBwcm92aWRlZCBpcyBhIElmRWxzZSBleHByZXNzaW9uIG9yIG5vdC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvblxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgSWZFbHNlRXhwcmVzc2lvblxuICovXG5mdW5jdGlvbiBpc0lmRWxzZUV4cHJlc3Npb24oZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KTogZXhwcmVzc2lvbiBpcyBDb25jYXRFeHByZXNzaW9uIHtcblx0cmV0dXJuIChleHByZXNzaW9uIGFzIEJhc2VFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+KT8uX3R5cGUgPT09IFwiSWZFbHNlXCI7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBleHByZXNzaW9uIHByb3ZpZGVkIGlzIGEgY29tcGFyaXNvbiBvciBub3QuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgZXhwcmVzc2lvblxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBleHByZXNzaW9uIGlzIGEgQ29tcGFyaXNvbkV4cHJlc3Npb25cbiAqL1xuZnVuY3Rpb24gaXNDb21wYXJpc29uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihleHByZXNzaW9uOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4pOiBleHByZXNzaW9uIGlzIENvbXBhcmlzb25FeHByZXNzaW9uIHtcblx0cmV0dXJuIGV4cHJlc3Npb24uX3R5cGUgPT09IFwiQ29tcGFyaXNvblwiO1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBpbnB1dCBwYXJhbWV0ZXIgaXMgYSBjb25zdGFudCBleHByZXNzaW9uIG9mIHR5cGUgdW5kZWZpbmVkLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBpbnB1dCBleHByZXNzaW9uIG9yIG9iamVjdCBpbiBnZW5lcmFsXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGlucHV0IGlzIGNvbnN0YW50IHdoaWNoIGhhcyB1bmRlZmluZWQgZm9yIHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1VuZGVmaW5lZEV4cHJlc3Npb24oZXhwcmVzc2lvbjogdW5rbm93bik6IGV4cHJlc3Npb24gaXMgQ29uc3RhbnRFeHByZXNzaW9uPHVuZGVmaW5lZD4ge1xuXHRjb25zdCBleHByZXNzaW9uQXNFeHByZXNzaW9uID0gZXhwcmVzc2lvbiBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj47XG5cdHJldHVybiBleHByZXNzaW9uQXNFeHByZXNzaW9uPy5fdHlwZSA9PT0gXCJDb25zdGFudFwiICYmIGV4cHJlc3Npb25Bc0V4cHJlc3Npb24/LnZhbHVlID09PSB1bmRlZmluZWQ7XG59XG5cbnR5cGUgQ29tcGxleEFubm90YXRpb25FeHByZXNzaW9uPFA+ID1cblx0fCBQYXRoQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBBcHBseUFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgSWZBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IE9yQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBBbmRBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IE5lQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBFcUFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgTm90QW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBHdEFubm90YXRpb25FeHByZXNzaW9uPFA+XG5cdHwgR2VBbm5vdGF0aW9uRXhwcmVzc2lvbjxQPlxuXHR8IExlQW5ub3RhdGlvbkV4cHJlc3Npb248UD5cblx0fCBMdEFubm90YXRpb25FeHByZXNzaW9uPFA+O1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZU9iamVjdChvYmplY3RUeXBlOiBvYmplY3QpOiBib29sZWFuIHtcblx0c3dpdGNoIChvYmplY3RUeXBlLmNvbnN0cnVjdG9yLm5hbWUpIHtcblx0XHRjYXNlIFwiU3RyaW5nXCI6XG5cdFx0Y2FzZSBcIk51bWJlclwiOlxuXHRcdGNhc2UgXCJCb29sZWFuXCI6XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59XG4vKipcbiAqIENoZWNrIGlmIHRoZSBwYXNzZWQgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWUgaXMgYSBDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb24uXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gIGFubm90YXRpb25WYWx1ZSBUaGUgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWUgdG8gZXZhbHVhdGVcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0IGlzIGEge0NvbXBsZXhBbm5vdGF0aW9uRXhwcmVzc2lvbn1cbiAqL1xuZnVuY3Rpb24gaXNDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb248VD4oYW5ub3RhdGlvblZhbHVlOiBQcm9wZXJ0eUFubm90YXRpb25WYWx1ZTxUPik6IGFubm90YXRpb25WYWx1ZSBpcyBDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb248VD4ge1xuXHRyZXR1cm4gdHlwZW9mIGFubm90YXRpb25WYWx1ZSA9PT0gXCJvYmplY3RcIiAmJiAhaXNQcmltaXRpdmVPYmplY3QoYW5ub3RhdGlvblZhbHVlIGFzIG9iamVjdCk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgdGhlIGNvcnJlc3BvbmRpbmcgYW5ub3RhdGlvblZhbHVlIGZvciBhIGdpdmVuIGFubm90YXRpb24gYW5ub3RhdGlvblZhbHVlLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGFubm90YXRpb25WYWx1ZSBUaGUgc291cmNlIGFubm90YXRpb24gYW5ub3RhdGlvblZhbHVlXG4gKiBAcGFyYW0gdmlzaXRlZE5hdmlnYXRpb25QYXRocyBUaGUgcGF0aCBmcm9tIHRoZSByb290IGVudGl0eSBzZXRcbiAqIEBwYXJhbSBkZWZhdWx0VmFsdWUgRGVmYXVsdCB2YWx1ZSBpZiB0aGUgYW5ub3RhdGlvblZhbHVlIGlzIHVuZGVmaW5lZFxuICogQHBhcmFtIHBhdGhWaXNpdG9yIEEgZnVuY3Rpb24gdG8gbW9kaWZ5IHRoZSByZXN1bHRpbmcgcGF0aFxuICogQHJldHVybnMgVGhlIGFubm90YXRpb25WYWx1ZSBlcXVpdmFsZW50IHRvIHRoYXQgYW5ub3RhdGlvbiBhbm5vdGF0aW9uVmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGFubm90YXRpb25WYWx1ZTogUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8VD4gfCB1bmRlZmluZWQsXG5cdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHM6IHN0cmluZ1tdID0gW10sXG5cdGRlZmF1bHRWYWx1ZT86IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGVDYXN0PFQ+PiB7XG5cdGlmIChhbm5vdGF0aW9uVmFsdWUgPT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiB3cmFwUHJpbWl0aXZlKGRlZmF1bHRWYWx1ZSBhcyBQcmltaXRpdmVUeXBlQ2FzdDxUPik7XG5cdH1cblx0YW5ub3RhdGlvblZhbHVlID0gYW5ub3RhdGlvblZhbHVlPy52YWx1ZU9mKCkgYXMgUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8VD47XG5cdGlmICghaXNDb21wbGV4QW5ub3RhdGlvbkV4cHJlc3Npb24oYW5ub3RhdGlvblZhbHVlKSkge1xuXHRcdHJldHVybiBjb25zdGFudChhbm5vdGF0aW9uVmFsdWUpO1xuXHR9XG5cblx0c3dpdGNoIChhbm5vdGF0aW9uVmFsdWUudHlwZSkge1xuXHRcdGNhc2UgXCJQYXRoXCI6XG5cdFx0XHRyZXR1cm4gcGF0aEluTW9kZWwoYW5ub3RhdGlvblZhbHVlLnBhdGgsIHVuZGVmaW5lZCwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHRcdGNhc2UgXCJJZlwiOlxuXHRcdFx0cmV0dXJuIGFubm90YXRpb25JZkV4cHJlc3Npb24oYW5ub3RhdGlvblZhbHVlLklmLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcikgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFxuXHRcdFx0XHRQcmltaXRpdmVUeXBlQ2FzdDxUPlxuXHRcdFx0Pjtcblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0XHRyZXR1cm4gbm90KHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuTm90LCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcikpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxcblx0XHRcdFx0UHJpbWl0aXZlVHlwZUNhc3Q8VD5cblx0XHRcdD47XG5cdFx0Y2FzZSBcIkVxXCI6XG5cdFx0XHRyZXR1cm4gZXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuRXFbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5FcVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIk5lXCI6XG5cdFx0XHRyZXR1cm4gbm90RXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuTmVbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5OZVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkd0XCI6XG5cdFx0XHRyZXR1cm4gZ3JlYXRlclRoYW4oXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuR3RbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5HdFsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkdlXCI6XG5cdFx0XHRyZXR1cm4gZ3JlYXRlck9yRXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuR2VbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5HZVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkx0XCI6XG5cdFx0XHRyZXR1cm4gbGVzc1RoYW4oXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuTHRbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5MdFsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIkxlXCI6XG5cdFx0XHRyZXR1cm4gbGVzc09yRXF1YWwoXG5cdFx0XHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWUuTGVbMF0sIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKSxcblx0XHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZS5MZVsxXSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdFx0Y2FzZSBcIk9yXCI6XG5cdFx0XHRyZXR1cm4gb3IoXG5cdFx0XHRcdC4uLmFubm90YXRpb25WYWx1ZS5Pci5tYXAoZnVuY3Rpb24gKG9yQ29uZGl0aW9uKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbjxib29sZWFuPihvckNvbmRpdGlvbiwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZUNhc3Q8VD4+O1xuXHRcdGNhc2UgXCJBbmRcIjpcblx0XHRcdHJldHVybiBhbmQoXG5cdFx0XHRcdC4uLmFubm90YXRpb25WYWx1ZS5BbmQubWFwKGZ1bmN0aW9uIChhbmRDb25kaXRpb24pIHtcblx0XHRcdFx0XHRyZXR1cm4gcGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uPGJvb2xlYW4+KGFuZENvbmRpdGlvbiwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZUNhc3Q8VD4+O1xuXHRcdGNhc2UgXCJBcHBseVwiOlxuXHRcdFx0cmV0dXJuIGFubm90YXRpb25BcHBseUV4cHJlc3Npb24oXG5cdFx0XHRcdGFubm90YXRpb25WYWx1ZSBhcyBBcHBseUFubm90YXRpb25FeHByZXNzaW9uPHN0cmluZz4sXG5cdFx0XHRcdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsXG5cdFx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlQ2FzdDxUPj47XG5cdH1cblx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG59XG5cbi8qKlxuICogUGFyc2UgdGhlIGFubm90YXRpb24gY29uZGl0aW9uIGludG8gYW4gZXhwcmVzc2lvbi5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBhbm5vdGF0aW9uVmFsdWUgVGhlIGNvbmRpdGlvbiBvciB2YWx1ZSBmcm9tIHRoZSBhbm5vdGF0aW9uXG4gKiBAcGFyYW0gdmlzaXRlZE5hdmlnYXRpb25QYXRocyBUaGUgcGF0aCBmcm9tIHRoZSByb290IGVudGl0eSBzZXRcbiAqIEBwYXJhbSBwYXRoVmlzaXRvciBBIGZ1bmN0aW9uIHRvIG1vZGlmeSB0aGUgcmVzdWx0aW5nIHBhdGhcbiAqIEByZXR1cm5zIEFuIGVxdWl2YWxlbnQgZXhwcmVzc2lvblxuICovXG5mdW5jdGlvbiBwYXJzZUFubm90YXRpb25Db25kaXRpb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRhbm5vdGF0aW9uVmFsdWU6IENvbmRpdGlvbmFsQ2hlY2tPclZhbHVlLFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4ge1xuXHRpZiAoYW5ub3RhdGlvblZhbHVlID09PSBudWxsIHx8IHR5cGVvZiBhbm5vdGF0aW9uVmFsdWUgIT09IFwib2JqZWN0XCIpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoYW5ub3RhdGlvblZhbHVlIGFzIFQpO1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRPclwiKSkge1xuXHRcdHJldHVybiBvcihcblx0XHRcdC4uLigoYW5ub3RhdGlvblZhbHVlIGFzIE9yQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kT3IubWFwKGZ1bmN0aW9uIChvckNvbmRpdGlvbikge1xuXHRcdFx0XHRyZXR1cm4gcGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKG9yQ29uZGl0aW9uLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0XHR9KSBhcyB1bmtub3duIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPltdKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRBbmRcIikpIHtcblx0XHRyZXR1cm4gYW5kKFxuXHRcdFx0Li4uKChhbm5vdGF0aW9uVmFsdWUgYXMgQW5kQ29uZGl0aW9uYWxFeHByZXNzaW9uKS4kQW5kLm1hcChmdW5jdGlvbiAoYW5kQ29uZGl0aW9uKSB7XG5cdFx0XHRcdHJldHVybiBwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5kQ29uZGl0aW9uLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdFx0XHR9KSBhcyB1bmtub3duIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPltdKVxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiROb3RcIikpIHtcblx0XHRyZXR1cm4gbm90KFxuXHRcdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKChhbm5vdGF0aW9uVmFsdWUgYXMgTm90Q29uZGl0aW9uYWxFeHByZXNzaW9uKS4kTm90LCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkRXFcIikpIHtcblx0XHRyZXR1cm4gZXF1YWwoXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBFcUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEVxWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBFcUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEVxWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkTmVcIikpIHtcblx0XHRyZXR1cm4gbm90RXF1YWwoXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBOZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJE5lWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBOZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJE5lWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkR3RcIikpIHtcblx0XHRyZXR1cm4gZ3JlYXRlclRoYW4oXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBHdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEd0WzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBHdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEd0WzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkR2VcIikpIHtcblx0XHRyZXR1cm4gZ3JlYXRlck9yRXF1YWwoXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBHZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEdlWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBHZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEdlWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkTHRcIikpIHtcblx0XHRyZXR1cm4gbGVzc1RoYW4oXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBMdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEx0WzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBMdENvbmRpdGlvbmFsRXhwcmVzc2lvbikuJEx0WzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkTGVcIikpIHtcblx0XHRyZXR1cm4gbGVzc09yRXF1YWwoXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBMZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJExlWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oKGFubm90YXRpb25WYWx1ZSBhcyBMZUNvbmRpdGlvbmFsRXhwcmVzc2lvbikuJExlWzFdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcilcblx0XHQpIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fSBlbHNlIGlmIChhbm5vdGF0aW9uVmFsdWUuaGFzT3duUHJvcGVydHkoXCIkUGF0aFwiKSkge1xuXHRcdHJldHVybiBwYXRoSW5Nb2RlbCgoYW5ub3RhdGlvblZhbHVlIGFzIFBhdGhDb25kaXRpb25FeHByZXNzaW9uPFQ+KS4kUGF0aCwgdW5kZWZpbmVkLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvcik7XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEFwcGx5XCIpKSB7XG5cdFx0cmV0dXJuIGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbihcblx0XHRcdHtcblx0XHRcdFx0dHlwZTogXCJBcHBseVwiLFxuXHRcdFx0XHRGdW5jdGlvbjogKGFubm90YXRpb25WYWx1ZSBhcyB7ICRGdW5jdGlvbj86IHN0cmluZyB9KS4kRnVuY3Rpb24sXG5cdFx0XHRcdEFwcGx5OiAoYW5ub3RhdGlvblZhbHVlIGFzIHsgJEFwcGx5PzogdW5rbm93biB9KS4kQXBwbHlcblx0XHRcdH0gYXMgQXBwbHlBbm5vdGF0aW9uRXhwcmVzc2lvbjxUPixcblx0XHRcdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsXG5cdFx0XHR1bmRlZmluZWQsXG5cdFx0XHRwYXRoVmlzaXRvclxuXHRcdCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGFubm90YXRpb25WYWx1ZS5oYXNPd25Qcm9wZXJ0eShcIiRJZlwiKSkge1xuXHRcdHJldHVybiBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24oXG5cdFx0XHR7XG5cdFx0XHRcdHR5cGU6IFwiSWZcIixcblx0XHRcdFx0SWY6IChhbm5vdGF0aW9uVmFsdWUgYXMgeyAkSWY/OiB1bmtub3duIH0pLiRJZlxuXHRcdFx0fSBhcyBJZkFubm90YXRpb25FeHByZXNzaW9uPFQ+LFxuXHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdHBhdGhWaXNpdG9yXG5cdFx0KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH0gZWxzZSBpZiAoYW5ub3RhdGlvblZhbHVlLmhhc093blByb3BlcnR5KFwiJEVudW1NZW1iZXJcIikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQocmVzb2x2ZUVudW1WYWx1ZSgoYW5ub3RhdGlvblZhbHVlIGFzIHsgJEVudW1NZW1iZXI/OiBzdHJpbmcgfSkuJEVudW1NZW1iZXIpIGFzIFQpO1xuXHR9XG5cdHJldHVybiBjb25zdGFudChmYWxzZSBhcyBUKTtcbn1cblxuLyoqXG4gKiBQcm9jZXNzIHRoZSB7SWZBbm5vdGF0aW9uRXhwcmVzc2lvblZhbHVlfSBpbnRvIGFuIGV4cHJlc3Npb24uXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gYW5ub3RhdGlvblZhbHVlIEFuIElmIGV4cHJlc3Npb24gcmV0dXJuaW5nIHRoZSB0eXBlIFRcbiAqIEBwYXJhbSB2aXNpdGVkTmF2aWdhdGlvblBhdGhzIFRoZSBwYXRoIGZyb20gdGhlIHJvb3QgZW50aXR5IHNldFxuICogQHBhcmFtIHBhdGhWaXNpdG9yIEEgZnVuY3Rpb24gdG8gbW9kaWZ5IHRoZSByZXN1bHRpbmcgcGF0aFxuICogQHJldHVybnMgVGhlIGVxdWl2YWxlbnQgaWZFbHNlIGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFubm90YXRpb25JZkV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRhbm5vdGF0aW9uVmFsdWU6IElmQW5ub3RhdGlvbkV4cHJlc3Npb25WYWx1ZTxUPixcblx0dmlzaXRlZE5hdmlnYXRpb25QYXRoczogc3RyaW5nW10gPSBbXSxcblx0cGF0aFZpc2l0b3I/OiBGdW5jdGlvblxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+IHtcblx0cmV0dXJuIGlmRWxzZShcblx0XHRwYXJzZUFubm90YXRpb25Db25kaXRpb24oYW5ub3RhdGlvblZhbHVlWzBdLCB2aXNpdGVkTmF2aWdhdGlvblBhdGhzLCBwYXRoVmlzaXRvciksXG5cdFx0cGFyc2VBbm5vdGF0aW9uQ29uZGl0aW9uKGFubm90YXRpb25WYWx1ZVsxXSBhcyBDb25kaXRpb25hbENoZWNrT3JWYWx1ZSwgdmlzaXRlZE5hdmlnYXRpb25QYXRocywgcGF0aFZpc2l0b3IpLFxuXHRcdHBhcnNlQW5ub3RhdGlvbkNvbmRpdGlvbihhbm5vdGF0aW9uVmFsdWVbMl0gYXMgQ29uZGl0aW9uYWxDaGVja09yVmFsdWUsIHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsIHBhdGhWaXNpdG9yKVxuXHQpO1xufVxuLy8gVGhpcyB0eXBlIGlzIG5vdCByZWN1cnNpdmVseSB0cmFuc2Zvcm1lZCBmcm9tIHRoZSBtZXRhbW9kZWwgY29udGVudCwgYXMgc3VjaCB3ZSBoYXZlIHNvbWUgdWdseSB0aGluZ3MgdGhlcmVcbnR5cGUgU3ViQXBwbHlFeHByZXNzaW9uRnJvbU1ldGFtb2RlbCA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuZnVuY3Rpb24gY29udmVydFN1YkFwcGx5UGFyYW1ldGVycyhhcHBseVBhcmFtOiBTdWJBcHBseUV4cHJlc3Npb25Gcm9tTWV0YW1vZGVsKTogU3ViQXBwbHlFeHByZXNzaW9uRnJvbU1ldGFtb2RlbCB7XG5cdGxldCBhcHBseVBhcmFtQ29udmVydGVkID0gYXBwbHlQYXJhbTtcblx0aWYgKGFwcGx5UGFyYW0uaGFzT3duUHJvcGVydHkoXCIkUGF0aFwiKSkge1xuXHRcdGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSB7XG5cdFx0XHR0eXBlOiBcIlBhdGhcIixcblx0XHRcdHBhdGg6IGFwcGx5UGFyYW0uJFBhdGhcblx0XHR9IGFzIFBhdGhBbm5vdGF0aW9uRXhwcmVzc2lvbjxzdHJpbmc+O1xuXHR9IGVsc2UgaWYgKGFwcGx5UGFyYW0uaGFzT3duUHJvcGVydHkoXCIkSWZcIikpIHtcblx0XHRhcHBseVBhcmFtQ29udmVydGVkID0ge1xuXHRcdFx0dHlwZTogXCJJZlwiLFxuXHRcdFx0SWY6IGFwcGx5UGFyYW0uJElmXG5cdFx0fSBhcyBJZkFubm90YXRpb25FeHByZXNzaW9uPHN0cmluZz47XG5cdH0gZWxzZSBpZiAoYXBwbHlQYXJhbS5oYXNPd25Qcm9wZXJ0eShcIiRBcHBseVwiKSkge1xuXHRcdGFwcGx5UGFyYW1Db252ZXJ0ZWQgPSB7XG5cdFx0XHR0eXBlOiBcIkFwcGx5XCIsXG5cdFx0XHRGdW5jdGlvbjogYXBwbHlQYXJhbS4kRnVuY3Rpb24sXG5cdFx0XHRBcHBseTogYXBwbHlQYXJhbS4kQXBwbHlcblx0XHR9IGFzIEFwcGx5QW5ub3RhdGlvbkV4cHJlc3Npb248c3RyaW5nPjtcblx0fVxuXHRyZXR1cm4gYXBwbHlQYXJhbUNvbnZlcnRlZDtcbn1cblxudHlwZSBPRGF0YUZ1bmN0aW9uID0gXCJvZGF0YS5jb25jYXRcIiB8IFwib2RhdGEuZmlsbFVyaVRlbXBsYXRlXCIgfCBcIm9kYXRhLnVyaUVuY29kZVwiO1xuZXhwb3J0IGZ1bmN0aW9uIGFubm90YXRpb25BcHBseUV4cHJlc3Npb24oXG5cdGFwcGx5RXhwcmVzc2lvbjogQXBwbHlBbm5vdGF0aW9uRXhwcmVzc2lvbjxzdHJpbmc+LFxuXHR2aXNpdGVkTmF2aWdhdGlvblBhdGhzOiBzdHJpbmdbXSA9IFtdLFxuXHRwYXRoVmlzaXRvcj86IEZ1bmN0aW9uXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248c3RyaW5nPiB7XG5cdHN3aXRjaCAoYXBwbHlFeHByZXNzaW9uLkZ1bmN0aW9uIGFzIE9EYXRhRnVuY3Rpb24pIHtcblx0XHRjYXNlIFwib2RhdGEuY29uY2F0XCI6XG5cdFx0XHRyZXR1cm4gY29uY2F0KFxuXHRcdFx0XHQuLi5hcHBseUV4cHJlc3Npb24uQXBwbHkubWFwKChhcHBseVBhcmFtKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbihcblx0XHRcdFx0XHRcdGNvbnZlcnRTdWJBcHBseVBhcmFtZXRlcnMoYXBwbHlQYXJhbSkgYXMgUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8c3RyaW5nPixcblx0XHRcdFx0XHRcdHZpc2l0ZWROYXZpZ2F0aW9uUGF0aHMsXG5cdFx0XHRcdFx0XHR1bmRlZmluZWQsXG5cdFx0XHRcdFx0XHRwYXRoVmlzaXRvclxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpO1xuXHRcdGNhc2UgXCJvZGF0YS51cmlFbmNvZGVcIjpcblx0XHRcdGNvbnN0IHBhcmFtZXRlciA9IGdldEV4cHJlc3Npb25Gcm9tQW5ub3RhdGlvbihcblx0XHRcdFx0Y29udmVydFN1YkFwcGx5UGFyYW1ldGVycyhcblx0XHRcdFx0XHRhcHBseUV4cHJlc3Npb24uQXBwbHlbMF0gYXMgdW5rbm93biBhcyBTdWJBcHBseUV4cHJlc3Npb25Gcm9tTWV0YW1vZGVsXG5cdFx0XHRcdCkgYXMgUHJvcGVydHlBbm5vdGF0aW9uVmFsdWU8c3RyaW5nPixcblx0XHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdFx0dW5kZWZpbmVkLFxuXHRcdFx0XHRwYXRoVmlzaXRvclxuXHRcdFx0KTtcblx0XHRcdC8vIFRoZSBzZWNvbmQgcGFyYW1ldGVyIGZvciB1cmlFbmNvZGUgaXMgYWx3YXlzIGEgc3RyaW5nIHNpbmNlIHRoZSB0YXJnZXQgZXZhbHVhdGlvbiBpcyBhZ2FpbnN0IGEgZm9ybWF0VmFsdWUgY2FsbCBpbiBPRGF0YVV0aWxzIHdoaWNoIGV4cGVjdCB0aGUgdGFyZ2V0IHR5cGUgYXMgc2Vjb25kIHBhcmFtZXRlclxuXHRcdFx0cmV0dXJuIGZuKFwib2RhdGEudXJpRW5jb2RlXCIsIFtwYXJhbWV0ZXIsIFwiRWRtLlN0cmluZ1wiXSwgdW5kZWZpbmVkLCB0cnVlKTtcblx0XHRjYXNlIFwib2RhdGEuZmlsbFVyaVRlbXBsYXRlXCI6XG5cdFx0XHRjb25zdCB0ZW1wbGF0ZSA9IGFwcGx5RXhwcmVzc2lvbi5BcHBseVswXTtcblx0XHRcdGNvbnN0IHRlbXBsYXRlUGFyYW1zID0gYXBwbHlFeHByZXNzaW9uLkFwcGx5LnNsaWNlKDEpIGFzIHVua25vd24gYXMgU3ViQXBwbHlFeHByZXNzaW9uRnJvbU1ldGFtb2RlbFtdO1xuXHRcdFx0Y29uc3QgdGFyZ2V0T2JqZWN0OiBSZWNvcmQ8c3RyaW5nLCBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj4+ID0ge307XG5cdFx0XHR0ZW1wbGF0ZVBhcmFtcy5mb3JFYWNoKChhcHBseVBhcmFtKSA9PiB7XG5cdFx0XHRcdHRhcmdldE9iamVjdFthcHBseVBhcmFtLiROYW1lIGFzIHN0cmluZ10gPSBnZXRFeHByZXNzaW9uRnJvbUFubm90YXRpb24oXG5cdFx0XHRcdFx0Y29udmVydFN1YkFwcGx5UGFyYW1ldGVycyhcblx0XHRcdFx0XHRcdGFwcGx5UGFyYW0uJExhYmVsZWRFbGVtZW50IGFzIFN1YkFwcGx5RXhwcmVzc2lvbkZyb21NZXRhbW9kZWxcblx0XHRcdFx0XHQpIGFzIFByb3BlcnR5QW5ub3RhdGlvblZhbHVlPHN0cmluZz4sXG5cdFx0XHRcdFx0dmlzaXRlZE5hdmlnYXRpb25QYXRocyxcblx0XHRcdFx0XHR1bmRlZmluZWQsXG5cdFx0XHRcdFx0cGF0aFZpc2l0b3Jcblx0XHRcdFx0KTtcblx0XHRcdH0pO1xuXHRcdFx0cmV0dXJuIGZuKFwib2RhdGEuZmlsbFVyaVRlbXBsYXRlXCIsIFt0ZW1wbGF0ZSwgdGFyZ2V0T2JqZWN0XSwgdW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcbn1cblxuLyoqXG4gKiBHZW5lcmljIGhlbHBlciBmb3IgdGhlIGNvbXBhcmlzb24gb3BlcmF0aW9ucyAoZXF1YWwsIG5vdEVxdWFsLCAuLi4pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIG9wZXJhdG9yIFRoZSBvcGVyYXRvciB0byBhcHBseVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGUgb2YgdGhlIG9wZXJhdG9yXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBvcGVyYXRvclxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZnVuY3Rpb24gY29tcGFyaXNvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdG9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IsXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRjb25zdCBsZWZ0RXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUobGVmdE9wZXJhbmQpO1xuXHRjb25zdCByaWdodEV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKHJpZ2h0T3BlcmFuZCk7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKGxlZnRFeHByZXNzaW9uLCByaWdodEV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0aWYgKGlzQ29uc3RhbnQobGVmdEV4cHJlc3Npb24pICYmIGlzQ29uc3RhbnQocmlnaHRFeHByZXNzaW9uKSkge1xuXHRcdHN3aXRjaCAob3BlcmF0b3IpIHtcblx0XHRcdGNhc2UgXCIhPT1cIjpcblx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGxlZnRFeHByZXNzaW9uLnZhbHVlICE9PSByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIj09PVwiOlxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPT09IHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSk7XG5cdFx0XHRjYXNlIFwiPFwiOlxuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWRcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPCByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIjw9XCI6XG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWQgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRyaWdodEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29uc3RhbnQoZmFsc2UpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb25zdGFudChsZWZ0RXhwcmVzc2lvbi52YWx1ZSA8PSByaWdodEV4cHJlc3Npb24udmFsdWUpO1xuXHRcdFx0Y2FzZSBcIj5cIjpcblx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdGxlZnRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZCB8fFxuXHRcdFx0XHRcdHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSA9PT0gbnVsbCB8fFxuXHRcdFx0XHRcdHJpZ2h0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJldHVybiBjb25zdGFudChmYWxzZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGxlZnRFeHByZXNzaW9uLnZhbHVlID4gcmlnaHRFeHByZXNzaW9uLnZhbHVlKTtcblx0XHRcdGNhc2UgXCI+PVwiOlxuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0bGVmdEV4cHJlc3Npb24udmFsdWUgPT09IG51bGwgfHxcblx0XHRcdFx0XHRsZWZ0RXhwcmVzc2lvbi52YWx1ZSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSBudWxsIHx8XG5cdFx0XHRcdFx0cmlnaHRFeHByZXNzaW9uLnZhbHVlID09PSB1bmRlZmluZWRcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gY29uc3RhbnQobGVmdEV4cHJlc3Npb24udmFsdWUgPj0gcmlnaHRFeHByZXNzaW9uLnZhbHVlKTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIkNvbXBhcmlzb25cIixcblx0XHRcdG9wZXJhdG9yOiBvcGVyYXRvcixcblx0XHRcdG9wZXJhbmQxOiBsZWZ0RXhwcmVzc2lvbixcblx0XHRcdG9wZXJhbmQyOiByaWdodEV4cHJlc3Npb25cblx0XHR9O1xuXHR9XG59XG5cbi8qKlxuICogR2VuZXJpYyBoZWxwZXIgZm9yIHRoZSBsZW5ndGggb2YgYW4gZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgaW5wdXQgZXhwcmVzc2lvbiBwb2ludGluZyB0byBhbiBhcnJheVxuICogQHBhcmFtIGNoZWNrVW5kZWZpbmVkIElzIHRoZSBhcnJheSBwb3RlbnRpYWxseSB1bmRlZmluZWRcbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBsZW5ndGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxlbmd0aChcblx0ZXhwcmVzc2lvbjogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+IHwgVW5yZXNvbHZhYmxlUGF0aEV4cHJlc3Npb24sXG5cdGNoZWNrVW5kZWZpbmVkID0gZmFsc2Vcbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxudW1iZXI+IHtcblx0aWYgKGV4cHJlc3Npb24uX3R5cGUgPT09IFwiVW5yZXNvbHZhYmxlXCIpIHtcblx0XHRyZXR1cm4gZXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoIWNoZWNrVW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdF90eXBlOiBcIkxlbmd0aFwiLFxuXHRcdFx0cGF0aEluTW9kZWw6IGV4cHJlc3Npb25cblx0XHR9O1xuXHR9XG5cdHJldHVybiBpZkVsc2UoZXF1YWwoZXhwcmVzc2lvbiwgdW5kZWZpbmVkKSwgLTEsIGxlbmd0aChleHByZXNzaW9uKSk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJlcXVhbFwiICg9PT0pLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGxlZnRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSBsZWZ0IHNpZGVcbiAqIEBwYXJhbSByaWdodE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm5zIEFuIGV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBjb21wYXJpc29uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbDxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRjb25zdCBsZWZ0RXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUobGVmdE9wZXJhbmQpO1xuXHRjb25zdCByaWdodEV4cHJlc3Npb24gPSB3cmFwUHJpbWl0aXZlKHJpZ2h0T3BlcmFuZCk7XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKGxlZnRFeHByZXNzaW9uLCByaWdodEV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIHVucmVzb2x2YWJsZUV4cHJlc3Npb247XG5cdH1cblx0aWYgKF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwobGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQodHJ1ZSk7XG5cdH1cblxuXHRmdW5jdGlvbiByZWR1Y2UobGVmdDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LCByaWdodDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+KTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHwgdW5kZWZpbmVkIHtcblx0XHRpZiAobGVmdC5fdHlwZSA9PT0gXCJDb21wYXJpc29uXCIgJiYgaXNUcnVlKHJpZ2h0KSkge1xuXHRcdFx0Ly8gY29tcGFyZShhLCBiKSA9PT0gdHJ1ZSB+fj4gY29tcGFyZShhLCBiKVxuXHRcdFx0cmV0dXJuIGxlZnQ7XG5cdFx0fSBlbHNlIGlmIChsZWZ0Ll90eXBlID09PSBcIkNvbXBhcmlzb25cIiAmJiBpc0ZhbHNlKHJpZ2h0KSkge1xuXHRcdFx0Ly8gY29tcGFyZShhLCBiKSA9PT0gZmFsc2Ugfn4+ICFjb21wYXJlKGEsIGIpXG5cdFx0XHRyZXR1cm4gbm90KGxlZnQpO1xuXHRcdH0gZWxzZSBpZiAobGVmdC5fdHlwZSA9PT0gXCJJZkVsc2VcIiAmJiBfY2hlY2tFeHByZXNzaW9uc0FyZUVxdWFsKGxlZnQub25UcnVlLCByaWdodCkpIHtcblx0XHRcdC8vIChpZiAoeCkgeyBhIH0gZWxzZSB7IGIgfSkgPT09IGEgfn4+IHggfHwgKGIgPT09IGEpXG5cdFx0XHRyZXR1cm4gb3IobGVmdC5jb25kaXRpb24sIGVxdWFsKGxlZnQub25GYWxzZSwgcmlnaHQpKTtcblx0XHR9IGVsc2UgaWYgKGxlZnQuX3R5cGUgPT09IFwiSWZFbHNlXCIgJiYgX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChsZWZ0Lm9uRmFsc2UsIHJpZ2h0KSkge1xuXHRcdFx0Ly8gKGlmICh4KSB7IGEgfSBlbHNlIHsgYiB9KSA9PT0gYiB+fj4gIXggfHwgKGEgPT09IGIpXG5cdFx0XHRyZXR1cm4gb3Iobm90KGxlZnQuY29uZGl0aW9uKSwgZXF1YWwobGVmdC5vblRydWUsIHJpZ2h0KSk7XG5cdFx0fSBlbHNlIGlmIChcblx0XHRcdGxlZnQuX3R5cGUgPT09IFwiSWZFbHNlXCIgJiZcblx0XHRcdGlzQ29uc3RhbnQobGVmdC5vblRydWUpICYmXG5cdFx0XHRpc0NvbnN0YW50KGxlZnQub25GYWxzZSkgJiZcblx0XHRcdGlzQ29uc3RhbnQocmlnaHQpICYmXG5cdFx0XHQhX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChsZWZ0Lm9uVHJ1ZSwgcmlnaHQpICYmXG5cdFx0XHQhX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChsZWZ0Lm9uRmFsc2UsIHJpZ2h0KVxuXHRcdCkge1xuXHRcdFx0cmV0dXJuIGNvbnN0YW50KGZhbHNlKTtcblx0XHR9XG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXG5cdC8vIGV4cGxvaXQgc3ltbWV0cnk6IGEgPT09IGIgPH4+IGIgPT09IGFcblx0Y29uc3QgcmVkdWNlZCA9IHJlZHVjZShsZWZ0RXhwcmVzc2lvbiwgcmlnaHRFeHByZXNzaW9uKSA/PyByZWR1Y2UocmlnaHRFeHByZXNzaW9uLCBsZWZ0RXhwcmVzc2lvbik7XG5cdHJldHVybiByZWR1Y2VkID8/IGNvbXBhcmlzb24oXCI9PT1cIiwgbGVmdEV4cHJlc3Npb24sIHJpZ2h0RXhwcmVzc2lvbik7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJub3QgZXF1YWxcIiAoIT09KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gbm90RXF1YWw8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRsZWZ0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRyaWdodE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPlxuKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+IHtcblx0cmV0dXJuIG5vdChlcXVhbChsZWZ0T3BlcmFuZCwgcmlnaHRPcGVyYW5kKSk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJncmVhdGVyIG9yIGVxdWFsXCIgKD49KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JlYXRlck9yRXF1YWw8VCBleHRlbmRzIERlZmluZWRQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPj1cIiwgbGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJncmVhdGVyIHRoYW5cIiAoPikuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZVxuICogQHBhcmFtIHJpZ2h0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgY29tcGFyaXNvblxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyZWF0ZXJUaGFuPFQgZXh0ZW5kcyBEZWZpbmVkUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRyZXR1cm4gY29tcGFyaXNvbihcIj5cIiwgbGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJsZXNzIG9yIGVxdWFsXCIgKDw9KS5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdGFyZ2V0IHR5cGVcbiAqIEBwYXJhbSBsZWZ0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgbGVmdCBzaWRlXG4gKiBAcGFyYW0gcmlnaHRPcGVyYW5kIFRoZSBvcGVyYW5kIG9uIHRoZSByaWdodCBzaWRlIG9mIHRoZSBjb21wYXJpc29uXG4gKiBAcmV0dXJucyBBbiBleHByZXNzaW9uIHJlcHJlc2VudGluZyB0aGUgY29tcGFyaXNvblxuICovXG5leHBvcnQgZnVuY3Rpb24gbGVzc09yRXF1YWw8VCBleHRlbmRzIERlZmluZWRQcmltaXRpdmVUeXBlPihcblx0bGVmdE9wZXJhbmQ6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0cmlnaHRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPiB7XG5cdHJldHVybiBjb21wYXJpc29uKFwiPD1cIiwgbGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCk7XG59XG5cbi8qKlxuICogQ29tcGFyaXNvbjogXCJsZXNzIHRoYW5cIiAoPCkuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gbGVmdE9wZXJhbmQgVGhlIG9wZXJhbmQgb24gdGhlIGxlZnQgc2lkZVxuICogQHBhcmFtIHJpZ2h0T3BlcmFuZCBUaGUgb3BlcmFuZCBvbiB0aGUgcmlnaHQgc2lkZSBvZiB0aGUgY29tcGFyaXNvblxuICogQHJldHVybnMgQW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBhcmlzb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxlc3NUaGFuPFQgZXh0ZW5kcyBEZWZpbmVkUHJpbWl0aXZlVHlwZT4oXG5cdGxlZnRPcGVyYW5kOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4sXG5cdHJpZ2h0T3BlcmFuZDogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+XG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRyZXR1cm4gY29tcGFyaXNvbihcIjxcIiwgbGVmdE9wZXJhbmQsIHJpZ2h0T3BlcmFuZCk7XG59XG5cbi8qKlxuICogSWYtdGhlbi1lbHNlIGV4cHJlc3Npb24uXG4gKlxuICogRXZhbHVhdGVzIHRvIG9uVHJ1ZSBpZiB0aGUgY29uZGl0aW9uIGV2YWx1YXRlcyB0byB0cnVlLCBlbHNlIGV2YWx1YXRlcyB0byBvbkZhbHNlLlxuICpcbiAqIEB0ZW1wbGF0ZSBUIFRoZSB0YXJnZXQgdHlwZVxuICogQHBhcmFtIGNvbmRpdGlvbiBUaGUgY29uZGl0aW9uIHRvIGV2YWx1YXRlXG4gKiBAcGFyYW0gb25UcnVlIEV4cHJlc3Npb24gcmVzdWx0IGlmIHRoZSBjb25kaXRpb24gZXZhbHVhdGVzIHRvIHRydWVcbiAqIEBwYXJhbSBvbkZhbHNlIEV4cHJlc3Npb24gcmVzdWx0IGlmIHRoZSBjb25kaXRpb24gZXZhbHVhdGVzIHRvIGZhbHNlXG4gKiBAcmV0dXJucyBUaGUgZXhwcmVzc2lvbiB0aGF0IHJlcHJlc2VudHMgdGhpcyBjb25kaXRpb25hbCBjaGVja1xuICovXG5leHBvcnQgZnVuY3Rpb24gaWZFbHNlPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0Y29uZGl0aW9uOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8Ym9vbGVhbj4sXG5cdG9uVHJ1ZTogRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFQ+LFxuXHRvbkZhbHNlOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD5cbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGxldCBjb25kaXRpb25FeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShjb25kaXRpb24pO1xuXHRsZXQgb25UcnVlRXhwcmVzc2lvbiA9IHdyYXBQcmltaXRpdmUob25UcnVlKTtcblx0bGV0IG9uRmFsc2VFeHByZXNzaW9uID0gd3JhcFByaW1pdGl2ZShvbkZhbHNlKTtcblxuXHQvLyBzd2FwIGJyYW5jaGVzIGlmIHRoZSBjb25kaXRpb24gaXMgYSBuZWdhdGlvblxuXHRpZiAoY29uZGl0aW9uRXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJOb3RcIikge1xuXHRcdC8vIGlmRWxzZShub3QoWCksIGEsIGIpIC0tPiBpZkVsc2UoWCwgYiwgYSlcblx0XHRbb25UcnVlRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb25dID0gW29uRmFsc2VFeHByZXNzaW9uLCBvblRydWVFeHByZXNzaW9uXTtcblx0XHRjb25kaXRpb25FeHByZXNzaW9uID0gbm90KGNvbmRpdGlvbkV4cHJlc3Npb24pO1xuXHR9XG5cblx0Ly8gaW5saW5lIG5lc3RlZCBpZi1lbHNlIGV4cHJlc3Npb25zOiBvblRydWUgYnJhbmNoXG5cdC8vIGlmRWxzZShYLCBpZkVsc2UoWCwgYSwgYiksIGMpID09PiBpZkVsc2UoWCwgYSwgYylcblx0aWYgKG9uVHJ1ZUV4cHJlc3Npb24uX3R5cGUgPT09IFwiSWZFbHNlXCIgJiYgX2NoZWNrRXhwcmVzc2lvbnNBcmVFcXVhbChjb25kaXRpb25FeHByZXNzaW9uLCBvblRydWVFeHByZXNzaW9uLmNvbmRpdGlvbikpIHtcblx0XHRvblRydWVFeHByZXNzaW9uID0gb25UcnVlRXhwcmVzc2lvbi5vblRydWU7XG5cdH1cblxuXHQvLyBpbmxpbmUgbmVzdGVkIGlmLWVsc2UgZXhwcmVzc2lvbnM6IG9uRmFsc2UgYnJhbmNoXG5cdC8vIGlmRWxzZShYLCBhLCBpZkVsc2UoWCwgYiwgYykpID09PiBpZkVsc2UoWCwgYSwgYylcblx0aWYgKG9uRmFsc2VFeHByZXNzaW9uLl90eXBlID09PSBcIklmRWxzZVwiICYmIF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwoY29uZGl0aW9uRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb24uY29uZGl0aW9uKSkge1xuXHRcdG9uRmFsc2VFeHByZXNzaW9uID0gb25GYWxzZUV4cHJlc3Npb24ub25GYWxzZTtcblx0fVxuXG5cdC8vIChpZiB0cnVlIHRoZW4gYSBlbHNlIGIpICB+fj4gYVxuXHQvLyAoaWYgZmFsc2UgdGhlbiBhIGVsc2UgYikgfn4+IGJcblx0aWYgKGlzQ29uc3RhbnQoY29uZGl0aW9uRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gY29uZGl0aW9uRXhwcmVzc2lvbi52YWx1ZSA/IG9uVHJ1ZUV4cHJlc3Npb24gOiBvbkZhbHNlRXhwcmVzc2lvbjtcblx0fVxuXG5cdC8vIGlmIChpc0NvbnN0YW50Qm9vbGVhbihvblRydWVFeHByZXNzaW9uKSB8fCBpc0NvbnN0YW50Qm9vbGVhbihvbkZhbHNlRXhwcmVzc2lvbikpIHtcblx0Ly8gXHRyZXR1cm4gb3IoYW5kKGNvbmRpdGlvbiwgb25UcnVlRXhwcmVzc2lvbiBhcyBFeHByZXNzaW9uPGJvb2xlYW4+KSwgYW5kKG5vdChjb25kaXRpb24pLCBvbkZhbHNlRXhwcmVzc2lvbiBhcyBFeHByZXNzaW9uPGJvb2xlYW4+KSkgYXMgRXhwcmVzc2lvbjxUPlxuXHQvLyB9XG5cblx0Ly8gKGlmIFggdGhlbiBhIGVsc2UgYSkgfn4+IGFcblx0aWYgKF9jaGVja0V4cHJlc3Npb25zQXJlRXF1YWwob25UcnVlRXhwcmVzc2lvbiwgb25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIG9uVHJ1ZUV4cHJlc3Npb247XG5cdH1cblxuXHQvLyBpZiBYIHRoZW4gYSBlbHNlIGZhbHNlIH5+PiBYICYmIGFcblx0aWYgKGlzRmFsc2Uob25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIGFuZChjb25kaXRpb25FeHByZXNzaW9uLCBvblRydWVFeHByZXNzaW9uIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPikgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9XG5cblx0Ly8gaWYgWCB0aGVuIGEgZWxzZSB0cnVlIH5+PiAhWCB8fCBhXG5cdGlmIChpc1RydWUob25GYWxzZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIG9yKG5vdChjb25kaXRpb25FeHByZXNzaW9uKSwgb25UcnVlRXhwcmVzc2lvbiBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4pIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPjtcblx0fVxuXG5cdC8vIGlmIFggdGhlbiBmYWxzZSBlbHNlIGEgfn4+ICFYICYmIGFcblx0aWYgKGlzRmFsc2Uob25UcnVlRXhwcmVzc2lvbikpIHtcblx0XHRyZXR1cm4gYW5kKG5vdChjb25kaXRpb25FeHByZXNzaW9uKSwgb25GYWxzZUV4cHJlc3Npb24gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPGJvb2xlYW4+KSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdH1cblxuXHQvLyBpZiBYIHRoZW4gdHJ1ZSBlbHNlIGEgfn4+IFggfHwgYVxuXHRpZiAoaXNUcnVlKG9uVHJ1ZUV4cHJlc3Npb24pKSB7XG5cdFx0cmV0dXJuIG9yKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uRmFsc2VFeHByZXNzaW9uIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxib29sZWFuPikgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHR9XG5cdGlmIChoYXNVbnJlc29sdmFibGVFeHByZXNzaW9uKGNvbmRpdGlvbkV4cHJlc3Npb24sIG9uVHJ1ZUV4cHJlc3Npb24sIG9uRmFsc2VFeHByZXNzaW9uKSkge1xuXHRcdHJldHVybiB1bnJlc29sdmFibGVFeHByZXNzaW9uO1xuXHR9XG5cdGlmIChpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbihjb25kaXRpb24pIHx8IGlzQ29tcGxleFR5cGVFeHByZXNzaW9uKG9uVHJ1ZSkgfHwgaXNDb21wbGV4VHlwZUV4cHJlc3Npb24ob25GYWxzZSkpIHtcblx0XHRsZXQgcGF0aElkeCA9IDA7XG5cdFx0Y29uc3QgbXlJZkVsc2VFeHByZXNzaW9uID0gZm9ybWF0UmVzdWx0KFtjb25kaXRpb24sIG9uVHJ1ZSwgb25GYWxzZV0sIFwic2FwLmZlLmNvcmUuZm9ybWF0dGVycy5TdGFuZGFyZEZvcm1hdHRlciNpZkVsc2VcIik7XG5cdFx0Y29uc3QgYWxsUGFydHMgPSBbXTtcblx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdG15SWZFbHNlRXhwcmVzc2lvbixcblx0XHRcdFwiUGF0aEluTW9kZWxcIixcblx0XHRcdChjb25zdGFudFBhdGg6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjx1bmtub3duPikgPT4ge1xuXHRcdFx0XHRhbGxQYXJ0cy5wdXNoKGNvbnN0YW50UGF0aCk7XG5cdFx0XHRcdHJldHVybiBwYXRoSW5Nb2RlbChgJCR7cGF0aElkeCsrfWAsIFwiJFwiKTtcblx0XHRcdH0sXG5cdFx0XHR0cnVlXG5cdFx0KTtcblx0XHRhbGxQYXJ0cy51bnNoaWZ0KGNvbnN0YW50KEpTT04uc3RyaW5naWZ5KG15SWZFbHNlRXhwcmVzc2lvbikpKTtcblx0XHRyZXR1cm4gZm9ybWF0UmVzdWx0KGFsbFBhcnRzLCBcInNhcC5mZS5jb3JlLmZvcm1hdHRlcnMuU3RhbmRhcmRGb3JtYXR0ZXIjZXZhbHVhdGVDb21wbGV4RXhwcmVzc2lvblwiLCB1bmRlZmluZWQsIHRydWUpO1xuXHR9XG5cdHJldHVybiB7XG5cdFx0X3R5cGU6IFwiSWZFbHNlXCIsXG5cdFx0Y29uZGl0aW9uOiBjb25kaXRpb25FeHByZXNzaW9uLFxuXHRcdG9uVHJ1ZTogb25UcnVlRXhwcmVzc2lvbixcblx0XHRvbkZhbHNlOiBvbkZhbHNlRXhwcmVzc2lvblxuXHR9O1xufVxuXG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBjdXJyZW50IGV4cHJlc3Npb24gaGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBkZWZhdWx0IG1vZGVsICh1bmRlZmluZWQpLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uIHRvIGV2YWx1YXRlXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlcmUgaXMgYSByZWZlcmVuY2UgdG8gdGhlIGRlZmF1bHQgY29udGV4dFxuICovXG5mdW5jdGlvbiBoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb246IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPik6IGJvb2xlYW4ge1xuXHRzd2l0Y2ggKGV4cHJlc3Npb24uX3R5cGUpIHtcblx0XHRjYXNlIFwiQ29uc3RhbnRcIjpcblx0XHRjYXNlIFwiRm9ybWF0dGVyXCI6XG5cdFx0Y2FzZSBcIkNvbXBsZXhUeXBlXCI6XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0Y2FzZSBcIlNldFwiOlxuXHRcdFx0cmV0dXJuIGV4cHJlc3Npb24ub3BlcmFuZHMuc29tZShoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KTtcblx0XHRjYXNlIFwiUGF0aEluTW9kZWxcIjpcblx0XHRcdHJldHVybiBleHByZXNzaW9uLm1vZGVsTmFtZSA9PT0gdW5kZWZpbmVkO1xuXHRcdGNhc2UgXCJDb21wYXJpc29uXCI6XG5cdFx0XHRyZXR1cm4gaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dChleHByZXNzaW9uLm9wZXJhbmQxKSB8fCBoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KGV4cHJlc3Npb24ub3BlcmFuZDIpO1xuXHRcdGNhc2UgXCJJZkVsc2VcIjpcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5jb25kaXRpb24pIHx8XG5cdFx0XHRcdGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5vblRydWUpIHx8XG5cdFx0XHRcdGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5vbkZhbHNlKVxuXHRcdFx0KTtcblx0XHRjYXNlIFwiTm90XCI6XG5cdFx0Y2FzZSBcIlRydXRoeVwiOlxuXHRcdFx0cmV0dXJuIGhhc1JlZmVyZW5jZVRvRGVmYXVsdENvbnRleHQoZXhwcmVzc2lvbi5vcGVyYW5kKTtcblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59XG5cbi8vIFRoaXMgaXMgb25lIGNhc2Ugd2hlcmUgYW55IGRvZXMgbWFrZSBzZW5zZS4uLlxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbmV4cG9ydCB0eXBlIEZuPFQ+ID0gKCguLi5wYXJhbXM6IGFueSkgPT4gVCB8IFByb21pc2U8VD4pICYge1xuXHRfX2Z1bmN0aW9uTmFtZTogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBAdHlwZWRlZiBXcmFwcGVkVHVwbGVcbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9iYW4tdHMtY29tbWVudFxuLy8gQHRzLWlnbm9yZVxudHlwZSBXcmFwcGVkVHVwbGU8VD4gPSB7IFtLIGluIGtleW9mIFRdOiBXcmFwcGVkVHVwbGU8VFtLXT4gfCBFeHByZXNzaW9uT3JQcmltaXRpdmU8VFtLXT4gfCB1bmRlZmluZWQgfTtcblxuLy8gU28sIHRoaXMgd29ya3MgYnV0IEkgY2Fubm90IGdldCBpdCB0byBjb21waWxlIDpELCBidXQgaXQgc3RpbGwgZG9lcyB3aGF0IGlzIGV4cGVjdGVkLi4uXG5cbi8qKlxuICogQSBmdW5jdGlvbiByZWZlcmVuY2Ugb3IgYSBmdW5jdGlvbiBuYW1lLlxuICovXG50eXBlIEZ1bmN0aW9uT3JOYW1lPFQ+ID0gRm48VD4gfCBzdHJpbmc7XG5cbi8qKlxuICogRnVuY3Rpb24gcGFyYW1ldGVycywgZWl0aGVyIGRlcml2ZWQgZnJvbSB0aGUgZnVuY3Rpb24gb3IgYW4gdW50eXBlZCBhcnJheS5cbiAqL1xudHlwZSBGdW5jdGlvblBhcmFtZXRlcnM8VCwgRiBleHRlbmRzIEZ1bmN0aW9uT3JOYW1lPFQ+PiA9IEYgZXh0ZW5kcyBGbjxUPiA/IFBhcmFtZXRlcnM8Rj4gOiB1bmtub3duW107XG5cbi8qKlxuICogQ2FsbHMgYSBmb3JtYXR0ZXIgZnVuY3Rpb24gdG8gcHJvY2VzcyB0aGUgcGFyYW1ldGVycy5cbiAqIElmIHJlcXVpcmVDb250ZXh0IGlzIHNldCB0byB0cnVlIGFuZCBubyBjb250ZXh0IGlzIHBhc3NlZCBhIGRlZmF1bHQgY29udGV4dCB3aWxsIGJlIGFkZGVkIGF1dG9tYXRpY2FsbHkuXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqIEB0ZW1wbGF0ZSBVXG4gKiBAcGFyYW0gcGFyYW1ldGVycyBUaGUgbGlzdCBvZiBwYXJhbWV0ZXIgdGhhdCBzaG91bGQgbWF0Y2ggdGhlIHR5cGUgYW5kIG51bWJlciBvZiB0aGUgZm9ybWF0dGVyIGZ1bmN0aW9uXG4gKiBAcGFyYW0gZm9ybWF0dGVyRnVuY3Rpb24gVGhlIGZ1bmN0aW9uIHRvIGNhbGxcbiAqIEBwYXJhbSBbY29udGV4dEVudGl0eVR5cGVdIElmIG5vIHBhcmFtZXRlciByZWZlcnMgdG8gdGhlIGNvbnRleHQgdGhlbiB3ZSB1c2UgdGhpcyBpbmZvcm1hdGlvbiB0byBhZGQgYSByZWZlcmVuY2UgdG8gdGhlIGtleXMgZnJvbSB0aGUgZW50aXR5IHR5cGUuXG4gKiBAcGFyYW0gW2lnbm9yZUNvbXBsZXhUeXBlXSBXaGV0aGVyIHRvIGlnbm9yZSB0aGUgdHJhbnNnZm9ybWF0aW9uIHRvIHRoZSBTdGFuZGFyZEZvcm1hdHRlciBvciBub3RcbiAqIEByZXR1cm5zIFRoZSBjb3JyZXNwb25kaW5nIGV4cHJlc3Npb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFJlc3VsdDxULCBVIGV4dGVuZHMgRm48VD4+KFxuXHRwYXJhbWV0ZXJzOiBXcmFwcGVkVHVwbGU8UGFyYW1ldGVyczxVPj4sXG5cdGZvcm1hdHRlckZ1bmN0aW9uOiBVIHwgc3RyaW5nLFxuXHRjb250ZXh0RW50aXR5VHlwZT86IEVudGl0eVR5cGUsXG5cdGlnbm9yZUNvbXBsZXhUeXBlID0gZmFsc2Vcbik6IEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxUPiB7XG5cdGNvbnN0IHBhcmFtZXRlckV4cHJlc3Npb25zID0gKHBhcmFtZXRlcnMgYXMgRXhwcmVzc2lvbk9yUHJpbWl0aXZlPFByaW1pdGl2ZVR5cGU+W10pLm1hcCh3cmFwUHJpbWl0aXZlKTtcblxuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbiguLi5wYXJhbWV0ZXJFeHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoY29udGV4dEVudGl0eVR5cGUpIHtcblx0XHQvLyBPdGhlcndpc2UsIGlmIHRoZSBjb250ZXh0IGlzIHJlcXVpcmVkIGFuZCBubyBjb250ZXh0IGlzIHByb3ZpZGVkIG1ha2Ugc3VyZSB0byBhZGQgdGhlIGRlZmF1bHQgYmluZGluZ1xuXHRcdGlmICghcGFyYW1ldGVyRXhwcmVzc2lvbnMuc29tZShoYXNSZWZlcmVuY2VUb0RlZmF1bHRDb250ZXh0KSkge1xuXHRcdFx0Y29udGV4dEVudGl0eVR5cGUua2V5cy5mb3JFYWNoKChrZXkpID0+IHBhcmFtZXRlckV4cHJlc3Npb25zLnB1c2gocGF0aEluTW9kZWwoa2V5Lm5hbWUsIFwiXCIpKSk7XG5cdFx0fVxuXHR9XG5cdGxldCBmdW5jdGlvbk5hbWUgPSBcIlwiO1xuXHRpZiAodHlwZW9mIGZvcm1hdHRlckZ1bmN0aW9uID09PSBcInN0cmluZ1wiKSB7XG5cdFx0ZnVuY3Rpb25OYW1lID0gZm9ybWF0dGVyRnVuY3Rpb247XG5cdH0gZWxzZSB7XG5cdFx0ZnVuY3Rpb25OYW1lID0gZm9ybWF0dGVyRnVuY3Rpb24uX19mdW5jdGlvbk5hbWU7XG5cdH1cblx0Ly8gRm9ybWF0dGVyTmFtZSBjYW4gYmUgb2YgZm9ybWF0IHNhcC5mZS5jb3JlLnh4eCNtZXRob2ROYW1lIHRvIGhhdmUgbXVsdGlwbGUgZm9ybWF0dGVyIGluIG9uZSBjbGFzc1xuXHRjb25zdCBbZm9ybWF0dGVyQ2xhc3MsIGZvcm1hdHRlck5hbWVdID0gZnVuY3Rpb25OYW1lLnNwbGl0KFwiI1wiKTtcblxuXHQvLyBJbiBzb21lIGNhc2Ugd2UgYWxzbyBjYW5ub3QgY2FsbCBkaXJlY3RseSBhIGZ1bmN0aW9uIGJlY2F1c2Ugb2YgdG9vIGNvbXBsZXggaW5wdXQsIGluIHRoYXQgY2FzZSB3ZSBuZWVkIHRvIGNvbnZlcnQgdG8gYSBzaW1wbGVyIGZ1bmN0aW9uIGNhbGxcblx0aWYgKFxuXHRcdCFpZ25vcmVDb21wbGV4VHlwZSAmJlxuXHRcdChwYXJhbWV0ZXJFeHByZXNzaW9ucy5zb21lKGlzQ29tcGxleFR5cGVFeHByZXNzaW9uKSB8fFxuXHRcdFx0cGFyYW1ldGVyRXhwcmVzc2lvbnMuc29tZShpc0NvbmNhdEV4cHJlc3Npb24pIHx8XG5cdFx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy5zb21lKGlzSWZFbHNlRXhwcmVzc2lvbikpXG5cdCkge1xuXHRcdGxldCBwYXRoSWR4ID0gMDtcblx0XHRjb25zdCBteUZvcm1hdEV4cHJlc3Npb24gPSBmb3JtYXRSZXN1bHQocGFyYW1ldGVyRXhwcmVzc2lvbnMsIGZ1bmN0aW9uTmFtZSwgdW5kZWZpbmVkLCB0cnVlKTtcblx0XHRjb25zdCBhbGxQYXJ0cyA9IFtdO1xuXHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0bXlGb3JtYXRFeHByZXNzaW9uLFxuXHRcdFx0XCJQYXRoSW5Nb2RlbFwiLFxuXHRcdFx0KGNvbnN0YW50UGF0aDogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+KSA9PiB7XG5cdFx0XHRcdGFsbFBhcnRzLnB1c2goY29uc3RhbnRQYXRoKTtcblx0XHRcdFx0cmV0dXJuIHBhdGhJbk1vZGVsKGAkJHtwYXRoSWR4Kyt9YCwgXCIkXCIpO1xuXHRcdFx0fSxcblx0XHRcdHRydWVcblx0XHQpO1xuXHRcdGFsbFBhcnRzLnVuc2hpZnQoY29uc3RhbnQoSlNPTi5zdHJpbmdpZnkobXlGb3JtYXRFeHByZXNzaW9uKSkpO1xuXHRcdHJldHVybiBmb3JtYXRSZXN1bHQoYWxsUGFydHMsIFwic2FwLmZlLmNvcmUuZm9ybWF0dGVycy5TdGFuZGFyZEZvcm1hdHRlciNldmFsdWF0ZUNvbXBsZXhFeHByZXNzaW9uXCIsIHVuZGVmaW5lZCwgdHJ1ZSk7XG5cdH0gZWxzZSBpZiAoISFmb3JtYXR0ZXJOYW1lICYmIGZvcm1hdHRlck5hbWUubGVuZ3RoID4gMCkge1xuXHRcdHBhcmFtZXRlckV4cHJlc3Npb25zLnVuc2hpZnQoY29uc3RhbnQoZm9ybWF0dGVyTmFtZSkpO1xuXHR9XG5cblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJGb3JtYXR0ZXJcIixcblx0XHRmbjogZm9ybWF0dGVyQ2xhc3MsXG5cdFx0cGFyYW1ldGVyczogcGFyYW1ldGVyRXhwcmVzc2lvbnNcblx0fTtcbn1cblxudHlwZSBCaW5kaW5nQ29uc3RyYWludHMgPSB7XG5cdHNjYWxlPzogbnVtYmVyO1xuXHRwcmVjaXNpb24/OiBudW1iZXI7XG5cdG1heExlbmd0aD86IG51bWJlcjtcblx0bnVsbGFibGU/OiBib29sZWFuO1xuXHRtaW5pbXVtPzogc3RyaW5nO1xuXHRtYXhpbXVtPzogc3RyaW5nO1xuXHRpc0RpZ2l0U2VxdWVuY2U/OiBib29sZWFuO1xuXHRWND86IGJvb2xlYW47XG59O1xuZXhwb3J0IGZ1bmN0aW9uIHNldFVwQ29uc3RyYWludHModGFyZ2V0TWFwcGluZzogVHlwZU1hcHBpbmdEZWZpbml0aW9uLCBwcm9wZXJ0eTogUHJvcGVydHkgfCBBY3Rpb25QYXJhbWV0ZXIpOiBCaW5kaW5nQ29uc3RyYWludHMge1xuXHRjb25zdCBjb25zdHJhaW50czogQmluZGluZ0NvbnN0cmFpbnRzID0ge307XG5cdGlmICh0YXJnZXRNYXBwaW5nPy5jb25zdHJhaW50cz8uJFNjYWxlICYmIHByb3BlcnR5LnNjYWxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRjb25zdHJhaW50cy5zY2FsZSA9IHByb3BlcnR5LnNjYWxlO1xuXHR9XG5cdGlmICh0YXJnZXRNYXBwaW5nPy5jb25zdHJhaW50cz8uJFByZWNpc2lvbiAmJiBwcm9wZXJ0eS5wcmVjaXNpb24gIT09IHVuZGVmaW5lZCkge1xuXHRcdGNvbnN0cmFpbnRzLnByZWNpc2lvbiA9IHByb3BlcnR5LnByZWNpc2lvbjtcblx0fVxuXHRpZiAodGFyZ2V0TWFwcGluZz8uY29uc3RyYWludHM/LiRNYXhMZW5ndGggJiYgcHJvcGVydHkubWF4TGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcblx0XHRjb25zdHJhaW50cy5tYXhMZW5ndGggPSBwcm9wZXJ0eS5tYXhMZW5ndGg7XG5cdH1cblx0aWYgKHByb3BlcnR5Lm51bGxhYmxlID09PSBmYWxzZSkge1xuXHRcdGNvbnN0cmFpbnRzLm51bGxhYmxlID0gZmFsc2U7XG5cdH1cblx0aWYgKHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy5bXCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWluaW11bS8kRGVjaW1hbFwiXSAmJiAhaXNOYU4ocHJvcGVydHkuYW5ub3RhdGlvbnM/LlZhbGlkYXRpb24/Lk1pbmltdW0pKSB7XG5cdFx0Y29uc3RyYWludHMubWluaW11bSA9IGAke3Byb3BlcnR5LmFubm90YXRpb25zPy5WYWxpZGF0aW9uPy5NaW5pbXVtfWA7XG5cdH1cblx0aWYgKHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy5bXCJAT3JnLk9EYXRhLlZhbGlkYXRpb24uVjEuTWF4aW11bS8kRGVjaW1hbFwiXSAmJiAhaXNOYU4ocHJvcGVydHkuYW5ub3RhdGlvbnM/LlZhbGlkYXRpb24/Lk1heGltdW0pKSB7XG5cdFx0Y29uc3RyYWludHMubWF4aW11bSA9IGAke3Byb3BlcnR5LmFubm90YXRpb25zPy5WYWxpZGF0aW9uPy5NYXhpbXVtfWA7XG5cdH1cblx0aWYgKFxuXHRcdHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRGlnaXRTZXF1ZW5jZSAmJlxuXHRcdHRhcmdldE1hcHBpbmcudHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5TdHJpbmdcIiAmJlxuXHRcdHRhcmdldE1hcHBpbmc/LmNvbnN0cmFpbnRzPy5bXCJAY29tLnNhcC52b2NhYnVsYXJpZXMuQ29tbW9uLnYxLklzRGlnaXRTZXF1ZW5jZVwiXVxuXHQpIHtcblx0XHRjb25zdHJhaW50cy5pc0RpZ2l0U2VxdWVuY2UgPSB0cnVlO1xuXHR9XG5cdGlmICh0YXJnZXRNYXBwaW5nPy5jb25zdHJhaW50cz8uJFY0KSB7XG5cdFx0Y29uc3RyYWludHMuVjQgPSB0cnVlO1xuXHR9XG5cdHJldHVybiBjb25zdHJhaW50cztcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgdGhlIGJpbmRpbmcgZXhwcmVzc2lvbiBmb3IgdGhlIHByb3BlcnR5LCBhbmQgc2V0cyB1cCB0aGUgZm9ybWF0T3B0aW9ucyBhbmQgY29uc3RyYWludHMuXG4gKlxuICogQHBhcmFtIHByb3BlcnR5IFRoZSBQcm9wZXJ0eSBmb3Igd2hpY2ggd2UgYXJlIHNldHRpbmcgdXAgdGhlIGJpbmRpbmdcbiAqIEBwYXJhbSBwcm9wZXJ0eUJpbmRpbmdFeHByZXNzaW9uIFRoZSBCaW5kaW5nRXhwcmVzc2lvbiBvZiB0aGUgcHJvcGVydHkgYWJvdmUuIFNlcnZlcyBhcyB0aGUgYmFzaXMgdG8gd2hpY2ggaW5mb3JtYXRpb24gY2FuIGJlIGFkZGVkXG4gKiBAcGFyYW0gaWdub3JlQ29uc3RyYWludHMgSWdub3JlIGNvbnN0cmFpbnRzIG9mIHRoZSBwcm9wZXJ0eVxuICogQHJldHVybnMgVGhlIGJpbmRpbmcgZXhwcmVzc2lvbiBmb3IgdGhlIHByb3BlcnR5IHdpdGggZm9ybWF0T3B0aW9ucyBhbmQgY29uc3RyYWludHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFdpdGhUeXBlSW5mb3JtYXRpb248VD4oXG5cdHByb3BlcnR5OiBQcm9wZXJ0eSB8IEFjdGlvblBhcmFtZXRlcixcblx0cHJvcGVydHlCaW5kaW5nRXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz4sXG5cdGlnbm9yZUNvbnN0cmFpbnRzID0gZmFsc2Vcbik6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPiB7XG5cdGNvbnN0IG91dEV4cHJlc3Npb246IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjx1bmtub3duPiA9IHByb3BlcnR5QmluZGluZ0V4cHJlc3Npb24gYXMgUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+O1xuXHRpZiAocHJvcGVydHkuX3R5cGUgIT09IFwiUHJvcGVydHlcIiAmJiBwcm9wZXJ0eS5fdHlwZSAhPT0gXCJBY3Rpb25QYXJhbWV0ZXJcIikge1xuXHRcdHJldHVybiBvdXRFeHByZXNzaW9uO1xuXHR9XG5cdGNvbnN0IHRhcmdldE1hcHBpbmcgPSBFRE1fVFlQRV9NQVBQSU5HW3Byb3BlcnR5LnR5cGVdO1xuXHRpZiAoIXRhcmdldE1hcHBpbmcpIHtcblx0XHRyZXR1cm4gb3V0RXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoIW91dEV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucykge1xuXHRcdG91dEV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucyA9IHt9O1xuXHR9XG5cdG91dEV4cHJlc3Npb24uY29uc3RyYWludHMgPSB7fTtcblxuXHRvdXRFeHByZXNzaW9uLnR5cGUgPSB0YXJnZXRNYXBwaW5nLnR5cGU7XG5cdGlmICghaWdub3JlQ29uc3RyYWludHMpIHtcblx0XHRvdXRFeHByZXNzaW9uLmNvbnN0cmFpbnRzID0gc2V0VXBDb25zdHJhaW50cyh0YXJnZXRNYXBwaW5nLCBwcm9wZXJ0eSk7XG5cdH1cblxuXHRpZiAoXG5cdFx0KG91dEV4cHJlc3Npb24/LnR5cGU/LmluZGV4T2YoXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnRcIikgPT09IDAgJiYgb3V0RXhwcmVzc2lvbj8udHlwZSAhPT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQ2NFwiKSB8fFxuXHRcdG91dEV4cHJlc3Npb24/LnR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuRG91YmxlXCJcblx0KSB7XG5cdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zID0gT2JqZWN0LmFzc2lnbihvdXRFeHByZXNzaW9uLmZvcm1hdE9wdGlvbnMsIHtcblx0XHRcdHBhcnNlQXNTdHJpbmc6IGZhbHNlXG5cdFx0fSk7XG5cdH1cblx0aWYgKG91dEV4cHJlc3Npb24udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5TdHJpbmdcIiAmJiBpc1Byb3BlcnR5KHByb3BlcnR5KSkge1xuXHRcdGlmICghb3V0RXhwcmVzc2lvbi5jb25zdHJhaW50cz8uaXNEaWdpdFNlcXVlbmNlIHx8IG91dEV4cHJlc3Npb24uY29uc3RyYWludHM/Lm51bGxhYmxlID09PSBmYWxzZSkge1xuXHRcdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zLnBhcnNlS2VlcHNFbXB0eVN0cmluZyA9IHRydWU7XG5cdFx0fVxuXHRcdGNvbnN0IGZpc2NhbFR5cGUgPSBnZXRGaXNjYWxUeXBlKHByb3BlcnR5KTtcblx0XHRpZiAoZmlzY2FsVHlwZSkge1xuXHRcdFx0b3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zLmZpc2NhbFR5cGUgPSBmaXNjYWxUeXBlO1xuXHRcdFx0b3V0RXhwcmVzc2lvbi50eXBlID0gXCJzYXAuZmUuY29yZS50eXBlLkZpc2NhbERhdGVcIjtcblx0XHR9XG5cdH1cblx0Y29uc3QgdHlwZXNTdXBwb3J0aW5nUGFyc2VFbXB0eVZhbHVlVG9aZXJvID0gW1xuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50MTZcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkludDMyXCIsXG5cdFx0XCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQ2NFwiLFxuXHRcdFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuU2luZ2xlXCIsXG5cdFx0XCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5Eb3VibGVcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRlY2ltYWxcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkJ5dGVcIixcblx0XHRcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLlNCeXRlXCJcblx0XTtcblx0aWYgKFxuXHRcdG91dEV4cHJlc3Npb24uY29uc3RyYWludHM/Lm51bGxhYmxlID09PSBmYWxzZSAmJlxuXHRcdG91dEV4cHJlc3Npb24udHlwZSAmJlxuXHRcdHR5cGVzU3VwcG9ydGluZ1BhcnNlRW1wdHlWYWx1ZVRvWmVyby5pbmNsdWRlcyhvdXRFeHByZXNzaW9uLnR5cGUpXG5cdCkge1xuXHRcdG91dEV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zLCB7XG5cdFx0XHRwYXJzZUVtcHR5VmFsdWVUb1plcm86IHRydWVcblx0XHR9KTtcblx0fVxuXHRpZiAoXG5cdFx0b3V0RXhwcmVzc2lvbi5jb25zdHJhaW50cz8ubnVsbGFibGUgIT09IGZhbHNlICYmXG5cdFx0KG91dEV4cHJlc3Npb24udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5JbnQ2NFwiIHx8IG91dEV4cHJlc3Npb24udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5EZWNpbWFsXCIpXG5cdCkge1xuXHRcdG91dEV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3V0RXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zLCB7XG5cdFx0XHRlbXB0eVN0cmluZzogXCJcIlxuXHRcdH0pO1xuXHR9XG5cblx0cmV0dXJuIG91dEV4cHJlc3Npb247XG59XG5cbmV4cG9ydCBjb25zdCBnZXRGaXNjYWxUeXBlID0gZnVuY3Rpb24gKHByb3BlcnR5OiBQcm9wZXJ0eSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0Zpc2NhbFllYXIpIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsWWVhcjtcblx0fVxuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnM/LkNvbW1vbj8uSXNGaXNjYWxQZXJpb2QpIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsUGVyaW9kO1xuXHR9XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0Zpc2NhbFllYXJQZXJpb2QpIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsWWVhclBlcmlvZDtcblx0fVxuXHRpZiAocHJvcGVydHkuYW5ub3RhdGlvbnM/LkNvbW1vbj8uSXNGaXNjYWxRdWFydGVyKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0Zpc2NhbFF1YXJ0ZXI7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRmlzY2FsWWVhclF1YXJ0ZXIpIHtcblx0XHRyZXR1cm4gQ29tbW9uQW5ub3RhdGlvblRlcm1zLklzRmlzY2FsWWVhclF1YXJ0ZXI7XG5cdH1cblx0aWYgKHByb3BlcnR5LmFubm90YXRpb25zPy5Db21tb24/LklzRmlzY2FsV2Vlaykge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNGaXNjYWxXZWVrO1xuXHR9XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0Zpc2NhbFllYXJXZWVrKSB7XG5cdFx0cmV0dXJuIENvbW1vbkFubm90YXRpb25UZXJtcy5Jc0Zpc2NhbFllYXJXZWVrO1xuXHR9XG5cdGlmIChwcm9wZXJ0eS5hbm5vdGF0aW9ucz8uQ29tbW9uPy5Jc0RheU9mRmlzY2FsWWVhcikge1xuXHRcdHJldHVybiBDb21tb25Bbm5vdGF0aW9uVGVybXMuSXNEYXlPZkZpc2NhbFllYXI7XG5cdH1cbn07XG5cbi8qKlxuICogQ2FsbHMgYSBjb21wbGV4IHR5cGUgdG8gcHJvY2VzcyB0aGUgcGFyYW1ldGVycy5cbiAqIElmIHJlcXVpcmVDb250ZXh0IGlzIHNldCB0byB0cnVlIGFuZCBubyBjb250ZXh0IGlzIHBhc3NlZCwgYSBkZWZhdWx0IGNvbnRleHQgd2lsbCBiZSBhZGRlZCBhdXRvbWF0aWNhbGx5LlxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdGVtcGxhdGUgVVxuICogQHBhcmFtIHBhcmFtZXRlcnMgVGhlIGxpc3Qgb2YgcGFyYW1ldGVycyB0aGF0IHNob3VsZCBtYXRjaCB0aGUgdHlwZSBmb3IgdGhlIGNvbXBsZXggdHlwZT1cbiAqIEBwYXJhbSB0eXBlIFRoZSBjb21wbGV4IHR5cGUgdG8gdXNlXG4gKiBAcGFyYW0gW2NvbnRleHRFbnRpdHlUeXBlXSBUaGUgY29udGV4dCBlbnRpdHkgdHlwZSB0byBjb25zaWRlclxuICogQHBhcmFtIG9Gb3JtYXRPcHRpb25zXG4gKiBAcmV0dXJucyBUaGUgY29ycmVzcG9uZGluZyBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRUeXBlSW5mb3JtYXRpb248VCwgVSBleHRlbmRzIEZuPFQ+Pihcblx0cGFyYW1ldGVyczogV3JhcHBlZFR1cGxlPFBhcmFtZXRlcnM8VT4+LFxuXHR0eXBlOiBzdHJpbmcsXG5cdGNvbnRleHRFbnRpdHlUeXBlPzogRW50aXR5VHlwZSxcblx0b0Zvcm1hdE9wdGlvbnM/OiBDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnNcbik6IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uIHwgQ29tcGxleFR5cGVFeHByZXNzaW9uPFQ+IHwgQ29uc3RhbnRFeHByZXNzaW9uPFQ+IHtcblx0Y29uc3QgcGFyYW1ldGVyRXhwcmVzc2lvbnMgPSAocGFyYW1ldGVycyBhcyBFeHByZXNzaW9uT3JQcmltaXRpdmU8UHJpbWl0aXZlVHlwZT5bXSkubWFwKHdyYXBQcmltaXRpdmUpO1xuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbiguLi5wYXJhbWV0ZXJFeHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHQvLyBJZiB0aGVyZSBpcyBvbmx5IG9uZSBwYXJhbWV0ZXIgYW5kIGl0IGlzIGEgY29uc3RhbnQgYW5kIHdlIGRvbid0IGV4cGVjdCB0aGUgY29udGV4dCB0aGVuIHJldHVybiB0aGUgY29uc3RhbnRcblx0aWYgKHBhcmFtZXRlckV4cHJlc3Npb25zLmxlbmd0aCA9PT0gMSAmJiBpc0NvbnN0YW50KHBhcmFtZXRlckV4cHJlc3Npb25zWzBdKSAmJiAhY29udGV4dEVudGl0eVR5cGUpIHtcblx0XHRyZXR1cm4gcGFyYW1ldGVyRXhwcmVzc2lvbnNbMF0gYXMgQ29uc3RhbnRFeHByZXNzaW9uPFQ+O1xuXHR9IGVsc2UgaWYgKGNvbnRleHRFbnRpdHlUeXBlKSB7XG5cdFx0Ly8gT3RoZXJ3aXNlLCBpZiB0aGUgY29udGV4dCBpcyByZXF1aXJlZCBhbmQgbm8gY29udGV4dCBpcyBwcm92aWRlZCBtYWtlIHN1cmUgdG8gYWRkIHRoZSBkZWZhdWx0IGJpbmRpbmdcblx0XHRpZiAoIXBhcmFtZXRlckV4cHJlc3Npb25zLnNvbWUoaGFzUmVmZXJlbmNlVG9EZWZhdWx0Q29udGV4dCkpIHtcblx0XHRcdGNvbnRleHRFbnRpdHlUeXBlLmtleXMuZm9yRWFjaCgoa2V5KSA9PiBwYXJhbWV0ZXJFeHByZXNzaW9ucy5wdXNoKHBhdGhJbk1vZGVsKGtleS5uYW1lLCBcIlwiKSkpO1xuXHRcdH1cblx0fVxuXHRvRm9ybWF0T3B0aW9ucyA9IF9nZXRDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnNGcm9tRmlyc3RQYXJhbShwYXJhbWV0ZXJzWzBdLCBvRm9ybWF0T3B0aW9ucyk7XG5cblx0aWYgKHR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuVW5pdFwiKSB7XG5cdFx0Y29uc3QgdW9tUGF0aCA9IHBhdGhJbk1vZGVsKFwiLyMjQEByZXF1ZXN0VW5pdHNPZk1lYXN1cmVcIik7XG5cdFx0dW9tUGF0aC50YXJnZXRUeXBlID0gXCJhbnlcIjtcblx0XHR1b21QYXRoLm1vZGUgPSBcIk9uZVRpbWVcIjtcblx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy5wdXNoKHVvbVBhdGgpO1xuXHR9IGVsc2UgaWYgKHR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuQ3VycmVuY3lcIikge1xuXHRcdGNvbnN0IGN1cnJlbmN5UGF0aCA9IHBhdGhJbk1vZGVsKFwiLyMjQEByZXF1ZXN0Q3VycmVuY3lDb2Rlc1wiKTtcblx0XHRjdXJyZW5jeVBhdGgudGFyZ2V0VHlwZSA9IFwiYW55XCI7XG5cdFx0Y3VycmVuY3lQYXRoLm1vZGUgPSBcIk9uZVRpbWVcIjtcblx0XHRwYXJhbWV0ZXJFeHByZXNzaW9ucy5wdXNoKGN1cnJlbmN5UGF0aCk7XG5cdH1cblxuXHRyZXR1cm4ge1xuXHRcdF90eXBlOiBcIkNvbXBsZXhUeXBlXCIsXG5cdFx0dHlwZTogdHlwZSxcblx0XHRmb3JtYXRPcHRpb25zOiBvRm9ybWF0T3B0aW9ucyB8fCB7fSxcblx0XHRwYXJhbWV0ZXJzOiB7fSxcblx0XHRiaW5kaW5nUGFyYW1ldGVyczogcGFyYW1ldGVyRXhwcmVzc2lvbnNcblx0fTtcbn1cblxudHlwZSBDb21wbGV4VHlwZUZvcm1hdE9wdGlvbnMgPSB7XG5cdHNob3dOdW1iZXI/OiBib29sZWFuO1xuXHRzaG93TWVhc3VyZT86IGJvb2xlYW47XG5cdHBhcnNlQXNTdHJpbmc/OiBib29sZWFuO1xuXHRwYXJzZUtlZXBzRW1wdHlTdHJpbmc/OiBib29sZWFuO1xuXHRlbXB0eVN0cmluZz86IHN0cmluZyB8IG51bWJlciB8IG51bGw7XG5cdHNob3dUaW1lPzogYm9vbGVhbjtcblx0c2hvd0RhdGU/OiBib29sZWFuO1xuXHRzaG93VGltZXpvbmU/OiBib29sZWFuO1xufTtcblxuLyoqXG4gKiBQcm9jZXNzIHRoZSBmb3JtYXRPcHRpb25zIGZvciBhIGNvbXBsZXhUeXBlIGJhc2VkIG9uIHRoZSBmaXJzdCBwYXJhbWV0ZXIuXG4gKlxuICogQHBhcmFtIHBhcmFtIFRoZSBmaXJzdCBwYXJhbWV0ZXIgb2YgdGhlIGNvbXBsZXggdHlwZVxuICogQHBhcmFtIGZvcm1hdE9wdGlvbnMgSW5pdGlhbCBmb3JtYXRPcHRpb25zXG4gKiBAcmV0dXJucyBUaGUgbW9kaWZpZWQgZm9ybWF0T3B0aW9uc1xuICovXG5mdW5jdGlvbiBfZ2V0Q29tcGxleFR5cGVGb3JtYXRPcHRpb25zRnJvbUZpcnN0UGFyYW08VCwgVSBleHRlbmRzIEZuPFQ+Pihcblx0cGFyYW06IFBhcmFtZXRlcnM8VT4sXG5cdGZvcm1hdE9wdGlvbnM6IHVuZGVmaW5lZCB8IENvbXBsZXhUeXBlRm9ybWF0T3B0aW9uc1xuKTogQ29tcGxleFR5cGVGb3JtYXRPcHRpb25zIHwgdW5kZWZpbmVkIHtcblx0Ly8gaWYgc2hvd01lYXN1cmUgaXMgc2V0IHRvIGZhbHNlIHdlIHdhbnQgdG8gbm90IHBhcnNlIGFzIHN0cmluZyB0byBzZWUgdGhlIDBcblx0Ly8gd2UgZG8gdGhhdCBhbHNvIGZvciBhbGwgYmluZGluZ3MgYmVjYXVzZSBvdGhlcndpc2UgdGhlIG1kYyBGaWVsZCBpc24ndCBlZGl0YWJsZVxuXHRpZiAoXG5cdFx0IShmb3JtYXRPcHRpb25zICYmIGZvcm1hdE9wdGlvbnMuc2hvd051bWJlciA9PT0gZmFsc2UpICYmXG5cdFx0KHBhcmFtPy50eXBlPy5pbmRleE9mKFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50XCIpID09PSAwIHx8XG5cdFx0XHRwYXJhbT8udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5EZWNpbWFsXCIgfHxcblx0XHRcdHBhcmFtPy50eXBlID09PSBcInNhcC51aS5tb2RlbC5vZGF0YS50eXBlLkRvdWJsZVwiKVxuXHQpIHtcblx0XHRpZiAocGFyYW0/LnR5cGUgPT09IFwic2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50NjRcIiB8fCBwYXJhbT8udHlwZSA9PT0gXCJzYXAudWkubW9kZWwub2RhdGEudHlwZS5EZWNpbWFsXCIpIHtcblx0XHRcdC8vc2FwLnVpLm1vZGVsLm9kYXRhLnR5cGUuSW50NjQgZG8gbm90IHN1cHBvcnQgcGFyc2VBc1N0cmluZyBmYWxzZVxuXHRcdFx0Zm9ybWF0T3B0aW9ucyA9IGZvcm1hdE9wdGlvbnM/LnNob3dNZWFzdXJlID09PSBmYWxzZSA/IHsgc2hvd01lYXN1cmU6IGZhbHNlIH0gOiB7fTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9ybWF0T3B0aW9ucyA9IGZvcm1hdE9wdGlvbnM/LnNob3dNZWFzdXJlID09PSBmYWxzZSA/IHsgcGFyc2VBc1N0cmluZzogZmFsc2UsIHNob3dNZWFzdXJlOiBmYWxzZSB9IDogeyBwYXJzZUFzU3RyaW5nOiBmYWxzZSB9O1xuXHRcdH1cblx0XHRmb3JtYXRPcHRpb25zLmVtcHR5U3RyaW5nID0gbnVsbDtcblx0fVxuXHRyZXR1cm4gZm9ybWF0T3B0aW9ucztcbn1cbi8qKlxuICogRnVuY3Rpb24gY2FsbCwgb3B0aW9uYWxseSB3aXRoIGFyZ3VtZW50cy5cbiAqXG4gKiBAcGFyYW0gZnVuYyBGdW5jdGlvbiBuYW1lIG9yIHJlZmVyZW5jZSB0byBmdW5jdGlvblxuICogQHBhcmFtIHBhcmFtZXRlcnMgQXJndW1lbnRzXG4gKiBAcGFyYW0gb24gT2JqZWN0IHRvIGNhbGwgdGhlIGZ1bmN0aW9uIG9uXG4gKiBAcGFyYW0gaXNGb3JtYXR0aW5nRm5cbiAqIEByZXR1cm5zIEV4cHJlc3Npb24gcmVwcmVzZW50aW5nIHRoZSBmdW5jdGlvbiBjYWxsIChub3QgdGhlIHJlc3VsdCBvZiB0aGUgZnVuY3Rpb24gY2FsbCEpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbjxULCBVIGV4dGVuZHMgRnVuY3Rpb25Pck5hbWU8VD4+KFxuXHRmdW5jOiBVLFxuXHRwYXJhbWV0ZXJzOiBXcmFwcGVkVHVwbGU8RnVuY3Rpb25QYXJhbWV0ZXJzPFQsIFU+Pixcblx0b24/OiBFeHByZXNzaW9uT3JQcmltaXRpdmU8b2JqZWN0Pixcblx0aXNGb3JtYXR0aW5nRm4gPSBmYWxzZVxuKTogRnVuY3Rpb25FeHByZXNzaW9uPFQ+IHtcblx0Y29uc3QgZnVuY3Rpb25OYW1lID0gdHlwZW9mIGZ1bmMgPT09IFwic3RyaW5nXCIgPyBmdW5jIDogZnVuYy5fX2Z1bmN0aW9uTmFtZTtcblx0cmV0dXJuIHtcblx0XHRfdHlwZTogXCJGdW5jdGlvblwiLFxuXHRcdG9iajogb24gIT09IHVuZGVmaW5lZCA/IHdyYXBQcmltaXRpdmUob24pIDogdW5kZWZpbmVkLFxuXHRcdGZuOiBmdW5jdGlvbk5hbWUsXG5cdFx0aXNGb3JtYXR0aW5nRm46IGlzRm9ybWF0dGluZ0ZuLFxuXHRcdHBhcmFtZXRlcnM6IChwYXJhbWV0ZXJzIGFzIEV4cHJlc3Npb25PclByaW1pdGl2ZTxQcmltaXRpdmVUeXBlPltdKS5tYXAod3JhcFByaW1pdGl2ZSlcblx0fTtcbn1cblxuLyoqXG4gKiBTaG9ydGN1dCBmdW5jdGlvbiB0byBkZXRlcm1pbmUgaWYgYSBiaW5kaW5nIHZhbHVlIGlzIG51bGwsIHVuZGVmaW5lZCBvciBlbXB0eS5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvblxuICogQHJldHVybnMgQSBCb29sZWFuIGV4cHJlc3Npb24gZXZhbHVhdGluZyB0aGUgZmFjdCB0aGF0IHRoZSBjdXJyZW50IGVsZW1lbnQgaXMgZW1wdHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW1wdHkoZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248Ym9vbGVhbj4ge1xuXHRjb25zdCBhQmluZGluZ3M6IEV4cHJlc3Npb25PclByaW1pdGl2ZTxib29sZWFuPltdID0gW107XG5cdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KGV4cHJlc3Npb24sIFwiUGF0aEluTW9kZWxcIiwgKGV4cHIpID0+IHtcblx0XHRhQmluZGluZ3MucHVzaChvcihlcXVhbChleHByLCBcIlwiKSwgZXF1YWwoZXhwciwgdW5kZWZpbmVkKSwgZXF1YWwoZXhwciwgbnVsbCkpKTtcblx0XHRyZXR1cm4gZXhwcjtcblx0fSk7XG5cdHJldHVybiBhbmQoLi4uYUJpbmRpbmdzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbmNhdCguLi5pbkV4cHJlc3Npb25zOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8c3RyaW5nPltdKTogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHN0cmluZz4ge1xuXHRjb25zdCBleHByZXNzaW9ucyA9IGluRXhwcmVzc2lvbnMubWFwKHdyYXBQcmltaXRpdmUpO1xuXHRpZiAoaGFzVW5yZXNvbHZhYmxlRXhwcmVzc2lvbiguLi5leHByZXNzaW9ucykpIHtcblx0XHRyZXR1cm4gdW5yZXNvbHZhYmxlRXhwcmVzc2lvbjtcblx0fVxuXHRpZiAoZXhwcmVzc2lvbnMuZXZlcnkoaXNDb25zdGFudCkpIHtcblx0XHRyZXR1cm4gY29uc3RhbnQoXG5cdFx0XHRleHByZXNzaW9ucy5yZWR1Y2UoKGNvbmNhdGVuYXRlZDogc3RyaW5nLCB2YWx1ZSkgPT4ge1xuXHRcdFx0XHRpZiAodmFsdWUudmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZS52YWx1ZSAhPT0gbnVsbCkge1xuXHRcdFx0XHRcdHJldHVybiBjb25jYXRlbmF0ZWQgKyB2YWx1ZS52YWx1ZS50b1N0cmluZygpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBjb25jYXRlbmF0ZWQ7XG5cdFx0XHR9LCBcIlwiKVxuXHRcdCk7XG5cdH0gZWxzZSBpZiAoZXhwcmVzc2lvbnMuc29tZShpc0NvbXBsZXhUeXBlRXhwcmVzc2lvbikpIHtcblx0XHRsZXQgcGF0aElkeCA9IDA7XG5cdFx0Y29uc3QgbXlDb25jYXRFeHByZXNzaW9uID0gZm9ybWF0UmVzdWx0KGV4cHJlc3Npb25zLCBcInNhcC5mZS5jb3JlLmZvcm1hdHRlcnMuU3RhbmRhcmRGb3JtYXR0ZXIjY29uY2F0XCIsIHVuZGVmaW5lZCwgdHJ1ZSk7XG5cdFx0Y29uc3QgYWxsUGFydHMgPSBbXTtcblx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShteUNvbmNhdEV4cHJlc3Npb24sIFwiUGF0aEluTW9kZWxcIiwgKGNvbnN0YW50UGF0aDogUGF0aEluTW9kZWxFeHByZXNzaW9uPHVua25vd24+KSA9PiB7XG5cdFx0XHRhbGxQYXJ0cy5wdXNoKGNvbnN0YW50UGF0aCk7XG5cdFx0XHRyZXR1cm4gcGF0aEluTW9kZWwoYCQke3BhdGhJZHgrK31gLCBcIiRcIik7XG5cdFx0fSk7XG5cdFx0YWxsUGFydHMudW5zaGlmdChjb25zdGFudChKU09OLnN0cmluZ2lmeShteUNvbmNhdEV4cHJlc3Npb24pKSk7XG5cdFx0cmV0dXJuIGZvcm1hdFJlc3VsdChhbGxQYXJ0cywgXCJzYXAuZmUuY29yZS5mb3JtYXR0ZXJzLlN0YW5kYXJkRm9ybWF0dGVyI2V2YWx1YXRlQ29tcGxleEV4cHJlc3Npb25cIiwgdW5kZWZpbmVkLCB0cnVlKTtcblx0fVxuXHRyZXR1cm4ge1xuXHRcdF90eXBlOiBcIkNvbmNhdFwiLFxuXHRcdGV4cHJlc3Npb25zOiBleHByZXNzaW9uc1xuXHR9O1xufVxuXG50eXBlIEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPFQgZXh0ZW5kcyBFeHByZXNzaW9uVHlwZSwgVj4gPSBUIGV4dGVuZHMgXCJDb25zdGFudFwiXG5cdD8gQ29uc3RhbnRFeHByZXNzaW9uPFY+XG5cdDogVCBleHRlbmRzIFwiUGF0aEluTW9kZWxcIlxuXHQ/IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxWPlxuXHQ6IFQgZXh0ZW5kcyBcIkZ1bmN0aW9uXCJcblx0PyBGdW5jdGlvbkV4cHJlc3Npb248Vj5cblx0OiBUIGV4dGVuZHMgXCJVbnJlc29sdmFibGVcIlxuXHQ/IFVucmVzb2x2YWJsZVBhdGhFeHByZXNzaW9uXG5cdDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFY+O1xuXG5leHBvcnQgdHlwZSBUcmFuc2Zvcm1GdW5jdGlvbjxULCBWPiA9IChleHByZXNzaW9uUGFydDogVCkgPT4gQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFY+O1xuZXhwb3J0IHR5cGUgRXhwcmVzc2lvblR5cGUgPSBQaWNrPEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPiwgXCJfdHlwZVwiPltcIl90eXBlXCJdO1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVJlY3Vyc2l2ZWx5PFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlIHwgdW5rbm93biwgRVQgZXh0ZW5kcyBFeHByZXNzaW9uVHlwZT4oXG5cdGluRXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LFxuXHRleHByZXNzaW9uVHlwZTogRVQsXG5cdHRyYW5zZm9ybUZ1bmN0aW9uOiBUcmFuc2Zvcm1GdW5jdGlvbjxFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgVD4sIFQ+LFxuXHRpbmNsdWRlQWxsRXhwcmVzc2lvbiA9IGZhbHNlXG4pOiBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4ge1xuXHRsZXQgZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+ID0gaW5FeHByZXNzaW9uO1xuXHRzd2l0Y2ggKGV4cHJlc3Npb24uX3R5cGUpIHtcblx0XHRjYXNlIFwiRnVuY3Rpb25cIjpcblx0XHRjYXNlIFwiRm9ybWF0dGVyXCI6XG5cdFx0XHRleHByZXNzaW9uLnBhcmFtZXRlcnMgPSBleHByZXNzaW9uLnBhcmFtZXRlcnMubWFwKChwYXJhbWV0ZXIpID0+XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KHBhcmFtZXRlciBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sIGV4cHJlc3Npb25UeXBlLCB0cmFuc2Zvcm1GdW5jdGlvbiwgaW5jbHVkZUFsbEV4cHJlc3Npb24pXG5cdFx0XHQpO1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIkNvbmNhdFwiOlxuXHRcdFx0ZXhwcmVzc2lvbi5leHByZXNzaW9ucyA9IGV4cHJlc3Npb24uZXhwcmVzc2lvbnMubWFwKChzdWJFeHByZXNzaW9uKSA9PlxuXHRcdFx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRzdWJFeHByZXNzaW9uLFxuXHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIHN0cmluZz4sIHN0cmluZz4sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KVxuXHRcdFx0KTtcblx0XHRcdGV4cHJlc3Npb24gPSBjb25jYXQoLi4uZXhwcmVzc2lvbi5leHByZXNzaW9ucykgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIkNvbXBsZXhUeXBlXCI6XG5cdFx0XHRleHByZXNzaW9uLmJpbmRpbmdQYXJhbWV0ZXJzID0gZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVycy5tYXAoKGJpbmRpbmdQYXJhbWV0ZXIpID0+XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGJpbmRpbmdQYXJhbWV0ZXIgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LFxuXHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uLFxuXHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdClcblx0XHRcdCk7XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiSWZFbHNlXCI6XG5cdFx0XHRjb25zdCBvblRydWUgPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0ZXhwcmVzc2lvbi5vblRydWUsXG5cdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbiBhcyB1bmtub3duIGFzIFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCB1bmtub3duPiwgdW5rbm93bj4sXG5cdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHQpO1xuXHRcdFx0Y29uc3Qgb25GYWxzZSA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRleHByZXNzaW9uLm9uRmFsc2UsXG5cdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbiBhcyB1bmtub3duIGFzIFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCB1bmtub3duPiwgdW5rbm93bj4sXG5cdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHQpO1xuXHRcdFx0bGV0IGNvbmRpdGlvbiA9IGV4cHJlc3Npb24uY29uZGl0aW9uO1xuXHRcdFx0aWYgKGluY2x1ZGVBbGxFeHByZXNzaW9uKSB7XG5cdFx0XHRcdGNvbmRpdGlvbiA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHJlc3Npb24uY29uZGl0aW9uLFxuXHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uIGFzIHVua25vd24gYXMgVHJhbnNmb3JtRnVuY3Rpb248RXhwcmVzc2lvblR5cGVUb0V4cHJlc3Npb248RVQsIGJvb2xlYW4+LCBib29sZWFuPixcblx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0ZXhwcmVzc2lvbiA9IGlmRWxzZShjb25kaXRpb24sIG9uVHJ1ZSwgb25GYWxzZSkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIk5vdFwiOlxuXHRcdFx0aWYgKGluY2x1ZGVBbGxFeHByZXNzaW9uKSB7XG5cdFx0XHRcdGNvbnN0IG9wZXJhbmQgPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRleHByZXNzaW9uLm9wZXJhbmQsXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24gYXMgdW5rbm93biBhcyBUcmFuc2Zvcm1GdW5jdGlvbjxFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgYm9vbGVhbj4sIGJvb2xlYW4+LFxuXHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdCk7XG5cdFx0XHRcdGV4cHJlc3Npb24gPSBub3Qob3BlcmFuZCkgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+O1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIlRydXRoeVwiOlxuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIlNldFwiOlxuXHRcdFx0aWYgKGluY2x1ZGVBbGxFeHByZXNzaW9uKSB7XG5cdFx0XHRcdGNvbnN0IG9wZXJhbmRzID0gZXhwcmVzc2lvbi5vcGVyYW5kcy5tYXAoKG9wZXJhbmQpID0+XG5cdFx0XHRcdFx0dHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0XHRvcGVyYW5kLFxuXHRcdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0XHR0cmFuc2Zvcm1GdW5jdGlvbiBhcyB1bmtub3duIGFzIFRyYW5zZm9ybUZ1bmN0aW9uPEV4cHJlc3Npb25UeXBlVG9FeHByZXNzaW9uPEVULCBib29sZWFuPiwgYm9vbGVhbj4sXG5cdFx0XHRcdFx0XHRpbmNsdWRlQWxsRXhwcmVzc2lvblxuXHRcdFx0XHRcdClcblx0XHRcdFx0KTtcblx0XHRcdFx0ZXhwcmVzc2lvbiA9XG5cdFx0XHRcdFx0ZXhwcmVzc2lvbi5vcGVyYXRvciA9PT0gXCJ8fFwiXG5cdFx0XHRcdFx0XHQ/IChvciguLi5vcGVyYW5kcykgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+KVxuXHRcdFx0XHRcdFx0OiAoYW5kKC4uLm9wZXJhbmRzKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4pO1xuXHRcdFx0fVxuXHRcdFx0YnJlYWs7XG5cdFx0Y2FzZSBcIkNvbXBhcmlzb25cIjpcblx0XHRcdGlmIChpbmNsdWRlQWxsRXhwcmVzc2lvbikge1xuXHRcdFx0XHRjb25zdCBvcGVyYW5kMSA9IHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHJlc3Npb24ub3BlcmFuZDEgYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFQ+LFxuXHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdHRyYW5zZm9ybUZ1bmN0aW9uLFxuXHRcdFx0XHRcdGluY2x1ZGVBbGxFeHByZXNzaW9uXG5cdFx0XHRcdCk7XG5cdFx0XHRcdGNvbnN0IG9wZXJhbmQyID0gdHJhbnNmb3JtUmVjdXJzaXZlbHkoXG5cdFx0XHRcdFx0ZXhwcmVzc2lvbi5vcGVyYW5kMiBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD4sXG5cdFx0XHRcdFx0ZXhwcmVzc2lvblR5cGUsXG5cdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24sXG5cdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0KTtcblx0XHRcdFx0ZXhwcmVzc2lvbiA9IGNvbXBhcmlzb24oZXhwcmVzc2lvbi5vcGVyYXRvciwgb3BlcmFuZDEsIG9wZXJhbmQyKSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248VD47XG5cdFx0XHR9XG5cdFx0XHRicmVhaztcblx0XHRjYXNlIFwiQ29uc3RhbnRcIjpcblx0XHRcdGNvbnN0IGNvbnN0YW50VmFsdWU6IFJlY29yZDxzdHJpbmcsIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjx1bmtub3duPj4gPSBleHByZXNzaW9uLnZhbHVlIGFzIFJlY29yZDxcblx0XHRcdFx0c3RyaW5nLFxuXHRcdFx0XHRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248dW5rbm93bj5cblx0XHRcdD47XG5cdFx0XHRpZiAodHlwZW9mIGNvbnN0YW50VmFsdWUgPT09IFwib2JqZWN0XCIgJiYgY29uc3RhbnRWYWx1ZSkge1xuXHRcdFx0XHRPYmplY3Qua2V5cyhjb25zdGFudFZhbHVlKS5mb3JFYWNoKChrZXkpID0+IHtcblx0XHRcdFx0XHRjb25zdGFudFZhbHVlW2tleV0gPSB0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRcdGNvbnN0YW50VmFsdWVba2V5XSxcblx0XHRcdFx0XHRcdGV4cHJlc3Npb25UeXBlLFxuXHRcdFx0XHRcdFx0dHJhbnNmb3JtRnVuY3Rpb24gYXMgdW5rbm93biBhcyBUcmFuc2Zvcm1GdW5jdGlvbjxFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgdW5rbm93bj4sIHVua25vd24+LFxuXHRcdFx0XHRcdFx0aW5jbHVkZUFsbEV4cHJlc3Npb25cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHRcdGJyZWFrO1xuXHRcdGNhc2UgXCJSZWZcIjpcblx0XHRjYXNlIFwiTGVuZ3RoXCI6XG5cdFx0Y2FzZSBcIlBhdGhJbk1vZGVsXCI6XG5cdFx0Y2FzZSBcIkVtYmVkZGVkQmluZGluZ1wiOlxuXHRcdGNhc2UgXCJFbWJlZGRlZEV4cHJlc3Npb25CaW5kaW5nXCI6XG5cdFx0Y2FzZSBcIlVucmVzb2x2YWJsZVwiOlxuXHRcdFx0Ly8gRG8gbm90aGluZ1xuXHRcdFx0YnJlYWs7XG5cdH1cblx0aWYgKGV4cHJlc3Npb25UeXBlID09PSBleHByZXNzaW9uLl90eXBlKSB7XG5cdFx0ZXhwcmVzc2lvbiA9IHRyYW5zZm9ybUZ1bmN0aW9uKGluRXhwcmVzc2lvbiBhcyBFeHByZXNzaW9uVHlwZVRvRXhwcmVzc2lvbjxFVCwgVD4pO1xuXHR9XG5cdHJldHVybiBleHByZXNzaW9uO1xufVxuXG5leHBvcnQgdHlwZSBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbiA9IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuY29uc3QgbmVlZFBhcmVudGhlc2lzID0gZnVuY3Rpb24gPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihleHByOiBFeHByZXNzaW9uT3JQcmltaXRpdmU8VD4pOiBib29sZWFuIHtcblx0cmV0dXJuIChcblx0XHQhaXNDb25zdGFudChleHByKSAmJlxuXHRcdCFpc1BhdGhJbk1vZGVsRXhwcmVzc2lvbihleHByKSAmJlxuXHRcdGlzQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uKGV4cHIpICYmXG5cdFx0ZXhwci5fdHlwZSAhPT0gXCJJZkVsc2VcIiAmJlxuXHRcdGV4cHIuX3R5cGUgIT09IFwiRnVuY3Rpb25cIlxuXHQpO1xufTtcblxuLyoqXG4gKiBDb21waWxlcyBhIGNvbnN0YW50IG9iamVjdCB0byBhIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gZXhwclxuICogQHBhcmFtIGlzTnVsbGFibGVcbiAqIEByZXR1cm5zIFRoZSBjb21waWxlZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gY29tcGlsZUNvbnN0YW50T2JqZWN0KGV4cHI6IENvbnN0YW50RXhwcmVzc2lvbjxvYmplY3Q+LCBpc051bGxhYmxlID0gZmFsc2UpOiBzdHJpbmcge1xuXHRpZiAoaXNOdWxsYWJsZSAmJiBPYmplY3Qua2V5cyhleHByLnZhbHVlKS5sZW5ndGggPT09IDApIHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fVxuXHRjb25zdCBvYmplY3RzID0gZXhwci52YWx1ZSBhcyBQbGFpbkV4cHJlc3Npb25PYmplY3Q7XG5cdGNvbnN0IHByb3BlcnRpZXM6IHN0cmluZ1tdID0gW107XG5cdE9iamVjdC5rZXlzKG9iamVjdHMpLmZvckVhY2goKGtleSkgPT4ge1xuXHRcdGNvbnN0IHZhbHVlID0gb2JqZWN0c1trZXldO1xuXHRcdGNvbnN0IGNoaWxkUmVzdWx0ID0gY29tcGlsZUV4cHJlc3Npb24odmFsdWUsIHRydWUsIGZhbHNlLCBpc051bGxhYmxlKTtcblx0XHRpZiAoY2hpbGRSZXN1bHQgJiYgY2hpbGRSZXN1bHQubGVuZ3RoID4gMCkge1xuXHRcdFx0cHJvcGVydGllcy5wdXNoKGAke2tleX06ICR7Y2hpbGRSZXN1bHR9YCk7XG5cdFx0fVxuXHR9KTtcblx0cmV0dXJuIGB7JHtwcm9wZXJ0aWVzLmpvaW4oXCIsIFwiKX19YDtcbn1cblxuLyoqXG4gKiBDb21waWxlcyBhIENvbnN0YW50IEJpbmRpbmcgRXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0gZXhwclxuICogQHBhcmFtIGVtYmVkZGVkSW5CaW5kaW5nXG4gKiBAcGFyYW0gaXNOdWxsYWJsZVxuICogQHBhcmFtIGRvTm90U3RyaW5naWZ5XG4gKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21waWxlQ29uc3RhbnQ8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRleHByOiBDb25zdGFudEV4cHJlc3Npb248VD4sXG5cdGVtYmVkZGVkSW5CaW5kaW5nOiBib29sZWFuLFxuXHRpc051bGxhYmxlPzogYm9vbGVhbixcblx0ZG9Ob3RTdHJpbmdpZnk/OiBmYWxzZVxuKTogQ29tcGlsZWRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb247XG5leHBvcnQgZnVuY3Rpb24gY29tcGlsZUNvbnN0YW50PFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0ZXhwcjogQ29uc3RhbnRFeHByZXNzaW9uPFQ+LFxuXHRlbWJlZGRlZEluQmluZGluZzogYm9vbGVhbixcblx0aXNOdWxsYWJsZT86IGJvb2xlYW4sXG5cdGRvTm90U3RyaW5naWZ5PzogdHJ1ZVxuKTogUHJpbWl0aXZlVHlwZTtcbmV4cG9ydCBmdW5jdGlvbiBjb21waWxlQ29uc3RhbnQ8VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KFxuXHRleHByOiBDb25zdGFudEV4cHJlc3Npb248VD4sXG5cdGVtYmVkZGVkSW5CaW5kaW5nOiBib29sZWFuLFxuXHRpc051bGxhYmxlID0gZmFsc2UsXG5cdGRvTm90U3RyaW5naWZ5ID0gZmFsc2Vcbik6IENvbXBpbGVkQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uIHwgUHJpbWl0aXZlVHlwZSB7XG5cdGlmIChleHByLnZhbHVlID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGRvTm90U3RyaW5naWZ5ID8gbnVsbCA6IFwibnVsbFwiO1xuXHR9XG5cdGlmIChleHByLnZhbHVlID09PSB1bmRlZmluZWQpIHtcblx0XHRyZXR1cm4gZG9Ob3RTdHJpbmdpZnkgPyB1bmRlZmluZWQgOiBcInVuZGVmaW5lZFwiO1xuXHR9XG5cdGlmICh0eXBlb2YgZXhwci52YWx1ZSA9PT0gXCJvYmplY3RcIikge1xuXHRcdGlmIChBcnJheS5pc0FycmF5KGV4cHIudmFsdWUpKSB7XG5cdFx0XHRjb25zdCBlbnRyaWVzID0gZXhwci52YWx1ZS5tYXAoKGV4cHJlc3Npb24pID0+IGNvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24sIHRydWUpKTtcblx0XHRcdHJldHVybiBgWyR7ZW50cmllcy5qb2luKFwiLCBcIil9XWA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBjb21waWxlQ29uc3RhbnRPYmplY3QoZXhwciBhcyBDb25zdGFudEV4cHJlc3Npb248b2JqZWN0PiwgaXNOdWxsYWJsZSk7XG5cdFx0fVxuXHR9XG5cblx0aWYgKGVtYmVkZGVkSW5CaW5kaW5nKSB7XG5cdFx0c3dpdGNoICh0eXBlb2YgZXhwci52YWx1ZSkge1xuXHRcdFx0Y2FzZSBcIm51bWJlclwiOlxuXHRcdFx0Y2FzZSBcImJpZ2ludFwiOlxuXHRcdFx0Y2FzZSBcImJvb2xlYW5cIjpcblx0XHRcdFx0cmV0dXJuIGV4cHIudmFsdWUudG9TdHJpbmcoKTtcblx0XHRcdGNhc2UgXCJzdHJpbmdcIjpcblx0XHRcdFx0cmV0dXJuIGAnJHtlc2NhcGVYbWxBdHRyaWJ1dGUoZXhwci52YWx1ZS50b1N0cmluZygpKX0nYDtcblx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdHJldHVybiBcIlwiO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gZG9Ob3RTdHJpbmdpZnkgPyBleHByLnZhbHVlIDogZXhwci52YWx1ZS50b1N0cmluZygpO1xuXHR9XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHRoZSBiaW5kaW5nIHN0cmluZyBmb3IgYSBCaW5kaW5nIGV4cHJlc3Npb24uXG4gKlxuICogQHBhcmFtIGV4cHJlc3Npb25Gb3JCaW5kaW5nIFRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGVcbiAqIEBwYXJhbSBlbWJlZGRlZEluQmluZGluZyBXaGV0aGVyIHRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGUgaXMgZW1iZWRkZWQgaW50byBhbm90aGVyIGV4cHJlc3Npb25cbiAqIEBwYXJhbSBlbWJlZGRlZFNlcGFyYXRvciBUaGUgYmluZGluZyB2YWx1ZSBldmFsdWF0b3IgKCQgb3IgJSBkZXBlbmRpbmcgb24gd2hldGhlciB3ZSB3YW50IHRvIGZvcmNlIHRoZSB0eXBlIG9yIG5vdClcbiAqIEByZXR1cm5zIFRoZSBjb3JyZXNwb25kaW5nIGV4cHJlc3Npb24gYmluZGluZ1xuICovXG5mdW5jdGlvbiBjb21waWxlUGF0aEluTW9kZWxFeHByZXNzaW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihcblx0ZXhwcmVzc2lvbkZvckJpbmRpbmc6IFBhdGhJbk1vZGVsRXhwcmVzc2lvbjxUPixcblx0ZW1iZWRkZWRJbkJpbmRpbmc6IGJvb2xlYW4sXG5cdGVtYmVkZGVkU2VwYXJhdG9yOiBzdHJpbmdcbik6IENvbXBpbGVkQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uIHtcblx0aWYgKFxuXHRcdGV4cHJlc3Npb25Gb3JCaW5kaW5nLnR5cGUgfHxcblx0XHRleHByZXNzaW9uRm9yQmluZGluZy5wYXJhbWV0ZXJzIHx8XG5cdFx0ZXhwcmVzc2lvbkZvckJpbmRpbmcudGFyZ2V0VHlwZSB8fFxuXHRcdGV4cHJlc3Npb25Gb3JCaW5kaW5nLmZvcm1hdE9wdGlvbnMgfHxcblx0XHRleHByZXNzaW9uRm9yQmluZGluZy5jb25zdHJhaW50c1xuXHQpIHtcblx0XHQvLyBUaGlzIGlzIG5vdyBhIGNvbXBsZXggYmluZGluZyBkZWZpbml0aW9uLCBsZXQncyBwcmVwYXJlIGZvciBpdFxuXHRcdGNvbnN0IGNvbXBsZXhCaW5kaW5nRGVmaW5pdGlvbiA9IHtcblx0XHRcdHBhdGg6IGNvbXBpbGVQYXRoSW5Nb2RlbChleHByZXNzaW9uRm9yQmluZGluZyksXG5cdFx0XHR0eXBlOiBleHByZXNzaW9uRm9yQmluZGluZy50eXBlLFxuXHRcdFx0dGFyZ2V0VHlwZTogZXhwcmVzc2lvbkZvckJpbmRpbmcudGFyZ2V0VHlwZSxcblx0XHRcdHBhcmFtZXRlcnM6IGV4cHJlc3Npb25Gb3JCaW5kaW5nLnBhcmFtZXRlcnMsXG5cdFx0XHRmb3JtYXRPcHRpb25zOiBleHByZXNzaW9uRm9yQmluZGluZy5mb3JtYXRPcHRpb25zLFxuXHRcdFx0Y29uc3RyYWludHM6IGV4cHJlc3Npb25Gb3JCaW5kaW5nLmNvbnN0cmFpbnRzXG5cdFx0fTtcblx0XHRjb25zdCBvdXRCaW5kaW5nID0gY29tcGlsZUV4cHJlc3Npb24oY29tcGxleEJpbmRpbmdEZWZpbml0aW9uLCBmYWxzZSwgZmFsc2UsIHRydWUpO1xuXHRcdGlmIChlbWJlZGRlZEluQmluZGluZykge1xuXHRcdFx0cmV0dXJuIGAke2VtYmVkZGVkU2VwYXJhdG9yfSR7b3V0QmluZGluZ31gO1xuXHRcdH1cblx0XHRyZXR1cm4gb3V0QmluZGluZztcblx0fSBlbHNlIGlmIChlbWJlZGRlZEluQmluZGluZykge1xuXHRcdHJldHVybiBgJHtlbWJlZGRlZFNlcGFyYXRvcn17JHtjb21waWxlUGF0aEluTW9kZWwoZXhwcmVzc2lvbkZvckJpbmRpbmcpfX1gO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBgeyR7Y29tcGlsZVBhdGhJbk1vZGVsKGV4cHJlc3Npb25Gb3JCaW5kaW5nKX19YDtcblx0fVxufVxuXG5mdW5jdGlvbiBjb21waWxlQ29tcGxleFR5cGVFeHByZXNzaW9uPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihleHByZXNzaW9uOiBDb21wbGV4VHlwZUV4cHJlc3Npb248VD4pOiBzdHJpbmcge1xuXHRpZiAoZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVycy5sZW5ndGggPT09IDEpIHtcblx0XHRyZXR1cm4gYHske2NvbXBpbGVQYXRoUGFyYW1ldGVyKGV4cHJlc3Npb24uYmluZGluZ1BhcmFtZXRlcnNbMF0gYXMgQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+LCB0cnVlKX0sIHR5cGU6ICcke1xuXHRcdFx0ZXhwcmVzc2lvbi50eXBlXG5cdFx0fSd9YDtcblx0fVxuXG5cdGxldCBvdXRwdXRFbmQgPSBgXSwgdHlwZTogJyR7ZXhwcmVzc2lvbi50eXBlfSdgO1xuXHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKSkge1xuXHRcdG91dHB1dEVuZCArPSBgLCBmb3JtYXRPcHRpb25zOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucyl9YDtcblx0fVxuXHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5wYXJhbWV0ZXJzKSkge1xuXHRcdG91dHB1dEVuZCArPSBgLCBwYXJhbWV0ZXJzOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24ucGFyYW1ldGVycyl9YDtcblx0fVxuXHRvdXRwdXRFbmQgKz0gXCJ9XCI7XG5cblx0cmV0dXJuIGB7bW9kZTonVHdvV2F5JywgcGFydHM6WyR7ZXhwcmVzc2lvbi5iaW5kaW5nUGFyYW1ldGVyc1xuXHRcdC5tYXAoKHBhcmFtKSA9PiBjb21waWxlUGF0aFBhcmFtZXRlcihwYXJhbSBhcyBCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb248UHJpbWl0aXZlVHlwZT4pKVxuXHRcdC5qb2luKFwiLFwiKX0ke291dHB1dEVuZH1gO1xufVxuXG4vKipcbiAqIFdyYXAgdGhlIGNvbXBpbGVkIGJpbmRpbmcgc3RyaW5nIGFzIHJlcXVpcmVkIGRlcGVuZGluZyBvbiBpdHMgY29udGV4dC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgY29tcGlsZWQgZXhwcmVzc2lvblxuICogQHBhcmFtIGVtYmVkZGVkSW5CaW5kaW5nIFRydWUgaWYgdGhlIGNvbXBpbGVkIGV4cHJlc3Npb24gaXMgdG8gYmUgZW1iZWRkZWQgaW4gYSBiaW5kaW5nXG4gKiBAcGFyYW0gcGFyZW50aGVzaXNSZXF1aXJlZCBUcnVlIGlmIHRoZSBlbWJlZGRlZCBiaW5kaW5nIG5lZWRzIHRvIGJlIHdyYXBwZWQgaW4gcGFyZXRoZXNpcyBzbyB0aGF0IGl0IGlzIGV2YWx1YXRlZCBhcyBvbmVcbiAqIEByZXR1cm5zIEZpbmFsaXplZCBjb21waWxlZCBleHByZXNzaW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cmFwQmluZGluZ0V4cHJlc3Npb24oXG5cdGV4cHJlc3Npb246IHN0cmluZyxcblx0ZW1iZWRkZWRJbkJpbmRpbmc6IGJvb2xlYW4sXG5cdHBhcmVudGhlc2lzUmVxdWlyZWQgPSBmYWxzZVxuKTogQ29tcGlsZWRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24ge1xuXHRpZiAoZW1iZWRkZWRJbkJpbmRpbmcpIHtcblx0XHRpZiAocGFyZW50aGVzaXNSZXF1aXJlZCkge1xuXHRcdFx0cmV0dXJuIGAoJHtleHByZXNzaW9ufSlgO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gZXhwcmVzc2lvbjtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0cmV0dXJuIGB7PSAke2V4cHJlc3Npb259fWA7XG5cdH1cbn1cblxuLyoqXG4gKiBDb21waWxlIGFuIGV4cHJlc3Npb24gaW50byBhbiBleHByZXNzaW9uIGJpbmRpbmcuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHRhcmdldCB0eXBlXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgZXhwcmVzc2lvbiB0byBjb21waWxlXG4gKiBAcGFyYW0gZW1iZWRkZWRJbkJpbmRpbmcgV2hldGhlciB0aGUgZXhwcmVzc2lvbiB0byBjb21waWxlIGlzIGVtYmVkZGVkIGludG8gYW5vdGhlciBleHByZXNzaW9uXG4gKiBAcGFyYW0ga2VlcFRhcmdldFR5cGUgS2VlcCB0aGUgdGFyZ2V0IHR5cGUgb2YgdGhlIGVtYmVkZGVkIGJpbmRpbmdzIGluc3RlYWQgb2YgY2FzdGluZyB0aGVtIHRvIGFueVxuICogQHBhcmFtIGlzTnVsbGFibGUgV2hldGhlciBiaW5kaW5nIGV4cHJlc3Npb24gY2FuIHJlc29sdmUgdG8gZW1wdHkgc3RyaW5nIG9yIG5vdFxuICogQHJldHVybnMgVGhlIGNvcnJlc3BvbmRpbmcgZXhwcmVzc2lvbiBiaW5kaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21waWxlRXhwcmVzc2lvbjxUIGV4dGVuZHMgUHJpbWl0aXZlVHlwZT4oXG5cdGV4cHJlc3Npb246IEV4cHJlc3Npb25PclByaW1pdGl2ZTxUPixcblx0ZW1iZWRkZWRJbkJpbmRpbmcgPSBmYWxzZSxcblx0a2VlcFRhcmdldFR5cGUgPSBmYWxzZSxcblx0aXNOdWxsYWJsZSA9IGZhbHNlXG4pOiBDb21waWxlZEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbiB7XG5cdGNvbnN0IGV4cHIgPSB3cmFwUHJpbWl0aXZlKGV4cHJlc3Npb24pO1xuXHRjb25zdCBlbWJlZGRlZFNlcGFyYXRvciA9IGtlZXBUYXJnZXRUeXBlID8gXCIkXCIgOiBcIiVcIjtcblxuXHRzd2l0Y2ggKGV4cHIuX3R5cGUpIHtcblx0XHRjYXNlIFwiVW5yZXNvbHZhYmxlXCI6XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXG5cdFx0Y2FzZSBcIkNvbnN0YW50XCI6XG5cdFx0XHRyZXR1cm4gY29tcGlsZUNvbnN0YW50KGV4cHIsIGVtYmVkZGVkSW5CaW5kaW5nLCBpc051bGxhYmxlKTtcblxuXHRcdGNhc2UgXCJSZWZcIjpcblx0XHRcdHJldHVybiBleHByLnJlZiB8fCBcIm51bGxcIjtcblxuXHRcdGNhc2UgXCJGdW5jdGlvblwiOlxuXHRcdFx0bGV0IGhhc0VtYmVkZGVkRnVuY3Rpb25DYWxsT3JCaW5kaW5nID0gZmFsc2U7XG5cdFx0XHRpZiAoZXhwci5pc0Zvcm1hdHRpbmdGbikge1xuXHRcdFx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShcblx0XHRcdFx0XHRleHByLFxuXHRcdFx0XHRcdFwiRnVuY3Rpb25cIixcblx0XHRcdFx0XHQoc3ViRm4pID0+IHtcblx0XHRcdFx0XHRcdGlmIChzdWJGbiAhPT0gZXhwciAmJiBzdWJGbi5vYmogPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdFx0XHRoYXNFbWJlZGRlZEZ1bmN0aW9uQ2FsbE9yQmluZGluZyA9IHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRyZXR1cm4gc3ViRm47XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHR0cnVlXG5cdFx0XHRcdCk7XG5cdFx0XHRcdHRyYW5zZm9ybVJlY3Vyc2l2ZWx5KFxuXHRcdFx0XHRcdGV4cHIsXG5cdFx0XHRcdFx0XCJDb25zdGFudFwiLFxuXHRcdFx0XHRcdChzdWJGbjogQ29uc3RhbnRFeHByZXNzaW9uPFQ+KSA9PiB7XG5cdFx0XHRcdFx0XHRpZiAoKHN1YkZuIGFzIHVua25vd24pICE9PSBleHByICYmIHR5cGVvZiBzdWJGbi52YWx1ZSA9PT0gXCJvYmplY3RcIikge1xuXHRcdFx0XHRcdFx0XHR0cmFuc2Zvcm1SZWN1cnNpdmVseShzdWJGbiwgXCJQYXRoSW5Nb2RlbFwiLCAoc3ViU3ViRm4pID0+IHtcblx0XHRcdFx0XHRcdFx0XHRoYXNFbWJlZGRlZEZ1bmN0aW9uQ2FsbE9yQmluZGluZyA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHN1YlN1YkZuO1xuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmV0dXJuIHN1YkZuO1xuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0dHJ1ZVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgYXJndW1lbnRTdHJpbmcgPSBgJHtleHByLnBhcmFtZXRlcnMubWFwKChhcmcpID0+IGNvbXBpbGVFeHByZXNzaW9uKGFyZywgdHJ1ZSkpLmpvaW4oXCIsIFwiKX1gO1xuXHRcdFx0bGV0IGZuQ2FsbCA9XG5cdFx0XHRcdGV4cHIub2JqID09PSB1bmRlZmluZWRcblx0XHRcdFx0XHQ/IGAke2V4cHIuZm59KCR7YXJndW1lbnRTdHJpbmd9KWBcblx0XHRcdFx0XHQ6IGAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIub2JqLCB0cnVlKX0uJHtleHByLmZufSgke2FyZ3VtZW50U3RyaW5nfSlgO1xuXHRcdFx0aWYgKCFlbWJlZGRlZEluQmluZGluZyAmJiBoYXNFbWJlZGRlZEZ1bmN0aW9uQ2FsbE9yQmluZGluZykge1xuXHRcdFx0XHRmbkNhbGwgPSBgez0gJHtmbkNhbGx9fWA7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZm5DYWxsO1xuXG5cdFx0Y2FzZSBcIkVtYmVkZGVkRXhwcmVzc2lvbkJpbmRpbmdcIjpcblx0XHRcdHJldHVybiBlbWJlZGRlZEluQmluZGluZyA/IGAoJHtleHByLnZhbHVlLnN1YnN0cmluZygyLCBleHByLnZhbHVlLmxlbmd0aCAtIDEpfSlgIDogYCR7ZXhwci52YWx1ZX1gO1xuXG5cdFx0Y2FzZSBcIkVtYmVkZGVkQmluZGluZ1wiOlxuXHRcdFx0cmV0dXJuIGVtYmVkZGVkSW5CaW5kaW5nID8gYCR7ZW1iZWRkZWRTZXBhcmF0b3J9JHtleHByLnZhbHVlfWAgOiBgJHtleHByLnZhbHVlfWA7XG5cblx0XHRjYXNlIFwiUGF0aEluTW9kZWxcIjpcblx0XHRcdHJldHVybiBjb21waWxlUGF0aEluTW9kZWxFeHByZXNzaW9uKGV4cHIsIGVtYmVkZGVkSW5CaW5kaW5nLCBlbWJlZGRlZFNlcGFyYXRvcik7XG5cblx0XHRjYXNlIFwiQ29tcGFyaXNvblwiOlxuXHRcdFx0Y29uc3QgY29tcGFyaXNvbkV4cHJlc3Npb24gPSBjb21waWxlQ29tcGFyaXNvbkV4cHJlc3Npb24oZXhwcik7XG5cdFx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKGNvbXBhcmlzb25FeHByZXNzaW9uLCBlbWJlZGRlZEluQmluZGluZyk7XG5cblx0XHRjYXNlIFwiSWZFbHNlXCI6XG5cdFx0XHRjb25zdCBpZkVsc2VFeHByZXNzaW9uID0gYCR7Y29tcGlsZUV4cHJlc3Npb24oZXhwci5jb25kaXRpb24sIHRydWUpfSA/ICR7Y29tcGlsZUV4cHJlc3Npb24oXG5cdFx0XHRcdGV4cHIub25UcnVlLFxuXHRcdFx0XHR0cnVlLFxuXHRcdFx0XHRrZWVwVGFyZ2V0VHlwZVxuXHRcdFx0KX0gOiAke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIub25GYWxzZSwgdHJ1ZSwga2VlcFRhcmdldFR5cGUpfWA7XG5cdFx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKGlmRWxzZUV4cHJlc3Npb24sIGVtYmVkZGVkSW5CaW5kaW5nLCB0cnVlKTtcblxuXHRcdGNhc2UgXCJTZXRcIjpcblx0XHRcdGNvbnN0IHNldEV4cHJlc3Npb24gPSBleHByLm9wZXJhbmRzLm1hcCgob3BlcmFuZCkgPT4gY29tcGlsZUV4cHJlc3Npb24ob3BlcmFuZCwgdHJ1ZSkpLmpvaW4oYCAke2V4cHIub3BlcmF0b3J9IGApO1xuXHRcdFx0cmV0dXJuIHdyYXBCaW5kaW5nRXhwcmVzc2lvbihzZXRFeHByZXNzaW9uLCBlbWJlZGRlZEluQmluZGluZywgdHJ1ZSk7XG5cblx0XHRjYXNlIFwiQ29uY2F0XCI6XG5cdFx0XHRjb25zdCBjb25jYXRFeHByZXNzaW9uID0gZXhwci5leHByZXNzaW9uc1xuXHRcdFx0XHQubWFwKChuZXN0ZWRFeHByZXNzaW9uKSA9PiBjb21waWxlRXhwcmVzc2lvbihuZXN0ZWRFeHByZXNzaW9uLCB0cnVlLCB0cnVlKSlcblx0XHRcdFx0LmpvaW4oXCIgKyBcIik7XG5cdFx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKGNvbmNhdEV4cHJlc3Npb24sIGVtYmVkZGVkSW5CaW5kaW5nKTtcblxuXHRcdGNhc2UgXCJMZW5ndGhcIjpcblx0XHRcdGNvbnN0IGxlbmd0aEV4cHJlc3Npb24gPSBgJHtjb21waWxlRXhwcmVzc2lvbihleHByLnBhdGhJbk1vZGVsLCB0cnVlKX0ubGVuZ3RoYDtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24obGVuZ3RoRXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcpO1xuXG5cdFx0Y2FzZSBcIk5vdFwiOlxuXHRcdFx0Y29uc3Qgbm90RXhwcmVzc2lvbiA9IGAhJHtjb21waWxlRXhwcmVzc2lvbihleHByLm9wZXJhbmQsIHRydWUpfWA7XG5cdFx0XHRyZXR1cm4gd3JhcEJpbmRpbmdFeHByZXNzaW9uKG5vdEV4cHJlc3Npb24sIGVtYmVkZGVkSW5CaW5kaW5nKTtcblxuXHRcdGNhc2UgXCJUcnV0aHlcIjpcblx0XHRcdGNvbnN0IHRydXRoeUV4cHJlc3Npb24gPSBgISEke2NvbXBpbGVFeHByZXNzaW9uKGV4cHIub3BlcmFuZCwgdHJ1ZSl9YDtcblx0XHRcdHJldHVybiB3cmFwQmluZGluZ0V4cHJlc3Npb24odHJ1dGh5RXhwcmVzc2lvbiwgZW1iZWRkZWRJbkJpbmRpbmcpO1xuXG5cdFx0Y2FzZSBcIkZvcm1hdHRlclwiOlxuXHRcdFx0Y29uc3QgZm9ybWF0dGVyRXhwcmVzc2lvbiA9IGNvbXBpbGVGb3JtYXR0ZXJFeHByZXNzaW9uKGV4cHIpO1xuXHRcdFx0cmV0dXJuIGVtYmVkZGVkSW5CaW5kaW5nID8gYCQke2Zvcm1hdHRlckV4cHJlc3Npb259YCA6IGZvcm1hdHRlckV4cHJlc3Npb247XG5cblx0XHRjYXNlIFwiQ29tcGxleFR5cGVcIjpcblx0XHRcdGNvbnN0IGNvbXBsZXhUeXBlRXhwcmVzc2lvbiA9IGNvbXBpbGVDb21wbGV4VHlwZUV4cHJlc3Npb24oZXhwcik7XG5cdFx0XHRyZXR1cm4gZW1iZWRkZWRJbkJpbmRpbmcgPyBgJCR7Y29tcGxleFR5cGVFeHByZXNzaW9ufWAgOiBjb21wbGV4VHlwZUV4cHJlc3Npb247XG5cblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuIFwiXCI7XG5cdH1cbn1cblxuLyoqXG4gKiBDb21waWxlIGEgY29tcGFyaXNvbiBleHByZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBjb21wYXJpc29uIGV4cHJlc3Npb24uXG4gKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgZXhwcmVzc2lvbi4gTmVlZHMgd3JhcHBpbmcgYmVmb3JlIGl0IGNhbiBiZSB1c2VkIGFzIGFuIGV4cHJlc3Npb24gYmluZGluZy5cbiAqL1xuZnVuY3Rpb24gY29tcGlsZUNvbXBhcmlzb25FeHByZXNzaW9uKGV4cHJlc3Npb246IENvbXBhcmlzb25FeHByZXNzaW9uKTogc3RyaW5nIHtcblx0ZnVuY3Rpb24gY29tcGlsZU9wZXJhbmQob3BlcmFuZDogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPHVua25vd24+KTogQ29tcGlsZWRCaW5kaW5nVG9vbGtpdEV4cHJlc3Npb24ge1xuXHRcdGNvbnN0IGNvbXBpbGVkT3BlcmFuZCA9IGNvbXBpbGVFeHByZXNzaW9uKG9wZXJhbmQsIHRydWUpID8/IFwidW5kZWZpbmVkXCI7XG5cdFx0cmV0dXJuIHdyYXBCaW5kaW5nRXhwcmVzc2lvbihjb21waWxlZE9wZXJhbmQsIHRydWUsIG5lZWRQYXJlbnRoZXNpcyhvcGVyYW5kKSk7XG5cdH1cblxuXHRyZXR1cm4gYCR7Y29tcGlsZU9wZXJhbmQoZXhwcmVzc2lvbi5vcGVyYW5kMSl9ICR7ZXhwcmVzc2lvbi5vcGVyYXRvcn0gJHtjb21waWxlT3BlcmFuZChleHByZXNzaW9uLm9wZXJhbmQyKX1gO1xufVxuXG4vKipcbiAqIENvbXBpbGUgYSBmb3JtYXR0ZXIgZXhwcmVzc2lvbi5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgZm9ybWF0dGVyIGV4cHJlc3Npb24uXG4gKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgZXhwcmVzc2lvbi5cbiAqL1xuZnVuY3Rpb24gY29tcGlsZUZvcm1hdHRlckV4cHJlc3Npb248VCBleHRlbmRzIFByaW1pdGl2ZVR5cGU+KGV4cHJlc3Npb246IEZvcm1hdHRlckV4cHJlc3Npb248VD4pOiBzdHJpbmcge1xuXHRpZiAoZXhwcmVzc2lvbi5wYXJhbWV0ZXJzLmxlbmd0aCA9PT0gMSkge1xuXHRcdHJldHVybiBgeyR7Y29tcGlsZVBhdGhQYXJhbWV0ZXIoZXhwcmVzc2lvbi5wYXJhbWV0ZXJzWzBdIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPiwgdHJ1ZSl9LCBmb3JtYXR0ZXI6ICcke1xuXHRcdFx0ZXhwcmVzc2lvbi5mblxuXHRcdH0nfWA7XG5cdH0gZWxzZSB7XG5cdFx0Y29uc3QgcGFydHMgPSBleHByZXNzaW9uLnBhcmFtZXRlcnMubWFwKChwYXJhbSkgPT4ge1xuXHRcdFx0aWYgKHBhcmFtLl90eXBlID09PSBcIkNvbXBsZXhUeXBlXCIpIHtcblx0XHRcdFx0cmV0dXJuIGNvbXBpbGVDb21wbGV4VHlwZUV4cHJlc3Npb24ocGFyYW0pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIGNvbXBpbGVQYXRoUGFyYW1ldGVyKHBhcmFtIGFzIEJpbmRpbmdUb29sa2l0RXhwcmVzc2lvbjxQcmltaXRpdmVUeXBlPik7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0cmV0dXJuIGB7cGFydHM6IFske3BhcnRzLmpvaW4oXCIsIFwiKX1dLCBmb3JtYXR0ZXI6ICcke2V4cHJlc3Npb24uZm59J31gO1xuXHR9XG59XG5cbi8qKlxuICogQ29tcGlsZSB0aGUgcGF0aCBwYXJhbWV0ZXIgb2YgYSBmb3JtYXR0ZXIgY2FsbC5cbiAqXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBUaGUgYmluZGluZyBwYXJ0IHRvIGV2YWx1YXRlXG4gKiBAcGFyYW0gc2luZ2xlUGF0aCBXaGV0aGVyIHRoZXJlIGlzIG9uZSBvciBtdWx0aXBsZSBwYXRoIHRvIGNvbnNpZGVyXG4gKiBAcmV0dXJucyBUaGUgc3RyaW5nIHNuaXBwZXQgdG8gaW5jbHVkZSBpbiB0aGUgb3ZlcmFsbCBiaW5kaW5nIGRlZmluaXRpb25cbiAqL1xuZnVuY3Rpb24gY29tcGlsZVBhdGhQYXJhbWV0ZXIoZXhwcmVzc2lvbjogQmluZGluZ1Rvb2xraXRFeHByZXNzaW9uPFByaW1pdGl2ZVR5cGU+LCBzaW5nbGVQYXRoID0gZmFsc2UpOiBzdHJpbmcge1xuXHRsZXQgb3V0VmFsdWUgPSBcIlwiO1xuXHRpZiAoZXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJDb25zdGFudFwiKSB7XG5cdFx0aWYgKGV4cHJlc3Npb24udmFsdWUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0Ly8gU3BlY2lhbCBjYXNlIG90aGVyd2lzZSB0aGUgSlNUb2tlbml6ZXIgY29tcGxhaW5zIGFib3V0IGluY29ycmVjdCBjb250ZW50XG5cdFx0XHRvdXRWYWx1ZSA9IGB2YWx1ZTogJ3VuZGVmaW5lZCdgO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvdXRWYWx1ZSA9IGB2YWx1ZTogJHtjb21waWxlQ29uc3RhbnQoZXhwcmVzc2lvbiwgdHJ1ZSl9YDtcblx0XHR9XG5cdH0gZWxzZSBpZiAoZXhwcmVzc2lvbi5fdHlwZSA9PT0gXCJQYXRoSW5Nb2RlbFwiKSB7XG5cdFx0b3V0VmFsdWUgPSBgcGF0aDogJyR7Y29tcGlsZVBhdGhJbk1vZGVsKGV4cHJlc3Npb24pfSdgO1xuXG5cdFx0b3V0VmFsdWUgKz0gZXhwcmVzc2lvbi50eXBlID8gYCwgdHlwZTogJyR7ZXhwcmVzc2lvbi50eXBlfSdgIDogYCwgdGFyZ2V0VHlwZTogJ2FueSdgO1xuXHRcdGlmIChleHByZXNzaW9uLm1vZGUpIHtcblx0XHRcdG91dFZhbHVlICs9IGAsIG1vZGU6ICcke2NvbXBpbGVFeHByZXNzaW9uKGV4cHJlc3Npb24ubW9kZSl9J2A7XG5cdFx0fVxuXHRcdGlmIChoYXNFbGVtZW50cyhleHByZXNzaW9uLmNvbnN0cmFpbnRzKSkge1xuXHRcdFx0b3V0VmFsdWUgKz0gYCwgY29uc3RyYWludHM6ICR7Y29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbi5jb25zdHJhaW50cyl9YDtcblx0XHR9XG5cdFx0aWYgKGhhc0VsZW1lbnRzKGV4cHJlc3Npb24uZm9ybWF0T3B0aW9ucykpIHtcblx0XHRcdG91dFZhbHVlICs9IGAsIGZvcm1hdE9wdGlvbnM6ICR7Y29tcGlsZUV4cHJlc3Npb24oZXhwcmVzc2lvbi5mb3JtYXRPcHRpb25zKX1gO1xuXHRcdH1cblx0XHRpZiAoaGFzRWxlbWVudHMoZXhwcmVzc2lvbi5wYXJhbWV0ZXJzKSkge1xuXHRcdFx0b3V0VmFsdWUgKz0gYCwgcGFyYW1ldGVyczogJHtjb21waWxlRXhwcmVzc2lvbihleHByZXNzaW9uLnBhcmFtZXRlcnMpfWA7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdHJldHVybiBcIlwiO1xuXHR9XG5cdHJldHVybiBzaW5nbGVQYXRoID8gb3V0VmFsdWUgOiBgeyR7b3V0VmFsdWV9fWA7XG59XG5cbmZ1bmN0aW9uIGhhc0VsZW1lbnRzKG9iajogb2JqZWN0IHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG5cdHJldHVybiAhIW9iaiAmJiBPYmplY3Qua2V5cyhvYmopLmxlbmd0aCA+IDA7XG59XG5cbi8qKlxuICogQ29tcGlsZSBhIGJpbmRpbmcgZXhwcmVzc2lvbiBwYXRoLlxuICpcbiAqIEBwYXJhbSBleHByZXNzaW9uIFRoZSBleHByZXNzaW9uIHRvIGNvbXBpbGUuXG4gKiBAcmV0dXJucyBUaGUgY29tcGlsZWQgcGF0aC5cbiAqL1xuZnVuY3Rpb24gY29tcGlsZVBhdGhJbk1vZGVsPFQgZXh0ZW5kcyBQcmltaXRpdmVUeXBlPihleHByZXNzaW9uOiBQYXRoSW5Nb2RlbEV4cHJlc3Npb248VD4pOiBzdHJpbmcge1xuXHRyZXR1cm4gYCR7ZXhwcmVzc2lvbi5tb2RlbE5hbWUgPyBl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