@angular/compiler 19.0.0-next.1 → 19.0.0-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/LICENSE +21 -0
  2. package/fesm2022/compiler.mjs +5465 -4675
  3. package/fesm2022/compiler.mjs.map +1 -1
  4. package/index.d.ts +115 -15
  5. package/package.json +2 -4
  6. package/esm2022/compiler.mjs +0 -13
  7. package/esm2022/index.mjs +0 -13
  8. package/esm2022/public_api.mjs +0 -15
  9. package/esm2022/src/assertions.mjs +0 -31
  10. package/esm2022/src/chars.mjs +0 -90
  11. package/esm2022/src/compiler.mjs +0 -88
  12. package/esm2022/src/compiler_facade_interface.mjs +0 -29
  13. package/esm2022/src/config.mjs +0 -20
  14. package/esm2022/src/constant_pool.mjs +0 -285
  15. package/esm2022/src/core.mjs +0 -96
  16. package/esm2022/src/expression_parser/ast.mjs +0 -755
  17. package/esm2022/src/expression_parser/lexer.mjs +0 -421
  18. package/esm2022/src/expression_parser/parser.mjs +0 -1222
  19. package/esm2022/src/i18n/digest.mjs +0 -322
  20. package/esm2022/src/i18n/extractor_merger.mjs +0 -409
  21. package/esm2022/src/i18n/i18n_ast.mjs +0 -212
  22. package/esm2022/src/i18n/i18n_html_parser.mjs +0 -54
  23. package/esm2022/src/i18n/i18n_parser.mjs +0 -247
  24. package/esm2022/src/i18n/index.mjs +0 -16
  25. package/esm2022/src/i18n/message_bundle.mjs +0 -93
  26. package/esm2022/src/i18n/parse_util.mjs +0 -17
  27. package/esm2022/src/i18n/serializers/placeholder.mjs +0 -139
  28. package/esm2022/src/i18n/serializers/serializer.mjs +0 -77
  29. package/esm2022/src/i18n/serializers/xliff.mjs +0 -300
  30. package/esm2022/src/i18n/serializers/xliff2.mjs +0 -349
  31. package/esm2022/src/i18n/serializers/xmb.mjs +0 -188
  32. package/esm2022/src/i18n/serializers/xml_helper.mjs +0 -94
  33. package/esm2022/src/i18n/serializers/xtb.mjs +0 -186
  34. package/esm2022/src/i18n/translation_bundle.mjs +0 -164
  35. package/esm2022/src/injectable_compiler_2.mjs +0 -138
  36. package/esm2022/src/jit_compiler_facade.mjs +0 -681
  37. package/esm2022/src/ml_parser/ast.mjs +0 -167
  38. package/esm2022/src/ml_parser/defaults.mjs +0 -24
  39. package/esm2022/src/ml_parser/entities.mjs +0 -2144
  40. package/esm2022/src/ml_parser/html_parser.mjs +0 -18
  41. package/esm2022/src/ml_parser/html_tags.mjs +0 -156
  42. package/esm2022/src/ml_parser/html_whitespaces.mjs +0 -107
  43. package/esm2022/src/ml_parser/icu_ast_expander.mjs +0 -125
  44. package/esm2022/src/ml_parser/lexer.mjs +0 -1210
  45. package/esm2022/src/ml_parser/parser.mjs +0 -539
  46. package/esm2022/src/ml_parser/tags.mjs +0 -47
  47. package/esm2022/src/ml_parser/tokens.mjs +0 -9
  48. package/esm2022/src/ml_parser/xml_parser.mjs +0 -19
  49. package/esm2022/src/ml_parser/xml_tags.mjs +0 -32
  50. package/esm2022/src/output/abstract_emitter.mjs +0 -524
  51. package/esm2022/src/output/abstract_js_emitter.mjs +0 -130
  52. package/esm2022/src/output/map_util.mjs +0 -19
  53. package/esm2022/src/output/output_ast.mjs +0 -1301
  54. package/esm2022/src/output/output_jit.mjs +0 -138
  55. package/esm2022/src/output/output_jit_trusted_types.mjs +0 -100
  56. package/esm2022/src/output/source_map.mjs +0 -150
  57. package/esm2022/src/parse_util.mjs +0 -198
  58. package/esm2022/src/render3/partial/api.mjs +0 -9
  59. package/esm2022/src/render3/partial/class_metadata.mjs +0 -52
  60. package/esm2022/src/render3/partial/component.mjs +0 -197
  61. package/esm2022/src/render3/partial/directive.mjs +0 -264
  62. package/esm2022/src/render3/partial/factory.mjs +0 -35
  63. package/esm2022/src/render3/partial/injectable.mjs +0 -67
  64. package/esm2022/src/render3/partial/injector.mjs +0 -41
  65. package/esm2022/src/render3/partial/ng_module.mjs +0 -63
  66. package/esm2022/src/render3/partial/pipe.mjs +0 -50
  67. package/esm2022/src/render3/partial/util.mjs +0 -79
  68. package/esm2022/src/render3/r3_ast.mjs +0 -493
  69. package/esm2022/src/render3/r3_class_debug_info_compiler.mjs +0 -35
  70. package/esm2022/src/render3/r3_class_metadata_compiler.mjs +0 -92
  71. package/esm2022/src/render3/r3_control_flow.mjs +0 -421
  72. package/esm2022/src/render3/r3_deferred_blocks.mjs +0 -170
  73. package/esm2022/src/render3/r3_deferred_triggers.mjs +0 -316
  74. package/esm2022/src/render3/r3_factory.mjs +0 -200
  75. package/esm2022/src/render3/r3_identifiers.mjs +0 -480
  76. package/esm2022/src/render3/r3_injector_compiler.mjs +0 -28
  77. package/esm2022/src/render3/r3_jit.mjs +0 -29
  78. package/esm2022/src/render3/r3_module_compiler.mjs +0 -211
  79. package/esm2022/src/render3/r3_pipe_compiler.mjs +0 -35
  80. package/esm2022/src/render3/r3_template_transform.mjs +0 -560
  81. package/esm2022/src/render3/util.mjs +0 -90
  82. package/esm2022/src/render3/view/api.mjs +0 -14
  83. package/esm2022/src/render3/view/compiler.mjs +0 -546
  84. package/esm2022/src/render3/view/i18n/get_msg_utils.mjs +0 -113
  85. package/esm2022/src/render3/view/i18n/icu_serializer.mjs +0 -43
  86. package/esm2022/src/render3/view/i18n/localize_utils.mjs +0 -118
  87. package/esm2022/src/render3/view/i18n/meta.mjs +0 -259
  88. package/esm2022/src/render3/view/i18n/util.mjs +0 -70
  89. package/esm2022/src/render3/view/query_generation.mjs +0 -182
  90. package/esm2022/src/render3/view/t2_api.mjs +0 -9
  91. package/esm2022/src/render3/view/t2_binder.mjs +0 -823
  92. package/esm2022/src/render3/view/template.mjs +0 -113
  93. package/esm2022/src/render3/view/util.mjs +0 -192
  94. package/esm2022/src/resource_loader.mjs +0 -17
  95. package/esm2022/src/schema/dom_element_schema_registry.mjs +0 -471
  96. package/esm2022/src/schema/dom_security_schema.mjs +0 -96
  97. package/esm2022/src/schema/element_schema_registry.mjs +0 -10
  98. package/esm2022/src/schema/trusted_types_sinks.mjs +0 -41
  99. package/esm2022/src/selector.mjs +0 -400
  100. package/esm2022/src/shadow_css.mjs +0 -1053
  101. package/esm2022/src/style_url_resolver.mjs +0 -17
  102. package/esm2022/src/template/pipeline/ir/index.mjs +0 -18
  103. package/esm2022/src/template/pipeline/ir/src/enums.mjs +0 -503
  104. package/esm2022/src/template/pipeline/ir/src/expression.mjs +0 -997
  105. package/esm2022/src/template/pipeline/ir/src/handle.mjs +0 -13
  106. package/esm2022/src/template/pipeline/ir/src/operations.mjs +0 -261
  107. package/esm2022/src/template/pipeline/ir/src/ops/create.mjs +0 -405
  108. package/esm2022/src/template/pipeline/ir/src/ops/host.mjs +0 -25
  109. package/esm2022/src/template/pipeline/ir/src/ops/shared.mjs +0 -43
  110. package/esm2022/src/template/pipeline/ir/src/ops/update.mjs +0 -277
  111. package/esm2022/src/template/pipeline/ir/src/traits.mjs +0 -64
  112. package/esm2022/src/template/pipeline/ir/src/variable.mjs +0 -13
  113. package/esm2022/src/template/pipeline/src/compilation.mjs +0 -194
  114. package/esm2022/src/template/pipeline/src/conversion.mjs +0 -64
  115. package/esm2022/src/template/pipeline/src/emit.mjs +0 -238
  116. package/esm2022/src/template/pipeline/src/ingest.mjs +0 -1058
  117. package/esm2022/src/template/pipeline/src/instruction.mjs +0 -564
  118. package/esm2022/src/template/pipeline/src/phases/any_cast.mjs +0 -32
  119. package/esm2022/src/template/pipeline/src/phases/apply_i18n_expressions.mjs +0 -63
  120. package/esm2022/src/template/pipeline/src/phases/assign_i18n_slot_dependencies.mjs +0 -63
  121. package/esm2022/src/template/pipeline/src/phases/attribute_extraction.mjs +0 -138
  122. package/esm2022/src/template/pipeline/src/phases/binding_specialization.mjs +0 -75
  123. package/esm2022/src/template/pipeline/src/phases/chaining.mjs +0 -112
  124. package/esm2022/src/template/pipeline/src/phases/collapse_singleton_interpolations.mjs +0 -32
  125. package/esm2022/src/template/pipeline/src/phases/conditionals.mjs +0 -58
  126. package/esm2022/src/template/pipeline/src/phases/const_collection.mjs +0 -214
  127. package/esm2022/src/template/pipeline/src/phases/convert_i18n_bindings.mjs +0 -52
  128. package/esm2022/src/template/pipeline/src/phases/create_i18n_contexts.mjs +0 -105
  129. package/esm2022/src/template/pipeline/src/phases/deduplicate_text_bindings.mjs +0 -40
  130. package/esm2022/src/template/pipeline/src/phases/defer_configs.mjs +0 -29
  131. package/esm2022/src/template/pipeline/src/phases/defer_resolve_targets.mjs +0 -113
  132. package/esm2022/src/template/pipeline/src/phases/empty_elements.mjs +0 -47
  133. package/esm2022/src/template/pipeline/src/phases/expand_safe_reads.mjs +0 -192
  134. package/esm2022/src/template/pipeline/src/phases/extract_i18n_messages.mjs +0 -218
  135. package/esm2022/src/template/pipeline/src/phases/generate_advance.mjs +0 -66
  136. package/esm2022/src/template/pipeline/src/phases/generate_local_let_references.mjs +0 -29
  137. package/esm2022/src/template/pipeline/src/phases/generate_projection_def.mjs +0 -46
  138. package/esm2022/src/template/pipeline/src/phases/generate_variables.mjs +0 -170
  139. package/esm2022/src/template/pipeline/src/phases/has_const_expression_collection.mjs +0 -28
  140. package/esm2022/src/template/pipeline/src/phases/host_style_property_parsing.mjs +0 -81
  141. package/esm2022/src/template/pipeline/src/phases/i18n_const_collection.mjs +0 -309
  142. package/esm2022/src/template/pipeline/src/phases/i18n_text_extraction.mjs +0 -97
  143. package/esm2022/src/template/pipeline/src/phases/local_refs.mjs +0 -43
  144. package/esm2022/src/template/pipeline/src/phases/namespace.mjs +0 -26
  145. package/esm2022/src/template/pipeline/src/phases/naming.mjs +0 -179
  146. package/esm2022/src/template/pipeline/src/phases/next_context_merging.mjs +0 -75
  147. package/esm2022/src/template/pipeline/src/phases/ng_container.mjs +0 -29
  148. package/esm2022/src/template/pipeline/src/phases/nonbindable.mjs +0 -47
  149. package/esm2022/src/template/pipeline/src/phases/nullish_coalescing.mjs +0 -33
  150. package/esm2022/src/template/pipeline/src/phases/ordering.mjs +0 -140
  151. package/esm2022/src/template/pipeline/src/phases/parse_extracted_styles.mjs +0 -137
  152. package/esm2022/src/template/pipeline/src/phases/phase_remove_content_selectors.mjs +0 -42
  153. package/esm2022/src/template/pipeline/src/phases/pipe_creation.mjs +0 -74
  154. package/esm2022/src/template/pipeline/src/phases/pipe_variadic.mjs +0 -30
  155. package/esm2022/src/template/pipeline/src/phases/propagate_i18n_blocks.mjs +0 -81
  156. package/esm2022/src/template/pipeline/src/phases/pure_function_extraction.mjs +0 -55
  157. package/esm2022/src/template/pipeline/src/phases/pure_literal_structures.mjs +0 -58
  158. package/esm2022/src/template/pipeline/src/phases/reify.mjs +0 -433
  159. package/esm2022/src/template/pipeline/src/phases/remove_empty_bindings.mjs +0 -31
  160. package/esm2022/src/template/pipeline/src/phases/remove_i18n_contexts.mjs +0 -27
  161. package/esm2022/src/template/pipeline/src/phases/remove_illegal_let_references.mjs +0 -36
  162. package/esm2022/src/template/pipeline/src/phases/remove_unused_i18n_attrs.mjs +0 -33
  163. package/esm2022/src/template/pipeline/src/phases/resolve_contexts.mjs +0 -60
  164. package/esm2022/src/template/pipeline/src/phases/resolve_defer_deps_fns.mjs +0 -31
  165. package/esm2022/src/template/pipeline/src/phases/resolve_dollar_event.mjs +0 -36
  166. package/esm2022/src/template/pipeline/src/phases/resolve_i18n_element_placeholders.mjs +0 -266
  167. package/esm2022/src/template/pipeline/src/phases/resolve_i18n_expression_placeholders.mjs +0 -70
  168. package/esm2022/src/template/pipeline/src/phases/resolve_names.mjs +0 -124
  169. package/esm2022/src/template/pipeline/src/phases/resolve_sanitizers.mjs +0 -123
  170. package/esm2022/src/template/pipeline/src/phases/save_restore_view.mjs +0 -64
  171. package/esm2022/src/template/pipeline/src/phases/slot_allocation.mjs +0 -62
  172. package/esm2022/src/template/pipeline/src/phases/store_let_optimization.mjs +0 -35
  173. package/esm2022/src/template/pipeline/src/phases/style_binding_specialization.mjs +0 -42
  174. package/esm2022/src/template/pipeline/src/phases/temporary_variables.mjs +0 -87
  175. package/esm2022/src/template/pipeline/src/phases/track_fn_generation.mjs +0 -52
  176. package/esm2022/src/template/pipeline/src/phases/track_fn_optimization.mjs +0 -88
  177. package/esm2022/src/template/pipeline/src/phases/track_variables.mjs +0 -36
  178. package/esm2022/src/template/pipeline/src/phases/transform_two_way_binding_set.mjs +0 -43
  179. package/esm2022/src/template/pipeline/src/phases/var_counting.mjs +0 -155
  180. package/esm2022/src/template/pipeline/src/phases/variable_optimization.mjs +0 -423
  181. package/esm2022/src/template/pipeline/src/phases/wrap_icus.mjs +0 -41
  182. package/esm2022/src/template/pipeline/src/util/elements.mjs +0 -29
  183. package/esm2022/src/template_parser/binding_parser.mjs +0 -465
  184. package/esm2022/src/template_parser/template_preparser.mjs +0 -84
  185. package/esm2022/src/util.mjs +0 -124
  186. package/esm2022/src/version.mjs +0 -15
@@ -1,421 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC All Rights Reserved.
4
- *
5
- * Use of this source code is governed by an MIT-style license that can be
6
- * found in the LICENSE file at https://angular.io/license
7
- */
8
- import { EmptyExpr } from '../expression_parser/ast';
9
- import * as html from '../ml_parser/ast';
10
- import { ParseError, ParseSourceSpan } from '../parse_util';
11
- import * as t from './r3_ast';
12
- /** Pattern for the expression in a for loop block. */
13
- const FOR_LOOP_EXPRESSION_PATTERN = /^\s*([0-9A-Za-z_$]*)\s+of\s+([\S\s]*)/;
14
- /** Pattern for the tracking expression in a for loop block. */
15
- const FOR_LOOP_TRACK_PATTERN = /^track\s+([\S\s]*)/;
16
- /** Pattern for the `as` expression in a conditional block. */
17
- const CONDITIONAL_ALIAS_PATTERN = /^(as\s)+(.*)/;
18
- /** Pattern used to identify an `else if` block. */
19
- const ELSE_IF_PATTERN = /^else[^\S\r\n]+if/;
20
- /** Pattern used to identify a `let` parameter. */
21
- const FOR_LOOP_LET_PATTERN = /^let\s+([\S\s]*)/;
22
- /**
23
- * Pattern to group a string into leading whitespace, non whitespace, and trailing whitespace.
24
- * Useful for getting the variable name span when a span can contain leading and trailing space.
25
- */
26
- const CHARACTERS_IN_SURROUNDING_WHITESPACE_PATTERN = /(\s*)(\S+)(\s*)/;
27
- /** Names of variables that are allowed to be used in the `let` expression of a `for` loop. */
28
- const ALLOWED_FOR_LOOP_LET_VARIABLES = new Set([
29
- '$index',
30
- '$first',
31
- '$last',
32
- '$even',
33
- '$odd',
34
- '$count',
35
- ]);
36
- /**
37
- * Predicate function that determines if a block with
38
- * a specific name cam be connected to a `for` block.
39
- */
40
- export function isConnectedForLoopBlock(name) {
41
- return name === 'empty';
42
- }
43
- /**
44
- * Predicate function that determines if a block with
45
- * a specific name cam be connected to an `if` block.
46
- */
47
- export function isConnectedIfLoopBlock(name) {
48
- return name === 'else' || ELSE_IF_PATTERN.test(name);
49
- }
50
- /** Creates an `if` loop block from an HTML AST node. */
51
- export function createIfBlock(ast, connectedBlocks, visitor, bindingParser) {
52
- const errors = validateIfConnectedBlocks(connectedBlocks);
53
- const branches = [];
54
- const mainBlockParams = parseConditionalBlockParameters(ast, errors, bindingParser);
55
- if (mainBlockParams !== null) {
56
- branches.push(new t.IfBlockBranch(mainBlockParams.expression, html.visitAll(visitor, ast.children, ast.children), mainBlockParams.expressionAlias, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan, ast.nameSpan, ast.i18n));
57
- }
58
- for (const block of connectedBlocks) {
59
- if (ELSE_IF_PATTERN.test(block.name)) {
60
- const params = parseConditionalBlockParameters(block, errors, bindingParser);
61
- if (params !== null) {
62
- const children = html.visitAll(visitor, block.children, block.children);
63
- branches.push(new t.IfBlockBranch(params.expression, children, params.expressionAlias, block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan, block.i18n));
64
- }
65
- }
66
- else if (block.name === 'else') {
67
- const children = html.visitAll(visitor, block.children, block.children);
68
- branches.push(new t.IfBlockBranch(null, children, null, block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan, block.i18n));
69
- }
70
- }
71
- // The outer IfBlock should have a span that encapsulates all branches.
72
- const ifBlockStartSourceSpan = branches.length > 0 ? branches[0].startSourceSpan : ast.startSourceSpan;
73
- const ifBlockEndSourceSpan = branches.length > 0 ? branches[branches.length - 1].endSourceSpan : ast.endSourceSpan;
74
- let wholeSourceSpan = ast.sourceSpan;
75
- const lastBranch = branches[branches.length - 1];
76
- if (lastBranch !== undefined) {
77
- wholeSourceSpan = new ParseSourceSpan(ifBlockStartSourceSpan.start, lastBranch.sourceSpan.end);
78
- }
79
- return {
80
- node: new t.IfBlock(branches, wholeSourceSpan, ast.startSourceSpan, ifBlockEndSourceSpan, ast.nameSpan),
81
- errors,
82
- };
83
- }
84
- /** Creates a `for` loop block from an HTML AST node. */
85
- export function createForLoop(ast, connectedBlocks, visitor, bindingParser) {
86
- const errors = [];
87
- const params = parseForLoopParameters(ast, errors, bindingParser);
88
- let node = null;
89
- let empty = null;
90
- for (const block of connectedBlocks) {
91
- if (block.name === 'empty') {
92
- if (empty !== null) {
93
- errors.push(new ParseError(block.sourceSpan, '@for loop can only have one @empty block'));
94
- }
95
- else if (block.parameters.length > 0) {
96
- errors.push(new ParseError(block.sourceSpan, '@empty block cannot have parameters'));
97
- }
98
- else {
99
- empty = new t.ForLoopBlockEmpty(html.visitAll(visitor, block.children, block.children), block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan, block.i18n);
100
- }
101
- }
102
- else {
103
- errors.push(new ParseError(block.sourceSpan, `Unrecognized @for loop block "${block.name}"`));
104
- }
105
- }
106
- if (params !== null) {
107
- if (params.trackBy === null) {
108
- // TODO: We should not fail here, and instead try to produce some AST for the language
109
- // service.
110
- errors.push(new ParseError(ast.sourceSpan, '@for loop must have a "track" expression'));
111
- }
112
- else {
113
- // The `for` block has a main span that includes the `empty` branch. For only the span of the
114
- // main `for` body, use `mainSourceSpan`.
115
- const endSpan = empty?.endSourceSpan ?? ast.endSourceSpan;
116
- const sourceSpan = new ParseSourceSpan(ast.sourceSpan.start, endSpan?.end ?? ast.sourceSpan.end);
117
- node = new t.ForLoopBlock(params.itemName, params.expression, params.trackBy.expression, params.trackBy.keywordSpan, params.context, html.visitAll(visitor, ast.children, ast.children), empty, sourceSpan, ast.sourceSpan, ast.startSourceSpan, endSpan, ast.nameSpan, ast.i18n);
118
- }
119
- }
120
- return { node, errors };
121
- }
122
- /** Creates a switch block from an HTML AST node. */
123
- export function createSwitchBlock(ast, visitor, bindingParser) {
124
- const errors = validateSwitchBlock(ast);
125
- const primaryExpression = ast.parameters.length > 0
126
- ? parseBlockParameterToBinding(ast.parameters[0], bindingParser)
127
- : bindingParser.parseBinding('', false, ast.sourceSpan, 0);
128
- const cases = [];
129
- const unknownBlocks = [];
130
- let defaultCase = null;
131
- // Here we assume that all the blocks are valid given that we validated them above.
132
- for (const node of ast.children) {
133
- if (!(node instanceof html.Block)) {
134
- continue;
135
- }
136
- if ((node.name !== 'case' || node.parameters.length === 0) && node.name !== 'default') {
137
- unknownBlocks.push(new t.UnknownBlock(node.name, node.sourceSpan, node.nameSpan));
138
- continue;
139
- }
140
- const expression = node.name === 'case' ? parseBlockParameterToBinding(node.parameters[0], bindingParser) : null;
141
- const ast = new t.SwitchBlockCase(expression, html.visitAll(visitor, node.children, node.children), node.sourceSpan, node.startSourceSpan, node.endSourceSpan, node.nameSpan, node.i18n);
142
- if (expression === null) {
143
- defaultCase = ast;
144
- }
145
- else {
146
- cases.push(ast);
147
- }
148
- }
149
- // Ensure that the default case is last in the array.
150
- if (defaultCase !== null) {
151
- cases.push(defaultCase);
152
- }
153
- return {
154
- node: new t.SwitchBlock(primaryExpression, cases, unknownBlocks, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan, ast.nameSpan),
155
- errors,
156
- };
157
- }
158
- /** Parses the parameters of a `for` loop block. */
159
- function parseForLoopParameters(block, errors, bindingParser) {
160
- if (block.parameters.length === 0) {
161
- errors.push(new ParseError(block.sourceSpan, '@for loop does not have an expression'));
162
- return null;
163
- }
164
- const [expressionParam, ...secondaryParams] = block.parameters;
165
- const match = stripOptionalParentheses(expressionParam, errors)?.match(FOR_LOOP_EXPRESSION_PATTERN);
166
- if (!match || match[2].trim().length === 0) {
167
- errors.push(new ParseError(expressionParam.sourceSpan, 'Cannot parse expression. @for loop expression must match the pattern "<identifier> of <expression>"'));
168
- return null;
169
- }
170
- const [, itemName, rawExpression] = match;
171
- if (ALLOWED_FOR_LOOP_LET_VARIABLES.has(itemName)) {
172
- errors.push(new ParseError(expressionParam.sourceSpan, `@for loop item name cannot be one of ${Array.from(ALLOWED_FOR_LOOP_LET_VARIABLES).join(', ')}.`));
173
- }
174
- // `expressionParam.expression` contains the variable declaration and the expression of the
175
- // for...of statement, i.e. 'user of users' The variable of a ForOfStatement is _only_ the "const
176
- // user" part and does not include "of x".
177
- const variableName = expressionParam.expression.split(' ')[0];
178
- const variableSpan = new ParseSourceSpan(expressionParam.sourceSpan.start, expressionParam.sourceSpan.start.moveBy(variableName.length));
179
- const result = {
180
- itemName: new t.Variable(itemName, '$implicit', variableSpan, variableSpan),
181
- trackBy: null,
182
- expression: parseBlockParameterToBinding(expressionParam, bindingParser, rawExpression),
183
- context: Array.from(ALLOWED_FOR_LOOP_LET_VARIABLES, (variableName) => {
184
- // Give ambiently-available context variables empty spans at the end of
185
- // the start of the `for` block, since they are not explicitly defined.
186
- const emptySpanAfterForBlockStart = new ParseSourceSpan(block.startSourceSpan.end, block.startSourceSpan.end);
187
- return new t.Variable(variableName, variableName, emptySpanAfterForBlockStart, emptySpanAfterForBlockStart);
188
- }),
189
- };
190
- for (const param of secondaryParams) {
191
- const letMatch = param.expression.match(FOR_LOOP_LET_PATTERN);
192
- if (letMatch !== null) {
193
- const variablesSpan = new ParseSourceSpan(param.sourceSpan.start.moveBy(letMatch[0].length - letMatch[1].length), param.sourceSpan.end);
194
- parseLetParameter(param.sourceSpan, letMatch[1], variablesSpan, itemName, result.context, errors);
195
- continue;
196
- }
197
- const trackMatch = param.expression.match(FOR_LOOP_TRACK_PATTERN);
198
- if (trackMatch !== null) {
199
- if (result.trackBy !== null) {
200
- errors.push(new ParseError(param.sourceSpan, '@for loop can only have one "track" expression'));
201
- }
202
- else {
203
- const expression = parseBlockParameterToBinding(param, bindingParser, trackMatch[1]);
204
- if (expression.ast instanceof EmptyExpr) {
205
- errors.push(new ParseError(param.sourceSpan, '@for loop must have a "track" expression'));
206
- }
207
- const keywordSpan = new ParseSourceSpan(param.sourceSpan.start, param.sourceSpan.start.moveBy('track'.length));
208
- result.trackBy = { expression, keywordSpan };
209
- }
210
- continue;
211
- }
212
- errors.push(new ParseError(param.sourceSpan, `Unrecognized @for loop paramater "${param.expression}"`));
213
- }
214
- return result;
215
- }
216
- /** Parses the `let` parameter of a `for` loop block. */
217
- function parseLetParameter(sourceSpan, expression, span, loopItemName, context, errors) {
218
- const parts = expression.split(',');
219
- let startSpan = span.start;
220
- for (const part of parts) {
221
- const expressionParts = part.split('=');
222
- const name = expressionParts.length === 2 ? expressionParts[0].trim() : '';
223
- const variableName = expressionParts.length === 2 ? expressionParts[1].trim() : '';
224
- if (name.length === 0 || variableName.length === 0) {
225
- errors.push(new ParseError(sourceSpan, `Invalid @for loop "let" parameter. Parameter should match the pattern "<name> = <variable name>"`));
226
- }
227
- else if (!ALLOWED_FOR_LOOP_LET_VARIABLES.has(variableName)) {
228
- errors.push(new ParseError(sourceSpan, `Unknown "let" parameter variable "${variableName}". The allowed variables are: ${Array.from(ALLOWED_FOR_LOOP_LET_VARIABLES).join(', ')}`));
229
- }
230
- else if (name === loopItemName) {
231
- errors.push(new ParseError(sourceSpan, `Invalid @for loop "let" parameter. Variable cannot be called "${loopItemName}"`));
232
- }
233
- else if (context.some((v) => v.name === name)) {
234
- errors.push(new ParseError(sourceSpan, `Duplicate "let" parameter variable "${variableName}"`));
235
- }
236
- else {
237
- const [, keyLeadingWhitespace, keyName] = expressionParts[0].match(CHARACTERS_IN_SURROUNDING_WHITESPACE_PATTERN) ?? [];
238
- const keySpan = keyLeadingWhitespace !== undefined && expressionParts.length === 2
239
- ? new ParseSourceSpan(
240
- /* strip leading spaces */
241
- startSpan.moveBy(keyLeadingWhitespace.length),
242
- /* advance to end of the variable name */
243
- startSpan.moveBy(keyLeadingWhitespace.length + keyName.length))
244
- : span;
245
- let valueSpan = undefined;
246
- if (expressionParts.length === 2) {
247
- const [, valueLeadingWhitespace, implicit] = expressionParts[1].match(CHARACTERS_IN_SURROUNDING_WHITESPACE_PATTERN) ?? [];
248
- valueSpan =
249
- valueLeadingWhitespace !== undefined
250
- ? new ParseSourceSpan(startSpan.moveBy(expressionParts[0].length + 1 + valueLeadingWhitespace.length), startSpan.moveBy(expressionParts[0].length + 1 + valueLeadingWhitespace.length + implicit.length))
251
- : undefined;
252
- }
253
- const sourceSpan = new ParseSourceSpan(keySpan.start, valueSpan?.end ?? keySpan.end);
254
- context.push(new t.Variable(name, variableName, sourceSpan, keySpan, valueSpan));
255
- }
256
- startSpan = startSpan.moveBy(part.length + 1 /* add 1 to move past the comma */);
257
- }
258
- }
259
- /**
260
- * Checks that the shape of the blocks connected to an
261
- * `@if` block is correct. Returns an array of errors.
262
- */
263
- function validateIfConnectedBlocks(connectedBlocks) {
264
- const errors = [];
265
- let hasElse = false;
266
- for (let i = 0; i < connectedBlocks.length; i++) {
267
- const block = connectedBlocks[i];
268
- if (block.name === 'else') {
269
- if (hasElse) {
270
- errors.push(new ParseError(block.sourceSpan, 'Conditional can only have one @else block'));
271
- }
272
- else if (connectedBlocks.length > 1 && i < connectedBlocks.length - 1) {
273
- errors.push(new ParseError(block.sourceSpan, '@else block must be last inside the conditional'));
274
- }
275
- else if (block.parameters.length > 0) {
276
- errors.push(new ParseError(block.sourceSpan, '@else block cannot have parameters'));
277
- }
278
- hasElse = true;
279
- }
280
- else if (!ELSE_IF_PATTERN.test(block.name)) {
281
- errors.push(new ParseError(block.sourceSpan, `Unrecognized conditional block @${block.name}`));
282
- }
283
- }
284
- return errors;
285
- }
286
- /** Checks that the shape of a `switch` block is valid. Returns an array of errors. */
287
- function validateSwitchBlock(ast) {
288
- const errors = [];
289
- let hasDefault = false;
290
- if (ast.parameters.length !== 1) {
291
- errors.push(new ParseError(ast.sourceSpan, '@switch block must have exactly one parameter'));
292
- return errors;
293
- }
294
- for (const node of ast.children) {
295
- // Skip over comments and empty text nodes inside the switch block.
296
- // Empty text nodes can be used for formatting while comments don't affect the runtime.
297
- if (node instanceof html.Comment ||
298
- (node instanceof html.Text && node.value.trim().length === 0)) {
299
- continue;
300
- }
301
- if (!(node instanceof html.Block) || (node.name !== 'case' && node.name !== 'default')) {
302
- errors.push(new ParseError(node.sourceSpan, '@switch block can only contain @case and @default blocks'));
303
- continue;
304
- }
305
- if (node.name === 'default') {
306
- if (hasDefault) {
307
- errors.push(new ParseError(node.sourceSpan, '@switch block can only have one @default block'));
308
- }
309
- else if (node.parameters.length > 0) {
310
- errors.push(new ParseError(node.sourceSpan, '@default block cannot have parameters'));
311
- }
312
- hasDefault = true;
313
- }
314
- else if (node.name === 'case' && node.parameters.length !== 1) {
315
- errors.push(new ParseError(node.sourceSpan, '@case block must have exactly one parameter'));
316
- }
317
- }
318
- return errors;
319
- }
320
- /**
321
- * Parses a block parameter into a binding AST.
322
- * @param ast Block parameter that should be parsed.
323
- * @param bindingParser Parser that the expression should be parsed with.
324
- * @param part Specific part of the expression that should be parsed.
325
- */
326
- function parseBlockParameterToBinding(ast, bindingParser, part) {
327
- let start;
328
- let end;
329
- if (typeof part === 'string') {
330
- // Note: `lastIndexOf` here should be enough to know the start index of the expression,
331
- // because we know that it'll be at the end of the param. Ideally we could use the `d`
332
- // flag when matching via regex and get the index from `match.indices`, but it's unclear
333
- // if we can use it yet since it's a relatively new feature. See:
334
- // https://github.com/tc39/proposal-regexp-match-indices
335
- start = Math.max(0, ast.expression.lastIndexOf(part));
336
- end = start + part.length;
337
- }
338
- else {
339
- start = 0;
340
- end = ast.expression.length;
341
- }
342
- return bindingParser.parseBinding(ast.expression.slice(start, end), false, ast.sourceSpan, ast.sourceSpan.start.offset + start);
343
- }
344
- /** Parses the parameter of a conditional block (`if` or `else if`). */
345
- function parseConditionalBlockParameters(block, errors, bindingParser) {
346
- if (block.parameters.length === 0) {
347
- errors.push(new ParseError(block.sourceSpan, 'Conditional block does not have an expression'));
348
- return null;
349
- }
350
- const expression = parseBlockParameterToBinding(block.parameters[0], bindingParser);
351
- let expressionAlias = null;
352
- // Start from 1 since we processed the first parameter already.
353
- for (let i = 1; i < block.parameters.length; i++) {
354
- const param = block.parameters[i];
355
- const aliasMatch = param.expression.match(CONDITIONAL_ALIAS_PATTERN);
356
- // For now conditionals can only have an `as` parameter.
357
- // We may want to rework this later if we add more.
358
- if (aliasMatch === null) {
359
- errors.push(new ParseError(param.sourceSpan, `Unrecognized conditional paramater "${param.expression}"`));
360
- }
361
- else if (block.name !== 'if') {
362
- errors.push(new ParseError(param.sourceSpan, '"as" expression is only allowed on the primary @if block'));
363
- }
364
- else if (expressionAlias !== null) {
365
- errors.push(new ParseError(param.sourceSpan, 'Conditional can only have one "as" expression'));
366
- }
367
- else {
368
- const name = aliasMatch[2].trim();
369
- const variableStart = param.sourceSpan.start.moveBy(aliasMatch[1].length);
370
- const variableSpan = new ParseSourceSpan(variableStart, variableStart.moveBy(name.length));
371
- expressionAlias = new t.Variable(name, name, variableSpan, variableSpan);
372
- }
373
- }
374
- return { expression, expressionAlias };
375
- }
376
- /** Strips optional parentheses around from a control from expression parameter. */
377
- function stripOptionalParentheses(param, errors) {
378
- const expression = param.expression;
379
- const spaceRegex = /^\s$/;
380
- let openParens = 0;
381
- let start = 0;
382
- let end = expression.length - 1;
383
- for (let i = 0; i < expression.length; i++) {
384
- const char = expression[i];
385
- if (char === '(') {
386
- start = i + 1;
387
- openParens++;
388
- }
389
- else if (spaceRegex.test(char)) {
390
- continue;
391
- }
392
- else {
393
- break;
394
- }
395
- }
396
- if (openParens === 0) {
397
- return expression;
398
- }
399
- for (let i = expression.length - 1; i > -1; i--) {
400
- const char = expression[i];
401
- if (char === ')') {
402
- end = i;
403
- openParens--;
404
- if (openParens === 0) {
405
- break;
406
- }
407
- }
408
- else if (spaceRegex.test(char)) {
409
- continue;
410
- }
411
- else {
412
- break;
413
- }
414
- }
415
- if (openParens !== 0) {
416
- errors.push(new ParseError(param.sourceSpan, 'Unclosed parentheses in expression'));
417
- return null;
418
- }
419
- return expression.slice(start, end);
420
- }
421
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicjNfY29udHJvbF9mbG93LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3JlbmRlcjMvcjNfY29udHJvbF9mbG93LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBZ0IsU0FBUyxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDbEUsT0FBTyxLQUFLLElBQUksTUFBTSxrQkFBa0IsQ0FBQztBQUN6QyxPQUFPLEVBQUMsVUFBVSxFQUFFLGVBQWUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUcxRCxPQUFPLEtBQUssQ0FBQyxNQUFNLFVBQVUsQ0FBQztBQUU5QixzREFBc0Q7QUFDdEQsTUFBTSwyQkFBMkIsR0FBRyx1Q0FBdUMsQ0FBQztBQUU1RSwrREFBK0Q7QUFDL0QsTUFBTSxzQkFBc0IsR0FBRyxvQkFBb0IsQ0FBQztBQUVwRCw4REFBOEQ7QUFDOUQsTUFBTSx5QkFBeUIsR0FBRyxjQUFjLENBQUM7QUFFakQsbURBQW1EO0FBQ25ELE1BQU0sZUFBZSxHQUFHLG1CQUFtQixDQUFDO0FBRTVDLGtEQUFrRDtBQUNsRCxNQUFNLG9CQUFvQixHQUFHLGtCQUFrQixDQUFDO0FBRWhEOzs7R0FHRztBQUNILE1BQU0sNENBQTRDLEdBQUcsaUJBQWlCLENBQUM7QUFFdkUsOEZBQThGO0FBQzlGLE1BQU0sOEJBQThCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDN0MsUUFBUTtJQUNSLFFBQVE7SUFDUixPQUFPO0lBQ1AsT0FBTztJQUNQLE1BQU07SUFDTixRQUFRO0NBQ1QsQ0FBQyxDQUFDO0FBRUg7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLHVCQUF1QixDQUFDLElBQVk7SUFDbEQsT0FBTyxJQUFJLEtBQUssT0FBTyxDQUFDO0FBQzFCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsSUFBWTtJQUNqRCxPQUFPLElB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QyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ2hELE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUzQixJQUFJLElBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNqQixHQUFHLEdBQUcsQ0FBQyxDQUFDO1lBQ1IsVUFBVSxFQUFFLENBQUM7WUFDYixJQUFJLFVBQVUsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDckIsTUFBTTtZQUNSLENBQUM7UUFDSCxDQUFDO2FBQU0sSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDakMsU0FBUztRQUNYLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTTtRQUNSLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxVQUFVLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDckIsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLFVBQVUsQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLG9DQUFvQyxDQUFDLENBQUMsQ0FBQztRQUNwRixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3RDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtBU1RXaXRoU291cmNlLCBFbXB0eUV4cHJ9IGZyb20gJy4uL2V4cHJlc3Npb25fcGFyc2VyL2FzdCc7XG5pbXBvcnQgKiBhcyBodG1sIGZyb20gJy4uL21sX3BhcnNlci9hc3QnO1xuaW1wb3J0IHtQYXJzZUVycm9yLCBQYXJzZVNvdXJjZVNwYW59IGZyb20gJy4uL3BhcnNlX3V0aWwnO1xuaW1wb3J0IHtCaW5kaW5nUGFyc2VyfSBmcm9tICcuLi90ZW1wbGF0ZV9wYXJzZXIvYmluZGluZ19wYXJzZXInO1xuXG5pbXBvcnQgKiBhcyB0IGZyb20gJy4vcjNfYXN0JztcblxuLyoqIFBhdHRlcm4gZm9yIHRoZSBleHByZXNzaW9uIGluIGEgZm9yIGxvb3AgYmxvY2suICovXG5jb25zdCBGT1JfTE9PUF9FWFBSRVNTSU9OX1BBVFRFUk4gPSAvXlxccyooWzAtOUEtWmEtel8kXSopXFxzK29mXFxzKyhbXFxTXFxzXSopLztcblxuLyoqIFBhdHRlcm4gZm9yIHRoZSB0cmFja2luZyBleHByZXNzaW9uIGluIGEgZm9yIGxvb3AgYmxvY2suICovXG5jb25zdCBGT1JfTE9PUF9UUkFDS19QQVRURVJOID0gL150cmFja1xccysoW1xcU1xcc10qKS87XG5cbi8qKiBQYXR0ZXJuIGZvciB0aGUgYGFzYCBleHByZXNzaW9uIGluIGEgY29uZGl0aW9uYWwgYmxvY2suICovXG5jb25zdCBDT05ESVRJT05BTF9BTElBU19QQVRURVJOID0gL14oYXNcXHMpKyguKikvO1xuXG4vKiogUGF0dGVybiB1c2VkIHRvIGlkZW50aWZ5IGFuIGBlbHNlIGlmYCBibG9jay4gKi9cbmNvbnN0IEVMU0VfSUZfUEFUVEVSTiA9IC9eZWxzZVteXFxTXFxyXFxuXStpZi87XG5cbi8qKiBQYXR0ZXJuIHVzZWQgdG8gaWRlbnRpZnkgYSBgbGV0YCBwYXJhbWV0ZXIuICovXG5jb25zdCBGT1JfTE9PUF9MRVRfUEFUVEVSTiA9IC9ebGV0XFxzKyhbXFxTXFxzXSopLztcblxuLyoqXG4gKiBQYXR0ZXJuIHRvIGdyb3VwIGEgc3RyaW5nIGludG8gbGVhZGluZyB3aGl0ZXNwYWNlLCBub24gd2hpdGVzcGFjZSwgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UuXG4gKiBVc2VmdWwgZm9yIGdldHRpbmcgdGhlIHZhcmlhYmxlIG5hbWUgc3BhbiB3aGVuIGEgc3BhbiBjYW4gY29udGFpbiBsZWFkaW5nIGFuZCB0cmFpbGluZyBzcGFjZS5cbiAqL1xuY29uc3QgQ0hBUkFDVEVSU19JTl9TVVJST1VORElOR19XSElURVNQQUNFX1BBVFRFUk4gPSAvKFxccyopKFxcUyspKFxccyopLztcblxuLyoqIE5hbWVzIG9mIHZhcmlhYmxlcyB0aGF0IGFyZSBhbGxvd2VkIHRvIGJlIHVzZWQgaW4gdGhlIGBsZXRgIGV4cHJlc3Npb24gb2YgYSBgZm9yYCBsb29wLiAqL1xuY29uc3QgQUxMT1dFRF9GT1JfTE9PUF9MRVRfVkFSSUFCTEVTID0gbmV3IFNldChbXG4gICckaW5kZXgnLFxuICAnJGZpcnN0JyxcbiAgJyRsYXN0JyxcbiAgJyRldmVuJyxcbiAgJyRvZGQnLFxuICAnJGNvdW50Jyxcbl0pO1xuXG4vKipcbiAqIFByZWRpY2F0ZSBmdW5jdGlvbiB0aGF0IGRldGVybWluZXMgaWYgYSBibG9jayB3aXRoXG4gKiBhIHNwZWNpZmljIG5hbWUgY2FtIGJlIGNvbm5lY3RlZCB0byBhIGBmb3JgIGJsb2NrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb25uZWN0ZWRGb3JMb29wQmxvY2sobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBuYW1lID09PSAnZW1wdHknO1xufVxuXG4vKipcbiAqIFByZWRpY2F0ZSBmdW5jdGlvbiB0aGF0IGRldGVybWluZXMgaWYgYSBibG9jayB3aXRoXG4gKiBhIHNwZWNpZmljIG5hbWUgY2FtIGJlIGNvbm5lY3RlZCB0byBhbiBgaWZgIGJsb2NrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb25uZWN0ZWRJZkxvb3BCbG9jayhuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIG5hbWUgPT09ICdlbHNlJyB8fCBFTFNFX0lGX1BBVFRFUk4udGVzdChuYW1lKTtcbn1cblxuLyoqIENyZWF0ZXMgYW4gYGlmYCBsb29wIGJsb2NrIGZyb20gYW4gSFRNTCBBU1Qgbm9kZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVJZkJsb2NrKFxuICBhc3Q6IGh0bWwuQmxvY2ssXG4gIGNvbm5lY3RlZEJsb2NrczogaHRtbC5CbG9ja1tdLFxuICB2aXNpdG9yOiBodG1sLlZpc2l0b3IsXG4gIGJpbmRpbmdQYXJzZXI6IEJpbmRpbmdQYXJzZXIsXG4pOiB7bm9kZTogdC5JZkJsb2NrIHwgbnVsbDsgZXJyb3JzOiBQYXJzZUVycm9yW119IHtcbiAgY29uc3QgZXJyb3JzOiBQYXJzZUVycm9yW10gPSB2YWxpZGF0ZUlmQ29ubmVjdGVkQmxvY2tzKGNvbm5lY3RlZEJsb2Nrcyk7XG4gIGNvbnN0IGJyYW5jaGVzOiB0LklmQmxvY2tCcmFuY2hbXSA9IFtdO1xuICBjb25zdCBtYWluQmxvY2tQYXJhbXMgPSBwYXJzZUNvbmRpdGlvbmFsQmxvY2tQYXJhbWV0ZXJzKGFzdCwgZXJyb3JzLCBiaW5kaW5nUGFyc2VyKTtcblxuICBpZiAobWFpbkJsb2NrUGFyYW1zICE9PSBudWxsKSB7XG4gICAgYnJhbmNoZXMucHVzaChcbiAgICAgIG5ldyB0LklmQmxvY2tCcmFuY2goXG4gICAgICAgIG1haW5CbG9ja1BhcmFtcy5leHByZXNzaW9uLFxuICAgICAgICBodG1sLnZpc2l0QWxsKHZpc2l0b3IsIGFzdC5jaGlsZHJlbiwgYXN0LmNoaWxkcmVuKSxcbiAgICAgICAgbWFpbkJsb2NrUGFyYW1zLmV4cHJlc3Npb25BbGlhcyxcbiAgICAgICAgYXN0LnNvdXJjZVNwYW4sXG4gICAgICAgIGFzdC5zdGFydFNvdXJjZVNwYW4sXG4gICAgICAgIGFzdC5lbmRTb3VyY2VTcGFuLFxuICAgICAgICBhc3QubmFtZVNwYW4sXG4gICAgICAgIGFzdC5pMThuLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgZm9yIChjb25zdCBibG9jayBvZiBjb25uZWN0ZWRCbG9ja3MpIHtcbiAgICBpZiAoRUxTRV9JRl9QQVRURVJOLnRlc3QoYmxvY2submFtZSkpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHBhcnNlQ29uZGl0aW9uYWxCbG9ja1BhcmFtZXRlcnMoYmxvY2ssIGVycm9ycywgYmluZGluZ1BhcnNlcik7XG5cbiAgICAgIGlmIChwYXJhbXMgIT09IG51bGwpIHtcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBodG1sLnZpc2l0QWxsKHZpc2l0b3IsIGJsb2NrLmNoaWxkcmVuLCBibG9jay5jaGlsZHJlbik7XG4gICAgICAgIGJyYW5jaGVzLnB1c2goXG4gICAgICAgICAgbmV3IHQuSWZCbG9ja0JyYW5jaChcbiAgICAgICAgICAgIHBhcmFtcy5leHByZXNzaW9uLFxuICAgICAgICAgICAgY2hpbGRyZW4sXG4gICAgICAgICAgICBwYXJhbXMuZXhwcmVzc2lvbkFsaWFzLFxuICAgICAgICAgICAgYmxvY2suc291cmNlU3BhbixcbiAgICAgICAgICAgIGJsb2NrLnN0YXJ0U291cmNlU3BhbixcbiAgICAgICAgICAgIGJsb2NrLmVuZFNvdXJjZVNwYW4sXG4gICAgICAgICAgICBibG9jay5uYW1lU3BhbixcbiAgICAgICAgICAgIGJsb2NrLmkxOG4sXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGJsb2NrLm5hbWUgPT09ICdlbHNlJykge1xuICAgICAgY29uc3QgY2hpbGRyZW4gPSBodG1sLnZpc2l0QWxsKHZpc2l0b3IsIGJsb2NrLmNoaWxkcmVuLCBibG9jay5jaGlsZHJlbik7XG4gICAgICBicmFuY2hlcy5wdXNoKFxuICAgICAgICBuZXcgdC5JZkJsb2NrQnJhbmNoKFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICAgY2hpbGRyZW4sXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgICBibG9jay5zb3VyY2VTcGFuLFxuICAgICAgICAgIGJsb2NrLnN0YXJ0U291cmNlU3BhbixcbiAgICAgICAgICBibG9jay5lbmRTb3VyY2VTcGFuLFxuICAgICAgICAgIGJsb2NrLm5hbWVTcGFuLFxuICAgICAgICAgIGJsb2NrLmkxOG4sXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRoZSBvdXRlciBJZkJsb2NrIHNob3VsZCBoYXZlIGEgc3BhbiB0aGF0IGVuY2Fwc3VsYXRlcyBhbGwgYnJhbmNoZXMuXG4gIGNvbnN0IGlmQmxvY2tTdGFydFNvdXJjZVNwYW4gPVxuICAgIGJyYW5jaGVzLmxlbmd0aCA+IDAgPyBicmFuY2hlc1swXS5zdGFydFNvdXJjZVNwYW4gOiBhc3Quc3RhcnRTb3VyY2VTcGFuO1xuICBjb25zdCBpZkJsb2NrRW5kU291cmNlU3BhbiA9XG4gICAgYnJhbmNoZXMubGVuZ3RoID4gMCA/IGJyYW5jaGVzW2JyYW5jaGVzLmxlbmd0aCAtIDFdLmVuZFNvdXJjZVNwYW4gOiBhc3QuZW5kU291cmNlU3BhbjtcblxuICBsZXQgd2hvbGVTb3VyY2VTcGFuID0gYXN0LnNvdXJjZVNwYW47XG4gIGNvbnN0IGxhc3RCcmFuY2ggPSBicmFuY2hlc1ticmFuY2hlcy5sZW5ndGggLSAxXTtcbiAgaWYgKGxhc3RCcmFuY2ggIT09IHVuZGVmaW5lZCkge1xuICAgIHdob2xlU291cmNlU3BhbiA9IG5ldyBQYXJzZVNvdXJjZVNwYW4oaWZCbG9ja1N0YXJ0U291cmNlU3Bhbi5zdGFydCwgbGFzdEJyYW5jaC5zb3VyY2VTcGFuLmVuZCk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5vZGU6IG5ldyB0LklmQmxvY2soXG4gICAgICBicmFuY2hlcyxcbiAgICAgIHdob2xlU291cmNlU3BhbixcbiAgICAgIGFzdC5zdGFydFNvdXJjZVNwYW4sXG4gICAgICBpZkJsb2NrRW5kU291cmNlU3BhbixcbiAgICAgIGFzdC5uYW1lU3BhbixcbiAgICApLFxuICAgIGVycm9ycyxcbiAgfTtcbn1cblxuLyoqIENyZWF0ZXMgYSBgZm9yYCBsb29wIGJsb2NrIGZyb20gYW4gSFRNTCBBU1Qgbm9kZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVGb3JMb29wKFxuICBhc3Q6IGh0bWwuQmxvY2ssXG4gIGNvbm5lY3RlZEJsb2NrczogaHRtbC5CbG9ja1tdLFxuICB2aXNpdG9yOiBodG1sLlZpc2l0b3IsXG4gIGJpbmRpbmdQYXJzZXI6IEJpbmRpbmdQYXJzZXIsXG4pOiB7bm9kZTogdC5Gb3JMb29wQmxvY2sgfCBudWxsOyBlcnJvcnM6IFBhcnNlRXJyb3JbXX0ge1xuICBjb25zdCBlcnJvcnM6IFBhcnNlRXJyb3JbXSA9IFtdO1xuICBjb25zdCBwYXJhbXMgPSBwYXJzZUZvckxvb3BQYXJhbWV0ZXJzKGFzdCwgZXJyb3JzLCBiaW5kaW5nUGFyc2VyKTtcbiAgbGV0IG5vZGU6IHQuRm9yTG9vcEJsb2NrIHwgbnVsbCA9IG51bGw7XG4gIGxldCBlbXB0eTogdC5Gb3JMb29wQmxvY2tFbXB0eSB8IG51bGwgPSBudWxsO1xuXG4gIGZvciAoY29uc3QgYmxvY2sgb2YgY29ubmVjdGVkQmxvY2tzKSB7XG4gICAgaWYgKGJsb2NrLm5hbWUgPT09ICdlbXB0eScpIHtcbiAgICAgIGlmIChlbXB0eSAhPT0gbnVsbCkge1xuICAgICAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihibG9jay5zb3VyY2VTcGFuLCAnQGZvciBsb29wIGNhbiBvbmx5IGhhdmUgb25lIEBlbXB0eSBibG9jaycpKTtcbiAgICAgIH0gZWxzZSBpZiAoYmxvY2sucGFyYW1ldGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKGJsb2NrLnNvdXJjZVNwYW4sICdAZW1wdHkgYmxvY2sgY2Fubm90IGhhdmUgcGFyYW1ldGVycycpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVtcHR5ID0gbmV3IHQuRm9yTG9vcEJsb2NrRW1wdHkoXG4gICAgICAgICAgaHRtbC52aXNpdEFsbCh2aXNpdG9yLCBibG9jay5jaGlsZHJlbiwgYmxvY2suY2hpbGRyZW4pLFxuICAgICAgICAgIGJsb2NrLnNvdXJjZVNwYW4sXG4gICAgICAgICAgYmxvY2suc3RhcnRTb3VyY2VTcGFuLFxuICAgICAgICAgIGJsb2NrLmVuZFNvdXJjZVNwYW4sXG4gICAgICAgICAgYmxvY2submFtZVNwYW4sXG4gICAgICAgICAgYmxvY2suaTE4bixcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3JzLnB1c2gobmV3IFBhcnNlRXJyb3IoYmxvY2suc291cmNlU3BhbiwgYFVucmVjb2duaXplZCBAZm9yIGxvb3AgYmxvY2sgXCIke2Jsb2NrLm5hbWV9XCJgKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHBhcmFtcyAhPT0gbnVsbCkge1xuICAgIGlmIChwYXJhbXMudHJhY2tCeSA9PT0gbnVsbCkge1xuICAgICAgLy8gVE9ETzogV2Ugc2hvdWxkIG5vdCBmYWlsIGhlcmUsIGFuZCBpbnN0ZWFkIHRyeSB0byBwcm9kdWNlIHNvbWUgQVNUIGZvciB0aGUgbGFuZ3VhZ2VcbiAgICAgIC8vIHNlcnZpY2UuXG4gICAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihhc3Quc291cmNlU3BhbiwgJ0Bmb3IgbG9vcCBtdXN0IGhhdmUgYSBcInRyYWNrXCIgZXhwcmVzc2lvbicpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhlIGBmb3JgIGJsb2NrIGhhcyBhIG1haW4gc3BhbiB0aGF0IGluY2x1ZGVzIHRoZSBgZW1wdHlgIGJyYW5jaC4gRm9yIG9ubHkgdGhlIHNwYW4gb2YgdGhlXG4gICAgICAvLyBtYWluIGBmb3JgIGJvZHksIHVzZSBgbWFpblNvdXJjZVNwYW5gLlxuICAgICAgY29uc3QgZW5kU3BhbiA9IGVtcHR5Py5lbmRTb3VyY2VTcGFuID8/IGFzdC5lbmRTb3VyY2VTcGFuO1xuICAgICAgY29uc3Qgc291cmNlU3BhbiA9IG5ldyBQYXJzZVNvdXJjZVNwYW4oXG4gICAgICAgIGFzdC5zb3VyY2VTcGFuLnN0YXJ0LFxuICAgICAgICBlbmRTcGFuPy5lbmQgPz8gYXN0LnNvdXJjZVNwYW4uZW5kLFxuICAgICAgKTtcbiAgICAgIG5vZGUgPSBuZXcgdC5Gb3JMb29wQmxvY2soXG4gICAgICAgIHBhcmFtcy5pdGVtTmFtZSxcbiAgICAgICAgcGFyYW1zLmV4cHJlc3Npb24sXG4gICAgICAgIHBhcmFtcy50cmFja0J5LmV4cHJlc3Npb24sXG4gICAgICAgIHBhcmFtcy50cmFja0J5LmtleXdvcmRTcGFuLFxuICAgICAgICBwYXJhbXMuY29udGV4dCxcbiAgICAgICAgaHRtbC52aXNpdEFsbCh2aXNpdG9yLCBhc3QuY2hpbGRyZW4sIGFzdC5jaGlsZHJlbiksXG4gICAgICAgIGVtcHR5LFxuICAgICAgICBzb3VyY2VTcGFuLFxuICAgICAgICBhc3Quc291cmNlU3BhbixcbiAgICAgICAgYXN0LnN0YXJ0U291cmNlU3BhbixcbiAgICAgICAgZW5kU3BhbixcbiAgICAgICAgYXN0Lm5hbWVTcGFuLFxuICAgICAgICBhc3QuaTE4bixcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtub2RlLCBlcnJvcnN9O1xufVxuXG4vKiogQ3JlYXRlcyBhIHN3aXRjaCBibG9jayBmcm9tIGFuIEhUTUwgQVNUIG5vZGUuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU3dpdGNoQmxvY2soXG4gIGFzdDogaHRtbC5CbG9jayxcbiAgdmlzaXRvcjogaHRtbC5WaXNpdG9yLFxuICBiaW5kaW5nUGFyc2VyOiBCaW5kaW5nUGFyc2VyLFxuKToge25vZGU6IHQuU3dpdGNoQmxvY2sgfCBudWxsOyBlcnJvcnM6IFBhcnNlRXJyb3JbXX0ge1xuICBjb25zdCBlcnJvcnMgPSB2YWxpZGF0ZVN3aXRjaEJsb2NrKGFzdCk7XG4gIGNvbnN0IHByaW1hcnlFeHByZXNzaW9uID1cbiAgICBhc3QucGFyYW1ldGVycy5sZW5ndGggPiAwXG4gICAgICA/IHBhcnNlQmxvY2tQYXJhbWV0ZXJUb0JpbmRpbmcoYXN0LnBhcmFtZXRlcnNbMF0sIGJpbmRpbmdQYXJzZXIpXG4gICAgICA6IGJpbmRpbmdQYXJzZXIucGFyc2VCaW5kaW5nKCcnLCBmYWxzZSwgYXN0LnNvdXJjZVNwYW4sIDApO1xuICBjb25zdCBjYXNlczogdC5Td2l0Y2hCbG9ja0Nhc2VbXSA9IFtdO1xuICBjb25zdCB1bmtub3duQmxvY2tzOiB0LlVua25vd25CbG9ja1tdID0gW107XG4gIGxldCBkZWZhdWx0Q2FzZTogdC5Td2l0Y2hCbG9ja0Nhc2UgfCBudWxsID0gbnVsbDtcblxuICAvLyBIZXJlIHdlIGFzc3VtZSB0aGF0IGFsbCB0aGUgYmxvY2tzIGFyZSB2YWxpZCBnaXZlbiB0aGF0IHdlIHZhbGlkYXRlZCB0aGVtIGFib3ZlLlxuICBmb3IgKGNvbnN0IG5vZGUgb2YgYXN0LmNoaWxkcmVuKSB7XG4gICAgaWYgKCEobm9kZSBpbnN0YW5jZW9mIGh0bWwuQmxvY2spKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoKG5vZGUubmFtZSAhPT0gJ2Nhc2UnIHx8IG5vZGUucGFyYW1ldGVycy5sZW5ndGggPT09IDApICYmIG5vZGUubmFtZSAhPT0gJ2RlZmF1bHQnKSB7XG4gICAgICB1bmtub3duQmxvY2tzLnB1c2gobmV3IHQuVW5rbm93bkJsb2NrKG5vZGUubmFtZSwgbm9kZS5zb3VyY2VTcGFuLCBub2RlLm5hbWVTcGFuKSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBleHByZXNzaW9uID1cbiAgICAgIG5vZGUubmFtZSA9PT0gJ2Nhc2UnID8gcGFyc2VCbG9ja1BhcmFtZXRlclRvQmluZGluZyhub2RlLnBhcmFtZXRlcnNbMF0sIGJpbmRpbmdQYXJzZXIpIDogbnVsbDtcbiAgICBjb25zdCBhc3QgPSBuZXcgdC5Td2l0Y2hCbG9ja0Nhc2UoXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgaHRtbC52aXNpdEFsbCh2aXNpdG9yLCBub2RlLmNoaWxkcmVuLCBub2RlLmNoaWxkcmVuKSxcbiAgICAgIG5vZGUuc291cmNlU3BhbixcbiAgICAgIG5vZGUuc3RhcnRTb3VyY2VTcGFuLFxuICAgICAgbm9kZS5lbmRTb3VyY2VTcGFuLFxuICAgICAgbm9kZS5uYW1lU3BhbixcbiAgICAgIG5vZGUuaTE4bixcbiAgICApO1xuXG4gICAgaWYgKGV4cHJlc3Npb24gPT09IG51bGwpIHtcbiAgICAgIGRlZmF1bHRDYXNlID0gYXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBjYXNlcy5wdXNoKGFzdCk7XG4gICAgfVxuICB9XG5cbiAgLy8gRW5zdXJlIHRoYXQgdGhlIGRlZmF1bHQgY2FzZSBpcyBsYXN0IGluIHRoZSBhcnJheS5cbiAgaWYgKGRlZmF1bHRDYXNlICE9PSBudWxsKSB7XG4gICAgY2FzZXMucHVzaChkZWZhdWx0Q2FzZSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5vZGU6IG5ldyB0LlN3aXRjaEJsb2NrKFxuICAgICAgcHJpbWFyeUV4cHJlc3Npb24sXG4gICAgICBjYXNlcyxcbiAgICAgIHVua25vd25CbG9ja3MsXG4gICAgICBhc3Quc291cmNlU3BhbixcbiAgICAgIGFzdC5zdGFydFNvdXJjZVNwYW4sXG4gICAgICBhc3QuZW5kU291cmNlU3BhbixcbiAgICAgIGFzdC5uYW1lU3BhbixcbiAgICApLFxuICAgIGVycm9ycyxcbiAgfTtcbn1cblxuLyoqIFBhcnNlcyB0aGUgcGFyYW1ldGVycyBvZiBhIGBmb3JgIGxvb3AgYmxvY2suICovXG5mdW5jdGlvbiBwYXJzZUZvckxvb3BQYXJhbWV0ZXJzKFxuICBibG9jazogaHRtbC5CbG9jayxcbiAgZXJyb3JzOiBQYXJzZUVycm9yW10sXG4gIGJpbmRpbmdQYXJzZXI6IEJpbmRpbmdQYXJzZXIsXG4pIHtcbiAgaWYgKGJsb2NrLnBhcmFtZXRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgZXJyb3JzLnB1c2gobmV3IFBhcnNlRXJyb3IoYmxvY2suc291cmNlU3BhbiwgJ0Bmb3IgbG9vcCBkb2VzIG5vdCBoYXZlIGFuIGV4cHJlc3Npb24nKSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBbZXhwcmVzc2lvblBhcmFtLCAuLi5zZWNvbmRhcnlQYXJhbXNdID0gYmxvY2sucGFyYW1ldGVycztcbiAgY29uc3QgbWF0Y2ggPSBzdHJpcE9wdGlvbmFsUGFyZW50aGVzZXMoZXhwcmVzc2lvblBhcmFtLCBlcnJvcnMpPy5tYXRjaChcbiAgICBGT1JfTE9PUF9FWFBSRVNTSU9OX1BBVFRFUk4sXG4gICk7XG5cbiAgaWYgKCFtYXRjaCB8fCBtYXRjaFsyXS50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgZXJyb3JzLnB1c2goXG4gICAgICBuZXcgUGFyc2VFcnJvcihcbiAgICAgICAgZXhwcmVzc2lvblBhcmFtLnNvdXJjZVNwYW4sXG4gICAgICAgICdDYW5ub3QgcGFyc2UgZXhwcmVzc2lvbi4gQGZvciBsb29wIGV4cHJlc3Npb24gbXVzdCBtYXRjaCB0aGUgcGF0dGVybiBcIjxpZGVudGlmaWVyPiBvZiA8ZXhwcmVzc2lvbj5cIicsXG4gICAgICApLFxuICAgICk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBbLCBpdGVtTmFtZSwgcmF3RXhwcmVzc2lvbl0gPSBtYXRjaDtcbiAgaWYgKEFMTE9XRURfRk9SX0xPT1BfTEVUX1ZBUklBQkxFUy5oYXMoaXRlbU5hbWUpKSB7XG4gICAgZXJyb3JzLnB1c2goXG4gICAgICBuZXcgUGFyc2VFcnJvcihcbiAgICAgICAgZXhwcmVzc2lvblBhcmFtLnNvdXJjZVNwYW4sXG4gICAgICAgIGBAZm9yIGxvb3AgaXRlbSBuYW1lIGNhbm5vdCBiZSBvbmUgb2YgJHtBcnJheS5mcm9tKEFMTE9XRURfRk9SX0xPT1BfTEVUX1ZBUklBQkxFUykuam9pbihcbiAgICAgICAgICAnLCAnLFxuICAgICAgICApfS5gLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgLy8gYGV4cHJlc3Npb25QYXJhbS5leHByZXNzaW9uYCBjb250YWlucyB0aGUgdmFyaWFibGUgZGVjbGFyYXRpb24gYW5kIHRoZSBleHByZXNzaW9uIG9mIHRoZVxuICAvLyBmb3IuLi5vZiBzdGF0ZW1lbnQsIGkuZS4gJ3VzZXIgb2YgdXNlcnMnIFRoZSB2YXJpYWJsZSBvZiBhIEZvck9mU3RhdGVtZW50IGlzIF9vbmx5XyB0aGUgXCJjb25zdFxuICAvLyB1c2VyXCIgcGFydCBhbmQgZG9lcyBub3QgaW5jbHVkZSBcIm9mIHhcIi5cbiAgY29uc3QgdmFyaWFibGVOYW1lID0gZXhwcmVzc2lvblBhcmFtLmV4cHJlc3Npb24uc3BsaXQoJyAnKVswXTtcbiAgY29uc3QgdmFyaWFibGVTcGFuID0gbmV3IFBhcnNlU291cmNlU3BhbihcbiAgICBleHByZXNzaW9uUGFyYW0uc291cmNlU3Bhbi5zdGFydCxcbiAgICBleHByZXNzaW9uUGFyYW0uc291cmNlU3Bhbi5zdGFydC5tb3ZlQnkodmFyaWFibGVOYW1lLmxlbmd0aCksXG4gICk7XG4gIGNvbnN0IHJlc3VsdCA9IHtcbiAgICBpdGVtTmFtZTogbmV3IHQuVmFyaWFibGUoaXRlbU5hbWUsICckaW1wbGljaXQnLCB2YXJpYWJsZVNwYW4sIHZhcmlhYmxlU3BhbiksXG4gICAgdHJhY2tCeTogbnVsbCBhcyB7ZXhwcmVzc2lvbjogQVNUV2l0aFNvdXJjZTsga2V5d29yZFNwYW46IFBhcnNlU291cmNlU3Bhbn0gfCBudWxsLFxuICAgIGV4cHJlc3Npb246IHBhcnNlQmxvY2tQYXJhbWV0ZXJUb0JpbmRpbmcoZXhwcmVzc2lvblBhcmFtLCBiaW5kaW5nUGFyc2VyLCByYXdFeHByZXNzaW9uKSxcbiAgICBjb250ZXh0OiBBcnJheS5mcm9tKEFMTE9XRURfRk9SX0xPT1BfTEVUX1ZBUklBQkxFUywgKHZhcmlhYmxlTmFtZSkgPT4ge1xuICAgICAgLy8gR2l2ZSBhbWJpZW50bHktYXZhaWxhYmxlIGNvbnRleHQgdmFyaWFibGVzIGVtcHR5IHNwYW5zIGF0IHRoZSBlbmQgb2ZcbiAgICAgIC8vIHRoZSBzdGFydCBvZiB0aGUgYGZvcmAgYmxvY2ssIHNpbmNlIHRoZXkgYXJlIG5vdCBleHBsaWNpdGx5IGRlZmluZWQuXG4gICAgICBjb25zdCBlbXB0eVNwYW5BZnRlckZvckJsb2NrU3RhcnQgPSBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgICBibG9jay5zdGFydFNvdXJjZVNwYW4uZW5kLFxuICAgICAgICBibG9jay5zdGFydFNvdXJjZVNwYW4uZW5kLFxuICAgICAgKTtcbiAgICAgIHJldHVybiBuZXcgdC5WYXJpYWJsZShcbiAgICAgICAgdmFyaWFibGVOYW1lLFxuICAgICAgICB2YXJpYWJsZU5hbWUsXG4gICAgICAgIGVtcHR5U3BhbkFmdGVyRm9yQmxvY2tTdGFydCxcbiAgICAgICAgZW1wdHlTcGFuQWZ0ZXJGb3JCbG9ja1N0YXJ0LFxuICAgICAgKTtcbiAgICB9KSxcbiAgfTtcblxuICBmb3IgKGNvbnN0IHBhcmFtIG9mIHNlY29uZGFyeVBhcmFtcykge1xuICAgIGNvbnN0IGxldE1hdGNoID0gcGFyYW0uZXhwcmVzc2lvbi5tYXRjaChGT1JfTE9PUF9MRVRfUEFUVEVSTik7XG5cbiAgICBpZiAobGV0TWF0Y2ggIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IHZhcmlhYmxlc1NwYW4gPSBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgICBwYXJhbS5zb3VyY2VTcGFuLnN0YXJ0Lm1vdmVCeShsZXRNYXRjaFswXS5sZW5ndGggLSBsZXRNYXRjaFsxXS5sZW5ndGgpLFxuICAgICAgICBwYXJhbS5zb3VyY2VTcGFuLmVuZCxcbiAgICAgICk7XG4gICAgICBwYXJzZUxldFBhcmFtZXRlcihcbiAgICAgICAgcGFyYW0uc291cmNlU3BhbixcbiAgICAgICAgbGV0TWF0Y2hbMV0sXG4gICAgICAgIHZhcmlhYmxlc1NwYW4sXG4gICAgICAgIGl0ZW1OYW1lLFxuICAgICAgICByZXN1bHQuY29udGV4dCxcbiAgICAgICAgZXJyb3JzLFxuICAgICAgKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHRyYWNrTWF0Y2ggPSBwYXJhbS5leHByZXNzaW9uLm1hdGNoKEZPUl9MT09QX1RSQUNLX1BBVFRFUk4pO1xuXG4gICAgaWYgKHRyYWNrTWF0Y2ggIT09IG51bGwpIHtcbiAgICAgIGlmIChyZXN1bHQudHJhY2tCeSAhPT0gbnVsbCkge1xuICAgICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgICBuZXcgUGFyc2VFcnJvcihwYXJhbS5zb3VyY2VTcGFuLCAnQGZvciBsb29wIGNhbiBvbmx5IGhhdmUgb25lIFwidHJhY2tcIiBleHByZXNzaW9uJyksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBleHByZXNzaW9uID0gcGFyc2VCbG9ja1BhcmFtZXRlclRvQmluZGluZyhwYXJhbSwgYmluZGluZ1BhcnNlciwgdHJhY2tNYXRjaFsxXSk7XG4gICAgICAgIGlmIChleHByZXNzaW9uLmFzdCBpbnN0YW5jZW9mIEVtcHR5RXhwcikge1xuICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKHBhcmFtLnNvdXJjZVNwYW4sICdAZm9yIGxvb3AgbXVzdCBoYXZlIGEgXCJ0cmFja1wiIGV4cHJlc3Npb24nKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qga2V5d29yZFNwYW4gPSBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgICAgIHBhcmFtLnNvdXJjZVNwYW4uc3RhcnQsXG4gICAgICAgICAgcGFyYW0uc291cmNlU3Bhbi5zdGFydC5tb3ZlQnkoJ3RyYWNrJy5sZW5ndGgpLFxuICAgICAgICApO1xuICAgICAgICByZXN1bHQudHJhY2tCeSA9IHtleHByZXNzaW9uLCBrZXl3b3JkU3Bhbn07XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBlcnJvcnMucHVzaChcbiAgICAgIG5ldyBQYXJzZUVycm9yKHBhcmFtLnNvdXJjZVNwYW4sIGBVbnJlY29nbml6ZWQgQGZvciBsb29wIHBhcmFtYXRlciBcIiR7cGFyYW0uZXhwcmVzc2lvbn1cImApLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKiogUGFyc2VzIHRoZSBgbGV0YCBwYXJhbWV0ZXIgb2YgYSBgZm9yYCBsb29wIGJsb2NrLiAqL1xuZnVuY3Rpb24gcGFyc2VMZXRQYXJhbWV0ZXIoXG4gIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3BhbixcbiAgZXhwcmVzc2lvbjogc3RyaW5nLFxuICBzcGFuOiBQYXJzZVNvdXJjZVNwYW4sXG4gIGxvb3BJdGVtTmFtZTogc3RyaW5nLFxuICBjb250ZXh0OiB0LlZhcmlhYmxlW10sXG4gIGVycm9yczogUGFyc2VFcnJvcltdLFxuKTogdm9pZCB7XG4gIGNvbnN0IHBhcnRzID0gZXhwcmVzc2lvbi5zcGxpdCgnLCcpO1xuICBsZXQgc3RhcnRTcGFuID0gc3Bhbi5zdGFydDtcbiAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgY29uc3QgZXhwcmVzc2lvblBhcnRzID0gcGFydC5zcGxpdCgnPScpO1xuICAgIGNvbnN0IG5hbWUgPSBleHByZXNzaW9uUGFydHMubGVuZ3RoID09PSAyID8gZXhwcmVzc2lvblBhcnRzWzBdLnRyaW0oKSA6ICcnO1xuICAgIGNvbnN0IHZhcmlhYmxlTmFtZSA9IGV4cHJlc3Npb25QYXJ0cy5sZW5ndGggPT09IDIgPyBleHByZXNzaW9uUGFydHNbMV0udHJpbSgpIDogJyc7XG5cbiAgICBpZiAobmFtZS5sZW5ndGggPT09IDAgfHwgdmFyaWFibGVOYW1lLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgIG5ldyBQYXJzZUVycm9yKFxuICAgICAgICAgIHNvdXJjZVNwYW4sXG4gICAgICAgICAgYEludmFsaWQgQGZvciBsb29wIFwibGV0XCIgcGFyYW1ldGVyLiBQYXJhbWV0ZXIgc2hvdWxkIG1hdGNoIHRoZSBwYXR0ZXJuIFwiPG5hbWU+ID0gPHZhcmlhYmxlIG5hbWU+XCJgLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKCFBTExPV0VEX0ZPUl9MT09QX0xFVF9WQVJJQUJMRVMuaGFzKHZhcmlhYmxlTmFtZSkpIHtcbiAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICBuZXcgUGFyc2VFcnJvcihcbiAgICAgICAgICBzb3VyY2VTcGFuLFxuICAgICAgICAgIGBVbmtub3duIFwibGV0XCIgcGFyYW1ldGVyIHZhcmlhYmxlIFwiJHt2YXJpYWJsZU5hbWV9XCIuIFRoZSBhbGxvd2VkIHZhcmlhYmxlcyBhcmU6ICR7QXJyYXkuZnJvbShcbiAgICAgICAgICAgIEFMTE9XRURfRk9SX0xPT1BfTEVUX1ZBUklBQkxFUyxcbiAgICAgICAgICApLmpvaW4oJywgJyl9YCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSBsb29wSXRlbU5hbWUpIHtcbiAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICBuZXcgUGFyc2VFcnJvcihcbiAgICAgICAgICBzb3VyY2VTcGFuLFxuICAgICAgICAgIGBJbnZhbGlkIEBmb3IgbG9vcCBcImxldFwiIHBhcmFtZXRlci4gVmFyaWFibGUgY2Fubm90IGJlIGNhbGxlZCBcIiR7bG9vcEl0ZW1OYW1lfVwiYCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChjb250ZXh0LnNvbWUoKHYpID0+IHYubmFtZSA9PT0gbmFtZSkpIHtcbiAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICBuZXcgUGFyc2VFcnJvcihzb3VyY2VTcGFuLCBgRHVwbGljYXRlIFwibGV0XCIgcGFyYW1ldGVyIHZhcmlhYmxlIFwiJHt2YXJpYWJsZU5hbWV9XCJgKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IFssIGtleUxlYWRpbmdXaGl0ZXNwYWNlLCBrZXlOYW1lXSA9XG4gICAgICAgIGV4cHJlc3Npb25QYXJ0c1swXS5tYXRjaChDSEFSQUNURVJTX0lOX1NVUlJPVU5ESU5HX1dISVRFU1BBQ0VfUEFUVEVSTikgPz8gW107XG4gICAgICBjb25zdCBrZXlTcGFuID1cbiAgICAgICAga2V5TGVhZGluZ1doaXRlc3BhY2UgIT09IHVuZGVmaW5lZCAmJiBleHByZXNzaW9uUGFydHMubGVuZ3RoID09PSAyXG4gICAgICAgICAgPyBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgICAgICAgICAvKiBzdHJpcCBsZWFkaW5nIHNwYWNlcyAqL1xuICAgICAgICAgICAgICBzdGFydFNwYW4ubW92ZUJ5KGtleUxlYWRpbmdXaGl0ZXNwYWNlLmxlbmd0aCksXG4gICAgICAgICAgICAgIC8qIGFkdmFuY2UgdG8gZW5kIG9mIHRoZSB2YXJpYWJsZSBuYW1lICovXG4gICAgICAgICAgICAgIHN0YXJ0U3Bhbi5tb3ZlQnkoa2V5TGVhZGluZ1doaXRlc3BhY2UubGVuZ3RoICsga2V5TmFtZS5sZW5ndGgpLFxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogc3BhbjtcblxuICAgICAgbGV0IHZhbHVlU3BhbjogUGFyc2VTb3VyY2VTcGFuIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKGV4cHJlc3Npb25QYXJ0cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgY29uc3QgWywgdmFsdWVMZWFkaW5nV2hpdGVzcGFjZSwgaW1wbGljaXRdID1cbiAgICAgICAgICBleHByZXNzaW9uUGFydHNbMV0ubWF0Y2goQ0hBUkFDVEVSU19JTl9TVVJST1VORElOR19XSElURVNQQUNFX1BBVFRFUk4pID8/IFtdO1xuICAgICAgICB2YWx1ZVNwYW4gPVxuICAgICAgICAgIHZhbHVlTGVhZGluZ1doaXRlc3BhY2UgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgICAgICAgICAgIHN0YXJ0U3Bhbi5tb3ZlQnkoZXhwcmVzc2lvblBhcnRzWzBdLmxlbmd0aCArIDEgKyB2YWx1ZUxlYWRpbmdXaGl0ZXNwYWNlLmxlbmd0aCksXG4gICAgICAgICAgICAgICAgc3RhcnRTcGFuLm1vdmVCeShcbiAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb25QYXJ0c1swXS5sZW5ndGggKyAxICsgdmFsdWVMZWFkaW5nV2hpdGVzcGFjZS5sZW5ndGggKyBpbXBsaWNpdC5sZW5ndGgsXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IFBhcnNlU291cmNlU3BhbihrZXlTcGFuLnN0YXJ0LCB2YWx1ZVNwYW4/LmVuZCA/PyBrZXlTcGFuLmVuZCk7XG4gICAgICBjb250ZXh0LnB1c2gobmV3IHQuVmFyaWFibGUobmFtZSwgdmFyaWFibGVOYW1lLCBzb3VyY2VTcGFuLCBrZXlTcGFuLCB2YWx1ZVNwYW4pKTtcbiAgICB9XG4gICAgc3RhcnRTcGFuID0gc3RhcnRTcGFuLm1vdmVCeShwYXJ0Lmxlbmd0aCArIDEgLyogYWRkIDEgdG8gbW92ZSBwYXN0IHRoZSBjb21tYSAqLyk7XG4gIH1cbn1cblxuLyoqXG4gKiBDaGVja3MgdGhhdCB0aGUgc2hhcGUgb2YgdGhlIGJsb2NrcyBjb25uZWN0ZWQgdG8gYW5cbiAqIGBAaWZgIGJsb2NrIGlzIGNvcnJlY3QuIFJldHVybnMgYW4gYXJyYXkgb2YgZXJyb3JzLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUlmQ29ubmVjdGVkQmxvY2tzKGNvbm5lY3RlZEJsb2NrczogaHRtbC5CbG9ja1tdKTogUGFyc2VFcnJvcltdIHtcbiAgY29uc3QgZXJyb3JzOiBQYXJzZUVycm9yW10gPSBbXTtcbiAgbGV0IGhhc0Vsc2UgPSBmYWxzZTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbm5lY3RlZEJsb2Nrcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGJsb2NrID0gY29ubmVjdGVkQmxvY2tzW2ldO1xuXG4gICAgaWYgKGJsb2NrLm5hbWUgPT09ICdlbHNlJykge1xuICAgICAgaWYgKGhhc0Vsc2UpIHtcbiAgICAgICAgZXJyb3JzLnB1c2gobmV3IFBhcnNlRXJyb3IoYmxvY2suc291cmNlU3BhbiwgJ0NvbmRpdGlvbmFsIGNhbiBvbmx5IGhhdmUgb25lIEBlbHNlIGJsb2NrJykpO1xuICAgICAgfSBlbHNlIGlmIChjb25uZWN0ZWRCbG9ja3MubGVuZ3RoID4gMSAmJiBpIDwgY29ubmVjdGVkQmxvY2tzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgICAgbmV3IFBhcnNlRXJyb3IoYmxvY2suc291cmNlU3BhbiwgJ0BlbHNlIGJsb2NrIG11c3QgYmUgbGFzdCBpbnNpZGUgdGhlIGNvbmRpdGlvbmFsJyksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKGJsb2NrLnBhcmFtZXRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihibG9jay5zb3VyY2VTcGFuLCAnQGVsc2UgYmxvY2sgY2Fubm90IGhhdmUgcGFyYW1ldGVycycpKTtcbiAgICAgIH1cbiAgICAgIGhhc0Vsc2UgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoIUVMU0VfSUZfUEFUVEVSTi50ZXN0KGJsb2NrLm5hbWUpKSB7XG4gICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgbmV3IFBhcnNlRXJyb3IoYmxvY2suc291cmNlU3BhbiwgYFVucmVjb2duaXplZCBjb25kaXRpb25hbCBibG9jayBAJHtibG9jay5uYW1lfWApLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXJyb3JzO1xufVxuXG4vKiogQ2hlY2tzIHRoYXQgdGhlIHNoYXBlIG9mIGEgYHN3aXRjaGAgYmxvY2sgaXMgdmFsaWQuIFJldHVybnMgYW4gYXJyYXkgb2YgZXJyb3JzLiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVTd2l0Y2hCbG9jayhhc3Q6IGh0bWwuQmxvY2spOiBQYXJzZUVycm9yW10ge1xuICBjb25zdCBlcnJvcnM6IFBhcnNlRXJyb3JbXSA9IFtdO1xuICBsZXQgaGFzRGVmYXVsdCA9IGZhbHNlO1xuXG4gIGlmIChhc3QucGFyYW1ldGVycy5sZW5ndGggIT09IDEpIHtcbiAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihhc3Quc291cmNlU3BhbiwgJ0Bzd2l0Y2ggYmxvY2sgbXVzdCBoYXZlIGV4YWN0bHkgb25lIHBhcmFtZXRlcicpKTtcbiAgICByZXR1cm4gZXJyb3JzO1xuICB9XG5cbiAgZm9yIChjb25zdCBub2RlIG9mIGFzdC5jaGlsZHJlbikge1xuICAgIC8vIFNraXAgb3ZlciBjb21tZW50cyBhbmQgZW1wdHkgdGV4dCBub2RlcyBpbnNpZGUgdGhlIHN3aXRjaCBibG9jay5cbiAgICAvLyBFbXB0eSB0ZXh0IG5vZGVzIGNhbiBiZSB1c2VkIGZvciBmb3JtYXR0aW5nIHdoaWxlIGNvbW1lbnRzIGRvbid0IGFmZmVjdCB0aGUgcnVudGltZS5cbiAgICBpZiAoXG4gICAgICBub2RlIGluc3RhbmNlb2YgaHRtbC5Db21tZW50IHx8XG4gICAgICAobm9kZSBpbnN0YW5jZW9mIGh0bWwuVGV4dCAmJiBub2RlLnZhbHVlLnRyaW0oKS5sZW5ndGggPT09IDApXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoIShub2RlIGluc3RhbmNlb2YgaHRtbC5CbG9jaykgfHwgKG5vZGUubmFtZSAhPT0gJ2Nhc2UnICYmIG5vZGUubmFtZSAhPT0gJ2RlZmF1bHQnKSkge1xuICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgIG5ldyBQYXJzZUVycm9yKG5vZGUuc291cmNlU3BhbiwgJ0Bzd2l0Y2ggYmxvY2sgY2FuIG9ubHkgY29udGFpbiBAY2FzZSBhbmQgQGRlZmF1bHQgYmxvY2tzJyksXG4gICAgICApO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUubmFtZSA9PT0gJ2RlZmF1bHQnKSB7XG4gICAgICBpZiAoaGFzRGVmYXVsdCkge1xuICAgICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgICBuZXcgUGFyc2VFcnJvcihub2RlLnNvdXJjZVNwYW4sICdAc3dpdGNoIGJsb2NrIGNhbiBvbmx5IGhhdmUgb25lIEBkZWZhdWx0IGJsb2NrJyksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKG5vZGUucGFyYW1ldGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKG5vZGUuc291cmNlU3BhbiwgJ0BkZWZhdWx0IGJsb2NrIGNhbm5vdCBoYXZlIHBhcmFtZXRlcnMnKSk7XG4gICAgICB9XG4gICAgICBoYXNEZWZhdWx0ID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKG5vZGUubmFtZSA9PT0gJ2Nhc2UnICYmIG5vZGUucGFyYW1ldGVycy5sZW5ndGggIT09IDEpIHtcbiAgICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKG5vZGUuc291cmNlU3BhbiwgJ0BjYXNlIGJsb2NrIG11c3QgaGF2ZSBleGFjdGx5IG9uZSBwYXJhbWV0ZXInKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVycm9ycztcbn1cblxuLyoqXG4gKiBQYXJzZXMgYSBibG9jayBwYXJhbWV0ZXIgaW50byBhIGJpbmRpbmcgQVNULlxuICogQHBhcmFtIGFzdCBCbG9jayBwYXJhbWV0ZXIgdGhhdCBzaG91bGQgYmUgcGFyc2VkLlxuICogQHBhcmFtIGJpbmRpbmdQYXJzZXIgUGFyc2VyIHRoYXQgdGhlIGV4cHJlc3Npb24gc2hvdWxkIGJlIHBhcnNlZCB3aXRoLlxuICogQHBhcmFtIHBhcnQgU3BlY2lmaWMgcGFydCBvZiB0aGUgZXhwcmVzc2lvbiB0aGF0IHNob3VsZCBiZSBwYXJzZWQuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlQmxvY2tQYXJhbWV0ZXJUb0JpbmRpbmcoXG4gIGFzdDogaHRtbC5CbG9ja1BhcmFtZXRlcixcbiAgYmluZGluZ1BhcnNlcjogQmluZGluZ1BhcnNlcixcbiAgcGFydD86IHN0cmluZyxcbik6IEFTVFdpdGhTb3VyY2Uge1xuICBsZXQgc3RhcnQ6IG51bWJlcjtcbiAgbGV0IGVuZDogbnVtYmVyO1xuXG4gIGlmICh0eXBlb2YgcGFydCA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBOb3RlOiBgbGFzdEluZGV4T2ZgIGhlcmUgc2hvdWxkIGJlIGVub3VnaCB0byBrbm93IHRoZSBzdGFydCBpbmRleCBvZiB0aGUgZXhwcmVzc2lvbixcbiAgICAvLyBiZWNhdXNlIHdlIGtub3cgdGhhdCBpdCdsbCBiZSBhdCB0aGUgZW5kIG9mIHRoZSBwYXJhbS4gSWRlYWxseSB3ZSBjb3VsZCB1c2UgdGhlIGBkYFxuICAgIC8vIGZsYWcgd2hlbiBtYXRjaGluZyB2aWEgcmVnZXggYW5kIGdldCB0aGUgaW5kZXggZnJvbSBgbWF0Y2guaW5kaWNlc2AsIGJ1dCBpdCdzIHVuY2xlYXJcbiAgICAvLyBpZiB3ZSBjYW4gdXNlIGl0IHlldCBzaW5jZSBpdCdzIGEgcmVsYXRpdmVseSBuZXcgZmVhdHVyZS4gU2VlOlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLXJlZ2V4cC1tYXRjaC1pbmRpY2VzXG4gICAgc3RhcnQgPSBNYXRoLm1heCgwLCBhc3QuZXhwcmVzc2lvbi5sYXN0SW5kZXhPZihwYXJ0KSk7XG4gICAgZW5kID0gc3RhcnQgKyBwYXJ0Lmxlbmd0aDtcbiAgfSBlbHNlIHtcbiAgICBzdGFydCA9IDA7XG4gICAgZW5kID0gYXN0LmV4cHJlc3Npb24ubGVuZ3RoO1xuICB9XG5cbiAgcmV0dXJuIGJpbmRpbmdQYXJzZXIucGFyc2VCaW5kaW5nKFxuICAgIGFzdC5leHByZXNzaW9uLnNsaWNlKHN0YXJ0LCBlbmQpLFxuICAgIGZhbHNlLFxuICAgIGFzdC5zb3VyY2VTcGFuLFxuICAgIGFzdC5zb3VyY2VTcGFuLnN0YXJ0Lm9mZnNldCArIHN0YXJ0LFxuICApO1xufVxuXG4vKiogUGFyc2VzIHRoZSBwYXJhbWV0ZXIgb2YgYSBjb25kaXRpb25hbCBibG9jayAoYGlmYCBvciBgZWxzZSBpZmApLiAqL1xuZnVuY3Rpb24gcGFyc2VDb25kaXRpb25hbEJsb2NrUGFyYW1ldGVycyhcbiAgYmxvY2s6IGh0bWwuQmxvY2ssXG4gIGVycm9yczogUGFyc2VFcnJvcltdLFxuICBiaW5kaW5nUGFyc2VyOiBCaW5kaW5nUGFyc2VyLFxuKSB7XG4gIGlmIChibG9jay5wYXJhbWV0ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKGJsb2NrLnNvdXJjZVNwYW4sICdDb25kaXRpb25hbCBibG9jayBkb2VzIG5vdCBoYXZlIGFuIGV4cHJlc3Npb24nKSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBleHByZXNzaW9uID0gcGFyc2VCbG9ja1BhcmFtZXRlclRvQmluZGluZyhibG9jay5wYXJhbWV0ZXJzWzBdLCBiaW5kaW5nUGFyc2VyKTtcbiAgbGV0IGV4cHJlc3Npb25BbGlhczogdC5WYXJpYWJsZSB8IG51bGwgPSBudWxsO1xuXG4gIC8vIFN0YXJ0IGZyb20gMSBzaW5jZSB3ZSBwcm9jZXNzZWQgdGhlIGZpcnN0IHBhcmFtZXRlciBhbHJlYWR5LlxuICBmb3IgKGxldCBpID0gMTsgaSA8IGJsb2NrLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBwYXJhbSA9IGJsb2NrLnBhcmFtZXRlcnNbaV07XG4gICAgY29uc3QgYWxpYXNNYXRjaCA9IHBhcmFtLmV4cHJlc3Npb24ubWF0Y2goQ09ORElUSU9OQUxfQUxJQVNfUEFUVEVSTik7XG5cbiAgICAvLyBGb3Igbm93IGNvbmRpdGlvbmFscyBjYW4gb25seSBoYXZlIGFuIGBhc2AgcGFyYW1ldGVyLlxuICAgIC8vIFdlIG1heSB3YW50IHRvIHJld29yayB0aGlzIGxhdGVyIGlmIHdlIGFkZCBtb3JlLlxuICAgIGlmIChhbGlhc01hdGNoID09PSBudWxsKSB7XG4gICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgbmV3IFBhcnNlRXJyb3IoXG4gICAgICAgICAgcGFyYW0uc291cmNlU3BhbixcbiAgICAgICAgICBgVW5yZWNvZ25pemVkIGNvbmRpdGlvbmFsIHBhcmFtYXRlciBcIiR7cGFyYW0uZXhwcmVzc2lvbn1cImAsXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoYmxvY2submFtZSAhPT0gJ2lmJykge1xuICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgIG5ldyBQYXJzZUVycm9yKFxuICAgICAgICAgIHBhcmFtLnNvdXJjZVNwYW4sXG4gICAgICAgICAgJ1wiYXNcIiBleHByZXNzaW9uIGlzIG9ubHkgYWxsb3dlZCBvbiB0aGUgcHJpbWFyeSBAaWYgYmxvY2snLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKGV4cHJlc3Npb25BbGlhcyAhPT0gbnVsbCkge1xuICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgIG5ldyBQYXJzZUVycm9yKHBhcmFtLnNvdXJjZVNwYW4sICdDb25kaXRpb25hbCBjYW4gb25seSBoYXZlIG9uZSBcImFzXCIgZXhwcmVzc2lvbicpLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbmFtZSA9IGFsaWFzTWF0Y2hbMl0udHJpbSgpO1xuICAgICAgY29uc3QgdmFyaWFibGVTdGFydCA9IHBhcmFtLnNvdXJjZVNwYW4uc3RhcnQubW92ZUJ5KGFsaWFzTWF0Y2hbMV0ubGVuZ3RoKTtcbiAgICAgIGNvbnN0IHZhcmlhYmxlU3BhbiA9IG5ldyBQYXJzZVNvdXJjZVNwYW4odmFyaWFibGVTdGFydCwgdmFyaWFibGVTdGFydC5tb3ZlQnkobmFtZS5sZW5ndGgpKTtcbiAgICAgIGV4cHJlc3Npb25BbGlhcyA9IG5ldyB0LlZhcmlhYmxlKG5hbWUsIG5hbWUsIHZhcmlhYmxlU3BhbiwgdmFyaWFibGVTcGFuKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge2V4cHJlc3Npb24sIGV4cHJlc3Npb25BbGlhc307XG59XG5cbi8qKiBTdHJpcHMgb3B0aW9uYWwgcGFyZW50aGVzZXMgYXJvdW5kIGZyb20gYSBjb250cm9sIGZyb20gZXhwcmVzc2lvbiBwYXJhbWV0ZXIuICovXG5mdW5jdGlvbiBzdHJpcE9wdGlvbmFsUGFyZW50aGVzZXMocGFyYW06IGh0bWwuQmxvY2tQYXJhbWV0ZXIsIGVycm9yczogUGFyc2VFcnJvcltdKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IGV4cHJlc3Npb24gPSBwYXJhbS5leHByZXNzaW9uO1xuICBjb25zdCBzcGFjZVJlZ2V4ID0gL15cXHMkLztcbiAgbGV0IG9wZW5QYXJlbnMgPSAwO1xuICBsZXQgc3RhcnQgPSAwO1xuICBsZXQgZW5kID0gZXhwcmVzc2lvbi5sZW5ndGggLSAxO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwcmVzc2lvbi5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoYXIgPSBleHByZXNzaW9uW2ldO1xuXG4gICAgaWYgKGNoYXIgPT09ICcoJykge1xuICAgICAgc3RhcnQgPSBpICsgMTtcbiAgICAgIG9wZW5QYXJlbnMrKztcbiAgICB9IGVsc2UgaWYgKHNwYWNlUmVnZXgudGVzdChjaGFyKSkge1xuICAgICAgY29udGludWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcGVuUGFyZW5zID09PSAwKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb247XG4gIH1cblxuICBmb3IgKGxldCBpID0gZXhwcmVzc2lvbi5sZW5ndGggLSAxOyBpID4gLTE7IGktLSkge1xuICAgIGNvbnN0IGNoYXIgPSBleHByZXNzaW9uW2ldO1xuXG4gICAgaWYgKGNoYXIgPT09ICcpJykge1xuICAgICAgZW5kID0gaTtcbiAgICAgIG9wZW5QYXJlbnMtLTtcbiAgICAgIGlmIChvcGVuUGFyZW5zID09PSAwKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc3BhY2VSZWdleC50ZXN0KGNoYXIpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKG9wZW5QYXJlbnMgIT09IDApIHtcbiAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihwYXJhbS5zb3VyY2VTcGFuLCAnVW5jbG9zZWQgcGFyZW50aGVzZXMgaW4gZXhwcmVzc2lvbicpKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBleHByZXNzaW9uLnNsaWNlKHN0YXJ0LCBlbmQpO1xufVxuIl19