@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,539 +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 { ParseError, ParseSourceSpan } from '../parse_util';
9
- import * as html from './ast';
10
- import { NAMED_ENTITIES } from './entities';
11
- import { tokenize } from './lexer';
12
- import { getNsPrefix, mergeNsAndName, splitNsName } from './tags';
13
- export class TreeError extends ParseError {
14
- static create(elementName, span, msg) {
15
- return new TreeError(elementName, span, msg);
16
- }
17
- constructor(elementName, span, msg) {
18
- super(span, msg);
19
- this.elementName = elementName;
20
- }
21
- }
22
- export class ParseTreeResult {
23
- constructor(rootNodes, errors) {
24
- this.rootNodes = rootNodes;
25
- this.errors = errors;
26
- }
27
- }
28
- export class Parser {
29
- constructor(getTagDefinition) {
30
- this.getTagDefinition = getTagDefinition;
31
- }
32
- parse(source, url, options) {
33
- const tokenizeResult = tokenize(source, url, this.getTagDefinition, options);
34
- const parser = new _TreeBuilder(tokenizeResult.tokens, this.getTagDefinition);
35
- parser.build();
36
- return new ParseTreeResult(parser.rootNodes, tokenizeResult.errors.concat(parser.errors));
37
- }
38
- }
39
- class _TreeBuilder {
40
- constructor(tokens, getTagDefinition) {
41
- this.tokens = tokens;
42
- this.getTagDefinition = getTagDefinition;
43
- this._index = -1;
44
- this._containerStack = [];
45
- this.rootNodes = [];
46
- this.errors = [];
47
- this._advance();
48
- }
49
- build() {
50
- while (this._peek.type !== 33 /* TokenType.EOF */) {
51
- if (this._peek.type === 0 /* TokenType.TAG_OPEN_START */ ||
52
- this._peek.type === 4 /* TokenType.INCOMPLETE_TAG_OPEN */) {
53
- this._consumeStartTag(this._advance());
54
- }
55
- else if (this._peek.type === 3 /* TokenType.TAG_CLOSE */) {
56
- this._consumeEndTag(this._advance());
57
- }
58
- else if (this._peek.type === 12 /* TokenType.CDATA_START */) {
59
- this._closeVoidElement();
60
- this._consumeCdata(this._advance());
61
- }
62
- else if (this._peek.type === 10 /* TokenType.COMMENT_START */) {
63
- this._closeVoidElement();
64
- this._consumeComment(this._advance());
65
- }
66
- else if (this._peek.type === 5 /* TokenType.TEXT */ ||
67
- this._peek.type === 7 /* TokenType.RAW_TEXT */ ||
68
- this._peek.type === 6 /* TokenType.ESCAPABLE_RAW_TEXT */) {
69
- this._closeVoidElement();
70
- this._consumeText(this._advance());
71
- }
72
- else if (this._peek.type === 19 /* TokenType.EXPANSION_FORM_START */) {
73
- this._consumeExpansion(this._advance());
74
- }
75
- else if (this._peek.type === 24 /* TokenType.BLOCK_OPEN_START */) {
76
- this._closeVoidElement();
77
- this._consumeBlockOpen(this._advance());
78
- }
79
- else if (this._peek.type === 26 /* TokenType.BLOCK_CLOSE */) {
80
- this._closeVoidElement();
81
- this._consumeBlockClose(this._advance());
82
- }
83
- else if (this._peek.type === 28 /* TokenType.INCOMPLETE_BLOCK_OPEN */) {
84
- this._closeVoidElement();
85
- this._consumeIncompleteBlock(this._advance());
86
- }
87
- else if (this._peek.type === 29 /* TokenType.LET_START */) {
88
- this._closeVoidElement();
89
- this._consumeLet(this._advance());
90
- }
91
- else if (this._peek.type === 32 /* TokenType.INCOMPLETE_LET */) {
92
- this._closeVoidElement();
93
- this._consumeIncompleteLet(this._advance());
94
- }
95
- else {
96
- // Skip all other tokens...
97
- this._advance();
98
- }
99
- }
100
- for (const leftoverContainer of this._containerStack) {
101
- // Unlike HTML elements, blocks aren't closed implicitly by the end of the file.
102
- if (leftoverContainer instanceof html.Block) {
103
- this.errors.push(TreeError.create(leftoverContainer.name, leftoverContainer.sourceSpan, `Unclosed block "${leftoverContainer.name}"`));
104
- }
105
- }
106
- }
107
- _advance() {
108
- const prev = this._peek;
109
- if (this._index < this.tokens.length - 1) {
110
- // Note: there is always an EOF token at the end
111
- this._index++;
112
- }
113
- this._peek = this.tokens[this._index];
114
- return prev;
115
- }
116
- _advanceIf(type) {
117
- if (this._peek.type === type) {
118
- return this._advance();
119
- }
120
- return null;
121
- }
122
- _consumeCdata(_startToken) {
123
- this._consumeText(this._advance());
124
- this._advanceIf(13 /* TokenType.CDATA_END */);
125
- }
126
- _consumeComment(token) {
127
- const text = this._advanceIf(7 /* TokenType.RAW_TEXT */);
128
- const endToken = this._advanceIf(11 /* TokenType.COMMENT_END */);
129
- const value = text != null ? text.parts[0].trim() : null;
130
- const sourceSpan = endToken == null
131
- ? token.sourceSpan
132
- : new ParseSourceSpan(token.sourceSpan.start, endToken.sourceSpan.end, token.sourceSpan.fullStart);
133
- this._addToParent(new html.Comment(value, sourceSpan));
134
- }
135
- _consumeExpansion(token) {
136
- const switchValue = this._advance();
137
- const type = this._advance();
138
- const cases = [];
139
- // read =
140
- while (this._peek.type === 20 /* TokenType.EXPANSION_CASE_VALUE */) {
141
- const expCase = this._parseExpansionCase();
142
- if (!expCase)
143
- return; // error
144
- cases.push(expCase);
145
- }
146
- // read the final }
147
- if (this._peek.type !== 23 /* TokenType.EXPANSION_FORM_END */) {
148
- this.errors.push(TreeError.create(null, this._peek.sourceSpan, `Invalid ICU message. Missing '}'.`));
149
- return;
150
- }
151
- const sourceSpan = new ParseSourceSpan(token.sourceSpan.start, this._peek.sourceSpan.end, token.sourceSpan.fullStart);
152
- this._addToParent(new html.Expansion(switchValue.parts[0], type.parts[0], cases, sourceSpan, switchValue.sourceSpan));
153
- this._advance();
154
- }
155
- _parseExpansionCase() {
156
- const value = this._advance();
157
- // read {
158
- if (this._peek.type !== 21 /* TokenType.EXPANSION_CASE_EXP_START */) {
159
- this.errors.push(TreeError.create(null, this._peek.sourceSpan, `Invalid ICU message. Missing '{'.`));
160
- return null;
161
- }
162
- // read until }
163
- const start = this._advance();
164
- const exp = this._collectExpansionExpTokens(start);
165
- if (!exp)
166
- return null;
167
- const end = this._advance();
168
- exp.push({ type: 33 /* TokenType.EOF */, parts: [], sourceSpan: end.sourceSpan });
169
- // parse everything in between { and }
170
- const expansionCaseParser = new _TreeBuilder(exp, this.getTagDefinition);
171
- expansionCaseParser.build();
172
- if (expansionCaseParser.errors.length > 0) {
173
- this.errors = this.errors.concat(expansionCaseParser.errors);
174
- return null;
175
- }
176
- const sourceSpan = new ParseSourceSpan(value.sourceSpan.start, end.sourceSpan.end, value.sourceSpan.fullStart);
177
- const expSourceSpan = new ParseSourceSpan(start.sourceSpan.start, end.sourceSpan.end, start.sourceSpan.fullStart);
178
- return new html.ExpansionCase(value.parts[0], expansionCaseParser.rootNodes, sourceSpan, value.sourceSpan, expSourceSpan);
179
- }
180
- _collectExpansionExpTokens(start) {
181
- const exp = [];
182
- const expansionFormStack = [21 /* TokenType.EXPANSION_CASE_EXP_START */];
183
- while (true) {
184
- if (this._peek.type === 19 /* TokenType.EXPANSION_FORM_START */ ||
185
- this._peek.type === 21 /* TokenType.EXPANSION_CASE_EXP_START */) {
186
- expansionFormStack.push(this._peek.type);
187
- }
188
- if (this._peek.type === 22 /* TokenType.EXPANSION_CASE_EXP_END */) {
189
- if (lastOnStack(expansionFormStack, 21 /* TokenType.EXPANSION_CASE_EXP_START */)) {
190
- expansionFormStack.pop();
191
- if (expansionFormStack.length === 0)
192
- return exp;
193
- }
194
- else {
195
- this.errors.push(TreeError.create(null, start.sourceSpan, `Invalid ICU message. Missing '}'.`));
196
- return null;
197
- }
198
- }
199
- if (this._peek.type === 23 /* TokenType.EXPANSION_FORM_END */) {
200
- if (lastOnStack(expansionFormStack, 19 /* TokenType.EXPANSION_FORM_START */)) {
201
- expansionFormStack.pop();
202
- }
203
- else {
204
- this.errors.push(TreeError.create(null, start.sourceSpan, `Invalid ICU message. Missing '}'.`));
205
- return null;
206
- }
207
- }
208
- if (this._peek.type === 33 /* TokenType.EOF */) {
209
- this.errors.push(TreeError.create(null, start.sourceSpan, `Invalid ICU message. Missing '}'.`));
210
- return null;
211
- }
212
- exp.push(this._advance());
213
- }
214
- }
215
- _consumeText(token) {
216
- const tokens = [token];
217
- const startSpan = token.sourceSpan;
218
- let text = token.parts[0];
219
- if (text.length > 0 && text[0] === '\n') {
220
- const parent = this._getContainer();
221
- if (parent != null &&
222
- parent.children.length === 0 &&
223
- this.getTagDefinition(parent.name).ignoreFirstLf) {
224
- text = text.substring(1);
225
- tokens[0] = { type: token.type, sourceSpan: token.sourceSpan, parts: [text] };
226
- }
227
- }
228
- while (this._peek.type === 8 /* TokenType.INTERPOLATION */ ||
229
- this._peek.type === 5 /* TokenType.TEXT */ ||
230
- this._peek.type === 9 /* TokenType.ENCODED_ENTITY */) {
231
- token = this._advance();
232
- tokens.push(token);
233
- if (token.type === 8 /* TokenType.INTERPOLATION */) {
234
- // For backward compatibility we decode HTML entities that appear in interpolation
235
- // expressions. This is arguably a bug, but it could be a considerable breaking change to
236
- // fix it. It should be addressed in a larger project to refactor the entire parser/lexer
237
- // chain after View Engine has been removed.
238
- text += token.parts.join('').replace(/&([^;]+);/g, decodeEntity);
239
- }
240
- else if (token.type === 9 /* TokenType.ENCODED_ENTITY */) {
241
- text += token.parts[0];
242
- }
243
- else {
244
- text += token.parts.join('');
245
- }
246
- }
247
- if (text.length > 0) {
248
- const endSpan = token.sourceSpan;
249
- this._addToParent(new html.Text(text, new ParseSourceSpan(startSpan.start, endSpan.end, startSpan.fullStart, startSpan.details), tokens));
250
- }
251
- }
252
- _closeVoidElement() {
253
- const el = this._getContainer();
254
- if (el instanceof html.Element && this.getTagDefinition(el.name).isVoid) {
255
- this._containerStack.pop();
256
- }
257
- }
258
- _consumeStartTag(startTagToken) {
259
- const [prefix, name] = startTagToken.parts;
260
- const attrs = [];
261
- while (this._peek.type === 14 /* TokenType.ATTR_NAME */) {
262
- attrs.push(this._consumeAttr(this._advance()));
263
- }
264
- const fullName = this._getElementFullName(prefix, name, this._getClosestParentElement());
265
- let selfClosing = false;
266
- // Note: There could have been a tokenizer error
267
- // so that we don't get a token for the end tag...
268
- if (this._peek.type === 2 /* TokenType.TAG_OPEN_END_VOID */) {
269
- this._advance();
270
- selfClosing = true;
271
- const tagDef = this.getTagDefinition(fullName);
272
- if (!(tagDef.canSelfClose || getNsPrefix(fullName) !== null || tagDef.isVoid)) {
273
- this.errors.push(TreeError.create(fullName, startTagToken.sourceSpan, `Only void, custom and foreign elements can be self closed "${startTagToken.parts[1]}"`));
274
- }
275
- }
276
- else if (this._peek.type === 1 /* TokenType.TAG_OPEN_END */) {
277
- this._advance();
278
- selfClosing = false;
279
- }
280
- const end = this._peek.sourceSpan.fullStart;
281
- const span = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart);
282
- // Create a separate `startSpan` because `span` will be modified when there is an `end` span.
283
- const startSpan = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart);
284
- const el = new html.Element(fullName, attrs, [], span, startSpan, undefined);
285
- const parentEl = this._getContainer();
286
- this._pushContainer(el, parentEl instanceof html.Element &&
287
- this.getTagDefinition(parentEl.name).isClosedByChild(el.name));
288
- if (selfClosing) {
289
- // Elements that are self-closed have their `endSourceSpan` set to the full span, as the
290
- // element start tag also represents the end tag.
291
- this._popContainer(fullName, html.Element, span);
292
- }
293
- else if (startTagToken.type === 4 /* TokenType.INCOMPLETE_TAG_OPEN */) {
294
- // We already know the opening tag is not complete, so it is unlikely it has a corresponding
295
- // close tag. Let's optimistically parse it as a full element and emit an error.
296
- this._popContainer(fullName, html.Element, null);
297
- this.errors.push(TreeError.create(fullName, span, `Opening tag "${fullName}" not terminated.`));
298
- }
299
- }
300
- _pushContainer(node, isClosedByChild) {
301
- if (isClosedByChild) {
302
- this._containerStack.pop();
303
- }
304
- this._addToParent(node);
305
- this._containerStack.push(node);
306
- }
307
- _consumeEndTag(endTagToken) {
308
- const fullName = this._getElementFullName(endTagToken.parts[0], endTagToken.parts[1], this._getClosestParentElement());
309
- if (this.getTagDefinition(fullName).isVoid) {
310
- this.errors.push(TreeError.create(fullName, endTagToken.sourceSpan, `Void elements do not have end tags "${endTagToken.parts[1]}"`));
311
- }
312
- else if (!this._popContainer(fullName, html.Element, endTagToken.sourceSpan)) {
313
- const errMsg = `Unexpected closing tag "${fullName}". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags`;
314
- this.errors.push(TreeError.create(fullName, endTagToken.sourceSpan, errMsg));
315
- }
316
- }
317
- /**
318
- * Closes the nearest element with the tag name `fullName` in the parse tree.
319
- * `endSourceSpan` is the span of the closing tag, or null if the element does
320
- * not have a closing tag (for example, this happens when an incomplete
321
- * opening tag is recovered).
322
- */
323
- _popContainer(expectedName, expectedType, endSourceSpan) {
324
- let unexpectedCloseTagDetected = false;
325
- for (let stackIndex = this._containerStack.length - 1; stackIndex >= 0; stackIndex--) {
326
- const node = this._containerStack[stackIndex];
327
- if ((node.name === expectedName || expectedName === null) && node instanceof expectedType) {
328
- // Record the parse span with the element that is being closed. Any elements that are
329
- // removed from the element stack at this point are closed implicitly, so they won't get
330
- // an end source span (as there is no explicit closing element).
331
- node.endSourceSpan = endSourceSpan;
332
- node.sourceSpan.end = endSourceSpan !== null ? endSourceSpan.end : node.sourceSpan.end;
333
- this._containerStack.splice(stackIndex, this._containerStack.length - stackIndex);
334
- return !unexpectedCloseTagDetected;
335
- }
336
- // Blocks and most elements are not self closing.
337
- if (node instanceof html.Block ||
338
- (node instanceof html.Element && !this.getTagDefinition(node.name).closedByParent)) {
339
- // Note that we encountered an unexpected close tag but continue processing the element
340
- // stack so we can assign an `endSourceSpan` if there is a corresponding start tag for this
341
- // end tag in the stack.
342
- unexpectedCloseTagDetected = true;
343
- }
344
- }
345
- return false;
346
- }
347
- _consumeAttr(attrName) {
348
- const fullName = mergeNsAndName(attrName.parts[0], attrName.parts[1]);
349
- let attrEnd = attrName.sourceSpan.end;
350
- // Consume any quote
351
- if (this._peek.type === 15 /* TokenType.ATTR_QUOTE */) {
352
- this._advance();
353
- }
354
- // Consume the attribute value
355
- let value = '';
356
- const valueTokens = [];
357
- let valueStartSpan = undefined;
358
- let valueEnd = undefined;
359
- // NOTE: We need to use a new variable `nextTokenType` here to hide the actual type of
360
- // `_peek.type` from TS. Otherwise TS will narrow the type of `_peek.type` preventing it from
361
- // being able to consider `ATTR_VALUE_INTERPOLATION` as an option. This is because TS is not
362
- // able to see that `_advance()` will actually mutate `_peek`.
363
- const nextTokenType = this._peek.type;
364
- if (nextTokenType === 16 /* TokenType.ATTR_VALUE_TEXT */) {
365
- valueStartSpan = this._peek.sourceSpan;
366
- valueEnd = this._peek.sourceSpan.end;
367
- while (this._peek.type === 16 /* TokenType.ATTR_VALUE_TEXT */ ||
368
- this._peek.type === 17 /* TokenType.ATTR_VALUE_INTERPOLATION */ ||
369
- this._peek.type === 9 /* TokenType.ENCODED_ENTITY */) {
370
- const valueToken = this._advance();
371
- valueTokens.push(valueToken);
372
- if (valueToken.type === 17 /* TokenType.ATTR_VALUE_INTERPOLATION */) {
373
- // For backward compatibility we decode HTML entities that appear in interpolation
374
- // expressions. This is arguably a bug, but it could be a considerable breaking change to
375
- // fix it. It should be addressed in a larger project to refactor the entire parser/lexer
376
- // chain after View Engine has been removed.
377
- value += valueToken.parts.join('').replace(/&([^;]+);/g, decodeEntity);
378
- }
379
- else if (valueToken.type === 9 /* TokenType.ENCODED_ENTITY */) {
380
- value += valueToken.parts[0];
381
- }
382
- else {
383
- value += valueToken.parts.join('');
384
- }
385
- valueEnd = attrEnd = valueToken.sourceSpan.end;
386
- }
387
- }
388
- // Consume any quote
389
- if (this._peek.type === 15 /* TokenType.ATTR_QUOTE */) {
390
- const quoteToken = this._advance();
391
- attrEnd = quoteToken.sourceSpan.end;
392
- }
393
- const valueSpan = valueStartSpan &&
394
- valueEnd &&
395
- new ParseSourceSpan(valueStartSpan.start, valueEnd, valueStartSpan.fullStart);
396
- return new html.Attribute(fullName, value, new ParseSourceSpan(attrName.sourceSpan.start, attrEnd, attrName.sourceSpan.fullStart), attrName.sourceSpan, valueSpan, valueTokens.length > 0 ? valueTokens : undefined, undefined);
397
- }
398
- _consumeBlockOpen(token) {
399
- const parameters = [];
400
- while (this._peek.type === 27 /* TokenType.BLOCK_PARAMETER */) {
401
- const paramToken = this._advance();
402
- parameters.push(new html.BlockParameter(paramToken.parts[0], paramToken.sourceSpan));
403
- }
404
- if (this._peek.type === 25 /* TokenType.BLOCK_OPEN_END */) {
405
- this._advance();
406
- }
407
- const end = this._peek.sourceSpan.fullStart;
408
- const span = new ParseSourceSpan(token.sourceSpan.start, end, token.sourceSpan.fullStart);
409
- // Create a separate `startSpan` because `span` will be modified when there is an `end` span.
410
- const startSpan = new ParseSourceSpan(token.sourceSpan.start, end, token.sourceSpan.fullStart);
411
- const block = new html.Block(token.parts[0], parameters, [], span, token.sourceSpan, startSpan);
412
- this._pushContainer(block, false);
413
- }
414
- _consumeBlockClose(token) {
415
- if (!this._popContainer(null, html.Block, token.sourceSpan)) {
416
- this.errors.push(TreeError.create(null, token.sourceSpan, `Unexpected closing block. The block may have been closed earlier. ` +
417
- `If you meant to write the } character, you should use the "&#125;" ` +
418
- `HTML entity instead.`));
419
- }
420
- }
421
- _consumeIncompleteBlock(token) {
422
- const parameters = [];
423
- while (this._peek.type === 27 /* TokenType.BLOCK_PARAMETER */) {
424
- const paramToken = this._advance();
425
- parameters.push(new html.BlockParameter(paramToken.parts[0], paramToken.sourceSpan));
426
- }
427
- const end = this._peek.sourceSpan.fullStart;
428
- const span = new ParseSourceSpan(token.sourceSpan.start, end, token.sourceSpan.fullStart);
429
- // Create a separate `startSpan` because `span` will be modified when there is an `end` span.
430
- const startSpan = new ParseSourceSpan(token.sourceSpan.start, end, token.sourceSpan.fullStart);
431
- const block = new html.Block(token.parts[0], parameters, [], span, token.sourceSpan, startSpan);
432
- this._pushContainer(block, false);
433
- // Incomplete blocks don't have children so we close them immediately and report an error.
434
- this._popContainer(null, html.Block, null);
435
- this.errors.push(TreeError.create(token.parts[0], span, `Incomplete block "${token.parts[0]}". If you meant to write the @ character, ` +
436
- `you should use the "&#64;" HTML entity instead.`));
437
- }
438
- _consumeLet(startToken) {
439
- const name = startToken.parts[0];
440
- let valueToken;
441
- let endToken;
442
- if (this._peek.type !== 30 /* TokenType.LET_VALUE */) {
443
- this.errors.push(TreeError.create(startToken.parts[0], startToken.sourceSpan, `Invalid @let declaration "${name}". Declaration must have a value.`));
444
- return;
445
- }
446
- else {
447
- valueToken = this._advance();
448
- }
449
- // Type cast is necessary here since TS narrowed the type of `peek` above.
450
- if (this._peek.type !== 31 /* TokenType.LET_END */) {
451
- this.errors.push(TreeError.create(startToken.parts[0], startToken.sourceSpan, `Unterminated @let declaration "${name}". Declaration must be terminated with a semicolon.`));
452
- return;
453
- }
454
- else {
455
- endToken = this._advance();
456
- }
457
- const end = endToken.sourceSpan.fullStart;
458
- const span = new ParseSourceSpan(startToken.sourceSpan.start, end, startToken.sourceSpan.fullStart);
459
- // The start token usually captures the `@let`. Construct a name span by
460
- // offsetting the start by the length of any text before the name.
461
- const startOffset = startToken.sourceSpan.toString().lastIndexOf(name);
462
- const nameStart = startToken.sourceSpan.start.moveBy(startOffset);
463
- const nameSpan = new ParseSourceSpan(nameStart, startToken.sourceSpan.end);
464
- const node = new html.LetDeclaration(name, valueToken.parts[0], span, nameSpan, valueToken.sourceSpan);
465
- this._addToParent(node);
466
- }
467
- _consumeIncompleteLet(token) {
468
- // Incomplete `@let` declaration may end up with an empty name.
469
- const name = token.parts[0] ?? '';
470
- const nameString = name ? ` "${name}"` : '';
471
- // If there's at least a name, we can salvage an AST node that can be used for completions.
472
- if (name.length > 0) {
473
- const startOffset = token.sourceSpan.toString().lastIndexOf(name);
474
- const nameStart = token.sourceSpan.start.moveBy(startOffset);
475
- const nameSpan = new ParseSourceSpan(nameStart, token.sourceSpan.end);
476
- const valueSpan = new ParseSourceSpan(token.sourceSpan.start, token.sourceSpan.start.moveBy(0));
477
- const node = new html.LetDeclaration(name, '', token.sourceSpan, nameSpan, valueSpan);
478
- this._addToParent(node);
479
- }
480
- this.errors.push(TreeError.create(token.parts[0], token.sourceSpan, `Incomplete @let declaration${nameString}. ` +
481
- `@let declarations must be written as \`@let <name> = <value>;\``));
482
- }
483
- _getContainer() {
484
- return this._containerStack.length > 0
485
- ? this._containerStack[this._containerStack.length - 1]
486
- : null;
487
- }
488
- _getClosestParentElement() {
489
- for (let i = this._containerStack.length - 1; i > -1; i--) {
490
- if (this._containerStack[i] instanceof html.Element) {
491
- return this._containerStack[i];
492
- }
493
- }
494
- return null;
495
- }
496
- _addToParent(node) {
497
- const parent = this._getContainer();
498
- if (parent === null) {
499
- this.rootNodes.push(node);
500
- }
501
- else {
502
- parent.children.push(node);
503
- }
504
- }
505
- _getElementFullName(prefix, localName, parentElement) {
506
- if (prefix === '') {
507
- prefix = this.getTagDefinition(localName).implicitNamespacePrefix || '';
508
- if (prefix === '' && parentElement != null) {
509
- const parentTagName = splitNsName(parentElement.name)[1];
510
- const parentTagDefinition = this.getTagDefinition(parentTagName);
511
- if (!parentTagDefinition.preventNamespaceInheritance) {
512
- prefix = getNsPrefix(parentElement.name);
513
- }
514
- }
515
- }
516
- return mergeNsAndName(prefix, localName);
517
- }
518
- }
519
- function lastOnStack(stack, element) {
520
- return stack.length > 0 && stack[stack.length - 1] === element;
521
- }
522
- /**
523
- * Decode the `entity` string, which we believe is the contents of an HTML entity.
524
- *
525
- * If the string is not actually a valid/known entity then just return the original `match` string.
526
- */
527
- function decodeEntity(match, entity) {
528
- if (NAMED_ENTITIES[entity] !== undefined) {
529
- return NAMED_ENTITIES[entity] || match;
530
- }
531
- if (/^#x[a-f0-9]+$/i.test(entity)) {
532
- return String.fromCodePoint(parseInt(entity.slice(2), 16));
533
- }
534
- if (/^#\d+$/.test(entity)) {
535
- return String.fromCodePoint(parseInt(entity.slice(1), 10));
536
- }
537
- return match;
538
- }
539
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL21sX3BhcnNlci9wYXJzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFDLFVBQVUsRUFBaUIsZUFBZSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRXpFLE9BQU8sS0FBSyxJQUFJLE1BQU0sT0FBTyxDQUFDO0FBQzlCLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxZQUFZLENBQUM7QUFDMUMsT0FBTyxFQUFDLFFBQVEsRUFBa0IsTUFBTSxTQUFTLENBQUM7QUFDbEQsT0FBTyxFQUFDLFdBQVcsRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFnQixNQUFNLFFBQVEsQ0FBQztBQW9DL0UsTUFBTSxPQUFPLFNBQVUsU0FBUSxVQUFVO0lBQ3ZDLE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBMEIsRUFBRSxJQUFxQixFQUFFLEdBQVc7UUFDMUUsT0FBTyxJQUFJLFNBQVMsQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFRCxZQUNTLFdBQTBCLEVBQ2pDLElBQXFCLEVBQ3JCLEdBQVc7UUFFWCxLQUFLLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBSlYsZ0JBQVcsR0FBWCxXQUFXLENBQWU7SUFLbkMsQ0FBQztDQUNGO0FBRUQsTUFBTSxPQUFPLGVBQWU7SUFDMUIsWUFDUyxTQUFzQixFQUN0QixNQUFvQjtRQURwQixjQUFTLEdBQVQsU0FBUyxDQUFhO1FBQ3RCLFdBQU0sR0FBTixNQUFNLENBQWM7SUFDMUIsQ0FBQztDQUNMO0FBRUQsTUFBTSxPQUFPLE1BQU07SUFDakIsWUFBbUIsZ0JBQW9EO1FBQXBELHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBb0M7SUFBRyxDQUFDO0lBRTNFLEtBQUssQ0FBQyxNQUFjLEVBQUUsR0FB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QyxPQUFPLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUM7SUFDekMsQ0FBQztJQUNELElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDbEMsT0FBTyxNQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUNELElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzFCLE9BQU8sTUFBTSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtQYXJzZUVycm9yLCBQYXJzZUxvY2F0aW9uLCBQYXJzZVNvdXJjZVNwYW59IGZyb20gJy4uL3BhcnNlX3V0aWwnO1xuXG5pbXBvcnQgKiBhcyBodG1sIGZyb20gJy4vYXN0JztcbmltcG9ydCB7TkFNRURfRU5USVRJRVN9IGZyb20gJy4vZW50aXRpZXMnO1xuaW1wb3J0IHt0b2tlbml6ZSwgVG9rZW5pemVPcHRpb25zfSBmcm9tICcuL2xleGVyJztcbmltcG9ydCB7Z2V0TnNQcmVmaXgsIG1lcmdlTnNBbmROYW1lLCBzcGxpdE5zTmFtZSwgVGFnRGVmaW5pdGlvbn0gZnJvbSAnLi90YWdzJztcbmltcG9ydCB7XG4gIEF0dHJpYnV0ZU5hbWVUb2tlbixcbiAgQXR0cmlidXRlUXVvdGVUb2tlbixcbiAgQmxvY2tDbG9zZVRva2VuLFxuICBCbG9ja09wZW5TdGFydFRva2VuLFxuICBCbG9ja1BhcmFtZXRlclRva2VuLFxuICBDZGF0YVN0YXJ0VG9rZW4sXG4gIENvbW1lbnRTdGFydFRva2VuLFxuICBFeHBhbnNpb25DYXNlRXhwcmVzc2lvbkVuZFRva2VuLFxuICBFeHBhbnNpb25DYXNlRXhwcmVzc2lvblN0YXJ0VG9rZW4sXG4gIEV4cGFuc2lvbkNhc2VWYWx1ZVRva2VuLFxuICBFeHBhbnNpb25Gb3JtU3RhcnRUb2tlbixcbiAgSW5jb21wbGV0ZUJsb2NrT3BlblRva2VuLFxuICBJbmNvbXBsZXRlTGV0VG9rZW4sXG4gIEluY29tcGxldGVUYWdPcGVuVG9rZW4sXG4gIEludGVycG9sYXRlZEF0dHJpYnV0ZVRva2VuLFxuICBJbnRlcnBvbGF0ZWRUZXh0VG9rZW4sXG4gIExldEVuZFRva2VuLFxuICBMZXRTdGFydFRva2VuLFxuICBMZXRWYWx1ZVRva2VuLFxuICBUYWdDbG9zZVRva2VuLFxuICBUYWdPcGVuU3RhcnRUb2tlbixcbiAgVGV4dFRva2VuLFxuICBUb2tlbixcbiAgVG9rZW5UeXBlLFxufSBmcm9tICcuL3Rva2Vucyc7XG5cbi8qKiBOb2RlcyB0aGF0IGNhbiBjb250YWluIG90aGVyIG5vZGVzLiAqL1xudHlwZSBOb2RlQ29udGFpbmVyID0gaHRtbC5FbGVtZW50IHwgaHRtbC5CbG9jaztcblxuLyoqIENsYXNzIHRoYXQgY2FuIGNvbnN0cnVjdCBhIGBOb2RlQ29udGFpbmVyYC4gKi9cbmludGVyZmFjZSBOb2RlQ29udGFpbmVyQ29uc3RydWN0b3IgZXh0ZW5kcyBGdW5jdGlvbiB7XG4gIG5ldyAoLi4uYXJnczogYW55W10pOiBOb2RlQ29udGFpbmVyO1xufVxuXG5leHBvcnQgY2xhc3MgVHJlZUVycm9yIGV4dGVuZHMgUGFyc2VFcnJvciB7XG4gIHN0YXRpYyBjcmVhdGUoZWxlbWVudE5hbWU6IHN0cmluZyB8IG51bGwsIHNwYW46IFBhcnNlU291cmNlU3BhbiwgbXNnOiBzdHJpbmcpOiBUcmVlRXJyb3Ige1xuICAgIHJldHVybiBuZXcgVHJlZUVycm9yKGVsZW1lbnROYW1lLCBzcGFuLCBtc2cpO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGVsZW1lbnROYW1lOiBzdHJpbmcgfCBudWxsLFxuICAgIHNwYW46IFBhcnNlU291cmNlU3BhbixcbiAgICBtc2c6IHN0cmluZyxcbiAgKSB7XG4gICAgc3VwZXIoc3BhbiwgbXNnKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUGFyc2VUcmVlUmVzdWx0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJvb3ROb2RlczogaHRtbC5Ob2RlW10sXG4gICAgcHVibGljIGVycm9yczogUGFyc2VFcnJvcltdLFxuICApIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBQYXJzZXIge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgZ2V0VGFnRGVmaW5pdGlvbjogKHRhZ05hbWU6IHN0cmluZykgPT4gVGFnRGVmaW5pdGlvbikge31cblxuICBwYXJzZShzb3VyY2U6IHN0cmluZywgdXJsOiBzdHJpbmcsIG9wdGlvbnM/OiBUb2tlbml6ZU9wdGlvbnMpOiBQYXJzZVRyZWVSZXN1bHQge1xuICAgIGNvbnN0IHRva2VuaXplUmVzdWx0ID0gdG9rZW5pemUoc291cmNlLCB1cmwsIHRoaXMuZ2V0VGFnRGVmaW5pdGlvbiwgb3B0aW9ucyk7XG4gICAgY29uc3QgcGFyc2VyID0gbmV3IF9UcmVlQnVpbGRlcih0b2tlbml6ZVJlc3VsdC50b2tlbnMsIHRoaXMuZ2V0VGFnRGVmaW5pdGlvbik7XG4gICAgcGFyc2VyLmJ1aWxkKCk7XG4gICAgcmV0dXJuIG5ldyBQYXJzZVRyZWVSZXN1bHQoXG4gICAgICBwYXJzZXIucm9vdE5vZGVzLFxuICAgICAgKHRva2VuaXplUmVzdWx0LmVycm9ycyBhcyBQYXJzZUVycm9yW10pLmNvbmNhdChwYXJzZXIuZXJyb3JzKSxcbiAgICApO1xuICB9XG59XG5cbmNsYXNzIF9UcmVlQnVpbGRlciB7XG4gIHByaXZhdGUgX2luZGV4OiBudW1iZXIgPSAtMTtcbiAgLy8gYF9wZWVrYCB3aWxsIGJlIGluaXRpYWxpemVkIGJ5IHRoZSBjYWxsIHRvIGBfYWR2YW5jZSgpYCBpbiB0aGUgY29uc3RydWN0b3IuXG4gIHByaXZhdGUgX3BlZWshOiBUb2tlbjtcbiAgcHJpdmF0ZSBfY29udGFpbmVyU3RhY2s6IE5vZGVDb250YWluZXJbXSA9IFtdO1xuXG4gIHJvb3ROb2RlczogaHRtbC5Ob2RlW10gPSBbXTtcbiAgZXJyb3JzOiBUcmVlRXJyb3JbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgdG9rZW5zOiBUb2tlbltdLFxuICAgIHByaXZhdGUgZ2V0VGFnRGVmaW5pdGlvbjogKHRhZ05hbWU6IHN0cmluZykgPT4gVGFnRGVmaW5pdGlvbixcbiAgKSB7XG4gICAgdGhpcy5fYWR2YW5jZSgpO1xuICB9XG5cbiAgYnVpbGQoKTogdm9pZCB7XG4gICAgd2hpbGUgKHRoaXMuX3BlZWsudHlwZSAhPT0gVG9rZW5UeXBlLkVPRikge1xuICAgICAgaWYgKFxuICAgICAgICB0aGlzLl9wZWVrLnR5cGUgPT09IFRva2VuVHlwZS5UQUdfT1BFTl9TVEFSVCB8fFxuICAgICAgICB0aGlzLl9wZWVrLnR5cGUgPT09IFRva2VuVHlwZS5JTkNPTVBMRVRFX1RBR19PUEVOXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5fY29uc3VtZVN0YXJ0VGFnKHRoaXMuX2FkdmFuY2UoKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuX3BlZWsudHlwZSA9PT0gVG9rZW5UeXBlLlRBR19DTE9TRSkge1xuICAgICAgICB0aGlzLl9jb25zdW1lRW5kVGFnKHRoaXMuX2FkdmFuY2UoKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuX3BlZWsudHlwZSA9PT0gVG9rZW5UeXBlLkNEQVRBX1NUQVJUKSB7XG4gICAgICAgIHRoaXMuX2Nsb3NlVm9pZEVsZW1lbnQoKTtcbiAgICAgICAgdGhpcy5fY29uc3VtZUNkYXRhKHRoaXMuX2FkdmFuY2UoKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuX3BlZWsudHlwZSA9PT0gVG9rZW5UeXBlLkNPTU1FTlRfU1RBUlQpIHtcbiAgICAgICAgdGhpcy5fY2xvc2VWb2lkRWxlbWVudCgpO1xuICAgICAgICB0aGlzLl9jb25zdW1lQ29tbWVudCh0aGlzLl9hZHZhbmNlKCkpO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgdGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuVEVYVCB8fFxuICAgICAgICB0aGlzLl9wZWVrLnR5cGUgPT09IFRva2VuVHlwZS5SQVdfVEVYVCB8fFxuICAgICAgICB0aGlzLl9wZWVrLnR5cGUgPT09IFRva2VuVHlwZS5FU0NBUEFCTEVfUkFXX1RFWFRcbiAgICAgICkge1xuICAgICAgICB0aGlzLl9jbG9zZVZvaWRFbGVtZW50KCk7XG4gICAgICAgIHRoaXMuX2NvbnN1bWVUZXh0KHRoaXMuX2FkdmFuY2UoKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuX3BlZWsudHlwZSA9PT0gVG9rZW5UeXBlLkVYUEFOU0lPTl9GT1JNX1NUQVJUKSB7XG4gICAgICAgIHRoaXMuX2NvbnN1bWVFeHBhbnNpb24odGhpcy5fYWR2YW5jZSgpKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuQkxPQ0tfT1BFTl9TVEFSVCkge1xuICAgICAgICB0aGlzLl9jbG9zZVZvaWRFbGVtZW50KCk7XG4gICAgICAgIHRoaXMuX2NvbnN1bWVCbG9ja09wZW4odGhpcy5fYWR2YW5jZSgpKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuQkxPQ0tfQ0xPU0UpIHtcbiAgICAgICAgdGhpcy5fY2xvc2VWb2lkRWxlbWVudCgpO1xuICAgICAgICB0aGlzLl9jb25zdW1lQmxvY2tDbG9zZSh0aGlzLl9hZHZhbmNlKCkpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLl9wZWVrLnR5cGUgPT09IFRva2VuVHlwZS5JTkNPTVBMRVRFX0JMT0NLX09QRU4pIHtcbiAgICAgICAgdGhpcy5fY2xvc2VWb2lkRWxlbWVudCgpO1xuICAgICAgICB0aGlzLl9jb25zdW1lSW5jb21wbGV0ZUJsb2NrKHRoaXMuX2FkdmFuY2UoKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuX3BlZWsudHlwZSA9PT0gVG9rZW5UeXBlLkxFVF9TVEFSVCkge1xuICAgICAgICB0aGlzLl9jbG9zZVZvaWRFbGVtZW50KCk7XG4gICAgICAgIHRoaXMuX2NvbnN1bWVMZXQodGhpcy5fYWR2YW5jZSgpKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuSU5DT01QTEVURV9MRVQpIHtcbiAgICAgICAgdGhpcy5fY2xvc2VWb2lkRWxlbWVudCgpO1xuICAgICAgICB0aGlzLl9jb25zdW1lSW5jb21wbGV0ZUxldCh0aGlzLl9hZHZhbmNlKCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gU2tpcCBhbGwgb3RoZXIgdG9rZW5zLi4uXG4gICAgICAgIHRoaXMuX2FkdmFuY2UoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGxlZnRvdmVyQ29udGFpbmVyIG9mIHRoaXMuX2NvbnRhaW5lclN0YWNrKSB7XG4gICAgICAvLyBVbmxpa2UgSFRNTCBlbGVtZW50cywgYmxvY2tzIGFyZW4ndCBjbG9zZWQgaW1wbGljaXRseSBieSB0aGUgZW5kIG9mIHRoZSBmaWxlLlxuICAgICAgaWYgKGxlZnRvdmVyQ29udGFpbmVyIGluc3RhbmNlb2YgaHRtbC5CbG9jaykge1xuICAgICAgICB0aGlzLmVycm9ycy5wdXNoKFxuICAgICAgICAgIFRyZWVFcnJvci5jcmVhdGUoXG4gICAgICAgICAgICBsZWZ0b3ZlckNvbnRhaW5lci5uYW1lLFxuICAgICAgICAgICAgbGVmdG92ZXJDb250YWluZXIuc291cmNlU3BhbixcbiAgICAgICAgICAgIGBVbmNsb3NlZCBibG9jayBcIiR7bGVmdG92ZXJDb250YWluZXIubmFtZX1cImAsXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9hZHZhbmNlPFQgZXh0ZW5kcyBUb2tlbj4oKTogVCB7XG4gICAgY29uc3QgcHJldiA9IHRoaXMuX3BlZWs7XG4gICAgaWYgKHRoaXMuX2luZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoIC0gMSkge1xuICAgICAgLy8gTm90ZTogdGhlcmUgaXMgYWx3YXlzIGFuIEVPRiB0b2tlbiBhdCB0aGUgZW5kXG4gICAgICB0aGlzLl9pbmRleCsrO1xuICAgIH1cbiAgICB0aGlzLl9wZWVrID0gdGhpcy50b2tlbnNbdGhpcy5faW5kZXhdO1xuICAgIHJldHVybiBwcmV2IGFzIFQ7XG4gIH1cblxuICBwcml2YXRlIF9hZHZhbmNlSWY8VCBleHRlbmRzIFRva2VuVHlwZT4odHlwZTogVCk6IChUb2tlbiAmIHt0eXBlOiBUfSkgfCBudWxsIHtcbiAgICBpZiAodGhpcy5fcGVlay50eXBlID09PSB0eXBlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fYWR2YW5jZTxUb2tlbiAmIHt0eXBlOiBUfT4oKTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9jb25zdW1lQ2RhdGEoX3N0YXJ0VG9rZW46IENkYXRhU3RhcnRUb2tlbikge1xuICAgIHRoaXMuX2NvbnN1bWVUZXh0KHRoaXMuX2FkdmFuY2U8VGV4dFRva2VuPigpKTtcbiAgICB0aGlzLl9hZHZhbmNlSWYoVG9rZW5UeXBlLkNEQVRBX0VORCk7XG4gIH1cblxuICBwcml2YXRlIF9jb25zdW1lQ29tbWVudCh0b2tlbjogQ29tbWVudFN0YXJ0VG9rZW4pIHtcbiAgICBjb25zdCB0ZXh0ID0gdGhpcy5fYWR2YW5jZUlmKFRva2VuVHlwZS5SQVdfVEVYVCk7XG4gICAgY29uc3QgZW5kVG9rZW4gPSB0aGlzLl9hZHZhbmNlSWYoVG9rZW5UeXBlLkNPTU1FTlRfRU5EKTtcbiAgICBjb25zdCB2YWx1ZSA9IHRleHQgIT0gbnVsbCA/IHRleHQucGFydHNbMF0udHJpbSgpIDogbnVsbDtcbiAgICBjb25zdCBzb3VyY2VTcGFuID1cbiAgICAgIGVuZFRva2VuID09IG51bGxcbiAgICAgICAgPyB0b2tlbi5zb3VyY2VTcGFuXG4gICAgICAgIDogbmV3IFBhcnNlU291cmNlU3BhbihcbiAgICAgICAgICAgIHRva2VuLnNvdXJjZVNwYW4uc3RhcnQsXG4gICAgICAgICAgICBlbmRUb2tlbi5zb3VyY2VTcGFuLmVuZCxcbiAgICAgICAgICAgIHRva2VuLnNvdXJjZVNwYW4uZnVsbFN0YXJ0LFxuICAgICAgICAgICk7XG4gICAgdGhpcy5fYWRkVG9QYXJlbnQobmV3IGh0bWwuQ29tbWVudCh2YWx1ZSwgc291cmNlU3BhbikpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY29uc3VtZUV4cGFuc2lvbih0b2tlbjogRXhwYW5zaW9uRm9ybVN0YXJ0VG9rZW4pIHtcbiAgICBjb25zdCBzd2l0Y2hWYWx1ZSA9IHRoaXMuX2FkdmFuY2U8VGV4dFRva2VuPigpO1xuXG4gICAgY29uc3QgdHlwZSA9IHRoaXMuX2FkdmFuY2U8VGV4dFRva2VuPigpO1xuICAgIGNvbnN0IGNhc2VzOiBodG1sLkV4cGFuc2lvbkNhc2VbXSA9IFtdO1xuXG4gICAgLy8gcmVhZCA9XG4gICAgd2hpbGUgKHRoaXMuX3BlZWsudHlwZSA9PT0gVG9rZW5UeXBlLkVYUEFOU0lPTl9DQVNFX1ZBTFVFKSB7XG4gICAgICBjb25zdCBleHBDYXNlID0gdGhpcy5fcGFyc2VFeHBhbnNpb25DYXNlKCk7XG4gICAgICBpZiAoIWV4cENhc2UpIHJldHVybjsgLy8gZXJyb3JcbiAgICAgIGNhc2VzLnB1c2goZXhwQ2FzZSk7XG4gICAgfVxuXG4gICAgLy8gcmVhZCB0aGUgZmluYWwgfVxuICAgIGlmICh0aGlzLl9wZWVrLnR5cGUgIT09IFRva2VuVHlwZS5FWFBBTlNJT05fRk9STV9FTkQpIHtcbiAgICAgIHRoaXMuZXJyb3JzLnB1c2goXG4gICAgICAgIFRyZWVFcnJvci5jcmVhdGUobnVsbCwgdGhpcy5fcGVlay5zb3VyY2VTcGFuLCBgSW52YWxpZCBJQ1UgbWVzc2FnZS4gTWlzc2luZyAnfScuYCksXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IFBhcnNlU291cmNlU3BhbihcbiAgICAgIHRva2VuLnNvdXJjZVNwYW4uc3RhcnQsXG4gICAgICB0aGlzLl9wZWVrLnNvdXJjZVNwYW4uZW5kLFxuICAgICAgdG9rZW4uc291cmNlU3Bhbi5mdWxsU3RhcnQsXG4gICAgKTtcbiAgICB0aGlzLl9hZGRUb1BhcmVudChcbiAgICAgIG5ldyBodG1sLkV4cGFuc2lvbihcbiAgICAgICAgc3dpdGNoVmFsdWUucGFydHNbMF0sXG4gICAgICAgIHR5cGUucGFydHNbMF0sXG4gICAgICAgIGNhc2VzLFxuICAgICAgICBzb3VyY2VTcGFuLFxuICAgICAgICBzd2l0Y2hWYWx1ZS5zb3VyY2VTcGFuLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgdGhpcy5fYWR2YW5jZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcGFyc2VFeHBhbnNpb25DYXNlKCk6IGh0bWwuRXhwYW5zaW9uQ2FzZSB8IG51bGwge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fYWR2YW5jZTxFeHBhbnNpb25DYXNlVmFsdWVUb2tlbj4oKTtcblxuICAgIC8vIHJlYWQge1xuICAgIGlmICh0aGlzLl9wZWVrLnR5cGUgIT09IFRva2VuVHlwZS5FWFBBTlNJT05fQ0FTRV9FWFBfU1RBUlQpIHtcbiAgICAgIHRoaXMuZXJyb3JzLnB1c2goXG4gICAgICAgIFRyZWVFcnJvci5jcmVhdGUobnVsbCwgdGhpcy5fcGVlay5zb3VyY2VTcGFuLCBgSW52YWxpZCBJQ1UgbWVzc2FnZS4gTWlzc2luZyAneycuYCksXG4gICAgICApO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gcmVhZCB1bnRpbCB9XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLl9hZHZhbmNlPEV4cGFuc2lvbkNhc2VFeHByZXNzaW9uU3RhcnRUb2tlbj4oKTtcblxuICAgIGNvbnN0IGV4cCA9IHRoaXMuX2NvbGxlY3RFeHBhbnNpb25FeHBUb2tlbnMoc3RhcnQpO1xuICAgIGlmICghZXhwKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IGVuZCA9IHRoaXMuX2FkdmFuY2U8RXhwYW5zaW9uQ2FzZUV4cHJlc3Npb25FbmRUb2tlbj4oKTtcbiAgICBleHAucHVzaCh7dHlwZTogVG9rZW5UeXBlLkVPRiwgcGFydHM6IFtdLCBzb3VyY2VTcGFuOiBlbmQuc291cmNlU3Bhbn0pO1xuXG4gICAgLy8gcGFyc2UgZXZlcnl0aGluZyBpbiBiZXR3ZWVuIHsgYW5kIH1cbiAgICBjb25zdCBleHBhbnNpb25DYXNlUGFyc2VyID0gbmV3IF9UcmVlQnVpbGRlcihleHAsIHRoaXMuZ2V0VGFnRGVmaW5pdGlvbik7XG4gICAgZXhwYW5zaW9uQ2FzZVBhcnNlci5idWlsZCgpO1xuICAgIGlmIChleHBhbnNpb25DYXNlUGFyc2VyLmVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmVycm9ycyA9IHRoaXMuZXJyb3JzLmNvbmNhdChleHBhbnNpb25DYXNlUGFyc2VyLmVycm9ycyk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IFBhcnNlU291cmNlU3BhbihcbiAgICAgIHZhbHVlLnNvdXJjZVNwYW4uc3RhcnQsXG4gICAgICBlbmQuc291cmNlU3Bhbi5lbmQsXG4gICAgICB2YWx1ZS5zb3VyY2VTcGFuLmZ1bGxTdGFydCxcbiAgICApO1xuICAgIGNvbnN0IGV4cFNvdXJjZVNwYW4gPSBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgc3RhcnQuc291cmNlU3Bhbi5zdGFydCxcbiAgICAgIGVuZC5zb3VyY2VTcGFuLmVuZCxcbiAgICAgIHN0YXJ0LnNvdXJjZVNwYW4uZnVsbFN0YXJ0LFxuICAgICk7XG4gICAgcmV0dXJuIG5ldyBodG1sLkV4cGFuc2lvbkNhc2UoXG4gICAgICB2YWx1ZS5wYXJ0c1swXSxcbiAgICAgIGV4cGFuc2lvbkNhc2VQYXJzZXIucm9vdE5vZGVzLFxuICAgICAgc291cmNlU3BhbixcbiAgICAgIHZhbHVlLnNvdXJjZVNwYW4sXG4gICAgICBleHBTb3VyY2VTcGFuLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIF9jb2xsZWN0RXhwYW5zaW9uRXhwVG9rZW5zKHN0YXJ0OiBUb2tlbik6IFRva2VuW10gfCBudWxsIHtcbiAgICBjb25zdCBleHA6IFRva2VuW10gPSBbXTtcbiAgICBjb25zdCBleHBhbnNpb25Gb3JtU3RhY2sgPSBbVG9rZW5UeXBlLkVYUEFOU0lPTl9DQVNFX0VYUF9TVEFSVF07XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKFxuICAgICAgICB0aGlzLl9wZWVrLnR5cGUgPT09IFRva2VuVHlwZS5FWFBBTlNJT05fRk9STV9TVEFSVCB8fFxuICAgICAgICB0aGlzLl9wZWVrLnR5cGUgPT09IFRva2VuVHlwZS5FWFBBTlNJT05fQ0FTRV9FWFBfU1RBUlRcbiAgICAgICkge1xuICAgICAgICBleHBhbnNpb25Gb3JtU3RhY2sucHVzaCh0aGlzLl9wZWVrLnR5cGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuRVhQQU5TSU9OX0NBU0VfRVhQX0VORCkge1xuICAgICAgICBpZiAobGFzdE9uU3RhY2soZXhwYW5zaW9uRm9ybVN0YWNrLCBUb2tlblR5cGUuRVhQQU5TSU9OX0NBU0VfRVhQX1NUQVJUKSkge1xuICAgICAgICAgIGV4cGFuc2lvbkZvcm1TdGFjay5wb3AoKTtcbiAgICAgICAgICBpZiAoZXhwYW5zaW9uRm9ybVN0YWNrLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGV4cDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmVycm9ycy5wdXNoKFxuICAgICAgICAgICAgVHJlZUVycm9yLmNyZWF0ZShudWxsLCBzdGFydC5zb3VyY2VTcGFuLCBgSW52YWxpZCBJQ1UgbWVzc2FnZS4gTWlzc2luZyAnfScuYCksXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuRVhQQU5TSU9OX0ZPUk1fRU5EKSB7XG4gICAgICAgIGlmIChsYXN0T25TdGFjayhleHBhbnNpb25Gb3JtU3RhY2ssIFRva2VuVHlwZS5FWFBBTlNJT05fRk9STV9TVEFSVCkpIHtcbiAgICAgICAgICBleHBhbnNpb25Gb3JtU3RhY2sucG9wKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5lcnJvcnMucHVzaChcbiAgICAgICAgICAgIFRyZWVFcnJvci5jcmVhdGUobnVsbCwgc3RhcnQuc291cmNlU3BhbiwgYEludmFsaWQgSUNVIG1lc3NhZ2UuIE1pc3NpbmcgJ30nLmApLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuX3BlZWsudHlwZSA9PT0gVG9rZW5UeXBlLkVPRikge1xuICAgICAgICB0aGlzLmVycm9ycy5wdXNoKFxuICAgICAgICAgIFRyZWVFcnJvci5jcmVhdGUobnVsbCwgc3RhcnQuc291cmNlU3BhbiwgYEludmFsaWQgSUNVIG1lc3NhZ2UuIE1pc3NpbmcgJ30nLmApLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cblxuICAgICAgZXhwLnB1c2godGhpcy5fYWR2YW5jZSgpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9jb25zdW1lVGV4dCh0b2tlbjogSW50ZXJwb2xhdGVkVGV4dFRva2VuKSB7XG4gICAgY29uc3QgdG9rZW5zID0gW3Rva2VuXTtcbiAgICBjb25zdCBzdGFydFNwYW4gPSB0b2tlbi5zb3VyY2VTcGFuO1xuICAgIGxldCB0ZXh0ID0gdG9rZW4ucGFydHNbMF07XG4gICAgaWYgKHRleHQubGVuZ3RoID4gMCAmJiB0ZXh0WzBdID09PSAnXFxuJykge1xuICAgICAgY29uc3QgcGFyZW50ID0gdGhpcy5fZ2V0Q29udGFpbmVyKCk7XG5cbiAgICAgIGlmIChcbiAgICAgICAgcGFyZW50ICE9IG51bGwgJiZcbiAgICAgICAgcGFyZW50LmNoaWxkcmVuLmxlbmd0aCA9PT0gMCAmJlxuICAgICAgICB0aGlzLmdldFRhZ0RlZmluaXRpb24ocGFyZW50Lm5hbWUpLmlnbm9yZUZpcnN0TGZcbiAgICAgICkge1xuICAgICAgICB0ZXh0ID0gdGV4dC5zdWJzdHJpbmcoMSk7XG4gICAgICAgIHRva2Vuc1swXSA9IHt0eXBlOiB0b2tlbi50eXBlLCBzb3VyY2VTcGFuOiB0b2tlbi5zb3VyY2VTcGFuLCBwYXJ0czogW3RleHRdfSBhcyB0eXBlb2YgdG9rZW47XG4gICAgICB9XG4gICAgfVxuXG4gICAgd2hpbGUgKFxuICAgICAgdGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuSU5URVJQT0xBVElPTiB8fFxuICAgICAgdGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuVEVYVCB8fFxuICAgICAgdGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuRU5DT0RFRF9FTlRJVFlcbiAgICApIHtcbiAgICAgIHRva2VuID0gdGhpcy5fYWR2YW5jZSgpO1xuICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuVHlwZS5JTlRFUlBPTEFUSU9OKSB7XG4gICAgICAgIC8vIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdlIGRlY29kZSBIVE1MIGVudGl0aWVzIHRoYXQgYXBwZWFyIGluIGludGVycG9sYXRpb25cbiAgICAgICAgLy8gZXhwcmVzc2lvbnMuIFRoaXMgaXMgYXJndWFibHkgYSBidWcsIGJ1dCBpdCBjb3VsZCBiZSBhIGNvbnNpZGVyYWJsZSBicmVha2luZyBjaGFuZ2UgdG9cbiAgICAgICAgLy8gZml4IGl0LiBJdCBzaG91bGQgYmUgYWRkcmVzc2VkIGluIGEgbGFyZ2VyIHByb2plY3QgdG8gcmVmYWN0b3IgdGhlIGVudGlyZSBwYXJzZXIvbGV4ZXJcbiAgICAgICAgLy8gY2hhaW4gYWZ0ZXIgVmlldyBFbmdpbmUgaGFzIGJlZW4gcmVtb3ZlZC5cbiAgICAgICAgdGV4dCArPSB0b2tlbi5wYXJ0cy5qb2luKCcnKS5yZXBsYWNlKC8mKFteO10rKTsvZywgZGVjb2RlRW50aXR5KTtcbiAgICAgIH0gZWxzZSBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW5UeXBlLkVOQ09ERURfRU5USVRZKSB7XG4gICAgICAgIHRleHQgKz0gdG9rZW4ucGFydHNbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZXh0ICs9IHRva2VuLnBhcnRzLmpvaW4oJycpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0ZXh0Lmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGVuZFNwYW4gPSB0b2tlbi5zb3VyY2VTcGFuO1xuICAgICAgdGhpcy5fYWRkVG9QYXJlbnQoXG4gICAgICAgIG5ldyBodG1sLlRleHQoXG4gICAgICAgICAgdGV4dCxcbiAgICAgICAgICBuZXcgUGFyc2VTb3VyY2VTcGFuKHN0YXJ0U3Bhbi5zdGFydCwgZW5kU3Bhbi5lbmQsIHN0YXJ0U3Bhbi5mdWxsU3RhcnQsIHN0YXJ0U3Bhbi5kZXRhaWxzKSxcbiAgICAgICAgICB0b2tlbnMsXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2Nsb3NlVm9pZEVsZW1lbnQoKTogdm9pZCB7XG4gICAgY29uc3QgZWwgPSB0aGlzLl9nZXRDb250YWluZXIoKTtcbiAgICBpZiAoZWwgaW5zdGFuY2VvZiBodG1sLkVsZW1lbnQgJiYgdGhpcy5nZXRUYWdEZWZpbml0aW9uKGVsLm5hbWUpLmlzVm9pZCkge1xuICAgICAgdGhpcy5fY29udGFpbmVyU3RhY2sucG9wKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfY29uc3VtZVN0YXJ0VGFnKHN0YXJ0VGFnVG9rZW46IFRhZ09wZW5TdGFydFRva2VuIHwgSW5jb21wbGV0ZVRhZ09wZW5Ub2tlbikge1xuICAgIGNvbnN0IFtwcmVmaXgsIG5hbWVdID0gc3RhcnRUYWdUb2tlbi5wYXJ0cztcbiAgICBjb25zdCBhdHRyczogaHRtbC5BdHRyaWJ1dGVbXSA9IFtdO1xuICAgIHdoaWxlICh0aGlzLl9wZWVrLnR5cGUgPT09IFRva2VuVHlwZS5BVFRSX05BTUUpIHtcbiAgICAgIGF0dHJzLnB1c2godGhpcy5fY29uc3VtZUF0dHIodGhpcy5fYWR2YW5jZTxBdHRyaWJ1dGVOYW1lVG9rZW4+KCkpKTtcbiAgICB9XG4gICAgY29uc3QgZnVsbE5hbWUgPSB0aGlzLl9nZXRFbGVtZW50RnVsbE5hbWUocHJlZml4LCBuYW1lLCB0aGlzLl9nZXRDbG9zZXN0UGFyZW50RWxlbWVudCgpKTtcbiAgICBsZXQgc2VsZkNsb3NpbmcgPSBmYWxzZTtcbiAgICAvLyBOb3RlOiBUaGVyZSBjb3VsZCBoYXZlIGJlZW4gYSB0b2tlbml6ZXIgZXJyb3JcbiAgICAvLyBzbyB0aGF0IHdlIGRvbid0IGdldCBhIHRva2VuIGZvciB0aGUgZW5kIHRhZy4uLlxuICAgIGlmICh0aGlzLl9wZWVrLnR5cGUgPT09IFRva2VuVHlwZS5UQUdfT1BFTl9FTkRfVk9JRCkge1xuICAgICAgdGhpcy5fYWR2YW5jZSgpO1xuICAgICAgc2VsZkNsb3NpbmcgPSB0cnVlO1xuICAgICAgY29uc3QgdGFnRGVmID0gdGhpcy5nZXRUYWdEZWZpbml0aW9uKGZ1bGxOYW1lKTtcbiAgICAgIGlmICghKHRhZ0RlZi5jYW5TZWxmQ2xvc2UgfHwgZ2V0TnNQcmVmaXgoZnVsbE5hbWUpICE9PSBudWxsIHx8IHRhZ0RlZi5pc1ZvaWQpKSB7XG4gICAgICAgIHRoaXMuZXJyb3JzLnB1c2goXG4gICAgICAgICAgVHJlZUVycm9yLmNyZWF0ZShcbiAgICAgICAgICAgIGZ1bGxOYW1lLFxuICAgICAgICAgICAgc3RhcnRUYWdUb2tlbi5zb3VyY2VTcGFuLFxuICAgICAgICAgICAgYE9ubHkgdm9pZCwgY3VzdG9tIGFuZCBmb3JlaWduIGVsZW1lbnRzIGNhbiBiZSBzZWxmIGNsb3NlZCBcIiR7c3RhcnRUYWdUb2tlbi5wYXJ0c1sxXX1cImAsXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHRoaXMuX3BlZWsudHlwZSA9PT0gVG9rZW5UeXBlLlRBR19PUEVOX0VORCkge1xuICAgICAgdGhpcy5fYWR2YW5jZSgpO1xuICAgICAgc2VsZkNsb3NpbmcgPSBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgZW5kID0gdGhpcy5fcGVlay5zb3VyY2VTcGFuLmZ1bGxTdGFydDtcbiAgICBjb25zdCBzcGFuID0gbmV3IFBhcnNlU291cmNlU3BhbihcbiAgICAgIHN0YXJ0VGFnVG9rZW4uc291cmNlU3Bhbi5zdGFydCxcbiAgICAgIGVuZCxcbiAgICAgIHN0YXJ0VGFnVG9rZW4uc291cmNlU3Bhbi5mdWxsU3RhcnQsXG4gICAgKTtcbiAgICAvLyBDcmVhdGUgYSBzZXBhcmF0ZSBgc3RhcnRTcGFuYCBiZWNhdXNlIGBzcGFuYCB3aWxsIGJlIG1vZGlmaWVkIHdoZW4gdGhlcmUgaXMgYW4gYGVuZGAgc3Bhbi5cbiAgICBjb25zdCBzdGFydFNwYW4gPSBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgc3RhcnRUYWdUb2tlbi5zb3VyY2VTcGFuLnN0YXJ0LFxuICAgICAgZW5kLFxuICAgICAgc3RhcnRUYWdUb2tlbi5zb3VyY2VTcGFuLmZ1bGxTdGFydCxcbiAgICApO1xuICAgIGNvbnN0IGVsID0gbmV3IGh0bWwuRWxlbWVudChmdWxsTmFtZSwgYXR0cnMsIFtdLCBzcGFuLCBzdGFydFNwYW4sIHVuZGVmaW5lZCk7XG4gICAgY29uc3QgcGFyZW50RWwgPSB0aGlzLl9nZXRDb250YWluZXIoKTtcbiAgICB0aGlzLl9wdXNoQ29udGFpbmVyKFxuICAgICAgZWwsXG4gICAgICBwYXJlbnRFbCBpbnN0YW5jZW9mIGh0bWwuRWxlbWVudCAmJlxuICAgICAgICB0aGlzLmdldFRhZ0RlZmluaXRpb24ocGFyZW50RWwubmFtZSkuaXNDbG9zZWRCeUNoaWxkKGVsLm5hbWUpLFxuICAgICk7XG4gICAgaWYgKHNlbGZDbG9zaW5nKSB7XG4gICAgICAvLyBFbGVtZW50cyB0aGF0IGFyZSBzZWxmLWNsb3NlZCBoYXZlIHRoZWlyIGBlbmRTb3VyY2VTcGFuYCBzZXQgdG8gdGhlIGZ1bGwgc3BhbiwgYXMgdGhlXG4gICAgICAvLyBlbGVtZW50IHN0YXJ0IHRhZyBhbHNvIHJlcHJlc2VudHMgdGhlIGVuZCB0YWcuXG4gICAgICB0aGlzLl9wb3BDb250YWluZXIoZnVsbE5hbWUsIGh0bWwuRWxlbWVudCwgc3Bhbik7XG4gICAgfSBlbHNlIGlmIChzdGFydFRhZ1Rva2VuLnR5cGUgPT09IFRva2VuVHlwZS5JTkNPTVBMRVRFX1RBR19PUEVOKSB7XG4gICAgICAvLyBXZSBhbHJlYWR5IGtub3cgdGhlIG9wZW5pbmcgdGFnIGlzIG5vdCBjb21wbGV0ZSwgc28gaXQgaXMgdW5saWtlbHkgaXQgaGFzIGEgY29ycmVzcG9uZGluZ1xuICAgICAgLy8gY2xvc2UgdGFnLiBMZXQncyBvcHRpbWlzdGljYWxseSBwYXJzZSBpdCBhcyBhIGZ1bGwgZWxlbWVudCBhbmQgZW1pdCBhbiBlcnJvci5cbiAgICAgIHRoaXMuX3BvcENvbnRhaW5lcihmdWxsTmFtZSwgaHRtbC5FbGVtZW50LCBudWxsKTtcbiAgICAgIHRoaXMuZXJyb3JzLnB1c2goXG4gICAgICAgIFRyZWVFcnJvci5jcmVhdGUoZnVsbE5hbWUsIHNwYW4sIGBPcGVuaW5nIHRhZyBcIiR7ZnVsbE5hbWV9XCIgbm90IHRlcm1pbmF0ZWQuYCksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3B1c2hDb250YWluZXIobm9kZTogTm9kZUNvbnRhaW5lciwgaXNDbG9zZWRCeUNoaWxkOiBib29sZWFuKSB7XG4gICAgaWYgKGlzQ2xvc2VkQnlDaGlsZCkge1xuICAgICAgdGhpcy5fY29udGFpbmVyU3RhY2sucG9wKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fYWRkVG9QYXJlbnQobm9kZSk7XG4gICAgdGhpcy5fY29udGFpbmVyU3RhY2sucHVzaChub2RlKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbnN1bWVFbmRUYWcoZW5kVGFnVG9rZW46IFRhZ0Nsb3NlVG9rZW4pIHtcbiAgICBjb25zdCBmdWxsTmFtZSA9IHRoaXMuX2dldEVsZW1lbnRGdWxsTmFtZShcbiAgICAgIGVuZFRhZ1Rva2VuLnBhcnRzWzBdLFxuICAgICAgZW5kVGFnVG9rZW4ucGFydHNbMV0sXG4gICAgICB0aGlzLl9nZXRDbG9zZXN0UGFyZW50RWxlbWVudCgpLFxuICAgICk7XG5cbiAgICBpZiAodGhpcy5nZXRUYWdEZWZpbml0aW9uKGZ1bGxOYW1lKS5pc1ZvaWQpIHtcbiAgICAgIHRoaXMuZXJyb3JzLnB1c2goXG4gICAgICAgIFRyZWVFcnJvci5jcmVhdGUoXG4gICAgICAgICAgZnVsbE5hbWUsXG4gICAgICAgICAgZW5kVGFnVG9rZW4uc291cmNlU3BhbixcbiAgICAgICAgICBgVm9pZCBlbGVtZW50cyBkbyBub3QgaGF2ZSBlbmQgdGFncyBcIiR7ZW5kVGFnVG9rZW4ucGFydHNbMV19XCJgLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKCF0aGlzLl9wb3BDb250YWluZXIoZnVsbE5hbWUsIGh0bWwuRWxlbWVudCwgZW5kVGFnVG9rZW4uc291cmNlU3BhbikpIHtcbiAgICAgIGNvbnN0IGVyck1zZyA9IGBVbmV4cGVjdGVkIGNsb3NpbmcgdGFnIFwiJHtmdWxsTmFtZX1cIi4gSXQgbWF5IGhhcHBlbiB3aGVuIHRoZSB0YWcgaGFzIGFscmVhZHkgYmVlbiBjbG9zZWQgYnkgYW5vdGhlciB0YWcuIEZvciBtb3JlIGluZm8gc2VlIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9odG1sNS9zeW50YXguaHRtbCNjbG9zaW5nLWVsZW1lbnRzLXRoYXQtaGF2ZS1pbXBsaWVkLWVuZC10YWdzYDtcbiAgICAgIHRoaXMuZXJyb3JzLnB1c2goVHJlZUVycm9yLmNyZWF0ZShmdWxsTmFtZSwgZW5kVGFnVG9rZW4uc291cmNlU3BhbiwgZXJyTXNnKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyB0aGUgbmVhcmVzdCBlbGVtZW50IHdpdGggdGhlIHRhZyBuYW1lIGBmdWxsTmFtZWAgaW4gdGhlIHBhcnNlIHRyZWUuXG4gICAqIGBlbmRTb3VyY2VTcGFuYCBpcyB0aGUgc3BhbiBvZiB0aGUgY2xvc2luZyB0YWcsIG9yIG51bGwgaWYgdGhlIGVsZW1lbnQgZG9lc1xuICAgKiBub3QgaGF2ZSBhIGNsb3NpbmcgdGFnIChmb3IgZXhhbXBsZSwgdGhpcyBoYXBwZW5zIHdoZW4gYW4gaW5jb21wbGV0ZVxuICAgKiBvcGVuaW5nIHRhZyBpcyByZWNvdmVyZWQpLlxuICAgKi9cbiAgcHJpdmF0ZSBfcG9wQ29udGFpbmVyKFxuICAgIGV4cGVjdGVkTmFtZTogc3RyaW5nIHwgbnVsbCxcbiAgICBleHBlY3RlZFR5cGU6IE5vZGVDb250YWluZXJDb25zdHJ1Y3RvcixcbiAgICBlbmRTb3VyY2VTcGFuOiBQYXJzZVNvdXJjZVNwYW4gfCBudWxsLFxuICApOiBib29sZWFuIHtcbiAgICBsZXQgdW5leHBlY3RlZENsb3NlVGFnRGV0ZWN0ZWQgPSBmYWxzZTtcbiAgICBmb3IgKGxldCBzdGFja0luZGV4ID0gdGhpcy5fY29udGFpbmVyU3RhY2subGVuZ3RoIC0gMTsgc3RhY2tJbmRleCA+PSAwOyBzdGFja0luZGV4LS0pIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLl9jb250YWluZXJTdGFja1tzdGFja0luZGV4XTtcblxuICAgICAgaWYgKChub2RlLm5hbWUgPT09IGV4cGVjdGVkTmFtZSB8fCBleHBlY3RlZE5hbWUgPT09IG51bGwpICYmIG5vZGUgaW5zdGFuY2VvZiBleHBlY3RlZFR5cGUpIHtcbiAgICAgICAgLy8gUmVjb3JkIHRoZSBwYXJzZSBzcGFuIHdpdGggdGhlIGVsZW1lbnQgdGhhdCBpcyBiZWluZyBjbG9zZWQuIEFueSBlbGVtZW50cyB0aGF0IGFyZVxuICAgICAgICAvLyByZW1vdmVkIGZyb20gdGhlIGVsZW1lbnQgc3RhY2sgYXQgdGhpcyBwb2ludCBhcmUgY2xvc2VkIGltcGxpY2l0bHksIHNvIHRoZXkgd29uJ3QgZ2V0XG4gICAgICAgIC8vIGFuIGVuZCBzb3VyY2Ugc3BhbiAoYXMgdGhlcmUgaXMgbm8gZXhwbGljaXQgY2xvc2luZyBlbGVtZW50KS5cbiAgICAgICAgbm9kZS5lbmRTb3VyY2VTcGFuID0gZW5kU291cmNlU3BhbjtcbiAgICAgICAgbm9kZS5zb3VyY2VTcGFuLmVuZCA9IGVuZFNvdXJjZVNwYW4gIT09IG51bGwgPyBlbmRTb3VyY2VTcGFuLmVuZCA6IG5vZGUuc291cmNlU3Bhbi5lbmQ7XG4gICAgICAgIHRoaXMuX2NvbnRhaW5lclN0YWNrLnNwbGljZShzdGFja0luZGV4LCB0aGlzLl9jb250YWluZXJTdGFjay5sZW5ndGggLSBzdGFja0luZGV4KTtcbiAgICAgICAgcmV0dXJuICF1bmV4cGVjdGVkQ2xvc2VUYWdEZXRlY3RlZDtcbiAgICAgIH1cblxuICAgICAgLy8gQmxvY2tzIGFuZCBtb3N0IGVsZW1lbnRzIGFyZSBub3Qgc2VsZiBjbG9zaW5nLlxuICAgICAgaWYgKFxuICAgICAgICBub2RlIGluc3RhbmNlb2YgaHRtbC5CbG9jayB8fFxuICAgICAgICAobm9kZSBpbnN0YW5jZW9mIGh0bWwuRWxlbWVudCAmJiAhdGhpcy5nZXRUYWdEZWZpbml0aW9uKG5vZGUubmFtZSkuY2xvc2VkQnlQYXJlbnQpXG4gICAgICApIHtcbiAgICAgICAgLy8gTm90ZSB0aGF0IHdlIGVuY291bnRlcmVkIGFuIHVuZXhwZWN0ZWQgY2xvc2UgdGFnIGJ1dCBjb250aW51ZSBwcm9jZXNzaW5nIHRoZSBlbGVtZW50XG4gICAgICAgIC8vIHN0YWNrIHNvIHdlIGNhbiBhc3NpZ24gYW4gYGVuZFNvdXJjZVNwYW5gIGlmIHRoZXJlIGlzIGEgY29ycmVzcG9uZGluZyBzdGFydCB0YWcgZm9yIHRoaXNcbiAgICAgICAgLy8gZW5kIHRhZyBpbiB0aGUgc3RhY2suXG4gICAgICAgIHVuZXhwZWN0ZWRDbG9zZVRhZ0RldGVjdGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBfY29uc3VtZUF0dHIoYXR0ck5hbWU6IEF0dHJpYnV0ZU5hbWVUb2tlbik6IGh0bWwuQXR0cmlidXRlIHtcbiAgICBjb25zdCBmdWxsTmFtZSA9IG1lcmdlTnNBbmROYW1lKGF0dHJOYW1lLnBhcnRzWzBdLCBhdHRyTmFtZS5wYXJ0c1sxXSk7XG4gICAgbGV0IGF0dHJFbmQgPSBhdHRyTmFtZS5zb3VyY2VTcGFuLmVuZDtcblxuICAgIC8vIENvbnN1bWUgYW55IHF1b3RlXG4gICAgaWYgKHRoaXMuX3BlZWsudHlwZSA9PT0gVG9rZW5UeXBlLkFUVFJfUVVPVEUpIHtcbiAgICAgIHRoaXMuX2FkdmFuY2UoKTtcbiAgICB9XG5cbiAgICAvLyBDb25zdW1lIHRoZSBhdHRyaWJ1dGUgdmFsdWVcbiAgICBsZXQgdmFsdWUgPSAnJztcbiAgICBjb25zdCB2YWx1ZVRva2VuczogSW50ZXJwb2xhdGVkQXR0cmlidXRlVG9rZW5bXSA9IFtdO1xuICAgIGxldCB2YWx1ZVN0YXJ0U3BhbjogUGFyc2VTb3VyY2VTcGFuIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIGxldCB2YWx1ZUVuZDogUGFyc2VMb2NhdGlvbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvLyBOT1RFOiBXZSBuZWVkIHRvIHVzZSBhIG5ldyB2YXJpYWJsZSBgbmV4dFRva2VuVHlwZWAgaGVyZSB0byBoaWRlIHRoZSBhY3R1YWwgdHlwZSBvZlxuICAgIC8vIGBfcGVlay50eXBlYCBmcm9tIFRTLiBPdGhlcndpc2UgVFMgd2lsbCBuYXJyb3cgdGhlIHR5cGUgb2YgYF9wZWVrLnR5cGVgIHByZXZlbnRpbmcgaXQgZnJvbVxuICAgIC8vIGJlaW5nIGFibGUgdG8gY29uc2lkZXIgYEFUVFJfVkFMVUVfSU5URVJQT0xBVElPTmAgYXMgYW4gb3B0aW9uLiBUaGlzIGlzIGJlY2F1c2UgVFMgaXMgbm90XG4gICAgLy8gYWJsZSB0byBzZWUgdGhhdCBgX2FkdmFuY2UoKWAgd2lsbCBhY3R1YWxseSBtdXRhdGUgYF9wZWVrYC5cbiAgICBjb25zdCBuZXh0VG9rZW5UeXBlID0gdGhpcy5fcGVlay50eXBlIGFzIFRva2VuVHlwZTtcbiAgICBpZiAobmV4dFRva2VuVHlwZSA9PT0gVG9rZW5UeXBlLkFUVFJfVkFMVUVfVEVYVCkge1xuICAgICAgdmFsdWVTdGFydFNwYW4gPSB0aGlzLl9wZWVrLnNvdXJjZVNwYW47XG4gICAgICB2YWx1ZUVuZCA9IHRoaXMuX3BlZWsuc291cmNlU3Bhbi5lbmQ7XG4gICAgICB3aGlsZSAoXG4gICAgICAgIHRoaXMuX3BlZWsudHlwZSA9PT0gVG9rZW5UeXBlLkFUVFJfVkFMVUVfVEVYVCB8fFxuICAgICAgICB0aGlzLl9wZWVrLnR5cGUgPT09IFRva2VuVHlwZS5BVFRSX1ZBTFVFX0lOVEVSUE9MQVRJT04gfHxcbiAgICAgICAgdGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuRU5DT0RFRF9FTlRJVFlcbiAgICAgICkge1xuICAgICAgICBjb25zdCB2YWx1ZVRva2VuID0gdGhpcy5fYWR2YW5jZTxJbnRlcnBvbGF0ZWRBdHRyaWJ1dGVUb2tlbj4oKTtcbiAgICAgICAgdmFsdWVUb2tlbnMucHVzaCh2YWx1ZVRva2VuKTtcbiAgICAgICAgaWYgKHZhbHVlVG9rZW4udHlwZSA9PT0gVG9rZW5UeXBlLkFUVFJfVkFMVUVfSU5URVJQT0xBVElPTikge1xuICAgICAgICAgIC8vIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdlIGRlY29kZSBIVE1MIGVudGl0aWVzIHRoYXQgYXBwZWFyIGluIGludGVycG9sYXRpb25cbiAgICAgICAgICAvLyBleHByZXNzaW9ucy4gVGhpcyBpcyBhcmd1YWJseSBhIGJ1ZywgYnV0IGl0IGNvdWxkIGJlIGEgY29uc2lkZXJhYmxlIGJyZWFraW5nIGNoYW5nZSB0b1xuICAgICAgICAgIC8vIGZpeCBpdC4gSXQgc2hvdWxkIGJlIGFkZHJlc3NlZCBpbiBhIGxhcmdlciBwcm9qZWN0IHRvIHJlZmFjdG9yIHRoZSBlbnRpcmUgcGFyc2VyL2xleGVyXG4gICAgICAgICAgLy8gY2hhaW4gYWZ0ZXIgVmlldyBFbmdpbmUgaGFzIGJlZW4gcmVtb3ZlZC5cbiAgICAgICAgICB2YWx1ZSArPSB2YWx1ZVRva2VuLnBhcnRzLmpvaW4oJycpLnJlcGxhY2UoLyYoW147XSspOy9nLCBkZWNvZGVFbnRpdHkpO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbHVlVG9rZW4udHlwZSA9PT0gVG9rZW5UeXBlLkVOQ09ERURfRU5USVRZKSB7XG4gICAgICAgICAgdmFsdWUgKz0gdmFsdWVUb2tlbi5wYXJ0c1swXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWx1ZSArPSB2YWx1ZVRva2VuLnBhcnRzLmpvaW4oJycpO1xuICAgICAgICB9XG4gICAgICAgIHZhbHVlRW5kID0gYXR0ckVuZCA9IHZhbHVlVG9rZW4uc291cmNlU3Bhbi5lbmQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ29uc3VtZSBhbnkgcXVvdGVcbiAgICBpZiAodGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuQVRUUl9RVU9URSkge1xuICAgICAgY29uc3QgcXVvdGVUb2tlbiA9IHRoaXMuX2FkdmFuY2U8QXR0cmlidXRlUXVvdGVUb2tlbj4oKTtcbiAgICAgIGF0dHJFbmQgPSBxdW90ZVRva2VuLnNvdXJjZVNwYW4uZW5kO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlU3BhbiA9XG4gICAgICB2YWx1ZVN0YXJ0U3BhbiAmJlxuICAgICAgdmFsdWVFbmQgJiZcbiAgICAgIG5ldyBQYXJzZVNvdXJjZVNwYW4odmFsdWVTdGFydFNwYW4uc3RhcnQsIHZhbHVlRW5kLCB2YWx1ZVN0YXJ0U3Bhbi5mdWxsU3RhcnQpO1xuICAgIHJldHVybiBuZXcgaHRtbC5BdHRyaWJ1dGUoXG4gICAgICBmdWxsTmFtZSxcbiAgICAgIHZhbHVlLFxuICAgICAgbmV3IFBhcnNlU291cmNlU3BhbihhdHRyTmFtZS5zb3VyY2VTcGFuLnN0YXJ0LCBhdHRyRW5kLCBhdHRyTmFtZS5zb3VyY2VTcGFuLmZ1bGxTdGFydCksXG4gICAgICBhdHRyTmFtZS5zb3VyY2VTcGFuLFxuICAgICAgdmFsdWVTcGFuLFxuICAgICAgdmFsdWVUb2tlbnMubGVuZ3RoID4gMCA/IHZhbHVlVG9rZW5zIDogdW5kZWZpbmVkLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIF9jb25zdW1lQmxvY2tPcGVuKHRva2VuOiBCbG9ja09wZW5TdGFydFRva2VuKSB7XG4gICAgY29uc3QgcGFyYW1ldGVyczogaHRtbC5CbG9ja1BhcmFtZXRlcltdID0gW107XG5cbiAgICB3aGlsZSAodGhpcy5fcGVlay50eXBlID09PSBUb2tlblR5cGUuQkxPQ0tfUEFSQU1FVEVSKSB7XG4gICAgICBjb25zdCBwYXJhbVRva2VuID0gdGhpcy5fYWR2YW5jZTxCbG9ja1BhcmFtZXRlclRva2VuPigpO1xuICAgICAgcGFyYW1ldGVycy5wdXNoKG5ldyBodG1sLkJsb2NrUGFyYW1ldGVyKHBhcmFtVG9rZW4ucGFydHNbMF0sIHBhcmFtVG9rZW4uc291cmNlU3BhbikpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9wZWVrLnR5cGUgPT09IFRva2VuVHlwZS5CTE9DS19PUEVOX0VORCkge1xuICAgICAgdGhpcy5fYWR2YW5jZSgpO1xuICAgIH1cblxuICAgIGNvbnN0IGVuZCA9IHRoaXMuX3BlZWsuc291cmNlU3Bhbi5mdWxsU3RhcnQ7XG4gICAgY29uc3Qgc3BhbiA9IG5ldyBQYXJzZVNvdXJjZVNwYW4odG9rZW4uc291cmNlU3Bhbi5zdGFydCwgZW5kLCB0b2tlbi5zb3VyY2VTcGFuLmZ1bGxTdGFydCk7XG4gICAgLy8gQ3JlYXRlIGEgc2VwYXJhdGUgYHN0YXJ0U3BhbmAgYmVjYXVzZSBgc3BhbmAgd2lsbCBiZSBtb2RpZmllZCB3aGVuIHRoZXJlIGlzIGFuIGBlbmRgIHNwYW4uXG4gICAgY29uc3Qgc3RhcnRTcGFuID0gbmV3IFBhcnNlU291cmNlU3Bhbih0b2tlbi5zb3VyY2VTcGFuLnN0YXJ0LCBlbmQsIHRva2VuLnNvdXJjZVNwYW4uZnVsbFN0YXJ0KTtcbiAgICBjb25zdCBibG9jayA9IG5ldyBodG1sLkJsb2NrKHRva2VuLnBhcnRzWzBdLCBwYXJhbWV0ZXJzLCBbXSwgc3BhbiwgdG9rZW4uc291cmNlU3Bhbiwgc3RhcnRTcGFuKTtcbiAgICB0aGlzLl9wdXNoQ29udGFpbmVyKGJsb2NrLCBmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIF9jb25zdW1lQmxvY2tDbG9zZSh0b2tlbjogQmxvY2tDbG9zZVRva2VuKSB7XG4gICAgaWYgKCF0aGlzLl9wb3BDb250YWluZXIobnVsbCwgaHRtbC5CbG9jaywgdG9rZW4uc291cmNlU3BhbikpIHtcbiAgICAgIHRoaXMuZXJyb3JzLnB1c2goXG4gICAgICAgIFRyZWVFcnJvci5jcmVhdGUoXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgICB0b2tlbi5zb3VyY2VTcGFuLFxuICAgICAgICAgIGBVbmV4cGVjdGVkIGNsb3NpbmcgYmxvY2suIFRoZSBibG9jayBtYXkgaGF2ZSBiZWVuIGNsb3NlZCBlYXJsaWVyLiBgICtcbiAgICAgICAgICAgIGBJZiB5b3UgbWVhbnQgdG8gd3JpdGUgdGhlIH0gY2hhcmFjdGVyLCB5b3Ugc2hvdWxkIHVzZSB0aGUgXCImIzEyNTtcIiBgICtcbiAgICAgICAgICAgIGBIVE1MIGVudGl0eSBpbnN0ZWFkLmAsXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2NvbnN1bWVJbmNvbXBsZXRlQmxvY2sodG9rZW46IEluY29tcGxldGVCbG9ja09wZW5Ub2tlbikge1xuICAgIGNvbnN0IHBhcmFtZXRlcnM6IGh0bWwuQmxvY2tQYXJhbWV0ZXJbXSA9IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMuX3BlZWsudHlwZSA9PT0gVG9rZW5UeXBlLkJMT0NLX1BBUkFNRVRFUikge1xuICAgICAgY29uc3QgcGFyYW1Ub2tlbiA9IHRoaXMuX2FkdmFuY2U8QmxvY2tQYXJhbWV0ZXJUb2tlbj4oKTtcbiAgICAgIHBhcmFtZXRlcnMucHVzaChuZXcgaHRtbC5CbG9ja1BhcmFtZXRlcihwYXJhbVRva2VuLnBhcnRzWzBdLCBwYXJhbVRva2VuLnNvdXJjZVNwYW4pKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbmQgPSB0aGlzLl9wZWVrLnNvdXJjZVNwYW4uZnVsbFN0YXJ0O1xuICAgIGNvbnN0IHNwYW4gPSBuZXcgUGFyc2VTb3VyY2VTcGFuKHRva2VuLnNvdXJjZVNwYW4uc3RhcnQsIGVuZCwgdG9rZW4uc291cmNlU3Bhbi5mdWxsU3RhcnQpO1xuICAgIC8vIENyZWF0ZSBhIHNlcGFyYXRlIGBzdGFydFNwYW5gIGJlY2F1c2UgYHNwYW5gIHdpbGwgYmUgbW9kaWZpZWQgd2hlbiB0aGVyZSBpcyBhbiBgZW5kYCBzcGFuLlxuICAgIGNvbnN0IHN0YXJ0U3BhbiA9IG5ldyBQYXJzZVNvdXJjZVNwYW4odG9rZW4uc291cmNlU3Bhbi5zdGFydCwgZW5kLCB0b2tlbi5zb3VyY2VTcGFuLmZ1bGxTdGFydCk7XG4gICAgY29uc3QgYmxvY2sgPSBuZXcgaHRtbC5CbG9jayh0b2tlbi5wYXJ0c1swXSwgcGFyYW1ldGVycywgW10sIHNwYW4sIHRva2VuLnNvdXJjZVNwYW4sIHN0YXJ0U3Bhbik7XG4gICAgdGhpcy5fcHVzaENvbnRhaW5lcihibG9jaywgZmFsc2UpO1xuXG4gICAgLy8gSW5jb21wbGV0ZSBibG9ja3MgZG9uJ3QgaGF2ZSBjaGlsZHJlbiBzbyB3ZSBjbG9zZSB0aGVtIGltbWVkaWF0ZWx5IGFuZCByZXBvcnQgYW4gZXJyb3IuXG4gICAgdGhpcy5fcG9wQ29udGFpbmVyKG51bGwsIGh0bWwuQmxvY2ssIG51bGwpO1xuXG4gICAgdGhpcy5lcnJvcnMucHVzaChcbiAgICAgIFRyZWVFcnJvci5jcmVhdGUoXG4gICAgICAgIHRva2VuLnBhcnRzWzBdLFxuICAgICAgICBzcGFuLFxuICAgICAgICBgSW5jb21wbGV0ZSBibG9jayBcIiR7dG9rZW4ucGFydHNbMF19XCIuIElmIHlvdSBtZWFudCB0byB3cml0ZSB0aGUgQCBjaGFyYWN0ZXIsIGAgK1xuICAgICAgICAgIGB5b3Ugc2hvdWxkIHVzZSB0aGUgXCImIzY0O1wiIEhUTUwgZW50aXR5IGluc3RlYWQuYCxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbnN1bWVMZXQoc3RhcnRUb2tlbjogTGV0U3RhcnRUb2tlbikge1xuICAgIGNvbnN0IG5hbWUgPSBzdGFydFRva2VuLnBhcnRzWzBdO1xuICAgIGxldCB2YWx1ZVRva2VuOiBMZXRWYWx1ZVRva2VuO1xuICAgIGxldCBlbmRUb2tlbjogTGV0RW5kVG9rZW47XG5cbiAgICBpZiAodGhpcy5fcGVlay50eXBlICE9PSBUb2tlblR5cGUuTEVUX1ZBTFVFKSB7XG4gICAgICB0aGlzLmVycm9ycy5wdXNoKFxuICAgICAgICBUcmVlRXJyb3IuY3JlYXRlKFxuICAgICAgICAgIHN0YXJ0VG9rZW4ucGFydHNbMF0sXG4gICAgICAgICAgc3RhcnRUb2tlbi5zb3VyY2VTcGFuLFxuICAgICAgICAgIGBJbnZhbGlkIEBsZXQgZGVjbGFyYXRpb24gXCIke25hbWV9XCIuIERlY2xhcmF0aW9uIG11c3QgaGF2ZSBhIHZhbHVlLmAsXG4gICAgICAgICksXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZVRva2VuID0gdGhpcy5fYWR2YW5jZSgpO1xuICAgIH1cblxuICAgIC8vIFR5cGUgY2FzdCBpcyBuZWNlc3NhcnkgaGVyZSBzaW5jZSBUUyBuYXJyb3dlZCB0aGUgdHlwZSBvZiBgcGVla2AgYWJvdmUuXG4gICAgaWYgKCh0aGlzLl9wZWVrIGFzIFRva2VuKS50eXBlICE9PSBUb2tlblR5cGUuTEVUX0VORCkge1xuICAgICAgdGhpcy5lcnJvcnMucHVzaChcbiAgICAgICAgVHJlZUVycm9yLmNyZWF0ZShcbiAgICAgICAgICBzdGFydFRva2VuLnBhcnRzWzBdLFxuICAgICAgICAgIHN0YXJ0VG9rZW4uc291cmNlU3BhbixcbiAgICAgICAgICBgVW50ZXJtaW5hdGVkIEBsZXQgZGVjbGFyYXRpb24gXCIke25hbWV9XCIuIERlY2xhcmF0aW9uIG11c3QgYmUgdGVybWluYXRlZCB3aXRoIGEgc2VtaWNvbG9uLmAsXG4gICAgICAgICksXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmRUb2tlbiA9IHRoaXMuX2FkdmFuY2UoKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbmQgPSBlbmRUb2tlbi5zb3VyY2VTcGFuLmZ1bGxTdGFydDtcbiAgICBjb25zdCBzcGFuID0gbmV3IFBhcnNlU291cmNlU3BhbihcbiAgICAgIHN0YXJ0VG9rZW4uc291cmNlU3Bhbi5zdGFydCxcbiAgICAgIGVuZCxcbiAgICAgIHN0YXJ0VG9rZW4uc291cmNlU3Bhbi5mdWxsU3RhcnQsXG4gICAgKTtcblxuICAgIC8vIFRoZSBzdGFydCB0b2tlbiB1c3VhbGx5IGNhcHR1cmVzIHRoZSBgQGxldGAuIENvbnN0cnVjdCBhIG5hbWUgc3BhbiBieVxuICAgIC8vIG9mZnNldHRpbmcgdGhlIHN0YXJ0IGJ5IHRoZSBsZW5ndGggb2YgYW55IHRleHQgYmVmb3JlIHRoZSBuYW1lLlxuICAgIGNvbnN0IHN0YXJ0T2Zmc2V0ID0gc3RhcnRUb2tlbi5zb3VyY2VTcGFuLnRvU3RyaW5nKCkubGFzdEluZGV4T2YobmFtZSk7XG4gICAgY29uc3QgbmFtZVN0YXJ0ID0gc3RhcnRUb2tlbi5zb3VyY2VTcGFuLnN0YXJ0Lm1vdmVCeShzdGFydE9mZnNldCk7XG4gICAgY29uc3QgbmFtZVNwYW4gPSBuZXcgUGFyc2VTb3VyY2VTcGFuKG5hbWVTdGFydCwgc3RhcnRUb2tlbi5zb3VyY2VTcGFuLmVuZCk7XG4gICAgY29uc3Qgbm9kZSA9IG5ldyBodG1sLkxldERlY2xhcmF0aW9uKFxuICAgICAgbmFtZSxcbiAgICAgIHZhbHVlVG9rZW4ucGFydHNbMF0sXG4gICAgICBzcGFuLFxuICAgICAgbmFtZVNwYW4sXG4gICAgICB2YWx1ZVRva2VuLnNvdXJjZVNwYW4sXG4gICAgKTtcblxuICAgIHRoaXMuX2FkZFRvUGFyZW50KG5vZGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY29uc3VtZUluY29tcGxldGVMZXQodG9rZW46IEluY29tcGxldGVMZXRUb2tlbikge1xuICAgIC8vIEluY29tcGxldGUgYEBsZXRgIGRlY2xhcmF0aW9uIG1heSBlbmQgdXAgd2l0aCBhbiBlbXB0eSBuYW1lLlxuICAgIGNvbnN0IG5hbWUgPSB0b2tlbi5wYXJ0c1swXSA/PyAnJztcbiAgICBjb25zdCBuYW1lU3RyaW5nID0gbmFtZSA/IGAgXCIke25hbWV9XCJgIDogJyc7XG5cbiAgICAvLyBJZiB0aGVyZSdzIGF0IGxlYXN0IGEgbmFtZSwgd2UgY2FuIHNhbHZhZ2UgYW4gQVNUIG5vZGUgdGhhdCBjYW4gYmUgdXNlZCBmb3IgY29tcGxldGlvbnMuXG4gICAgaWYgKG5hbWUubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3Qgc3RhcnRPZmZzZXQgPSB0b2tlbi5zb3VyY2VTcGFuLnRvU3RyaW5nKCkubGFzdEluZGV4T2YobmFtZSk7XG4gICAgICBjb25zdCBuYW1lU3RhcnQgPSB0b2tlbi5zb3VyY2VTcGFuLnN0YXJ0Lm1vdmVCeShzdGFydE9mZnNldCk7XG4gICAgICBjb25zdCBuYW1lU3BhbiA9IG5ldyBQYXJzZVNvdXJjZVNwYW4obmFtZVN0YXJ0LCB0b2tlbi5zb3VyY2VTcGFuLmVuZCk7XG4gICAgICBjb25zdCB2YWx1ZVNwYW4gPSBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgICB0b2tlbi5zb3VyY2VTcGFuLnN0YXJ0LFxuICAgICAgICB0b2tlbi5zb3VyY2VTcGFuLnN0YXJ0Lm1vdmVCeSgwKSxcbiAgICAgICk7XG4gICAgICBjb25zdCBub2RlID0gbmV3IGh0bWwuTGV0RGVjbGFyYXRpb24obmFtZSwgJycsIHRva2VuLnNvdXJjZVNwYW4sIG5hbWVTcGFuLCB2YWx1ZVNwYW4pO1xuICAgICAgdGhpcy5fYWRkVG9QYXJlbnQobm9kZSk7XG4gICAgfVxuXG4gICAgdGhpcy5lcnJvcnMucHVzaChcbiAgICAgIFRyZWVFcnJvci5jcmVhdGUoXG4gICAgICAgIHRva2VuLnBhcnRzWzBdLFxuICAgICAgICB0b2tlbi5zb3VyY2VTcGFuLFxuICAgICAgICBgSW5jb21wbGV0ZSBAbGV0IGRlY2xhcmF0aW9uJHtuYW1lU3RyaW5nfS4gYCArXG4gICAgICAgICAgYEBsZXQgZGVjbGFyYXRpb25zIG11c3QgYmUgd3JpdHRlbiBhcyBcXGBAbGV0IDxuYW1lPiA9IDx2YWx1ZT47XFxgYCxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldENvbnRhaW5lcigpOiBOb2RlQ29udGFpbmVyIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbnRhaW5lclN0YWNrLmxlbmd0aCA+IDBcbiAgICAgID8gdGhpcy5fY29udGFpbmVyU3RhY2tbdGhpcy5fY29udGFpbmVyU3RhY2subGVuZ3RoIC0gMV1cbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgX2dldENsb3Nlc3RQYXJlbnRFbGVtZW50KCk6IGh0bWwuRWxlbWVudCB8IG51bGwge1xuICAgIGZvciAobGV0IGkgPSB0aGlzLl9jb250YWluZXJTdGFjay5sZW5ndGggLSAxOyBpID4gLTE7IGktLSkge1xuICAgICAgaWYgKHRoaXMuX2NvbnRhaW5lclN0YWNrW2ldIGluc3RhbmNlb2YgaHRtbC5FbGVtZW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250YWluZXJTdGFja1tpXSBhcyBodG1sLkVsZW1lbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9hZGRUb1BhcmVudChub2RlOiBodG1sLk5vZGUpIHtcbiAgICBjb25zdCBwYXJlbnQgPSB0aGlzLl9nZXRDb250YWluZXIoKTtcblxuICAgIGlmIChwYXJlbnQgPT09IG51bGwpIHtcbiAgICAgIHRoaXMucm9vdE5vZGVzLnB1c2gobm9kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcmVudC5jaGlsZHJlbi5wdXNoKG5vZGUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2dldEVsZW1lbnRGdWxsTmFtZShcbiAgICBwcmVmaXg6IHN0cmluZyxcbiAgICBsb2NhbE5hbWU6IHN0cmluZyxcbiAgICBwYXJlbnRFbGVtZW50OiBodG1sLkVsZW1lbnQgfCBudWxsLFxuICApOiBzdHJpbmcge1xuICAgIGlmIChwcmVmaXggPT09ICcnKSB7XG4gICAgICBwcmVmaXggPSB0aGlzLmdldFRhZ0RlZmluaXRpb24obG9jYWxOYW1lKS5pbXBsaWNpdE5hbWVzcGFjZVByZWZpeCB8fCAnJztcbiAgICAgIGlmIChwcmVmaXggPT09ICcnICYmIHBhcmVudEVsZW1lbnQgIT0gbnVsbCkge1xuICAgICAgICBjb25zdCBwYXJlbnRUYWdOYW1lID0gc3BsaXROc05hbWUocGFyZW50RWxlbWVudC5uYW1lKVsxXTtcbiAgICAgICAgY29uc3QgcGFyZW50VGFnRGVmaW5pdGlvbiA9IHRoaXMuZ2V0VGFnRGVmaW5pdGlvbihwYXJlbnRUYWdOYW1lKTtcbiAgICAgICAgaWYgKCFwYXJlbnRUYWdEZWZpbml0aW9uLnByZXZlbnROYW1lc3BhY2VJbmhlcml0YW5jZSkge1xuICAgICAgICAgIHByZWZpeCA9IGdldE5zUHJlZml4KHBhcmVudEVsZW1lbnQubmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbWVyZ2VOc0FuZE5hbWUocHJlZml4LCBsb2NhbE5hbWUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGxhc3RPblN0YWNrKHN0YWNrOiBhbnlbXSwgZWxlbWVudDogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiBzdGFjay5sZW5ndGggPiAwICYmIHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdID09PSBlbGVtZW50O1xufVxuXG4vKipcbiAqIERlY29kZSB0aGUgYGVudGl0eWAgc3RyaW5nLCB3aGljaCB3ZSBiZWxpZXZlIGlzIHRoZSBjb250ZW50cyBvZiBhbiBIVE1MIGVudGl0eS5cbiAqXG4gKiBJZiB0aGUgc3RyaW5nIGlzIG5vdCBhY3R1YWxseSBhIHZhbGlkL2tub3duIGVudGl0eSB0aGVuIGp1c3QgcmV0dXJuIHRoZSBvcmlnaW5hbCBgbWF0Y2hgIHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gZGVjb2RlRW50aXR5KG1hdGNoOiBzdHJpbmcsIGVudGl0eTogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKE5BTUVEX0VOVElUSUVTW2VudGl0eV0gIT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBOQU1FRF9FTlRJVElFU1tlbnRpdHldIHx8IG1hdGNoO1xuICB9XG4gIGlmICgvXiN4W2EtZjAtOV0rJC9pLnRlc3QoZW50aXR5KSkge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNvZGVQb2ludChwYXJzZUludChlbnRpdHkuc2xpY2UoMiksIDE2KSk7XG4gIH1cbiAgaWYgKC9eI1xcZCskLy50ZXN0KGVudGl0eSkpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21Db2RlUG9pbnQocGFyc2VJbnQoZW50aXR5LnNsaWNlKDEpLCAxMCkpO1xuICB9XG4gIHJldHVybiBtYXRjaDtcbn1cbiJdfQ==