@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,1058 +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 { SecurityContext } from '../../../core';
9
- import * as e from '../../../expression_parser/ast';
10
- import * as i18n from '../../../i18n/i18n_ast';
11
- import { splitNsName } from '../../../ml_parser/tags';
12
- import * as o from '../../../output/output_ast';
13
- import { ParseSourceSpan } from '../../../parse_util';
14
- import * as t from '../../../render3/r3_ast';
15
- import { icuFromI18nMessage } from '../../../render3/view/i18n/util';
16
- import { DomElementSchemaRegistry } from '../../../schema/dom_element_schema_registry';
17
- import * as ir from '../ir';
18
- import { ComponentCompilationJob, HostBindingCompilationJob, } from './compilation';
19
- import { BINARY_OPERATORS, namespaceForKey, prefixWithNamespace } from './conversion';
20
- const compatibilityMode = ir.CompatibilityMode.TemplateDefinitionBuilder;
21
- // Schema containing DOM elements and their properties.
22
- const domSchema = new DomElementSchemaRegistry();
23
- // Tag name of the `ng-template` element.
24
- const NG_TEMPLATE_TAG_NAME = 'ng-template';
25
- export function isI18nRootNode(meta) {
26
- return meta instanceof i18n.Message;
27
- }
28
- export function isSingleI18nIcu(meta) {
29
- return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof i18n.Icu;
30
- }
31
- /**
32
- * Process a template AST and convert it into a `ComponentCompilation` in the intermediate
33
- * representation.
34
- * TODO: Refactor more of the ingestion code into phases.
35
- */
36
- export function ingestComponent(componentName, template, constantPool, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn) {
37
- const job = new ComponentCompilationJob(componentName, constantPool, compatibilityMode, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn);
38
- ingestNodes(job.root, template);
39
- return job;
40
- }
41
- /**
42
- * Process a host binding AST and convert it into a `HostBindingCompilationJob` in the intermediate
43
- * representation.
44
- */
45
- export function ingestHostBinding(input, bindingParser, constantPool) {
46
- const job = new HostBindingCompilationJob(input.componentName, constantPool, compatibilityMode);
47
- for (const property of input.properties ?? []) {
48
- let bindingKind = ir.BindingKind.Property;
49
- // TODO: this should really be handled in the parser.
50
- if (property.name.startsWith('attr.')) {
51
- property.name = property.name.substring('attr.'.length);
52
- bindingKind = ir.BindingKind.Attribute;
53
- }
54
- if (property.isAnimation) {
55
- bindingKind = ir.BindingKind.Animation;
56
- }
57
- const securityContexts = bindingParser
58
- .calcPossibleSecurityContexts(input.componentSelector, property.name, bindingKind === ir.BindingKind.Attribute)
59
- .filter((context) => context !== SecurityContext.NONE);
60
- ingestHostProperty(job, property, bindingKind, securityContexts);
61
- }
62
- for (const [name, expr] of Object.entries(input.attributes) ?? []) {
63
- const securityContexts = bindingParser
64
- .calcPossibleSecurityContexts(input.componentSelector, name, true)
65
- .filter((context) => context !== SecurityContext.NONE);
66
- ingestHostAttribute(job, name, expr, securityContexts);
67
- }
68
- for (const event of input.events ?? []) {
69
- ingestHostEvent(job, event);
70
- }
71
- return job;
72
- }
73
- // TODO: We should refactor the parser to use the same types and structures for host bindings as
74
- // with ordinary components. This would allow us to share a lot more ingestion code.
75
- export function ingestHostProperty(job, property, bindingKind, securityContexts) {
76
- let expression;
77
- const ast = property.expression.ast;
78
- if (ast instanceof e.Interpolation) {
79
- expression = new ir.Interpolation(ast.strings, ast.expressions.map((expr) => convertAst(expr, job, property.sourceSpan)), []);
80
- }
81
- else {
82
- expression = convertAst(ast, job, property.sourceSpan);
83
- }
84
- job.root.update.push(ir.createBindingOp(job.root.xref, bindingKind, property.name, expression, null, securityContexts, false, false, null,
85
- /* TODO: How do Host bindings handle i18n attrs? */ null, property.sourceSpan));
86
- }
87
- export function ingestHostAttribute(job, name, value, securityContexts) {
88
- const attrBinding = ir.createBindingOp(job.root.xref, ir.BindingKind.Attribute, name, value, null, securityContexts,
89
- /* Host attributes should always be extracted to const hostAttrs, even if they are not
90
- *strictly* text literals */
91
- true, false, null,
92
- /* TODO */ null,
93
- /** TODO: May be null? */ value.sourceSpan);
94
- job.root.update.push(attrBinding);
95
- }
96
- export function ingestHostEvent(job, event) {
97
- const [phase, target] = event.type !== e.ParsedEventType.Animation
98
- ? [null, event.targetOrPhase]
99
- : [event.targetOrPhase, null];
100
- const eventBinding = ir.createListenerOp(job.root.xref, new ir.SlotHandle(), event.name, null, makeListenerHandlerOps(job.root, event.handler, event.handlerSpan), phase, target, true, event.sourceSpan);
101
- job.root.create.push(eventBinding);
102
- }
103
- /**
104
- * Ingest the nodes of a template AST into the given `ViewCompilation`.
105
- */
106
- function ingestNodes(unit, template) {
107
- for (const node of template) {
108
- if (node instanceof t.Element) {
109
- ingestElement(unit, node);
110
- }
111
- else if (node instanceof t.Template) {
112
- ingestTemplate(unit, node);
113
- }
114
- else if (node instanceof t.Content) {
115
- ingestContent(unit, node);
116
- }
117
- else if (node instanceof t.Text) {
118
- ingestText(unit, node, null);
119
- }
120
- else if (node instanceof t.BoundText) {
121
- ingestBoundText(unit, node, null);
122
- }
123
- else if (node instanceof t.IfBlock) {
124
- ingestIfBlock(unit, node);
125
- }
126
- else if (node instanceof t.SwitchBlock) {
127
- ingestSwitchBlock(unit, node);
128
- }
129
- else if (node instanceof t.DeferredBlock) {
130
- ingestDeferBlock(unit, node);
131
- }
132
- else if (node instanceof t.Icu) {
133
- ingestIcu(unit, node);
134
- }
135
- else if (node instanceof t.ForLoopBlock) {
136
- ingestForBlock(unit, node);
137
- }
138
- else if (node instanceof t.LetDeclaration) {
139
- ingestLetDeclaration(unit, node);
140
- }
141
- else {
142
- throw new Error(`Unsupported template node: ${node.constructor.name}`);
143
- }
144
- }
145
- }
146
- /**
147
- * Ingest an element AST from the template into the given `ViewCompilation`.
148
- */
149
- function ingestElement(unit, element) {
150
- if (element.i18n !== undefined &&
151
- !(element.i18n instanceof i18n.Message || element.i18n instanceof i18n.TagPlaceholder)) {
152
- throw Error(`Unhandled i18n metadata type for element: ${element.i18n.constructor.name}`);
153
- }
154
- const id = unit.job.allocateXrefId();
155
- const [namespaceKey, elementName] = splitNsName(element.name);
156
- const startOp = ir.createElementStartOp(elementName, id, namespaceForKey(namespaceKey), element.i18n instanceof i18n.TagPlaceholder ? element.i18n : undefined, element.startSourceSpan, element.sourceSpan);
157
- unit.create.push(startOp);
158
- ingestElementBindings(unit, startOp, element);
159
- ingestReferences(startOp, element);
160
- // Start i18n, if needed, goes after the element create and bindings, but before the nodes
161
- let i18nBlockId = null;
162
- if (element.i18n instanceof i18n.Message) {
163
- i18nBlockId = unit.job.allocateXrefId();
164
- unit.create.push(ir.createI18nStartOp(i18nBlockId, element.i18n, undefined, element.startSourceSpan));
165
- }
166
- ingestNodes(unit, element.children);
167
- // The source span for the end op is typically the element closing tag. However, if no closing tag
168
- // exists, such as in `<input>`, we use the start source span instead. Usually the start and end
169
- // instructions will be collapsed into one `element` instruction, negating the purpose of this
170
- // fallback, but in cases when it is not collapsed (such as an input with a binding), we still
171
- // want to map the end instruction to the main element.
172
- const endOp = ir.createElementEndOp(id, element.endSourceSpan ?? element.startSourceSpan);
173
- unit.create.push(endOp);
174
- // If there is an i18n message associated with this element, insert i18n start and end ops.
175
- if (i18nBlockId !== null) {
176
- ir.OpList.insertBefore(ir.createI18nEndOp(i18nBlockId, element.endSourceSpan ?? element.startSourceSpan), endOp);
177
- }
178
- }
179
- /**
180
- * Ingest an `ng-template` node from the AST into the given `ViewCompilation`.
181
- */
182
- function ingestTemplate(unit, tmpl) {
183
- if (tmpl.i18n !== undefined &&
184
- !(tmpl.i18n instanceof i18n.Message || tmpl.i18n instanceof i18n.TagPlaceholder)) {
185
- throw Error(`Unhandled i18n metadata type for template: ${tmpl.i18n.constructor.name}`);
186
- }
187
- const childView = unit.job.allocateView(unit.xref);
188
- let tagNameWithoutNamespace = tmpl.tagName;
189
- let namespacePrefix = '';
190
- if (tmpl.tagName) {
191
- [namespacePrefix, tagNameWithoutNamespace] = splitNsName(tmpl.tagName);
192
- }
193
- const i18nPlaceholder = tmpl.i18n instanceof i18n.TagPlaceholder ? tmpl.i18n : undefined;
194
- const namespace = namespaceForKey(namespacePrefix);
195
- const functionNameSuffix = tagNameWithoutNamespace === null ? '' : prefixWithNamespace(tagNameWithoutNamespace, namespace);
196
- const templateKind = isPlainTemplate(tmpl)
197
- ? ir.TemplateKind.NgTemplate
198
- : ir.TemplateKind.Structural;
199
- const templateOp = ir.createTemplateOp(childView.xref, templateKind, tagNameWithoutNamespace, functionNameSuffix, namespace, i18nPlaceholder, tmpl.startSourceSpan, tmpl.sourceSpan);
200
- unit.create.push(templateOp);
201
- ingestTemplateBindings(unit, templateOp, tmpl, templateKind);
202
- ingestReferences(templateOp, tmpl);
203
- ingestNodes(childView, tmpl.children);
204
- for (const { name, value } of tmpl.variables) {
205
- childView.contextVariables.set(name, value !== '' ? value : '$implicit');
206
- }
207
- // If this is a plain template and there is an i18n message associated with it, insert i18n start
208
- // and end ops. For structural directive templates, the i18n ops will be added when ingesting the
209
- // element/template the directive is placed on.
210
- if (templateKind === ir.TemplateKind.NgTemplate && tmpl.i18n instanceof i18n.Message) {
211
- const id = unit.job.allocateXrefId();
212
- ir.OpList.insertAfter(ir.createI18nStartOp(id, tmpl.i18n, undefined, tmpl.startSourceSpan), childView.create.head);
213
- ir.OpList.insertBefore(ir.createI18nEndOp(id, tmpl.endSourceSpan ?? tmpl.startSourceSpan), childView.create.tail);
214
- }
215
- }
216
- /**
217
- * Ingest a content node from the AST into the given `ViewCompilation`.
218
- */
219
- function ingestContent(unit, content) {
220
- if (content.i18n !== undefined && !(content.i18n instanceof i18n.TagPlaceholder)) {
221
- throw Error(`Unhandled i18n metadata type for element: ${content.i18n.constructor.name}`);
222
- }
223
- let fallbackView = null;
224
- // Don't capture default content that's only made up of empty text nodes and comments.
225
- // Note that we process the default content before the projection in order to match the
226
- // insertion order at runtime.
227
- if (content.children.some((child) => !(child instanceof t.Comment) &&
228
- (!(child instanceof t.Text) || child.value.trim().length > 0))) {
229
- fallbackView = unit.job.allocateView(unit.xref);
230
- ingestNodes(fallbackView, content.children);
231
- }
232
- const id = unit.job.allocateXrefId();
233
- const op = ir.createProjectionOp(id, content.selector, content.i18n, fallbackView?.xref ?? null, content.sourceSpan);
234
- for (const attr of content.attributes) {
235
- const securityContext = domSchema.securityContext(content.name, attr.name, true);
236
- unit.update.push(ir.createBindingOp(op.xref, ir.BindingKind.Attribute, attr.name, o.literal(attr.value), null, securityContext, true, false, null, asMessage(attr.i18n), attr.sourceSpan));
237
- }
238
- unit.create.push(op);
239
- }
240
- /**
241
- * Ingest a literal text node from the AST into the given `ViewCompilation`.
242
- */
243
- function ingestText(unit, text, icuPlaceholder) {
244
- unit.create.push(ir.createTextOp(unit.job.allocateXrefId(), text.value, icuPlaceholder, text.sourceSpan));
245
- }
246
- /**
247
- * Ingest an interpolated text node from the AST into the given `ViewCompilation`.
248
- */
249
- function ingestBoundText(unit, text, icuPlaceholder) {
250
- let value = text.value;
251
- if (value instanceof e.ASTWithSource) {
252
- value = value.ast;
253
- }
254
- if (!(value instanceof e.Interpolation)) {
255
- throw new Error(`AssertionError: expected Interpolation for BoundText node, got ${value.constructor.name}`);
256
- }
257
- if (text.i18n !== undefined && !(text.i18n instanceof i18n.Container)) {
258
- throw Error(`Unhandled i18n metadata type for text interpolation: ${text.i18n?.constructor.name}`);
259
- }
260
- const i18nPlaceholders = text.i18n instanceof i18n.Container
261
- ? text.i18n.children
262
- .filter((node) => node instanceof i18n.Placeholder)
263
- .map((placeholder) => placeholder.name)
264
- : [];
265
- if (i18nPlaceholders.length > 0 && i18nPlaceholders.length !== value.expressions.length) {
266
- throw Error(`Unexpected number of i18n placeholders (${value.expressions.length}) for BoundText with ${value.expressions.length} expressions`);
267
- }
268
- const textXref = unit.job.allocateXrefId();
269
- unit.create.push(ir.createTextOp(textXref, '', icuPlaceholder, text.sourceSpan));
270
- // TemplateDefinitionBuilder does not generate source maps for sub-expressions inside an
271
- // interpolation. We copy that behavior in compatibility mode.
272
- // TODO: is it actually correct to generate these extra maps in modern mode?
273
- const baseSourceSpan = unit.job.compatibility ? null : text.sourceSpan;
274
- unit.update.push(ir.createInterpolateTextOp(textXref, new ir.Interpolation(value.strings, value.expressions.map((expr) => convertAst(expr, unit.job, baseSourceSpan)), i18nPlaceholders), text.sourceSpan));
275
- }
276
- /**
277
- * Ingest an `@if` block into the given `ViewCompilation`.
278
- */
279
- function ingestIfBlock(unit, ifBlock) {
280
- let firstXref = null;
281
- let conditions = [];
282
- for (let i = 0; i < ifBlock.branches.length; i++) {
283
- const ifCase = ifBlock.branches[i];
284
- const cView = unit.job.allocateView(unit.xref);
285
- const tagName = ingestControlFlowInsertionPoint(unit, cView.xref, ifCase);
286
- if (ifCase.expressionAlias !== null) {
287
- cView.contextVariables.set(ifCase.expressionAlias.name, ir.CTX_REF);
288
- }
289
- let ifCaseI18nMeta = undefined;
290
- if (ifCase.i18n !== undefined) {
291
- if (!(ifCase.i18n instanceof i18n.BlockPlaceholder)) {
292
- throw Error(`Unhandled i18n metadata type for if block: ${ifCase.i18n?.constructor.name}`);
293
- }
294
- ifCaseI18nMeta = ifCase.i18n;
295
- }
296
- const templateOp = ir.createTemplateOp(cView.xref, ir.TemplateKind.Block, tagName, 'Conditional', ir.Namespace.HTML, ifCaseI18nMeta, ifCase.startSourceSpan, ifCase.sourceSpan);
297
- unit.create.push(templateOp);
298
- if (firstXref === null) {
299
- firstXref = cView.xref;
300
- }
301
- const caseExpr = ifCase.expression ? convertAst(ifCase.expression, unit.job, null) : null;
302
- const conditionalCaseExpr = new ir.ConditionalCaseExpr(caseExpr, templateOp.xref, templateOp.handle, ifCase.expressionAlias);
303
- conditions.push(conditionalCaseExpr);
304
- ingestNodes(cView, ifCase.children);
305
- }
306
- unit.update.push(ir.createConditionalOp(firstXref, null, conditions, ifBlock.sourceSpan));
307
- }
308
- /**
309
- * Ingest an `@switch` block into the given `ViewCompilation`.
310
- */
311
- function ingestSwitchBlock(unit, switchBlock) {
312
- // Don't ingest empty switches since they won't render anything.
313
- if (switchBlock.cases.length === 0) {
314
- return;
315
- }
316
- let firstXref = null;
317
- let conditions = [];
318
- for (const switchCase of switchBlock.cases) {
319
- const cView = unit.job.allocateView(unit.xref);
320
- const tagName = ingestControlFlowInsertionPoint(unit, cView.xref, switchCase);
321
- let switchCaseI18nMeta = undefined;
322
- if (switchCase.i18n !== undefined) {
323
- if (!(switchCase.i18n instanceof i18n.BlockPlaceholder)) {
324
- throw Error(`Unhandled i18n metadata type for switch block: ${switchCase.i18n?.constructor.name}`);
325
- }
326
- switchCaseI18nMeta = switchCase.i18n;
327
- }
328
- const templateOp = ir.createTemplateOp(cView.xref, ir.TemplateKind.Block, tagName, 'Case', ir.Namespace.HTML, switchCaseI18nMeta, switchCase.startSourceSpan, switchCase.sourceSpan);
329
- unit.create.push(templateOp);
330
- if (firstXref === null) {
331
- firstXref = cView.xref;
332
- }
333
- const caseExpr = switchCase.expression
334
- ? convertAst(switchCase.expression, unit.job, switchBlock.startSourceSpan)
335
- : null;
336
- const conditionalCaseExpr = new ir.ConditionalCaseExpr(caseExpr, templateOp.xref, templateOp.handle);
337
- conditions.push(conditionalCaseExpr);
338
- ingestNodes(cView, switchCase.children);
339
- }
340
- unit.update.push(ir.createConditionalOp(firstXref, convertAst(switchBlock.expression, unit.job, null), conditions, switchBlock.sourceSpan));
341
- }
342
- function ingestDeferView(unit, suffix, i18nMeta, children, sourceSpan) {
343
- if (i18nMeta !== undefined && !(i18nMeta instanceof i18n.BlockPlaceholder)) {
344
- throw Error('Unhandled i18n metadata type for defer block');
345
- }
346
- if (children === undefined) {
347
- return null;
348
- }
349
- const secondaryView = unit.job.allocateView(unit.xref);
350
- ingestNodes(secondaryView, children);
351
- const templateOp = ir.createTemplateOp(secondaryView.xref, ir.TemplateKind.Block, null, `Defer${suffix}`, ir.Namespace.HTML, i18nMeta, sourceSpan, sourceSpan);
352
- unit.create.push(templateOp);
353
- return templateOp;
354
- }
355
- function ingestDeferBlock(unit, deferBlock) {
356
- let ownResolverFn = null;
357
- if (unit.job.deferMeta.mode === 0 /* DeferBlockDepsEmitMode.PerBlock */) {
358
- if (!unit.job.deferMeta.blocks.has(deferBlock)) {
359
- throw new Error(`AssertionError: unable to find a dependency function for this deferred block`);
360
- }
361
- ownResolverFn = unit.job.deferMeta.blocks.get(deferBlock) ?? null;
362
- }
363
- // Generate the defer main view and all secondary views.
364
- const main = ingestDeferView(unit, '', deferBlock.i18n, deferBlock.children, deferBlock.sourceSpan);
365
- const loading = ingestDeferView(unit, 'Loading', deferBlock.loading?.i18n, deferBlock.loading?.children, deferBlock.loading?.sourceSpan);
366
- const placeholder = ingestDeferView(unit, 'Placeholder', deferBlock.placeholder?.i18n, deferBlock.placeholder?.children, deferBlock.placeholder?.sourceSpan);
367
- const error = ingestDeferView(unit, 'Error', deferBlock.error?.i18n, deferBlock.error?.children, deferBlock.error?.sourceSpan);
368
- // Create the main defer op, and ops for all secondary views.
369
- const deferXref = unit.job.allocateXrefId();
370
- const deferOp = ir.createDeferOp(deferXref, main.xref, main.handle, ownResolverFn, unit.job.allDeferrableDepsFn, deferBlock.sourceSpan);
371
- deferOp.placeholderView = placeholder?.xref ?? null;
372
- deferOp.placeholderSlot = placeholder?.handle ?? null;
373
- deferOp.loadingSlot = loading?.handle ?? null;
374
- deferOp.errorSlot = error?.handle ?? null;
375
- deferOp.placeholderMinimumTime = deferBlock.placeholder?.minimumTime ?? null;
376
- deferOp.loadingMinimumTime = deferBlock.loading?.minimumTime ?? null;
377
- deferOp.loadingAfterTime = deferBlock.loading?.afterTime ?? null;
378
- unit.create.push(deferOp);
379
- // Configure all defer `on` conditions.
380
- // TODO: refactor prefetch triggers to use a separate op type, with a shared superclass. This will
381
- // make it easier to refactor prefetch behavior in the future.
382
- let prefetch = false;
383
- let deferOnOps = [];
384
- let deferWhenOps = [];
385
- for (const triggers of [deferBlock.triggers, deferBlock.prefetchTriggers]) {
386
- if (triggers.idle !== undefined) {
387
- const deferOnOp = ir.createDeferOnOp(deferXref, { kind: ir.DeferTriggerKind.Idle }, prefetch, triggers.idle.sourceSpan);
388
- deferOnOps.push(deferOnOp);
389
- }
390
- if (triggers.immediate !== undefined) {
391
- const deferOnOp = ir.createDeferOnOp(deferXref, { kind: ir.DeferTriggerKind.Immediate }, prefetch, triggers.immediate.sourceSpan);
392
- deferOnOps.push(deferOnOp);
393
- }
394
- if (triggers.timer !== undefined) {
395
- const deferOnOp = ir.createDeferOnOp(deferXref, { kind: ir.DeferTriggerKind.Timer, delay: triggers.timer.delay }, prefetch, triggers.timer.sourceSpan);
396
- deferOnOps.push(deferOnOp);
397
- }
398
- if (triggers.hover !== undefined) {
399
- const deferOnOp = ir.createDeferOnOp(deferXref, {
400
- kind: ir.DeferTriggerKind.Hover,
401
- targetName: triggers.hover.reference,
402
- targetXref: null,
403
- targetSlot: null,
404
- targetView: null,
405
- targetSlotViewSteps: null,
406
- }, prefetch, triggers.hover.sourceSpan);
407
- deferOnOps.push(deferOnOp);
408
- }
409
- if (triggers.interaction !== undefined) {
410
- const deferOnOp = ir.createDeferOnOp(deferXref, {
411
- kind: ir.DeferTriggerKind.Interaction,
412
- targetName: triggers.interaction.reference,
413
- targetXref: null,
414
- targetSlot: null,
415
- targetView: null,
416
- targetSlotViewSteps: null,
417
- }, prefetch, triggers.interaction.sourceSpan);
418
- deferOnOps.push(deferOnOp);
419
- }
420
- if (triggers.viewport !== undefined) {
421
- const deferOnOp = ir.createDeferOnOp(deferXref, {
422
- kind: ir.DeferTriggerKind.Viewport,
423
- targetName: triggers.viewport.reference,
424
- targetXref: null,
425
- targetSlot: null,
426
- targetView: null,
427
- targetSlotViewSteps: null,
428
- }, prefetch, triggers.viewport.sourceSpan);
429
- deferOnOps.push(deferOnOp);
430
- }
431
- if (triggers.when !== undefined) {
432
- if (triggers.when.value instanceof e.Interpolation) {
433
- // TemplateDefinitionBuilder supports this case, but it's very strange to me. What would it
434
- // even mean?
435
- throw new Error(`Unexpected interpolation in defer block when trigger`);
436
- }
437
- const deferOnOp = ir.createDeferWhenOp(deferXref, convertAst(triggers.when.value, unit.job, triggers.when.sourceSpan), prefetch, triggers.when.sourceSpan);
438
- deferWhenOps.push(deferOnOp);
439
- }
440
- // If no (non-prefetching) defer triggers were provided, default to `idle`.
441
- if (deferOnOps.length === 0 && deferWhenOps.length === 0) {
442
- deferOnOps.push(ir.createDeferOnOp(deferXref, { kind: ir.DeferTriggerKind.Idle }, false, null));
443
- }
444
- prefetch = true;
445
- }
446
- unit.create.push(deferOnOps);
447
- unit.update.push(deferWhenOps);
448
- }
449
- function ingestIcu(unit, icu) {
450
- if (icu.i18n instanceof i18n.Message && isSingleI18nIcu(icu.i18n)) {
451
- const xref = unit.job.allocateXrefId();
452
- unit.create.push(ir.createIcuStartOp(xref, icu.i18n, icuFromI18nMessage(icu.i18n).name, null));
453
- for (const [placeholder, text] of Object.entries({ ...icu.vars, ...icu.placeholders })) {
454
- if (text instanceof t.BoundText) {
455
- ingestBoundText(unit, text, placeholder);
456
- }
457
- else {
458
- ingestText(unit, text, placeholder);
459
- }
460
- }
461
- unit.create.push(ir.createIcuEndOp(xref));
462
- }
463
- else {
464
- throw Error(`Unhandled i18n metadata type for ICU: ${icu.i18n?.constructor.name}`);
465
- }
466
- }
467
- /**
468
- * Ingest an `@for` block into the given `ViewCompilation`.
469
- */
470
- function ingestForBlock(unit, forBlock) {
471
- const repeaterView = unit.job.allocateView(unit.xref);
472
- // We copy TemplateDefinitionBuilder's scheme of creating names for `$count` and `$index`
473
- // that are suffixed with special information, to disambiguate which level of nested loop
474
- // the below aliases refer to.
475
- // TODO: We should refactor Template Pipeline's variable phases to gracefully handle
476
- // shadowing, and arbitrarily many levels of variables depending on each other.
477
- const indexName = `ɵ$index_${repeaterView.xref}`;
478
- const countName = `ɵ$count_${repeaterView.xref}`;
479
- const indexVarNames = new Set();
480
- // Set all the context variables and aliases available in the repeater.
481
- repeaterView.contextVariables.set(forBlock.item.name, forBlock.item.value);
482
- for (const variable of forBlock.contextVariables) {
483
- if (variable.value === '$index') {
484
- indexVarNames.add(variable.name);
485
- }
486
- if (variable.name === '$index') {
487
- repeaterView.contextVariables.set('$index', variable.value).set(indexName, variable.value);
488
- }
489
- else if (variable.name === '$count') {
490
- repeaterView.contextVariables.set('$count', variable.value).set(countName, variable.value);
491
- }
492
- else {
493
- repeaterView.aliases.add({
494
- kind: ir.SemanticVariableKind.Alias,
495
- name: null,
496
- identifier: variable.name,
497
- expression: getComputedForLoopVariableExpression(variable, indexName, countName),
498
- });
499
- }
500
- }
501
- const sourceSpan = convertSourceSpan(forBlock.trackBy.span, forBlock.sourceSpan);
502
- const track = convertAst(forBlock.trackBy, unit.job, sourceSpan);
503
- ingestNodes(repeaterView, forBlock.children);
504
- let emptyView = null;
505
- let emptyTagName = null;
506
- if (forBlock.empty !== null) {
507
- emptyView = unit.job.allocateView(unit.xref);
508
- ingestNodes(emptyView, forBlock.empty.children);
509
- emptyTagName = ingestControlFlowInsertionPoint(unit, emptyView.xref, forBlock.empty);
510
- }
511
- const varNames = {
512
- $index: indexVarNames,
513
- $implicit: forBlock.item.name,
514
- };
515
- if (forBlock.i18n !== undefined && !(forBlock.i18n instanceof i18n.BlockPlaceholder)) {
516
- throw Error('AssertionError: Unhandled i18n metadata type or @for');
517
- }
518
- if (forBlock.empty?.i18n !== undefined &&
519
- !(forBlock.empty.i18n instanceof i18n.BlockPlaceholder)) {
520
- throw Error('AssertionError: Unhandled i18n metadata type or @empty');
521
- }
522
- const i18nPlaceholder = forBlock.i18n;
523
- const emptyI18nPlaceholder = forBlock.empty?.i18n;
524
- const tagName = ingestControlFlowInsertionPoint(unit, repeaterView.xref, forBlock);
525
- const repeaterCreate = ir.createRepeaterCreateOp(repeaterView.xref, emptyView?.xref ?? null, tagName, track, varNames, emptyTagName, i18nPlaceholder, emptyI18nPlaceholder, forBlock.startSourceSpan, forBlock.sourceSpan);
526
- unit.create.push(repeaterCreate);
527
- const expression = convertAst(forBlock.expression, unit.job, convertSourceSpan(forBlock.expression.span, forBlock.sourceSpan));
528
- const repeater = ir.createRepeaterOp(repeaterCreate.xref, repeaterCreate.handle, expression, forBlock.sourceSpan);
529
- unit.update.push(repeater);
530
- }
531
- /**
532
- * Gets an expression that represents a variable in an `@for` loop.
533
- * @param variable AST representing the variable.
534
- * @param indexName Loop-specific name for `$index`.
535
- * @param countName Loop-specific name for `$count`.
536
- */
537
- function getComputedForLoopVariableExpression(variable, indexName, countName) {
538
- switch (variable.value) {
539
- case '$index':
540
- return new ir.LexicalReadExpr(indexName);
541
- case '$count':
542
- return new ir.LexicalReadExpr(countName);
543
- case '$first':
544
- return new ir.LexicalReadExpr(indexName).identical(o.literal(0));
545
- case '$last':
546
- return new ir.LexicalReadExpr(indexName).identical(new ir.LexicalReadExpr(countName).minus(o.literal(1)));
547
- case '$even':
548
- return new ir.LexicalReadExpr(indexName).modulo(o.literal(2)).identical(o.literal(0));
549
- case '$odd':
550
- return new ir.LexicalReadExpr(indexName).modulo(o.literal(2)).notIdentical(o.literal(0));
551
- default:
552
- throw new Error(`AssertionError: unknown @for loop variable ${variable.value}`);
553
- }
554
- }
555
- function ingestLetDeclaration(unit, node) {
556
- const target = unit.job.allocateXrefId();
557
- unit.create.push(ir.createDeclareLetOp(target, node.name, node.sourceSpan));
558
- unit.update.push(ir.createStoreLetOp(target, node.name, convertAst(node.value, unit.job, node.valueSpan), node.sourceSpan));
559
- }
560
- /**
561
- * Convert a template AST expression into an output AST expression.
562
- */
563
- function convertAst(ast, job, baseSourceSpan) {
564
- if (ast instanceof e.ASTWithSource) {
565
- return convertAst(ast.ast, job, baseSourceSpan);
566
- }
567
- else if (ast instanceof e.PropertyRead) {
568
- const isThisReceiver = ast.receiver instanceof e.ThisReceiver;
569
- // Whether this is an implicit receiver, *excluding* explicit reads of `this`.
570
- const isImplicitReceiver = ast.receiver instanceof e.ImplicitReceiver && !(ast.receiver instanceof e.ThisReceiver);
571
- // Whether the name of the read is a node that should be never retain its explicit this
572
- // receiver.
573
- const isSpecialNode = ast.name === '$any' || ast.name === '$event';
574
- // TODO: The most sensible condition here would be simply `isImplicitReceiver`, to convert only
575
- // actual implicit `this` reads, and not explicit ones. However, TemplateDefinitionBuilder (and
576
- // the Typecheck block!) both have the same bug, in which they also consider explicit `this`
577
- // reads to be implicit. This causes problems when the explicit `this` read is inside a
578
- // template with a context that also provides the variable name being read:
579
- // ```
580
- // <ng-template let-a>{{this.a}}</ng-template>
581
- // ```
582
- // The whole point of the explicit `this` was to access the class property, but TDB and the
583
- // current TCB treat the read as implicit, and give you the context property instead!
584
- //
585
- // For now, we emulate this old behavior by aggressively converting explicit reads to to
586
- // implicit reads, except for the special cases that TDB and the current TCB protect. However,
587
- // it would be an improvement to fix this.
588
- //
589
- // See also the corresponding comment for the TCB, in `type_check_block.ts`.
590
- if (isImplicitReceiver || (isThisReceiver && !isSpecialNode)) {
591
- return new ir.LexicalReadExpr(ast.name);
592
- }
593
- else {
594
- return new o.ReadPropExpr(convertAst(ast.receiver, job, baseSourceSpan), ast.name, null, convertSourceSpan(ast.span, baseSourceSpan));
595
- }
596
- }
597
- else if (ast instanceof e.PropertyWrite) {
598
- if (ast.receiver instanceof e.ImplicitReceiver) {
599
- return new o.WritePropExpr(
600
- // TODO: Is it correct to always use the root context in place of the implicit receiver?
601
- new ir.ContextExpr(job.root.xref), ast.name, convertAst(ast.value, job, baseSourceSpan), null, convertSourceSpan(ast.span, baseSourceSpan));
602
- }
603
- return new o.WritePropExpr(convertAst(ast.receiver, job, baseSourceSpan), ast.name, convertAst(ast.value, job, baseSourceSpan), undefined, convertSourceSpan(ast.span, baseSourceSpan));
604
- }
605
- else if (ast instanceof e.KeyedWrite) {
606
- return new o.WriteKeyExpr(convertAst(ast.receiver, job, baseSourceSpan), convertAst(ast.key, job, baseSourceSpan), convertAst(ast.value, job, baseSourceSpan), undefined, convertSourceSpan(ast.span, baseSourceSpan));
607
- }
608
- else if (ast instanceof e.Call) {
609
- if (ast.receiver instanceof e.ImplicitReceiver) {
610
- throw new Error(`Unexpected ImplicitReceiver`);
611
- }
612
- else {
613
- return new o.InvokeFunctionExpr(convertAst(ast.receiver, job, baseSourceSpan), ast.args.map((arg) => convertAst(arg, job, baseSourceSpan)), undefined, convertSourceSpan(ast.span, baseSourceSpan));
614
- }
615
- }
616
- else if (ast instanceof e.LiteralPrimitive) {
617
- return o.literal(ast.value, undefined, convertSourceSpan(ast.span, baseSourceSpan));
618
- }
619
- else if (ast instanceof e.Unary) {
620
- switch (ast.operator) {
621
- case '+':
622
- return new o.UnaryOperatorExpr(o.UnaryOperator.Plus, convertAst(ast.expr, job, baseSourceSpan), undefined, convertSourceSpan(ast.span, baseSourceSpan));
623
- case '-':
624
- return new o.UnaryOperatorExpr(o.UnaryOperator.Minus, convertAst(ast.expr, job, baseSourceSpan), undefined, convertSourceSpan(ast.span, baseSourceSpan));
625
- default:
626
- throw new Error(`AssertionError: unknown unary operator ${ast.operator}`);
627
- }
628
- }
629
- else if (ast instanceof e.Binary) {
630
- const operator = BINARY_OPERATORS.get(ast.operation);
631
- if (operator === undefined) {
632
- throw new Error(`AssertionError: unknown binary operator ${ast.operation}`);
633
- }
634
- return new o.BinaryOperatorExpr(operator, convertAst(ast.left, job, baseSourceSpan), convertAst(ast.right, job, baseSourceSpan), undefined, convertSourceSpan(ast.span, baseSourceSpan));
635
- }
636
- else if (ast instanceof e.ThisReceiver) {
637
- // TODO: should context expressions have source maps?
638
- return new ir.ContextExpr(job.root.xref);
639
- }
640
- else if (ast instanceof e.KeyedRead) {
641
- return new o.ReadKeyExpr(convertAst(ast.receiver, job, baseSourceSpan), convertAst(ast.key, job, baseSourceSpan), undefined, convertSourceSpan(ast.span, baseSourceSpan));
642
- }
643
- else if (ast instanceof e.Chain) {
644
- throw new Error(`AssertionError: Chain in unknown context`);
645
- }
646
- else if (ast instanceof e.LiteralMap) {
647
- const entries = ast.keys.map((key, idx) => {
648
- const value = ast.values[idx];
649
- // TODO: should literals have source maps, or do we just map the whole surrounding
650
- // expression?
651
- return new o.LiteralMapEntry(key.key, convertAst(value, job, baseSourceSpan), key.quoted);
652
- });
653
- return new o.LiteralMapExpr(entries, undefined, convertSourceSpan(ast.span, baseSourceSpan));
654
- }
655
- else if (ast instanceof e.LiteralArray) {
656
- // TODO: should literals have source maps, or do we just map the whole surrounding expression?
657
- return new o.LiteralArrayExpr(ast.expressions.map((expr) => convertAst(expr, job, baseSourceSpan)));
658
- }
659
- else if (ast instanceof e.Conditional) {
660
- return new o.ConditionalExpr(convertAst(ast.condition, job, baseSourceSpan), convertAst(ast.trueExp, job, baseSourceSpan), convertAst(ast.falseExp, job, baseSourceSpan), undefined, convertSourceSpan(ast.span, baseSourceSpan));
661
- }
662
- else if (ast instanceof e.NonNullAssert) {
663
- // A non-null assertion shouldn't impact generated instructions, so we can just drop it.
664
- return convertAst(ast.expression, job, baseSourceSpan);
665
- }
666
- else if (ast instanceof e.BindingPipe) {
667
- // TODO: pipes should probably have source maps; figure out details.
668
- return new ir.PipeBindingExpr(job.allocateXrefId(), new ir.SlotHandle(), ast.name, [
669
- convertAst(ast.exp, job, baseSourceSpan),
670
- ...ast.args.map((arg) => convertAst(arg, job, baseSourceSpan)),
671
- ]);
672
- }
673
- else if (ast instanceof e.SafeKeyedRead) {
674
- return new ir.SafeKeyedReadExpr(convertAst(ast.receiver, job, baseSourceSpan), convertAst(ast.key, job, baseSourceSpan), convertSourceSpan(ast.span, baseSourceSpan));
675
- }
676
- else if (ast instanceof e.SafePropertyRead) {
677
- // TODO: source span
678
- return new ir.SafePropertyReadExpr(convertAst(ast.receiver, job, baseSourceSpan), ast.name);
679
- }
680
- else if (ast instanceof e.SafeCall) {
681
- // TODO: source span
682
- return new ir.SafeInvokeFunctionExpr(convertAst(ast.receiver, job, baseSourceSpan), ast.args.map((a) => convertAst(a, job, baseSourceSpan)));
683
- }
684
- else if (ast instanceof e.EmptyExpr) {
685
- return new ir.EmptyExpr(convertSourceSpan(ast.span, baseSourceSpan));
686
- }
687
- else if (ast instanceof e.PrefixNot) {
688
- return o.not(convertAst(ast.expression, job, baseSourceSpan), convertSourceSpan(ast.span, baseSourceSpan));
689
- }
690
- else {
691
- throw new Error(`Unhandled expression type "${ast.constructor.name}" in file "${baseSourceSpan?.start.file.url}"`);
692
- }
693
- }
694
- function convertAstWithInterpolation(job, value, i18nMeta, sourceSpan) {
695
- let expression;
696
- if (value instanceof e.Interpolation) {
697
- expression = new ir.Interpolation(value.strings, value.expressions.map((e) => convertAst(e, job, sourceSpan ?? null)), Object.keys(asMessage(i18nMeta)?.placeholders ?? {}));
698
- }
699
- else if (value instanceof e.AST) {
700
- expression = convertAst(value, job, sourceSpan ?? null);
701
- }
702
- else {
703
- expression = o.literal(value);
704
- }
705
- return expression;
706
- }
707
- // TODO: Can we populate Template binding kinds in ingest?
708
- const BINDING_KINDS = new Map([
709
- [e.BindingType.Property, ir.BindingKind.Property],
710
- [e.BindingType.TwoWay, ir.BindingKind.TwoWayProperty],
711
- [e.BindingType.Attribute, ir.BindingKind.Attribute],
712
- [e.BindingType.Class, ir.BindingKind.ClassName],
713
- [e.BindingType.Style, ir.BindingKind.StyleProperty],
714
- [e.BindingType.Animation, ir.BindingKind.Animation],
715
- ]);
716
- /**
717
- * Checks whether the given template is a plain ng-template (as opposed to another kind of template
718
- * such as a structural directive template or control flow template). This is checked based on the
719
- * tagName. We can expect that only plain ng-templates will come through with a tagName of
720
- * 'ng-template'.
721
- *
722
- * Here are some of the cases we expect:
723
- *
724
- * | Angular HTML | Template tagName |
725
- * | ---------------------------------- | ------------------ |
726
- * | `<ng-template>` | 'ng-template' |
727
- * | `<div *ngIf="true">` | 'div' |
728
- * | `<svg><ng-template>` | 'svg:ng-template' |
729
- * | `@if (true) {` | 'Conditional' |
730
- * | `<ng-template *ngIf>` (plain) | 'ng-template' |
731
- * | `<ng-template *ngIf>` (structural) | null |
732
- */
733
- function isPlainTemplate(tmpl) {
734
- return splitNsName(tmpl.tagName ?? '')[1] === NG_TEMPLATE_TAG_NAME;
735
- }
736
- /**
737
- * Ensures that the i18nMeta, if provided, is an i18n.Message.
738
- */
739
- function asMessage(i18nMeta) {
740
- if (i18nMeta == null) {
741
- return null;
742
- }
743
- if (!(i18nMeta instanceof i18n.Message)) {
744
- throw Error(`Expected i18n meta to be a Message, but got: ${i18nMeta.constructor.name}`);
745
- }
746
- return i18nMeta;
747
- }
748
- /**
749
- * Process all of the bindings on an element in the template AST and convert them to their IR
750
- * representation.
751
- */
752
- function ingestElementBindings(unit, op, element) {
753
- let bindings = new Array();
754
- let i18nAttributeBindingNames = new Set();
755
- for (const attr of element.attributes) {
756
- // Attribute literal bindings, such as `attr.foo="bar"`.
757
- const securityContext = domSchema.securityContext(element.name, attr.name, true);
758
- bindings.push(ir.createBindingOp(op.xref, ir.BindingKind.Attribute, attr.name, convertAstWithInterpolation(unit.job, attr.value, attr.i18n), null, securityContext, true, false, null, asMessage(attr.i18n), attr.sourceSpan));
759
- if (attr.i18n) {
760
- i18nAttributeBindingNames.add(attr.name);
761
- }
762
- }
763
- for (const input of element.inputs) {
764
- if (i18nAttributeBindingNames.has(input.name)) {
765
- console.error(`On component ${unit.job.componentName}, the binding ${input.name} is both an i18n attribute and a property. You may want to remove the property binding. This will become a compilation error in future versions of Angular.`);
766
- }
767
- // All dynamic bindings (both attribute and property bindings).
768
- bindings.push(ir.createBindingOp(op.xref, BINDING_KINDS.get(input.type), input.name, convertAstWithInterpolation(unit.job, astOf(input.value), input.i18n), input.unit, input.securityContext, false, false, null, asMessage(input.i18n) ?? null, input.sourceSpan));
769
- }
770
- unit.create.push(bindings.filter((b) => b?.kind === ir.OpKind.ExtractedAttribute));
771
- unit.update.push(bindings.filter((b) => b?.kind === ir.OpKind.Binding));
772
- for (const output of element.outputs) {
773
- if (output.type === e.ParsedEventType.Animation && output.phase === null) {
774
- throw Error('Animation listener should have a phase');
775
- }
776
- if (output.type === e.ParsedEventType.TwoWay) {
777
- unit.create.push(ir.createTwoWayListenerOp(op.xref, op.handle, output.name, op.tag, makeTwoWayListenerHandlerOps(unit, output.handler, output.handlerSpan), output.sourceSpan));
778
- }
779
- else {
780
- unit.create.push(ir.createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
781
- }
782
- }
783
- // If any of the bindings on this element have an i18n message, then an i18n attrs configuration
784
- // op is also required.
785
- if (bindings.some((b) => b?.i18nMessage) !== null) {
786
- unit.create.push(ir.createI18nAttributesOp(unit.job.allocateXrefId(), new ir.SlotHandle(), op.xref));
787
- }
788
- }
789
- /**
790
- * Process all of the bindings on a template in the template AST and convert them to their IR
791
- * representation.
792
- */
793
- function ingestTemplateBindings(unit, op, template, templateKind) {
794
- let bindings = new Array();
795
- for (const attr of template.templateAttrs) {
796
- if (attr instanceof t.TextAttribute) {
797
- const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
798
- bindings.push(createTemplateBinding(unit, op.xref, e.BindingType.Attribute, attr.name, attr.value, null, securityContext, true, templateKind, asMessage(attr.i18n), attr.sourceSpan));
799
- }
800
- else {
801
- bindings.push(createTemplateBinding(unit, op.xref, attr.type, attr.name, astOf(attr.value), attr.unit, attr.securityContext, true, templateKind, asMessage(attr.i18n), attr.sourceSpan));
802
- }
803
- }
804
- for (const attr of template.attributes) {
805
- // Attribute literal bindings, such as `attr.foo="bar"`.
806
- const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
807
- bindings.push(createTemplateBinding(unit, op.xref, e.BindingType.Attribute, attr.name, attr.value, null, securityContext, false, templateKind, asMessage(attr.i18n), attr.sourceSpan));
808
- }
809
- for (const input of template.inputs) {
810
- // Dynamic bindings (both attribute and property bindings).
811
- bindings.push(createTemplateBinding(unit, op.xref, input.type, input.name, astOf(input.value), input.unit, input.securityContext, false, templateKind, asMessage(input.i18n), input.sourceSpan));
812
- }
813
- unit.create.push(bindings.filter((b) => b?.kind === ir.OpKind.ExtractedAttribute));
814
- unit.update.push(bindings.filter((b) => b?.kind === ir.OpKind.Binding));
815
- for (const output of template.outputs) {
816
- if (output.type === e.ParsedEventType.Animation && output.phase === null) {
817
- throw Error('Animation listener should have a phase');
818
- }
819
- if (templateKind === ir.TemplateKind.NgTemplate) {
820
- if (output.type === e.ParsedEventType.TwoWay) {
821
- unit.create.push(ir.createTwoWayListenerOp(op.xref, op.handle, output.name, op.tag, makeTwoWayListenerHandlerOps(unit, output.handler, output.handlerSpan), output.sourceSpan));
822
- }
823
- else {
824
- unit.create.push(ir.createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
825
- }
826
- }
827
- if (templateKind === ir.TemplateKind.Structural &&
828
- output.type !== e.ParsedEventType.Animation) {
829
- // Animation bindings are excluded from the structural template's const array.
830
- const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, output.name, false);
831
- unit.create.push(ir.createExtractedAttributeOp(op.xref, ir.BindingKind.Property, null, output.name, null, null, null, securityContext));
832
- }
833
- }
834
- // TODO: Perhaps we could do this in a phase? (It likely wouldn't change the slot indices.)
835
- if (bindings.some((b) => b?.i18nMessage) !== null) {
836
- unit.create.push(ir.createI18nAttributesOp(unit.job.allocateXrefId(), new ir.SlotHandle(), op.xref));
837
- }
838
- }
839
- /**
840
- * Helper to ingest an individual binding on a template, either an explicit `ng-template`, or an
841
- * implicit template created via structural directive.
842
- *
843
- * Bindings on templates are *extremely* tricky. I have tried to isolate all of the confusing edge
844
- * cases into this function, and to comment it well to document the behavior.
845
- *
846
- * Some of this behavior is intuitively incorrect, and we should consider changing it in the future.
847
- *
848
- * @param view The compilation unit for the view containing the template.
849
- * @param xref The xref of the template op.
850
- * @param type The binding type, according to the parser. This is fairly reasonable, e.g. both
851
- * dynamic and static attributes have e.BindingType.Attribute.
852
- * @param name The binding's name.
853
- * @param value The bindings's value, which will either be an input AST expression, or a string
854
- * literal. Note that the input AST expression may or may not be const -- it will only be a
855
- * string literal if the parser considered it a text binding.
856
- * @param unit If the binding has a unit (e.g. `px` for style bindings), then this is the unit.
857
- * @param securityContext The security context of the binding.
858
- * @param isStructuralTemplateAttribute Whether this binding actually applies to the structural
859
- * ng-template. For example, an `ngFor` would actually apply to the structural template. (Most
860
- * bindings on structural elements target the inner element, not the template.)
861
- * @param templateKind Whether this is an explicit `ng-template` or an implicit template created by
862
- * a structural directive. This should never be a block template.
863
- * @param i18nMessage The i18n metadata for the binding, if any.
864
- * @param sourceSpan The source span of the binding.
865
- * @returns An IR binding op, or null if the binding should be skipped.
866
- */
867
- function createTemplateBinding(view, xref, type, name, value, unit, securityContext, isStructuralTemplateAttribute, templateKind, i18nMessage, sourceSpan) {
868
- const isTextBinding = typeof value === 'string';
869
- // If this is a structural template, then several kinds of bindings should not result in an
870
- // update instruction.
871
- if (templateKind === ir.TemplateKind.Structural) {
872
- if (!isStructuralTemplateAttribute) {
873
- switch (type) {
874
- case e.BindingType.Property:
875
- case e.BindingType.Class:
876
- case e.BindingType.Style:
877
- // Because this binding doesn't really target the ng-template, it must be a binding on an
878
- // inner node of a structural template. We can't skip it entirely, because we still need
879
- // it on the ng-template's consts (e.g. for the purposes of directive matching). However,
880
- // we should not generate an update instruction for it.
881
- return ir.createExtractedAttributeOp(xref, ir.BindingKind.Property, null, name, null, null, i18nMessage, securityContext);
882
- case e.BindingType.TwoWay:
883
- return ir.createExtractedAttributeOp(xref, ir.BindingKind.TwoWayProperty, null, name, null, null, i18nMessage, securityContext);
884
- }
885
- }
886
- if (!isTextBinding && (type === e.BindingType.Attribute || type === e.BindingType.Animation)) {
887
- // Again, this binding doesn't really target the ng-template; it actually targets the element
888
- // inside the structural template. In the case of non-text attribute or animation bindings,
889
- // the binding doesn't even show up on the ng-template const array, so we just skip it
890
- // entirely.
891
- return null;
892
- }
893
- }
894
- let bindingType = BINDING_KINDS.get(type);
895
- if (templateKind === ir.TemplateKind.NgTemplate) {
896
- // We know we are dealing with bindings directly on an explicit ng-template.
897
- // Static attribute bindings should be collected into the const array as k/v pairs. Property
898
- // bindings should result in a `property` instruction, and `AttributeMarker.Bindings` const
899
- // entries.
900
- //
901
- // The difficulty is with dynamic attribute, style, and class bindings. These don't really make
902
- // sense on an `ng-template` and should probably be parser errors. However,
903
- // TemplateDefinitionBuilder generates `property` instructions for them, and so we do that as
904
- // well.
905
- //
906
- // Note that we do have a slight behavior difference with TemplateDefinitionBuilder: although
907
- // TDB emits `property` instructions for dynamic attributes, styles, and classes, only styles
908
- // and classes also get const collected into the `AttributeMarker.Bindings` field. Dynamic
909
- // attribute bindings are missing from the consts entirely. We choose to emit them into the
910
- // consts field anyway, to avoid creating special cases for something so arcane and nonsensical.
911
- if (type === e.BindingType.Class ||
912
- type === e.BindingType.Style ||
913
- (type === e.BindingType.Attribute && !isTextBinding)) {
914
- // TODO: These cases should be parse errors.
915
- bindingType = ir.BindingKind.Property;
916
- }
917
- }
918
- return ir.createBindingOp(xref, bindingType, name, convertAstWithInterpolation(view.job, value, i18nMessage), unit, securityContext, isTextBinding, isStructuralTemplateAttribute, templateKind, i18nMessage, sourceSpan);
919
- }
920
- function makeListenerHandlerOps(unit, handler, handlerSpan) {
921
- handler = astOf(handler);
922
- const handlerOps = new Array();
923
- let handlerExprs = handler instanceof e.Chain ? handler.expressions : [handler];
924
- if (handlerExprs.length === 0) {
925
- throw new Error('Expected listener to have non-empty expression list.');
926
- }
927
- const expressions = handlerExprs.map((expr) => convertAst(expr, unit.job, handlerSpan));
928
- const returnExpr = expressions.pop();
929
- handlerOps.push(...expressions.map((e) => ir.createStatementOp(new o.ExpressionStatement(e, e.sourceSpan))));
930
- handlerOps.push(ir.createStatementOp(new o.ReturnStatement(returnExpr, returnExpr.sourceSpan)));
931
- return handlerOps;
932
- }
933
- function makeTwoWayListenerHandlerOps(unit, handler, handlerSpan) {
934
- handler = astOf(handler);
935
- const handlerOps = new Array();
936
- if (handler instanceof e.Chain) {
937
- if (handler.expressions.length === 1) {
938
- handler = handler.expressions[0];
939
- }
940
- else {
941
- // This is validated during parsing already, but we do it here just in case.
942
- throw new Error('Expected two-way listener to have a single expression.');
943
- }
944
- }
945
- const handlerExpr = convertAst(handler, unit.job, handlerSpan);
946
- const eventReference = new ir.LexicalReadExpr('$event');
947
- const twoWaySetExpr = new ir.TwoWayBindingSetExpr(handlerExpr, eventReference);
948
- handlerOps.push(ir.createStatementOp(new o.ExpressionStatement(twoWaySetExpr)));
949
- handlerOps.push(ir.createStatementOp(new o.ReturnStatement(eventReference)));
950
- return handlerOps;
951
- }
952
- function astOf(ast) {
953
- return ast instanceof e.ASTWithSource ? ast.ast : ast;
954
- }
955
- /**
956
- * Process all of the local references on an element-like structure in the template AST and
957
- * convert them to their IR representation.
958
- */
959
- function ingestReferences(op, element) {
960
- assertIsArray(op.localRefs);
961
- for (const { name, value } of element.references) {
962
- op.localRefs.push({
963
- name,
964
- target: value,
965
- });
966
- }
967
- }
968
- /**
969
- * Assert that the given value is an array.
970
- */
971
- function assertIsArray(value) {
972
- if (!Array.isArray(value)) {
973
- throw new Error(`AssertionError: expected an array`);
974
- }
975
- }
976
- /**
977
- * Creates an absolute `ParseSourceSpan` from the relative `ParseSpan`.
978
- *
979
- * `ParseSpan` objects are relative to the start of the expression.
980
- * This method converts these to full `ParseSourceSpan` objects that
981
- * show where the span is within the overall source file.
982
- *
983
- * @param span the relative span to convert.
984
- * @param baseSourceSpan a span corresponding to the base of the expression tree.
985
- * @returns a `ParseSourceSpan` for the given span or null if no `baseSourceSpan` was provided.
986
- */
987
- function convertSourceSpan(span, baseSourceSpan) {
988
- if (baseSourceSpan === null) {
989
- return null;
990
- }
991
- const start = baseSourceSpan.start.moveBy(span.start);
992
- const end = baseSourceSpan.start.moveBy(span.end);
993
- const fullStart = baseSourceSpan.fullStart.moveBy(span.start);
994
- return new ParseSourceSpan(start, end, fullStart);
995
- }
996
- /**
997
- * With the directive-based control flow users were able to conditionally project content using
998
- * the `*` syntax. E.g. `<div *ngIf="expr" projectMe></div>` will be projected into
999
- * `<ng-content select="[projectMe]"/>`, because the attributes and tag name from the `div` are
1000
- * copied to the template via the template creation instruction. With `@if` and `@for` that is
1001
- * not the case, because the conditional is placed *around* elements, rather than *on* them.
1002
- * The result is that content projection won't work in the same way if a user converts from
1003
- * `*ngIf` to `@if`.
1004
- *
1005
- * This function aims to cover the most common case by doing the same copying when a control flow
1006
- * node has *one and only one* root element or template node.
1007
- *
1008
- * This approach comes with some caveats:
1009
- * 1. As soon as any other node is added to the root, the copying behavior won't work anymore.
1010
- * A diagnostic will be added to flag cases like this and to explain how to work around it.
1011
- * 2. If `preserveWhitespaces` is enabled, it's very likely that indentation will break this
1012
- * workaround, because it'll include an additional text node as the first child. We can work
1013
- * around it here, but in a discussion it was decided not to, because the user explicitly opted
1014
- * into preserving the whitespace and we would have to drop it from the generated code.
1015
- * The diagnostic mentioned point #1 will flag such cases to users.
1016
- *
1017
- * @returns Tag name to be used for the control flow template.
1018
- */
1019
- function ingestControlFlowInsertionPoint(unit, xref, node) {
1020
- let root = null;
1021
- for (const child of node.children) {
1022
- // Skip over comment nodes.
1023
- if (child instanceof t.Comment) {
1024
- continue;
1025
- }
1026
- // We can only infer the tag name/attributes if there's a single root node.
1027
- if (root !== null) {
1028
- return null;
1029
- }
1030
- // Root nodes can only elements or templates with a tag name (e.g. `<div *foo></div>`).
1031
- if (child instanceof t.Element || (child instanceof t.Template && child.tagName !== null)) {
1032
- root = child;
1033
- }
1034
- }
1035
- // If we've found a single root node, its tag name and attributes can be
1036
- // copied to the surrounding template to be used for content projection.
1037
- if (root !== null) {
1038
- // Collect the static attributes for content projection purposes.
1039
- for (const attr of root.attributes) {
1040
- const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
1041
- unit.update.push(ir.createBindingOp(xref, ir.BindingKind.Attribute, attr.name, o.literal(attr.value), null, securityContext, true, false, null, asMessage(attr.i18n), attr.sourceSpan));
1042
- }
1043
- // Also collect the inputs since they participate in content projection as well.
1044
- // Note that TDB used to collect the outputs as well, but it wasn't passing them into
1045
- // the template instruction. Here we just don't collect them.
1046
- for (const attr of root.inputs) {
1047
- if (attr.type !== e.BindingType.Animation && attr.type !== e.BindingType.Attribute) {
1048
- const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
1049
- unit.create.push(ir.createExtractedAttributeOp(xref, ir.BindingKind.Property, null, attr.name, null, null, null, securityContext));
1050
- }
1051
- }
1052
- const tagName = root instanceof t.Element ? root.name : root.tagName;
1053
- // Don't pass along `ng-template` tag name since it enables directive matching.
1054
- return tagName === NG_TEMPLATE_TAG_NAME ? null : tagName;
1055
- }
1056
- return null;
1057
- }
1058
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5nZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3RlbXBsYXRlL3BpcGVsaW5lL3NyYy9pbmdlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBR0gsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUM5QyxPQUFPLEtBQUssQ0FBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQ3BELE9BQU8sS0FBSyxJQUFJLE1BQU0sd0JBQXdCLENBQUM7QUFDL0MsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBQ3BELE9BQU8sS0FBSyxDQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDaEQsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ3BELE9BQU8sS0FBSyxDQUFDLE1BQU0seUJBQXlCLENBQUM7QUFFN0MsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0saUNBQWlDLENBQUM7QUFDbkUsT0FBTyxFQUFDLHdCQUF3QixFQUFDLE1BQU0sNkNBQTZDLENBQUM7QUFFckYsT0FBTyxLQUFLLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFFNUIsT0FBTyxFQUVMLHVCQUF1QixFQUN2Qix5QkFBeUIsR0FHMUIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLGdCQUFnQixFQUFFLGVBQWUsRUFBRSxtQkFBbUIsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUVwRixNQUFNLGlCQUFpQixHQUFHLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQyx5QkFBeUIsQ0FBQztBQUV6RSx1REFBdUQ7QUFDdkQsTUFBTSxTQUFTLEdBQUcsSUFBSSx3QkFBd0IsRUFBRSxDQUFDO0FBRWpELHlDQUF5QztBQUN6QyxNQUFNLG9CQUFvQixHQUFHLGFBQWEsQ0FBQztBQUUzQyxNQUFNLFVBQVUsY0FBYyxDQUFDLElBQW9CO0lB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dkIsSUFBSSxFQUNKLElBQUksQ0FBQyxJQUFJLEVBQ1QsSUFBSSxFQUNKLElBQUksRUFDSixJQUFJLEVBQ0osZUFBZSxDQUNoQixDQUNGLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sT0FBTyxHQUFHLElBQUksWUFBWSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBRXJFLCtFQUErRTtRQUMvRSxPQUFPLE9BQU8sS0FBSyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7SUFDM0QsQ0FBQztJQUVELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0NvbnN0YW50UG9vbH0gZnJvbSAnLi4vLi4vLi4vY29uc3RhbnRfcG9vbCc7XG5pbXBvcnQge1NlY3VyaXR5Q29udGV4dH0gZnJvbSAnLi4vLi4vLi4vY29yZSc7XG5pbXBvcnQgKiBhcyBlIGZyb20gJy4uLy4uLy4uL2V4cHJlc3Npb25fcGFyc2VyL2FzdCc7XG5pbXBvcnQgKiBhcyBpMThuIGZyb20gJy4uLy4uLy4uL2kxOG4vaTE4bl9hc3QnO1xuaW1wb3J0IHtzcGxpdE5zTmFtZX0gZnJvbSAnLi4vLi4vLi4vbWxfcGFyc2VyL3RhZ3MnO1xuaW1wb3J0ICogYXMgbyBmcm9tICcuLi8uLi8uLi9vdXRwdXQvb3V0cHV0X2FzdCc7XG5pbXBvcnQge1BhcnNlU291cmNlU3Bhbn0gZnJvbSAnLi4vLi4vLi4vcGFyc2VfdXRpbCc7XG5pbXBvcnQgKiBhcyB0IGZyb20gJy4uLy4uLy4uL3JlbmRlcjMvcjNfYXN0JztcbmltcG9ydCB7RGVmZXJCbG9ja0RlcHNFbWl0TW9kZSwgUjNDb21wb25lbnREZWZlck1ldGFkYXRhfSBmcm9tICcuLi8uLi8uLi9yZW5kZXIzL3ZpZXcvYXBpJztcbmltcG9ydCB7aWN1RnJvbUkxOG5NZXNzYWdlfSBmcm9tICcuLi8uLi8uLi9yZW5kZXIzL3ZpZXcvaTE4bi91dGlsJztcbmltcG9ydCB7RG9tRWxlbWVudFNjaGVtYVJlZ2lzdHJ5fSBmcm9tICcuLi8uLi8uLi9zY2hlbWEvZG9tX2VsZW1lbnRfc2NoZW1hX3JlZ2lzdHJ5JztcbmltcG9ydCB7QmluZGluZ1BhcnNlcn0gZnJvbSAnLi4vLi4vLi4vdGVtcGxhdGVfcGFyc2VyL2JpbmRpbmdfcGFyc2VyJztcbmltcG9ydCAqIGFzIGlyIGZyb20gJy4uL2lyJztcblxuaW1wb3J0IHtcbiAgQ29tcGlsYXRpb25Vbml0LFxuICBDb21wb25lbnRDb21waWxhdGlvbkpvYixcbiAgSG9zdEJpbmRpbmdDb21waWxhdGlvbkpvYixcbiAgdHlwZSBDb21waWxhdGlvbkpvYixcbiAgdHlwZSBWaWV3Q29tcGlsYXRpb25Vbml0LFxufSBmcm9tICcuL2NvbXBpbGF0aW9uJztcbmltcG9ydCB7QklOQVJZX09QRVJBVE9SUywgbmFtZXNwYWNlRm9yS2V5LCBwcmVmaXhXaXRoTmFtZXNwYWNlfSBmcm9tICcuL2NvbnZlcnNpb24nO1xuXG5jb25zdCBjb21wYXRpYmlsaXR5TW9kZSA9IGlyLkNvbXBhdGliaWxpdHlNb2RlLlRlbXBsYXRlRGVmaW5pdGlvbkJ1aWxkZXI7XG5cbi8vIFNjaGVtYSBjb250YWluaW5nIERPTSBlbGVtZW50cyBhbmQgdGhlaXIgcHJvcGVydGllcy5cbmNvbnN0IGRvbVNjaGVtYSA9IG5ldyBEb21FbGVtZW50U2NoZW1hUmVnaXN0cnkoKTtcblxuLy8gVGFnIG5hbWUgb2YgdGhlIGBuZy10ZW1wbGF0ZWAgZWxlbWVudC5cbmNvbnN0IE5HX1RFTVBMQVRFX1RBR19OQU1FID0gJ25nLXRlbXBsYXRlJztcblxuZXhwb3J0IGZ1bmN0aW9uIGlzSTE4blJvb3ROb2RlKG1ldGE/OiBpMThuLkkxOG5NZXRhKTogbWV0YSBpcyBpMThuLk1lc3NhZ2Uge1xuICByZXR1cm4gbWV0YSBpbnN0YW5jZW9mIGkxOG4uTWVzc2FnZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2luZ2xlSTE4bkljdShtZXRhPzogaTE4bi5JMThuTWV0YSk6IG1ldGEgaXMgaTE4bi5JMThuTWV0YSAmIHtub2RlczogW2kxOG4uSWN1XX0ge1xuICByZXR1cm4gaXNJMThuUm9vdE5vZGUobWV0YSkgJiYgbWV0YS5ub2Rlcy5sZW5ndGggPT09IDEgJiYgbWV0YS5ub2Rlc1swXSBpbnN0YW5jZW9mIGkxOG4uSWN1O1xufVxuXG4vKipcbiAqIFByb2Nlc3MgYSB0ZW1wbGF0ZSBBU1QgYW5kIGNvbnZlcnQgaXQgaW50byBhIGBDb21wb25lbnRDb21waWxhdGlvbmAgaW4gdGhlIGludGVybWVkaWF0ZVxuICogcmVwcmVzZW50YXRpb24uXG4gKiBUT0RPOiBSZWZhY3RvciBtb3JlIG9mIHRoZSBpbmdlc3Rpb24gY29kZSBpbnRvIHBoYXNlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluZ2VzdENvbXBvbmVudChcbiAgY29tcG9uZW50TmFtZTogc3RyaW5nLFxuICB0ZW1wbGF0ZTogdC5Ob2RlW10sXG4gIGNvbnN0YW50UG9vbDogQ29uc3RhbnRQb29sLFxuICByZWxhdGl2ZUNvbnRleHRGaWxlUGF0aDogc3RyaW5nLFxuICBpMThuVXNlRXh0ZXJuYWxJZHM6IGJvb2xlYW4sXG4gIGRlZmVyTWV0YTogUjNDb21wb25lbnREZWZlck1ldGFkYXRhLFxuICBhbGxEZWZlcnJhYmxlRGVwc0ZuOiBvLlJlYWRWYXJFeHByIHwgbnVsbCxcbik6IENvbXBvbmVudENvbXBpbGF0aW9uSm9iIHtcbiAgY29uc3Qgam9iID0gbmV3IENvbXBvbmVudENvbXBpbGF0aW9uSm9iKFxuICAgIGNvbXBvbmVudE5hbWUsXG4gICAgY29uc3RhbnRQb29sLFxuICAgIGNvbXBhdGliaWxpdHlNb2RlLFxuICAgIHJlbGF0aXZlQ29udGV4dEZpbGVQYXRoLFxuICAgIGkxOG5Vc2VFeHRlcm5hbElkcyxcbiAgICBkZWZlck1ldGEsXG4gICAgYWxsRGVmZXJyYWJsZURlcHNGbixcbiAgKTtcbiAgaW5nZXN0Tm9kZXMoam9iLnJvb3QsIHRlbXBsYXRlKTtcbiAgcmV0dXJuIGpvYjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBIb3N0QmluZGluZ0lucHV0IHtcbiAgY29tcG9uZW50TmFtZTogc3RyaW5nO1xuICBjb21wb25lbnRTZWxlY3Rvcjogc3RyaW5nO1xuICBwcm9wZXJ0aWVzOiBlLlBhcnNlZFByb3BlcnR5W10gfCBudWxsO1xuICBhdHRyaWJ1dGVzOiB7W2tleTogc3RyaW5nXTogby5FeHByZXNzaW9ufTtcbiAgZXZlbnRzOiBlLlBhcnNlZEV2ZW50W10gfCBudWxsO1xufVxuXG4vKipcbiAqIFByb2Nlc3MgYSBob3N0IGJpbmRpbmcgQVNUIGFuZCBjb252ZXJ0IGl0IGludG8gYSBgSG9zdEJpbmRpbmdDb21waWxhdGlvbkpvYmAgaW4gdGhlIGludGVybWVkaWF0ZVxuICogcmVwcmVzZW50YXRpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmdlc3RIb3N0QmluZGluZyhcbiAgaW5wdXQ6IEhvc3RCaW5kaW5nSW5wdXQsXG4gIGJpbmRpbmdQYXJzZXI6IEJpbmRpbmdQYXJzZXIsXG4gIGNvbnN0YW50UG9vbDogQ29uc3RhbnRQb29sLFxuKTogSG9zdEJpbmRpbmdDb21waWxhdGlvbkpvYiB7XG4gIGNvbnN0IGpvYiA9IG5ldyBIb3N0QmluZGluZ0NvbXBpbGF0aW9uSm9iKGlucHV0LmNvbXBvbmVudE5hbWUsIGNvbnN0YW50UG9vbCwgY29tcGF0aWJpbGl0eU1vZGUpO1xuICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIGlucHV0LnByb3BlcnRpZXMgPz8gW10pIHtcbiAgICBsZXQgYmluZGluZ0tpbmQgPSBpci5CaW5kaW5nS2luZC5Qcm9wZXJ0eTtcbiAgICAvLyBUT0RPOiB0aGlzIHNob3VsZCByZWFsbHkgYmUgaGFuZGxlZCBpbiB0aGUgcGFyc2VyLlxuICAgIGlmIChwcm9wZXJ0eS5uYW1lLnN0YXJ0c1dpdGgoJ2F0dHIuJykpIHtcbiAgICAgIHByb3BlcnR5Lm5hbWUgPSBwcm9wZXJ0eS5uYW1lLnN1YnN0cmluZygnYXR0ci4nLmxlbmd0aCk7XG4gICAgICBiaW5kaW5nS2luZCA9IGlyLkJpbmRpbmdLaW5kLkF0dHJpYnV0ZTtcbiAgICB9XG4gICAgaWYgKHByb3BlcnR5LmlzQW5pbWF0aW9uKSB7XG4gICAgICBiaW5kaW5nS2luZCA9IGlyLkJpbmRpbmdLaW5kLkFuaW1hdGlvbjtcbiAgICB9XG4gICAgY29uc3Qgc2VjdXJpdHlDb250ZXh0cyA9IGJpbmRpbmdQYXJzZXJcbiAgICAgIC5jYWxjUG9zc2libGVTZWN1cml0eUNvbnRleHRzKFxuICAgICAgICBpbnB1dC5jb21wb25lbnRTZWxlY3RvcixcbiAgICAgICAgcHJvcGVydHkubmFtZSxcbiAgICAgICAgYmluZGluZ0tpbmQgPT09IGlyLkJpbmRpbmdLaW5kLkF0dHJpYnV0ZSxcbiAgICAgIClcbiAgICAgIC5maWx0ZXIoKGNvbnRleHQpID0+IGNvbnRleHQgIT09IFNlY3VyaXR5Q29udGV4dC5OT05FKTtcbiAgICBpbmdlc3RIb3N0UHJvcGVydHkoam9iLCBwcm9wZXJ0eSwgYmluZGluZ0tpbmQsIHNlY3VyaXR5Q29udGV4dHMpO1xuICB9XG4gIGZvciAoY29uc3QgW25hbWUsIGV4cHJdIG9mIE9iamVjdC5lbnRyaWVzKGlucHV0LmF0dHJpYnV0ZXMpID8/IFtdKSB7XG4gICAgY29uc3Qgc2VjdXJpdHlDb250ZXh0cyA9IGJpbmRpbmdQYXJzZXJcbiAgICAgIC5jYWxjUG9zc2libGVTZWN1cml0eUNvbnRleHRzKGlucHV0LmNvbXBvbmVudFNlbGVjdG9yLCBuYW1lLCB0cnVlKVxuICAgICAgLmZpbHRlcigoY29udGV4dCkgPT4gY29udGV4dCAhPT0gU2VjdXJpdHlDb250ZXh0Lk5PTkUpO1xuICAgIGluZ2VzdEhvc3RBdHRyaWJ1dGUoam9iLCBuYW1lLCBleHByLCBzZWN1cml0eUNvbnRleHRzKTtcbiAgfVxuICBmb3IgKGNvbnN0IGV2ZW50IG9mIGlucHV0LmV2ZW50cyA/PyBbXSkge1xuICAgIGluZ2VzdEhvc3RFdmVudChqb2IsIGV2ZW50KTtcbiAgfVxuICByZXR1cm4gam9iO1xufVxuXG4vLyBUT0RPOiBXZSBzaG91bGQgcmVmYWN0b3IgdGhlIHBhcnNlciB0byB1c2UgdGhlIHNhbWUgdHlwZXMgYW5kIHN0cnVjdHVyZXMgZm9yIGhvc3QgYmluZGluZ3MgYXNcbi8vIHdpdGggb3JkaW5hcnkgY29tcG9uZW50cy4gVGhpcyB3b3VsZCBhbGxvdyB1cyB0byBzaGFyZSBhIGxvdCBtb3JlIGluZ2VzdGlvbiBjb2RlLlxuZXhwb3J0IGZ1bmN0aW9uIGluZ2VzdEhvc3RQcm9wZXJ0eShcbiAgam9iOiBIb3N0QmluZGluZ0NvbXBpbGF0aW9uSm9iLFxuICBwcm9wZXJ0eTogZS5QYXJzZWRQcm9wZXJ0eSxcbiAgYmluZGluZ0tpbmQ6IGlyLkJpbmRpbmdLaW5kLFxuICBzZWN1cml0eUNvbnRleHRzOiBTZWN1cml0eUNvbnRleHRbXSxcbik6IHZvaWQge1xuICBsZXQgZXhwcmVzc2lvbjogby5FeHByZXNzaW9uIHwgaXIuSW50ZXJwb2xhdGlvbjtcbiAgY29uc3QgYXN0ID0gcHJvcGVydHkuZXhwcmVzc2lvbi5hc3Q7XG4gIGlmIChhc3QgaW5zdGFuY2VvZiBlLkludGVycG9sYXRpb24pIHtcbiAgICBleHByZXNzaW9uID0gbmV3IGlyLkludGVycG9sYXRpb24oXG4gICAgICBhc3Quc3RyaW5ncyxcbiAgICAgIGFzdC5leHByZXNzaW9ucy5tYXAoKGV4cHIpID0+IGNvbnZlcnRBc3QoZXhwciwgam9iLCBwcm9wZXJ0eS5zb3VyY2VTcGFuKSksXG4gICAgICBbXSxcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIGV4cHJlc3Npb24gPSBjb252ZXJ0QXN0KGFzdCwgam9iLCBwcm9wZXJ0eS5zb3VyY2VTcGFuKTtcbiAgfVxuICBqb2Iucm9vdC51cGRhdGUucHVzaChcbiAgICBpci5jcmVhdGVCaW5kaW5nT3AoXG4gICAgICBqb2Iucm9vdC54cmVmLFxuICAgICAgYmluZGluZ0tpbmQsXG4gICAgICBwcm9wZXJ0eS5uYW1lLFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIG51bGwsXG4gICAgICBzZWN1cml0eUNvbnRleHRzLFxuICAgICAgZmFsc2UsXG4gICAgICBmYWxzZSxcbiAgICAgIG51bGwsXG4gICAgICAvKiBUT0RPOiBIb3cgZG8gSG9zdCBiaW5kaW5ncyBoYW5kbGUgaTE4biBhdHRycz8gKi8gbnVsbCxcbiAgICAgIHByb3BlcnR5LnNvdXJjZVNwYW4sXG4gICAgKSxcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluZ2VzdEhvc3RBdHRyaWJ1dGUoXG4gIGpvYjogSG9zdEJpbmRpbmdDb21waWxhdGlvbkpvYixcbiAgbmFtZTogc3RyaW5nLFxuICB2YWx1ZTogby5FeHByZXNzaW9uLFxuICBzZWN1cml0eUNvbnRleHRzOiBTZWN1cml0eUNvbnRleHRbXSxcbik6IHZvaWQge1xuICBjb25zdCBhdHRyQmluZGluZyA9IGlyLmNyZWF0ZUJpbmRpbmdPcChcbiAgICBqb2Iucm9vdC54cmVmLFxuICAgIGlyLkJpbmRpbmdLaW5kLkF0dHJpYnV0ZSxcbiAgICBuYW1lLFxuICAgIHZhbHVlLFxuICAgIG51bGwsXG4gICAgc2VjdXJpdHlDb250ZXh0cyxcbiAgICAvKiBIb3N0IGF0dHJpYnV0ZXMgc2hvdWxkIGFsd2F5cyBiZSBleHRyYWN0ZWQgdG8gY29uc3QgaG9zdEF0dHJzLCBldmVuIGlmIHRoZXkgYXJlIG5vdFxuICAgICAqc3RyaWN0bHkqIHRleHQgbGl0ZXJhbHMgKi9cbiAgICB0cnVlLFxuICAgIGZhbHNlLFxuICAgIG51bGwsXG4gICAgLyogVE9ETyAqLyBudWxsLFxuICAgIC8qKiBUT0RPOiBNYXkgYmUgbnVsbD8gKi8gdmFsdWUuc291cmNlU3BhbiEsXG4gICk7XG4gIGpvYi5yb290LnVwZGF0ZS5wdXNoKGF0dHJCaW5kaW5nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluZ2VzdEhvc3RFdmVudChqb2I6IEhvc3RCaW5kaW5nQ29tcGlsYXRpb25Kb2IsIGV2ZW50OiBlLlBhcnNlZEV2ZW50KSB7XG4gIGNvbnN0IFtwaGFzZSwgdGFyZ2V0XSA9XG4gICAgZXZlbnQudHlwZSAhPT0gZS5QYXJzZWRFdmVudFR5cGUuQW5pbWF0aW9uXG4gICAgICA/IFtudWxsLCBldmVudC50YXJnZXRPclBoYXNlXVxuICAgICAgOiBbZXZlbnQudGFyZ2V0T3JQaGFzZSwgbnVsbF07XG4gIGNvbnN0IGV2ZW50QmluZGluZyA9IGlyLmNyZWF0ZUxpc3RlbmVyT3AoXG4gICAgam9iLnJvb3QueHJlZixcbiAgICBuZXcgaXIuU2xvdEhhbmRsZSgpLFxuICAgIGV2ZW50Lm5hbWUsXG4gICAgbnVsbCxcbiAgICBtYWtlTGlzdGVuZXJIYW5kbGVyT3BzKGpvYi5yb290LCBldmVudC5oYW5kbGVyLCBldmVudC5oYW5kbGVyU3BhbiksXG4gICAgcGhhc2UsXG4gICAgdGFyZ2V0LFxuICAgIHRydWUsXG4gICAgZXZlbnQuc291cmNlU3BhbixcbiAgKTtcbiAgam9iLnJvb3QuY3JlYXRlLnB1c2goZXZlbnRCaW5kaW5nKTtcbn1cblxuLyoqXG4gKiBJbmdlc3QgdGhlIG5vZGVzIG9mIGEgdGVtcGxhdGUgQVNUIGludG8gdGhlIGdpdmVuIGBWaWV3Q29tcGlsYXRpb25gLlxuICovXG5mdW5jdGlvbiBpbmdlc3ROb2Rlcyh1bml0OiBWaWV3Q29tcGlsYXRpb25Vbml0LCB0ZW1wbGF0ZTogdC5Ob2RlW10pOiB2b2lkIHtcbiAgZm9yIChjb25zdCBub2RlIG9mIHRlbXBsYXRlKSB7XG4gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiB0LkVsZW1lbnQpIHtcbiAgICAgIGluZ2VzdEVsZW1lbnQodW5pdCwgbm9kZSk7XG4gICAgfSBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgdC5UZW1wbGF0ZSkge1xuICAgICAgaW5nZXN0VGVtcGxhdGUodW5pdCwgbm9kZSk7XG4gICAgfSBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgdC5Db250ZW50KSB7XG4gICAgICBpbmdlc3RDb250ZW50KHVuaXQsIG5vZGUpO1xuICAgIH0gZWxzZSBpZiAobm9kZSBpbnN0YW5jZW9mIHQuVGV4dCkge1xuICAgICAgaW5nZXN0VGV4dCh1bml0LCBub2RlLCBudWxsKTtcbiAgICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiB0LkJvdW5kVGV4dCkge1xuICAgICAgaW5nZXN0Qm91bmRUZXh0KHVuaXQsIG5vZGUsIG51bGwpO1xuICAgIH0gZWxzZSBpZiAobm9kZSBpbnN0YW5jZW9mIHQuSWZCbG9jaykge1xuICAgICAgaW5nZXN0SWZCbG9jayh1bml0LCBub2RlKTtcbiAgICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiB0LlN3aXRjaEJsb2NrKSB7XG4gICAgICBpbmdlc3RTd2l0Y2hCbG9jayh1bml0LCBub2RlKTtcbiAgICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiB0LkRlZmVycmVkQmxvY2spIHtcbiAgICAgIGluZ2VzdERlZmVyQmxvY2sodW5pdCwgbm9kZSk7XG4gICAgfSBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgdC5JY3UpIHtcbiAgICAgIGluZ2VzdEljdSh1bml0LCBub2RlKTtcbiAgICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiB0LkZvckxvb3BCbG9jaykge1xuICAgICAgaW5nZXN0Rm9yQmxvY2sodW5pdCwgbm9kZSk7XG4gICAgfSBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgdC5MZXREZWNsYXJhdGlvbikge1xuICAgICAgaW5nZXN0TGV0RGVjbGFyYXRpb24odW5pdCwgbm9kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgdGVtcGxhdGUgbm9kZTogJHtub2RlLmNvbnN0cnVjdG9yLm5hbWV9YCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogSW5nZXN0IGFuIGVsZW1lbnQgQVNUIGZyb20gdGhlIHRlbXBsYXRlIGludG8gdGhlIGdpdmVuIGBWaWV3Q29tcGlsYXRpb25gLlxuICovXG5mdW5jdGlvbiBpbmdlc3RFbGVtZW50KHVuaXQ6IFZpZXdDb21waWxhdGlvblVuaXQsIGVsZW1lbnQ6IHQuRWxlbWVudCk6IHZvaWQge1xuICBpZiAoXG4gICAgZWxlbWVudC5pMThuICE9PSB1bmRlZmluZWQgJiZcbiAgICAhKGVsZW1lbnQuaTE4biBpbnN0YW5jZW9mIGkxOG4uTWVzc2FnZSB8fCBlbGVtZW50LmkxOG4gaW5zdGFuY2VvZiBpMThuLlRhZ1BsYWNlaG9sZGVyKVxuICApIHtcbiAgICB0aHJvdyBFcnJvcihgVW5oYW5kbGVkIGkxOG4gbWV0YWRhdGEgdHlwZSBmb3IgZWxlbWVudDogJHtlbGVtZW50LmkxOG4uY29uc3RydWN0b3IubmFtZX1gKTtcbiAgfVxuXG4gIGNvbnN0IGlkID0gdW5pdC5qb2IuYWxsb2NhdGVYcmVmSWQoKTtcblxuICBjb25zdCBbbmFtZXNwYWNlS2V5LCBlbGVtZW50TmFtZV0gPSBzcGxpdE5zTmFtZShlbGVtZW50Lm5hbWUpO1xuXG4gIGNvbnN0IHN0YXJ0T3AgPSBpci5jcmVhdGVFbGVtZW50U3RhcnRPcChcbiAgICBlbGVtZW50TmFtZSxcbiAgICBpZCxcbiAgICBuYW1lc3BhY2VGb3JLZXkobmFtZXNwYWNlS2V5KSxcbiAgICBlbGVtZW50LmkxOG4gaW5zdGFuY2VvZiBpMThuLlRhZ1BsYWNlaG9sZGVyID8gZWxlbWVudC5pMThuIDogdW5kZWZpbmVkLFxuICAgIGVsZW1lbnQuc3RhcnRTb3VyY2VTcGFuLFxuICAgIGVsZW1lbnQuc291cmNlU3BhbixcbiAgKTtcbiAgdW5pdC5jcmVhdGUucHVzaChzdGFydE9wKTtcblxuICBpbmdlc3RFbGVtZW50QmluZGluZ3ModW5pdCwgc3RhcnRPcCwgZWxlbWVudCk7XG4gIGluZ2VzdFJlZmVyZW5jZXMoc3RhcnRPcCwgZWxlbWVudCk7XG5cbiAgLy8gU3RhcnQgaTE4biwgaWYgbmVlZGVkLCBnb2VzIGFmdGVyIHRoZSBlbGVtZW50IGNyZWF0ZSBhbmQgYmluZGluZ3MsIGJ1dCBiZWZvcmUgdGhlIG5vZGVzXG4gIGxldCBpMThuQmxvY2tJZDogaXIuWHJlZklkIHwgbnVsbCA9IG51bGw7XG4gIGlmIChlbGVtZW50LmkxOG4gaW5zdGFuY2VvZiBpMThuLk1lc3NhZ2UpIHtcbiAgICBpMThuQmxvY2tJZCA9IHVuaXQuam9iLmFsbG9jYXRlWHJlZklkKCk7XG4gICAgdW5pdC5jcmVhdGUucHVzaChcbiAgICAgIGlyLmNyZWF0ZUkxOG5TdGFydE9wKGkxOG5CbG9ja0lkLCBlbGVtZW50LmkxOG4sIHVuZGVmaW5lZCwgZWxlbWVudC5zdGFydFNvdXJjZVNwYW4pLFxuICAgICk7XG4gIH1cblxuICBpbmdlc3ROb2Rlcyh1bml0LCBlbGVtZW50LmNoaWxkcmVuKTtcblxuICAvLyBUaGUgc291cmNlIHNwYW4gZm9yIHRoZSBlbmQgb3AgaXMgdHlwaWNhbGx5IHRoZSBlbGVtZW50IGNsb3NpbmcgdGFnLiBIb3dldmVyLCBpZiBubyBjbG9zaW5nIHRhZ1xuICAvLyBleGlzdHMsIHN1Y2ggYXMgaW4gYDxpbnB1dD5gLCB3ZSB1c2UgdGhlIHN0YXJ0IHNvdXJjZSBzcGFuIGluc3RlYWQuIFVzdWFsbHkgdGhlIHN0YXJ0IGFuZCBlbmRcbiAgLy8gaW5zdHJ1Y3Rpb25zIHdpbGwgYmUgY29sbGFwc2VkIGludG8gb25lIGBlbGVtZW50YCBpbnN0cnVjdGlvbiwgbmVnYXRpbmcgdGhlIHB1cnBvc2Ugb2YgdGhpc1xuICAvLyBmYWxsYmFjaywgYnV0IGluIGNhc2VzIHdoZW4gaXQgaXMgbm90IGNvbGxhcHNlZCAoc3VjaCBhcyBhbiBpbnB1dCB3aXRoIGEgYmluZGluZyksIHdlIHN0aWxsXG4gIC8vIHdhbnQgdG8gbWFwIHRoZSBlbmQgaW5zdHJ1Y3Rpb24gdG8gdGhlIG1haW4gZWxlbWVudC5cbiAgY29uc3QgZW5kT3AgPSBpci5jcmVhdGVFbGVtZW50RW5kT3AoaWQsIGVsZW1lbnQuZW5kU291cmNlU3BhbiA/PyBlbGVtZW50LnN0YXJ0U291cmNlU3Bhbik7XG4gIHVuaXQuY3JlYXRlLnB1c2goZW5kT3ApO1xuXG4gIC8vIElmIHRoZXJlIGlzIGFuIGkxOG4gbWVzc2FnZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBlbGVtZW50LCBpbnNlcnQgaTE4biBzdGFydCBhbmQgZW5kIG9wcy5cbiAgaWYgKGkxOG5CbG9ja0lkICE9PSBudWxsKSB7XG4gICAgaXIuT3BMaXN0Lmluc2VydEJlZm9yZTxpci5DcmVhdGVPcD4oXG4gICAgICBpci5jcmVhdGVJMThuRW5kT3AoaTE4bkJsb2NrSWQsIGVsZW1lbnQuZW5kU291cmNlU3BhbiA/PyBlbGVtZW50LnN0YXJ0U291cmNlU3BhbiksXG4gICAgICBlbmRPcCxcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogSW5nZXN0IGFuIGBuZy10ZW1wbGF0ZWAgbm9kZSBmcm9tIHRoZSBBU1QgaW50byB0aGUgZ2l2ZW4gYFZpZXdDb21waWxhdGlvbmAuXG4gKi9cbmZ1bmN0aW9uIGluZ2VzdFRlbXBsYXRlKHVuaXQ6IFZpZXdDb21waWxhdGlvblVuaXQsIHRtcGw6IHQuVGVtcGxhdGUpOiB2b2lkIHtcbiAgaWYgKFxuICAgIHRtcGwuaTE4biAhPT0gdW5kZWZpbmVkICYmXG4gICAgISh0bXBsLmkxOG4gaW5zdGFuY2VvZiBpMThuLk1lc3NhZ2UgfHwgdG1wbC5pMThuIGluc3RhbmNlb2YgaTE4bi5UYWdQbGFjZWhvbGRlcilcbiAgKSB7XG4gICAgdGhyb3cgRXJyb3IoYFVuaGFuZGxlZCBpMThuIG1ldGFkYXRhIHR5cGUgZm9yIHRlbXBsYXRlOiAke3RtcGwuaTE4bi5jb25zdHJ1Y3Rvci5uYW1lfWApO1xuICB9XG5cbiAgY29uc3QgY2hpbGRWaWV3ID0gdW5pdC5qb2IuYWxsb2NhdGVWaWV3KHVuaXQueHJlZik7XG5cbiAgbGV0IHRhZ05hbWVXaXRob3V0TmFtZXNwYWNlID0gdG1wbC50YWdOYW1lO1xuICBsZXQgbmFtZXNwYWNlUHJlZml4OiBzdHJpbmcgfCBudWxsID0gJyc7XG4gIGlmICh0bXBsLnRhZ05hbWUpIHtcbiAgICBbbmFtZXNwYWNlUHJlZml4LCB0YWdOYW1lV2l0aG91dE5hbWVzcGFjZV0gPSBzcGxpdE5zTmFtZSh0bXBsLnRhZ05hbWUpO1xuICB9XG5cbiAgY29uc3QgaTE4blBsYWNlaG9sZGVyID0gdG1wbC5pMThuIGluc3RhbmNlb2YgaTE4bi5UYWdQbGFjZWhvbGRlciA/IHRtcGwuaTE4biA6IHVuZGVmaW5lZDtcbiAgY29uc3QgbmFtZXNwYWNlID0gbmFtZXNwYWNlRm9yS2V5KG5hbWVzcGFjZVByZWZpeCk7XG4gIGNvbnN0IGZ1bmN0aW9uTmFtZVN1ZmZpeCA9XG4gICAgdGFnTmFtZVdpdGhvdXROYW1lc3BhY2UgPT09IG51bGwgPyAnJyA6IHByZWZpeFdpdGhOYW1lc3BhY2UodGFnTmFtZVdpdGhvdXROYW1lc3BhY2UsIG5hbWVzcGFjZSk7XG4gIGNvbnN0IHRlbXBsYXRlS2luZCA9IGlzUGxhaW5UZW1wbGF0ZSh0bXBsKVxuICAgID8gaXIuVGVtcGxhdGVLaW5kLk5nVGVtcGxhdGVcbiAgICA6IGlyLlRlbXBsYXRlS2luZC5TdHJ1Y3R1cmFsO1xuICBjb25zdCB0ZW1wbGF0ZU9wID0gaXIuY3JlYXRlVGVtcGxhdGVPcChcbiAgICBjaGlsZFZpZXcueHJlZixcbiAgICB0ZW1wbGF0ZUtpbmQsXG4gICAgdGFnTmFtZVdpdGhvdXROYW1lc3BhY2UsXG4gICAgZnVuY3Rpb25OYW1lU3VmZml4LFxuICAgIG5hbWVzcGFjZSxcbiAgICBpMThuUGxhY2Vob2xkZXIsXG4gICAgdG1wbC5zdGFydFNvdXJjZVNwYW4sXG4gICAgdG1wbC5zb3VyY2VTcGFuLFxuICApO1xuICB1bml0LmNyZWF0ZS5wdXNoKHRlbXBsYXRlT3ApO1xuXG4gIGluZ2VzdFRlbXBsYXRlQmluZGluZ3ModW5pdCwgdGVtcGxhdGVPcCwgdG1wbCwgdGVtcGxhdGVLaW5kKTtcbiAgaW5nZXN0UmVmZXJlbmNlcyh0ZW1wbGF0ZU9wLCB0bXBsKTtcbiAgaW5nZXN0Tm9kZXMoY2hpbGRWaWV3LCB0bXBsLmNoaWxkcmVuKTtcblxuICBmb3IgKGNvbnN0IHtuYW1lLCB2YWx1ZX0gb2YgdG1wbC52YXJpYWJsZXMpIHtcbiAgICBjaGlsZFZpZXcuY29udGV4dFZhcmlhYmxlcy5zZXQobmFtZSwgdmFsdWUgIT09ICcnID8gdmFsdWUgOiAnJGltcGxpY2l0Jyk7XG4gIH1cblxuICAvLyBJZiB0aGlzIGlzIGEgcGxhaW4gdGVtcGxhdGUgYW5kIHRoZXJlIGlzIGFuIGkxOG4gbWVzc2FnZSBhc3NvY2lhdGVkIHdpdGggaXQsIGluc2VydCBpMThuIHN0YXJ0XG4gIC8vIGFuZCBlbmQgb3BzLiBGb3Igc3RydWN0dXJhbCBkaXJlY3RpdmUgdGVtcGxhdGVzLCB0aGUgaTE4biBvcHMgd2lsbCBiZSBhZGRlZCB3aGVuIGluZ2VzdGluZyB0aGVcbiAgLy8gZWxlbWVudC90ZW1wbGF0ZSB0aGUgZGlyZWN0aXZlIGlzIHBsYWNlZCBvbi5cbiAgaWYgKHRlbXBsYXRlS2luZCA9PT0gaXIuVGVtcGxhdGVLaW5kLk5nVGVtcGxhdGUgJiYgdG1wbC5pMThuIGluc3RhbmNlb2YgaTE4bi5NZXNzYWdlKSB7XG4gICAgY29uc3QgaWQgPSB1bml0LmpvYi5hbGxvY2F0ZVhyZWZJZCgpO1xuICAgIGlyLk9wTGlzdC5pbnNlcnRBZnRlcihcbiAgICAgIGlyLmNyZWF0ZUkxOG5TdGFydE9wKGlkLCB0bXBsLmkxOG4sIHVuZGVmaW5lZCwgdG1wbC5zdGFydFNvdXJjZVNwYW4pLFxuICAgICAgY2hpbGRWaWV3LmNyZWF0ZS5oZWFkLFxuICAgICk7XG4gICAgaXIuT3BMaXN0Lmluc2VydEJlZm9yZShcbiAgICAgIGlyLmNyZWF0ZUkxOG5FbmRPcChpZCwgdG1wbC5lbmRTb3VyY2VTcGFuID8/IHRtcGwuc3RhcnRTb3VyY2VTcGFuKSxcbiAgICAgIGNoaWxkVmlldy5jcmVhdGUudGFpbCxcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogSW5nZXN0IGEgY29udGVudCBub2RlIGZyb20gdGhlIEFTVCBpbnRvIHRoZSBnaXZlbiBgVmlld0NvbXBpbGF0aW9uYC5cbiAqL1xuZnVuY3Rpb24gaW5nZXN0Q29udGVudCh1bml0OiBWaWV3Q29tcGlsYXRpb25Vbml0LCBjb250ZW50OiB0LkNvbnRlbnQpOiB2b2lkIHtcbiAgaWYgKGNvbnRlbnQuaTE4biAhPT0gdW5kZWZpbmVkICYmICEoY29udGVudC5pMThuIGluc3RhbmNlb2YgaTE4bi5UYWdQbGFjZWhvbGRlcikpIHtcbiAgICB0aHJvdyBFcnJvcihgVW5oYW5kbGVkIGkxOG4gbWV0YWRhdGEgdHlwZSBmb3IgZWxlbWVudDogJHtjb250ZW50LmkxOG4uY29uc3RydWN0b3IubmFtZX1gKTtcbiAgfVxuXG4gIGxldCBmYWxsYmFja1ZpZXc6IFZpZXdDb21waWxhdGlvblVuaXQgfCBudWxsID0gbnVsbDtcblxuICAvLyBEb24ndCBjYXB0dXJlIGRlZmF1bHQgY29udGVudCB0aGF0J3Mgb25seSBtYWRlIHVwIG9mIGVtcHR5IHRleHQgbm9kZXMgYW5kIGNvbW1lbnRzLlxuICAvLyBOb3RlIHRoYXQgd2UgcHJvY2VzcyB0aGUgZGVmYXVsdCBjb250ZW50IGJlZm9yZSB0aGUgcHJvamVjdGlvbiBpbiBvcmRlciB0byBtYXRjaCB0aGVcbiAgLy8gaW5zZXJ0aW9uIG9yZGVyIGF0IHJ1bnRpbWUuXG4gIGlmIChcbiAgICBjb250ZW50LmNoaWxkcmVuLnNvbWUoXG4gICAgICAoY2hpbGQpID0+XG4gICAgICAgICEoY2hpbGQgaW5zdGFuY2VvZiB0LkNvbW1lbnQpICYmXG4gICAgICAgICghKGNoaWxkIGluc3RhbmNlb2YgdC5UZXh0KSB8fCBjaGlsZC52YWx1ZS50cmltKCkubGVuZ3RoID4gMCksXG4gICAgKVxuICApIHtcbiAgICBmYWxsYmFja1ZpZXcgPSB1bml0LmpvYi5hbGxvY2F0ZVZpZXcodW5pdC54cmVmKTtcbiAgICBpbmdlc3ROb2RlcyhmYWxsYmFja1ZpZXcsIGNvbnRlbnQuY2hpbGRyZW4pO1xuICB9XG5cbiAgY29uc3QgaWQgPSB1bml0LmpvYi5hbGxvY2F0ZVhyZWZJZCgpO1xuICBjb25zdCBvcCA9IGlyLmNyZWF0ZVByb2plY3Rpb25PcChcbiAgICBpZCxcbiAgICBjb250ZW50LnNlbGVjdG9yLFxuICAgIGNvbnRlbnQuaTE4bixcbiAgICBmYWxsYmFja1ZpZXc/LnhyZWYgPz8gbnVsbCxcbiAgICBjb250ZW50LnNvdXJjZVNwYW4sXG4gICk7XG4gIGZvciAoY29uc3QgYXR0ciBvZiBjb250ZW50LmF0dHJpYnV0ZXMpIHtcbiAgICBjb25zdCBzZWN1cml0eUNvbnRleHQgPSBkb21TY2hlbWEuc2VjdXJpdHlDb250ZXh0KGNvbnRlbnQubmFtZSwgYXR0ci5uYW1lLCB0cnVlKTtcbiAgICB1bml0LnVwZGF0ZS5wdXNoKFxuICAgICAgaXIuY3JlYXRlQmluZGluZ09wKFxuICAgICAgICBvcC54cmVmLFxuICAgICAgICBpci5CaW5kaW5nS2luZC5BdHRyaWJ1dGUsXG4gICAgICAgIGF0dHIubmFtZSxcbiAgICAgICAgby5saXRlcmFsKGF0dHIudmFsdWUpLFxuICAgICAgICBudWxsLFxuICAgICAgICBzZWN1cml0eUNvbnRleHQsXG4gICAgICAgIHRydWUsXG4gICAgICAgIGZhbHNlLFxuICAgICAgICBudWxsLFxuICAgICAgICBhc01lc3NhZ2UoYXR0ci5pMThuKSxcbiAgICAgICAgYXR0ci5zb3VyY2VTcGFuLFxuICAgICAgKSxcbiAgICApO1xuICB9XG4gIHVuaXQuY3JlYXRlLnB1c2gob3ApO1xufVxuXG4vKipcbiAqIEluZ2VzdCBhIGxpdGVyYWwgdGV4dCBub2RlIGZyb20gdGhlIEFTVCBpbnRvIHRoZSBnaXZlbiBgVmlld0NvbXBpbGF0aW9uYC5cbiAqL1xuZnVuY3Rpb24gaW5nZXN0VGV4dCh1bml0OiBWaWV3Q29tcGlsYXRpb25Vbml0LCB0ZXh0OiB0LlRleHQsIGljdVBsYWNlaG9sZGVyOiBzdHJpbmcgfCBudWxsKTogdm9pZCB7XG4gIHVuaXQuY3JlYXRlLnB1c2goXG4gICAgaXIuY3JlYXRlVGV4dE9wKHVuaXQuam9iLmFsbG9jYXRlWHJlZklkKCksIHRleHQudmFsdWUsIGljdVBsYWNlaG9sZGVyLCB0ZXh0LnNvdXJjZVNwYW4pLFxuICApO1xufVxuXG4vKipcbiAqIEluZ2VzdCBhbiBpbnRlcnBvbGF0ZWQgdGV4dCBub2RlIGZyb20gdGhlIEFTVCBpbnRvIHRoZSBnaXZlbiBgVmlld0NvbXBpbGF0aW9uYC5cbiAqL1xuZnVuY3Rpb24gaW5nZXN0Qm91bmRUZXh0KFxuICB1bml0OiBWaWV3Q29tcGlsYXRpb25Vbml0LFxuICB0ZXh0OiB0LkJvdW5kVGV4dCxcbiAgaWN1UGxhY2Vob2xkZXI6IHN0cmluZyB8IG51bGwsXG4pOiB2b2lkIHtcbiAgbGV0IHZhbHVlID0gdGV4dC52YWx1ZTtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgZS5BU1RXaXRoU291cmNlKSB7XG4gICAgdmFsdWUgPSB2YWx1ZS5hc3Q7XG4gIH1cbiAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBlLkludGVycG9sYXRpb24pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEFzc2VydGlvbkVycm9yOiBleHBlY3RlZCBJbnRlcnBvbGF0aW9uIGZvciBCb3VuZFRleHQgbm9kZSwgZ290ICR7dmFsdWUuY29uc3RydWN0b3IubmFtZX1gLFxuICAgICk7XG4gIH1cbiAgaWYgKHRleHQuaTE4biAhPT0gdW5kZWZpbmVkICYmICEodGV4dC5pMThuIGluc3RhbmNlb2YgaTE4bi5Db250YWluZXIpKSB7XG4gICAgdGhyb3cgRXJyb3IoXG4gICAgICBgVW5oYW5kbGVkIGkxOG4gbWV0YWRhdGEgdHlwZSBmb3IgdGV4dCBpbnRlcnBvbGF0aW9uOiAke3RleHQuaTE4bj8uY29uc3RydWN0b3IubmFtZX1gLFxuICAgICk7XG4gIH1cblxuICBjb25zdCBpMThuUGxhY2Vob2xkZXJzID1cbiAgICB0ZXh0LmkxOG4gaW5zdGFuY2VvZiBpMThuLkNvbnRhaW5lclxuICAgICAgPyB0ZXh0LmkxOG4uY2hpbGRyZW5cbiAgICAgICAgICAuZmlsdGVyKChub2RlKTogbm9kZSBpcyBpMThuLlBsYWNlaG9sZGVyID0+IG5vZGUgaW5zdGFuY2VvZiBpMThuLlBsYWNlaG9sZGVyKVxuICAgICAgICAgIC5tYXAoKHBsYWNlaG9sZGVyKSA9PiBwbGFjZWhvbGRlci5uYW1lKVxuICAgICAgOiBbXTtcbiAgaWYgKGkxOG5QbGFjZWhvbGRlcnMubGVuZ3RoID4gMCAmJiBpMThuUGxhY2Vob2xkZXJzLmxlbmd0aCAhPT0gdmFsdWUuZXhwcmVzc2lvbnMubGVuZ3RoKSB7XG4gICAgdGhyb3cgRXJyb3IoXG4gICAgICBgVW5leHBlY3RlZCBudW1iZXIgb2YgaTE4biBwbGFjZWhvbGRlcnMgKCR7dmFsdWUuZXhwcmVzc2lvbnMubGVuZ3RofSkgZm9yIEJvdW5kVGV4dCB3aXRoICR7dmFsdWUuZXhwcmVzc2lvbnMubGVuZ3RofSBleHByZXNzaW9uc2AsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHRleHRYcmVmID0gdW5pdC5qb2IuYWxsb2NhdGVYcmVmSWQoKTtcbiAgdW5pdC5jcmVhdGUucHVzaChpci5jcmVhdGVUZXh0T3AodGV4dFhyZWYsICcnLCBpY3VQbGFjZWhvbGRlciwgdGV4dC5zb3VyY2VTcGFuKSk7XG4gIC8vIFRlbXBsYXRlRGVmaW5pdGlvbkJ1aWxkZXIgZG9lcyBub3QgZ2VuZXJhdGUgc291cmNlIG1hcHMgZm9yIHN1Yi1leHByZXNzaW9ucyBpbnNpZGUgYW5cbiAgLy8gaW50ZXJwb2xhdGlvbi4gV2UgY29weSB0aGF0IGJlaGF2aW9yIGluIGNvbXBhdGliaWxpdHkgbW9kZS5cbiAgLy8gVE9ETzogaXMgaXQgYWN0dWFsbHkgY29ycmVjdCB0byBnZW5lcmF0ZSB0aGVzZSBleHRyYSBtYXBzIGluIG1vZGVybiBtb2RlP1xuICBjb25zdCBiYXNlU291cmNlU3BhbiA9IHVuaXQuam9iLmNvbXBhdGliaWxpdHkgPyBudWxsIDogdGV4dC5zb3VyY2VTcGFuO1xuICB1bml0LnVwZGF0ZS5wdXNoKFxuICAgIGlyLmNyZWF0ZUludGVycG9sYXRlVGV4dE9wKFxuICAgICAgdGV4dFhyZWYsXG4gICAgICBuZXcgaXIuSW50ZXJwb2xhdGlvbihcbiAgICAgICAgdmFsdWUuc3RyaW5ncyxcbiAgICAgICAgdmFsdWUuZXhwcmVzc2lvbnMubWFwKChleHByKSA9PiBjb252ZXJ0QXN0KGV4cHIsIHVuaXQuam9iLCBiYXNlU291cmNlU3BhbikpLFxuICAgICAgICBpMThuUGxhY2Vob2xkZXJzLFxuICAgICAgKSxcbiAgICAgIHRleHQuc291cmNlU3BhbixcbiAgICApLFxuICApO1xufVxuXG4vKipcbiAqIEluZ2VzdCBhbiBgQGlmYCBibG9jayBpbnRvIHRoZSBnaXZlbiBgVmlld0NvbXBpbGF0aW9uYC5cbiAqL1xuZnVuY3Rpb24gaW5nZXN0SWZCbG9jayh1bml0OiBWaWV3Q29tcGlsYXRpb25Vbml0LCBpZkJsb2NrOiB0LklmQmxvY2spOiB2b2lkIHtcbiAgbGV0IGZpcnN0WHJlZjogaXIuWHJlZklkIHwgbnVsbCA9IG51bGw7XG4gIGxldCBjb25kaXRpb25zOiBBcnJheTxpci5Db25kaXRpb25hbENhc2VFeHByPiA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGlmQmxvY2suYnJhbmNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBpZkNhc2UgPSBpZkJsb2NrLmJyYW5jaGVzW2ldO1xuICAgIGNvbnN0IGNWaWV3ID0gdW5pdC5qb2IuYWxsb2NhdGVWaWV3KHVuaXQueHJlZik7XG4gICAgY29uc3QgdGFnTmFtZSA9IGluZ2VzdENvbnRyb2xGbG93SW5zZXJ0aW9uUG9pbnQodW5pdCwgY1ZpZXcueHJlZiwgaWZDYXNlKTtcblxuICAgIGlmIChpZkNhc2UuZXhwcmVzc2lvbkFsaWFzICE9PSBudWxsKSB7XG4gICAgICBjVmlldy5jb250ZXh0VmFyaWFibGVzLnNldChpZkNhc2UuZXhwcmVzc2lvbkFsaWFzLm5hbWUsIGlyLkNUWF9SRUYpO1xuICAgIH1cblxuICAgIGxldCBpZkNhc2VJMThuTWV0YTogaTE4bi5CbG9ja1BsYWNlaG9sZGVyIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIGlmIChpZkNhc2UuaTE4biAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoIShpZkNhc2UuaTE4biBpbnN0YW5jZW9mIGkxOG4uQmxvY2tQbGFjZWhvbGRlcikpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoYFVuaGFuZGxlZCBpMThuIG1ldGFkYXRhIHR5cGUgZm9yIGlmIGJsb2NrOiAke2lmQ2FzZS5pMThuPy5jb25zdHJ1Y3Rvci5uYW1lfWApO1xuICAgICAgfVxuICAgICAgaWZDYXNlSTE4bk1ldGEgPSBpZkNhc2UuaTE4bjtcbiAgICB9XG5cbiAgICBjb25zdCB0ZW1wbGF0ZU9wID0gaXIuY3JlYXRlVGVtcGxhdGVPcChcbiAgICAgIGNWaWV3LnhyZWYsXG4gICAgICBpci5UZW1wbGF0ZUtpbmQuQmxvY2ssXG4gICAgICB0YWdOYW1lLFxuICAgICAgJ0NvbmRpdGlvbmFsJyxcbiAgICAgIGlyLk5hbWVzcGFjZS5IVE1MLFxuICAgICAgaWZDYXNlSTE4bk1ldGEsXG4gICAgICBpZkNhc2Uuc3RhcnRTb3VyY2VTcGFuLFxuICAgICAgaWZDYXNlLnNvdXJjZVNwYW4sXG4gICAgKTtcbiAgICB1bml0LmNyZWF0ZS5wdXNoKHRlbXBsYXRlT3ApO1xuXG4gICAgaWYgKGZpcnN0WHJlZiA9PT0gbnVsbCkge1xuICAgICAgZmlyc3RYcmVmID0gY1ZpZXcueHJlZjtcbiAgICB9XG5cbiAgICBjb25zdCBjYXNlRXhwciA9IGlmQ2FzZS5leHByZXNzaW9uID8gY29udmVydEFzdChpZkNhc2UuZXhwcmVzc2lvbiwgdW5pdC5qb2IsIG51bGwpIDogbnVsbDtcbiAgICBjb25zdCBjb25kaXRpb25hbENhc2VFeHByID0gbmV3IGlyLkNvbmRpdGlvbmFsQ2FzZUV4cHIoXG4gICAgICBjYXNlRXhwcixcbiAgICAgIHRlbXBsYXRlT3AueHJlZixcbiAgICAgIHRlbXBsYXRlT3AuaGFuZGxlLFxuICAgICAgaWZDYXNlLmV4cHJlc3Npb25BbGlhcyxcbiAgICApO1xuICAgIGNvbmRpdGlvbnMucHVzaChjb25kaXRpb25hbENhc2VFeHByKTtcbiAgICBpbmdlc3ROb2RlcyhjVmlldywgaWZDYXNlLmNoaWxkcmVuKTtcbiAgfVxuICB1bml0LnVwZGF0ZS5wdXNoKGlyLmNyZWF0ZUNvbmRpdGlvbmFsT3AoZmlyc3RYcmVmISwgbnVsbCwgY29uZGl0aW9ucywgaWZCbG9jay5zb3VyY2VTcGFuKSk7XG59XG5cbi8qKlxuICogSW5nZXN0IGFuIGBAc3dpdGNoYCBibG9jayBpbnRvIHRoZSBnaXZlbiBgVmlld0NvbXBpbGF0aW9uYC5cbiAqL1xuZnVuY3Rpb24gaW5nZXN0U3dpdGNoQmxvY2sodW5pdDogVmlld0NvbXBpbGF0aW9uVW5pdCwgc3dpdGNoQmxvY2s6IHQuU3dpdGNoQmxvY2spOiB2b2lkIHtcbiAgLy8gRG9uJ3QgaW5nZXN0IGVtcHR5IHN3aXRjaGVzIHNpbmNlIHRoZXkgd29uJ3QgcmVuZGVyIGFueXRoaW5nLlxuICBpZiAoc3dpdGNoQmxvY2suY2FzZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbGV0IGZpcnN0WHJlZjogaXIuWHJlZklkIHwgbnVsbCA9IG51bGw7XG4gIGxldCBjb25kaXRpb25zOiBBcnJheTxpci5Db25kaXRpb25hbENhc2VFeHByPiA9IFtdO1xuICBmb3IgKGNvbnN0IHN3aXRjaENhc2Ugb2Ygc3dpdGNoQmxvY2suY2FzZXMpIHtcbiAgICBjb25zdCBjVmlldyA9IHVuaXQuam9iLmFsbG9jYXRlVmlldyh1bml0LnhyZWYpO1xuICAgIGNvbnN0IHRhZ05hbWUgPSBpbmdlc3RDb250cm9sRmxvd0luc2VydGlvblBvaW50KHVuaXQsIGNWaWV3LnhyZWYsIHN3aXRjaENhc2UpO1xuICAgIGxldCBzd2l0Y2hDYXNlSTE4bk1ldGE6IGkxOG4uQmxvY2tQbGFjZWhvbGRlciB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICBpZiAoc3dpdGNoQ2FzZS5pMThuICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICghKHN3aXRjaENhc2UuaTE4biBpbnN0YW5jZW9mIGkxOG4uQmxvY2tQbGFjZWhvbGRlcikpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgYFVuaGFuZGxlZCBpMThuIG1ldGFkYXRhIHR5cGUgZm9yIHN3aXRjaCBibG9jazogJHtzd2l0Y2hDYXNlLmkxOG4/LmNvbnN0cnVjdG9yLm5hbWV9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHN3aXRjaENhc2VJMThuTWV0YSA9IHN3aXRjaENhc2UuaTE4bjtcbiAgICB9XG4gICAgY29uc3QgdGVtcGxhdGVPcCA9IGlyLmNyZWF0ZVRlbXBsYXRlT3AoXG4gICAgICBjVmlldy54cmVmLFxuICAgICAgaXIuVGVtcGxhdGVLaW5kLkJsb2NrLFxuICAgICAgdGFnTmFtZSxcbiAgICAgICdDYXNlJyxcbiAgICAgIGlyLk5hbWVzcGFjZS5IVE1MLFxuICAgICAgc3dpdGNoQ2FzZUkxOG5NZXRhLFxuICAgICAgc3dpdGNoQ2FzZS5zdGFydFNvdXJjZVNwYW4sXG4gICAgICBzd2l0Y2hDYXNlLnNvdXJjZVNwYW4sXG4gICAgKTtcbiAgICB1bml0LmNyZWF0ZS5wdXNoKHRlbXBsYXRlT3ApO1xuICAgIGlmIChmaXJzdFhyZWYgPT09IG51bGwpIHtcbiAgICAgIGZpcnN0WHJlZiA9IGNWaWV3LnhyZWY7XG4gICAgfVxuICAgIGNvbnN0IGNhc2VFeHByID0gc3dpdGNoQ2FzZS5leHByZXNzaW9uXG4gICAgICA/IGNvbnZlcnRBc3Qoc3dpdGNoQ2FzZS5leHByZXNzaW9uLCB1bml0LmpvYiwgc3dpdGNoQmxvY2suc3RhcnRTb3VyY2VTcGFuKVxuICAgICAgOiBudWxsO1xuICAgIGNvbnN0IGNvbmRpdGlvbmFsQ2FzZUV4cHIgPSBuZXcgaXIuQ29uZGl0aW9uYWxDYXNlRXhwcihcbiAgICAgIGNhc2VFeHByLFxuICAgICAgdGVtcGxhdGVPcC54cmVmLFxuICAgICAgdGVtcGxhdGVPcC5oYW5kbGUsXG4gICAgKTtcbiAgICBjb25kaXRpb25zLnB1c2goY29uZGl0aW9uYWxDYXNlRXhwcik7XG4gICAgaW5nZXN0Tm9kZXMoY1ZpZXcsIHN3aXRjaENhc2UuY2hpbGRyZW4pO1xuICB9XG4gIHVuaXQudXBkYXRlLnB1c2goXG4gICAgaXIuY3JlYXRlQ29uZGl0aW9uYWxPcChcbiAgICAgIGZpcnN0WHJlZiEsXG4gICAgICBjb252ZXJ0QXN0KHN3aXRjaEJsb2NrLmV4cHJlc3Npb24sIHVuaXQuam9iLCBudWxsKSxcbiAgICAgIGNvbmRpdGlvbnMsXG4gICAgICBzd2l0Y2hCbG9jay5zb3VyY2VTcGFuLFxuICAgICksXG4gICk7XG59XG5cbmZ1bmN0aW9uIGluZ2VzdERlZmVyVmlldyhcbiAgdW5pdDogVmlld0NvbXBpbGF0aW9uVW5pdCxcbiAgc3VmZml4OiBzdHJpbmcsXG4gIGkxOG5NZXRhOiBpMThuLkkxOG5NZXRhIHwgdW5kZWZpbmVkLFxuICBjaGlsZHJlbj86IHQuTm9kZVtdLFxuICBzb3VyY2VTcGFuPzogUGFyc2VTb3VyY2VTcGFuLFxuKTogaXIuVGVtcGxhdGVPcCB8IG51bGwge1xuICBpZiAoaTE4bk1ldGEgIT09IHVuZGVmaW5lZCAmJiAhKGkxOG5NZXRhIGluc3RhbmNlb2YgaTE4bi5CbG9ja1BsYWNlaG9sZGVyKSkge1xuICAgIHRocm93IEVycm9yKCdVbmhhbmRsZWQgaTE4biBtZXRhZGF0YSB0eXBlIGZvciBkZWZlciBibG9jaycpO1xuICB9XG4gIGlmIChjaGlsZHJlbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3Qgc2Vjb25kYXJ5VmlldyA9IHVuaXQuam9iLmFsbG9jYXRlVmlldyh1bml0LnhyZWYpO1xuICBpbmdlc3ROb2RlcyhzZWNvbmRhcnlWaWV3LCBjaGlsZHJlbik7XG4gIGNvbnN0IHRlbXBsYXRlT3AgPSBpci5jcmVhdGVUZW1wbGF0ZU9wKFxuICAgIHNlY29uZGFyeVZpZXcueHJlZixcbiAgICBpci5UZW1wbGF0ZUtpbmQuQmxvY2ssXG4gICAgbnVsbCxcbiAgICBgRGVmZXIke3N1ZmZpeH1gLFxuICAgIGlyLk5hbWVzcGFjZS5IVE1MLFxuICAgIGkxOG5NZXRhLFxuICAgIHNvdXJjZVNwYW4hLFxuICAgIHNvdXJjZVNwYW4hLFxuICApO1xuICB1bml0LmNyZWF0ZS5wdXNoKHRlbXBsYXRlT3ApO1xuICByZXR1cm4gdGVtcGxhdGVPcDtcbn1cblxuZnVuY3Rpb24gaW5nZXN0RGVmZXJCbG9jayh1bml0OiBWaWV3Q29tcGlsYXRpb25Vbml0LCBkZWZlckJsb2NrOiB0LkRlZmVycmVkQmxvY2spOiB2b2lkIHtcbiAgbGV0IG93blJlc29sdmVyRm46IG8uRXhwcmVzc2lvbiB8IG51bGwgPSBudWxsO1xuXG4gIGlmICh1bml0LmpvYi5kZWZlck1ldGEubW9kZSA9PT0gRGVmZXJCbG9ja0RlcHNFbWl0TW9kZS5QZXJCbG9jaykge1xuICAgIGlmICghdW5pdC5qb2IuZGVmZXJNZXRhLmJsb2Nrcy5oYXMoZGVmZXJCbG9jaykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEFzc2VydGlvbkVycm9yOiB1bmFibGUgdG8gZmluZCBhIGRlcGVuZGVuY3kgZnVuY3Rpb24gZm9yIHRoaXMgZGVmZXJyZWQgYmxvY2tgLFxuICAgICAgKTtcbiAgICB9XG4gICAgb3duUmVzb2x2ZXJGbiA9IHVuaXQuam9iLmRlZmVyTWV0YS5ibG9ja3MuZ2V0KGRlZmVyQmxvY2spID8/IG51bGw7XG4gIH1cblxuICAvLyBHZW5lcmF0ZSB0aGUgZGVmZXIgbWFpbiB2aWV3IGFuZCBhbGwgc2Vjb25kYXJ5IHZpZXdzLlxuICBjb25zdCBtYWluID0gaW5nZXN0RGVmZXJWaWV3KFxuICAgIHVuaXQsXG4gICAgJycsXG4gICAgZGVmZXJCbG9jay5pMThuLFxuICAgIGRlZmVyQmxvY2suY2hpbGRyZW4sXG4gICAgZGVmZXJCbG9jay5zb3VyY2VTcGFuLFxuICApITtcbiAgY29uc3QgbG9hZGluZyA9IGluZ2VzdERlZmVyVmlldyhcbiAgICB1bml0LFxuICAgICdMb2FkaW5nJyxcbiAgICBkZWZlckJsb2NrLmxvYWRpbmc/LmkxOG4sXG4gICAgZGVmZXJCbG9jay5sb2FkaW5nPy5jaGlsZHJlbixcbiAgICBkZWZlckJsb2NrLmxvYWRpbmc/LnNvdXJjZVNwYW4sXG4gICk7XG4gIGNvbnN0IHBsYWNlaG9sZGVyID0gaW5nZXN0RGVmZXJWaWV3KFxuICAgIHVuaXQsXG4gICAgJ1BsYWNlaG9sZGVyJyxcbiAgICBkZWZlckJsb2NrLnBsYWNlaG9sZGVyPy5pMThuLFxuICAgIGRlZmVyQmxvY2sucGxhY2Vob2xkZXI/LmNoaWxkcmVuLFxuICAgIGRlZmVyQmxvY2sucGxhY2Vob2xkZXI/LnNvdXJjZVNwYW4sXG4gICk7XG4gIGNvbnN0IGVycm9yID0gaW5nZXN0RGVmZXJWaWV3KFxuICAgIHVuaXQsXG4gICAgJ0Vycm9yJyxcbiAgICBkZWZlckJsb2NrLmVycm9yPy5pMThuLFxuICAgIGRlZmVyQmxvY2suZXJyb3I/LmNoaWxkcmVuLFxuICAgIGRlZmVyQmxvY2suZXJyb3I/LnNvdXJjZVNwYW4sXG4gICk7XG5cbiAgLy8gQ3JlYXRlIHRoZSBtYWluIGRlZmVyIG9wLCBhbmQgb3BzIGZvciBhbGwgc2Vjb25kYXJ5IHZpZXdzLlxuICBjb25zdCBkZWZlclhyZWYgPSB1bml0LmpvYi5hbGxvY2F0ZVhyZWZJZCgpO1xuICBjb25zdCBkZWZlck9wID0gaXIuY3JlYXRlRGVmZXJPcChcbiAgICBkZWZlclhyZWYsXG4gICAgbWFpbi54cmVmLFxuICAgIG1haW4uaGFuZGxlLFxuICAgIG93blJlc29sdmVyRm4sXG4gICAgdW5pdC5qb2IuYWxsRGVmZXJyYWJsZURlcHNGbixcbiAgICBkZWZlckJsb2NrLnNvdXJjZVNwYW4sXG4gICk7XG4gIGRlZmVyT3AucGxhY2Vob2xkZXJWaWV3ID0gcGxhY2Vob2xkZXI/LnhyZWYgPz8gbnVsbDtcbiAgZGVmZXJPcC5wbGFjZWhvbGRlclNsb3QgPSBwbGFjZWhvbGRlcj8uaGFuZGxlID8/IG51bGw7XG4gIGRlZmVyT3AubG9hZGluZ1Nsb3QgPSBsb2FkaW5nPy5oYW5kbGUgPz8gbnVsbDtcbiAgZGVmZXJPcC5lcnJvclNsb3QgPSBlcnJvcj8uaGFuZGxlID8/IG51bGw7XG4gIGRlZmVyT3AucGxhY2Vob2xkZXJNaW5pbXVtVGltZSA9IGRlZmVyQmxvY2sucGxhY2Vob2xkZXI/Lm1pbmltdW1UaW1lID8/IG51bGw7XG4gIGRlZmVyT3AubG9hZGluZ01pbmltdW1UaW1lID0gZGVmZXJCbG9jay5sb2FkaW5nPy5taW5pbXVtVGltZSA/PyBudWxsO1xuICBkZWZlck9wLmxvYWRpbmdBZnRlclRpbWUgPSBkZWZlckJsb2NrLmxvYWRpbmc/LmFmdGVyVGltZSA/PyBudWxsO1xuICB1bml0LmNyZWF0ZS5wdXNoKGRlZmVyT3ApO1xuXG4gIC8vIENvbmZpZ3VyZSBhbGwgZGVmZXIgYG9uYCBjb25kaXRpb25zLlxuICAvLyBUT0RPOiByZWZhY3RvciBwcmVmZXRjaCB0cmlnZ2VycyB0byB1c2UgYSBzZXBhcmF0ZSBvcCB0eXBlLCB3aXRoIGEgc2hhcmVkIHN1cGVyY2xhc3MuIFRoaXMgd2lsbFxuICAvLyBtYWtlIGl0IGVhc2llciB0byByZWZhY3RvciBwcmVmZXRjaCBiZWhhdmlvciBpbiB0aGUgZnV0dXJlLlxuICBsZXQgcHJlZmV0Y2ggPSBmYWxzZTtcbiAgbGV0IGRlZmVyT25PcHM6IGlyLkRlZmVyT25PcFtdID0gW107XG4gIGxldCBkZWZlcldoZW5PcHM6IGlyLkRlZmVyV2hlbk9wW10gPSBbXTtcbiAgZm9yIChjb25zdCB0cmlnZ2VycyBvZiBbZGVmZXJCbG9jay50cmlnZ2VycywgZGVmZXJCbG9jay5wcmVmZXRjaFRyaWdnZXJzXSkge1xuICAgIGlmICh0cmlnZ2Vycy5pZGxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGRlZmVyT25PcCA9IGlyLmNyZWF0ZURlZmVyT25PcChcbiAgICAgICAgZGVmZXJYcmVmLFxuICAgICAgICB7a2luZDogaXIuRGVmZXJUcmlnZ2VyS2luZC5JZGxlfSxcbiAgICAgICAgcHJlZmV0Y2gsXG4gICAgICAgIHRyaWdnZXJzLmlkbGUuc291cmNlU3BhbixcbiAgICAgICk7XG4gICAgICBkZWZlck9uT3BzLnB1c2goZGVmZXJPbk9wKTtcbiAgICB9XG4gICAgaWYgKHRyaWdnZXJzLmltbWVkaWF0ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBkZWZlck9uT3AgPSBpci5jcmVhdGVEZWZlck9uT3AoXG4gICAgICAgIGRlZmVyWHJlZixcbiAgICAgICAge2tpbmQ6IGlyLkRlZmVyVHJpZ2dlcktpbmQuSW1tZWRpYXRlfSxcbiAgICAgICAgcHJlZmV0Y2gsXG4gICAgICAgIHRyaWdnZXJzLmltbWVkaWF0ZS5zb3VyY2VTcGFuLFxuICAgICAgKTtcbiAgICAgIGRlZmVyT25PcHMucHVzaChkZWZlck9uT3ApO1xuICAgIH1cbiAgICBpZiAodHJpZ2dlcnMudGltZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZGVmZXJPbk9wID0gaXIuY3JlYXRlRGVmZXJPbk9wKFxuICAgICAgICBkZWZlclhyZWYsXG4gICAgICAgIHtraW5kOiBpci5EZWZlclRyaWdnZXJLaW5kLlRpbWVyLCBkZWxheTogdHJpZ2dlcnMudGltZXIuZGVsYXl9LFxuICAgICAgICBwcmVmZXRjaCxcbiAgICAgICAgdHJpZ2dlcnMudGltZXIuc291cmNlU3BhbixcbiAgICAgICk7XG4gICAgICBkZWZlck9uT3BzLnB1c2goZGVmZXJPbk9wKTtcbiAgICB9XG4gICAgaWYgKHRyaWdnZXJzLmhvdmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGRlZmVyT25PcCA9IGlyLmNyZWF0ZURlZmVyT25PcChcbiAgICAgICAgZGVmZXJYcmVmLFxuICAgICAgICB7XG4gICAgICAgICAga2luZDogaXIuRGVmZXJUcmlnZ2VyS2luZC5Ib3ZlcixcbiAgICAgICAgICB0YXJnZXROYW1lOiB0cmlnZ2Vycy5ob3Zlci5yZWZlcmVuY2UsXG4gICAgICAgICAgdGFyZ2V0WHJlZjogbnVsbCxcbiAgICAgICAgICB0YXJnZXRTbG90OiBudWxsLFxuICAgICAgICAgIHRhcmdldFZpZXc6IG51bGwsXG4gICAgICAgICAgdGFyZ2V0U2xvdFZpZXdTdGVwczogbnVsbCxcbiAgICAgICAgfSxcbiAgICAgICAgcHJlZmV0Y2gsXG4gICAgICAgIHRyaWdnZXJzLmhvdmVyLnNvdXJjZVNwYW4sXG4gICAgICApO1xuICAgICAgZGVmZXJPbk9wcy5wdXNoKGRlZmVyT25PcCk7XG4gICAgfVxuICAgIGlmICh0cmlnZ2Vycy5pbnRlcmFjdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBkZWZlck9uT3AgPSBpci5jcmVhdGVEZWZlck9uT3AoXG4gICAgICAgIGRlZmVyWHJlZixcbiAgICAgICAge1xuICAgICAgICAgIGtpbmQ6IGlyLkRlZmVyVHJpZ2dlcktpbmQuSW50ZXJhY3Rpb24sXG4gICAgICAgICAgdGFyZ2V0TmFtZTogdHJpZ2dlcnMuaW50ZXJhY3Rpb24ucmVmZXJlbmNlLFxuICAgICAgICAgIHRhcmdldFhyZWY6IG51bGwsXG4gICAgICAgICAgdGFyZ2V0U2xvdDogbnVsbCxcbiAgICAgICAgICB0YXJnZXRWaWV3OiBudWxsLFxuICAgICAgICAgIHRhcmdldFNsb3RWaWV3U3RlcHM6IG51bGwsXG4gICAgICAgIH0sXG4gICAgICAgIHByZWZldGNoLFxuICAgICAgICB0cmlnZ2Vycy5pbnRlcmFjdGlvbi5zb3VyY2VTcGFuLFxuICAgICAgKTtcbiAgICAgIGRlZmVyT25PcHMucHVzaChkZWZlck9uT3ApO1xuICAgIH1cbiAgICBpZiAodHJpZ2dlcnMudmlld3BvcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZGVmZXJPbk9wID0gaXIuY3JlYXRlRGVmZXJPbk9wKFxuICAgICAgICBkZWZlclhyZWYsXG4gICAgICAgIHtcbiAgICAgICAgICBraW5kOiBpci5EZWZlclRyaWdnZXJLaW5kLlZpZXdwb3J0LFxuICAgICAgICAgIHRhcmdldE5hbWU6IHRyaWdnZXJzLnZpZXdwb3J0LnJlZmVyZW5jZSxcbiAgICAgICAgICB0YXJnZXRYcmVmOiBudWxsLFxuICAgICAgICAgIHRhcmdldFNsb3Q6IG51bGwsXG4gICAgICAgICAgdGFyZ2V0VmlldzogbnVsbCxcbiAgICAgICAgICB0YXJnZXRTbG90Vmlld1N0ZXBzOiBudWxsLFxuICAgICAgICB9LFxuICAgICAgICBwcmVmZXRjaCxcbiAgICAgICAgdHJpZ2dlcnMudmlld3BvcnQuc291cmNlU3BhbixcbiAgICAgICk7XG4gICAgICBkZWZlck9uT3BzLnB1c2goZGVmZXJPbk9wKTtcbiAgICB9XG4gICAgaWYgKHRyaWdnZXJzLndoZW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHRyaWdnZXJzLndoZW4udmFsdWUgaW5zdGFuY2VvZiBlLkludGVycG9sYXRpb24pIHtcbiAgICAgICAgLy8gVGVtcGxhdGVEZWZpbml0aW9uQnVpbGRlciBzdXBwb3J0cyB0aGlzIGNhc2UsIGJ1dCBpdCdzIHZlcnkgc3RyYW5nZSB0byBtZS4gV2hhdCB3b3VsZCBpdFxuICAgICAgICAvLyBldmVuIG1lYW4/XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBpbnRlcnBvbGF0aW9uIGluIGRlZmVyIGJsb2NrIHdoZW4gdHJpZ2dlcmApO1xuICAgICAgfVxuICAgICAgY29uc3QgZGVmZXJPbk9wID0gaXIuY3JlYXRlRGVmZXJXaGVuT3AoXG4gICAgICAgIGRlZmVyWHJlZixcbiAgICAgICAgY29udmVydEFzdCh0cmlnZ2Vycy53aGVuLnZhbHVlLCB1bml0LmpvYiwgdHJpZ2dlcnMud2hlbi5zb3VyY2VTcGFuKSxcbiAgICAgICAgcHJlZmV0Y2gsXG4gICAgICAgIHRyaWdnZXJzLndoZW4uc291cmNlU3BhbixcbiAgICAgICk7XG4gICAgICBkZWZlcldoZW5PcHMucHVzaChkZWZlck9uT3ApO1xuICAgIH1cblxuICAgIC8vIElmIG5vIChub24tcHJlZmV0Y2hpbmcpIGRlZmVyIHRyaWdnZXJzIHdlcmUgcHJvdmlkZWQsIGRlZmF1bHQgdG8gYGlkbGVgLlxuICAgIGlmIChkZWZlck9uT3BzLmxlbmd0aCA9PT0gMCAmJiBkZWZlcldoZW5PcHMubGVuZ3RoID09PSAwKSB7XG4gICAgICBkZWZlck9uT3BzLnB1c2goXG4gICAgICAgIGlyLmNyZWF0ZURlZmVyT25PcChkZWZlclhyZWYsIHtraW5kOiBpci5EZWZlclRyaWdnZXJLaW5kLklkbGV9LCBmYWxzZSwgbnVsbCEpLFxuICAgICAgKTtcbiAgICB9XG4gICAgcHJlZmV0Y2ggPSB0cnVlO1xuICB9XG5cbiAgdW5pdC5jcmVhdGUucHVzaChkZWZlck9uT3BzKTtcbiAgdW5pdC51cGRhdGUucHVzaChkZWZlcldoZW5PcHMpO1xufVxuXG5mdW5jdGlvbiBpbmdlc3RJY3UodW5pdDogVmlld0NvbXBpbGF0aW9uVW5pdCwgaWN1OiB0LkljdSkge1xuICBpZiAoaWN1LmkxOG4gaW5zdGFuY2VvZiBpMThuLk1lc3NhZ2UgJiYgaXNTaW5nbGVJMThuSWN1KGljdS5pMThuKSkge1xuICAgIGNvbnN0IHhyZWYgPSB1bml0LmpvYi5hbGxvY2F0ZVhyZWZJZCgpO1xuICAgIHVuaXQuY3JlYXRlLnB1c2goaXIuY3JlYXRlSWN1U3RhcnRPcCh4cmVmLCBpY3UuaTE4biwgaWN1RnJvbUkxOG5NZXNzYWdlKGljdS5pMThuKS5uYW1lLCBudWxsISkpO1xuICAgIGZvciAoY29uc3QgW3BsYWNlaG9sZGVyLCB0ZXh0XSBvZiBPYmplY3QuZW50cmllcyh7Li4uaWN1LnZhcnMsIC4uLmljdS5wbGFjZWhvbGRlcnN9KSkge1xuICAgICAgaWYgKHRleHQgaW5zdGFuY2VvZiB0LkJvdW5kVGV4dCkge1xuICAgICAgICBpbmdlc3RCb3VuZFRleHQodW5pdCwgdGV4dCwgcGxhY2Vob2xkZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW5nZXN0VGV4dCh1bml0LCB0ZXh0LCBwbGFjZWhvbGRlcik7XG4gICAgICB9XG4gICAgfVxuICAgIHVuaXQuY3JlYXRlLnB1c2goaXIuY3JlYXRlSWN1RW5kT3AoeHJlZikpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IEVycm9yKGBVbmhhbmRsZWQgaTE4biBtZXRhZGF0YSB0eXBlIGZvciBJQ1U6ICR7aWN1LmkxOG4/LmNvbnN0cnVjdG9yLm5hbWV9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBJbmdlc3QgYW4gYEBmb3JgIGJsb2NrIGludG8gdGhlIGdpdmVuIGBWaWV3Q29tcGlsYXRpb25gLlxuICovXG5mdW5jdGlvbiBpbmdlc3RGb3JCbG9jayh1bml0OiBWaWV3Q29tcGlsYXRpb25Vbml0LCBmb3JCbG9jazogdC5Gb3JMb29wQmxvY2spOiB2b2lkIHtcbiAgY29uc3QgcmVwZWF0ZXJWaWV3ID0gdW5pdC5qb2IuYWxsb2NhdGVWaWV3KHVuaXQueHJlZik7XG5cbiAgLy8gV2UgY29weSBUZW1wbGF0ZURlZmluaXRpb25CdWlsZGVyJ3Mgc2NoZW1lIG9mIGNyZWF0aW5nIG5hbWVzIGZvciBgJGNvdW50YCBhbmQgYCRpbmRleGBcbiAgLy8gdGhhdCBhcmUgc3VmZml4ZWQgd2l0aCBzcGVjaWFsIGluZm9ybWF0aW9uLCB0byBkaXNhbWJpZ3VhdGUgd2hpY2ggbGV2ZWwgb2YgbmVzdGVkIGxvb3BcbiAgLy8gdGhlIGJlbG93IGFsaWFzZXMgcmVmZXIgdG8uXG4gIC8vIFRPRE86IFdlIHNob3VsZCByZWZhY3RvciBUZW1wbGF0ZSBQaXBlbGluZSdzIHZhcmlhYmxlIHBoYXNlcyB0byBncmFjZWZ1bGx5IGhhbmRsZVxuICAvLyBzaGFkb3dpbmcsIGFuZCBhcmJpdHJhcmlseSBtYW55IGxldmVscyBvZiB2YXJpYWJsZXMgZGVwZW5kaW5nIG9uIGVhY2ggb3RoZXIuXG4gIGNvbnN0IGluZGV4TmFtZSA9IGDJtSRpbmRleF8ke3JlcGVhdGVyVmlldy54cmVmfWA7XG4gIGNvbnN0IGNvdW50TmFtZSA9IGDJtSRjb3VudF8ke3JlcGVhdGVyVmlldy54cmVmfWA7XG4gIGNvbnN0IGluZGV4VmFyTmFtZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAvLyBTZXQgYWxsIHRoZSBjb250ZXh0IHZhcmlhYmxlcyBhbmQgYWxpYXNlcyBhdmFpbGFibGUgaW4gdGhlIHJlcGVhdGVyLlxuICByZXBlYXRlclZpZXcuY29udGV4dFZhcmlhYmxlcy5zZXQoZm9yQmxvY2suaXRlbS5uYW1lLCBmb3JCbG9jay5pdGVtLnZhbHVlKTtcblxuICBmb3IgKGNvbnN0IHZhcmlhYmxlIG9mIGZvckJsb2NrLmNvbnRleHRWYXJpYWJsZXMpIHtcbiAgICBpZiAodmFyaWFibGUudmFsdWUgPT09ICckaW5kZXgnKSB7XG4gICAgICBpbmRleFZhck5hbWVzLmFkZCh2YXJpYWJsZS5uYW1lKTtcbiAgICB9XG4gICAgaWYgKHZhcmlhYmxlLm5hbWUgPT09ICckaW5kZXgnKSB7XG4gICAgICByZXBlYXRlclZpZXcuY29udGV4dFZhcmlhYmxlcy5zZXQoJyRpbmRleCcsIHZhcmlhYmxlLnZhbHVlKS5zZXQoaW5kZXhOYW1lLCB2YXJpYWJsZS52YWx1ZSk7XG4gICAgfSBlbHNlIGlmICh2YXJpYWJsZS5uYW1lID09PSAnJGNvdW50Jykge1xuICAgICAgcmVwZWF0ZXJWaWV3LmNvbnRleHRWYXJpYWJsZXMuc2V0KCckY291bnQnLCB2YXJpYWJsZS52YWx1ZSkuc2V0KGNvdW50TmFtZSwgdmFyaWFibGUudmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXBlYXRlclZpZXcuYWxpYXNlcy5hZGQoe1xuICAgICAgICBraW5kOiBpci5TZW1hbnRpY1ZhcmlhYmxlS2luZC5BbGlhcyxcbiAgICAgICAgbmFtZTogbnVsbCxcbiAgICAgICAgaWRlbnRpZmllcjogdmFyaWFibGUubmFtZSxcbiAgICAgICAgZXhwcmVzc2lvbjogZ2V0Q29tcHV0ZWRGb3JMb29wVmFyaWFibGVFeHByZXNzaW9uKHZhcmlhYmxlLCBpbmRleE5hbWUsIGNvdW50TmFtZSksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBzb3VyY2VTcGFuID0gY29udmVydFNvdXJjZVNwYW4oZm9yQmxvY2sudHJhY2tCeS5zcGFuLCBmb3JCbG9jay5zb3VyY2VTcGFuKTtcbiAgY29uc3QgdHJhY2sgPSBjb252ZXJ0QXN0KGZvckJsb2NrLnRyYWNrQnksIHVuaXQuam9iLCBzb3VyY2VTcGFuKTtcblxuICBpbmdlc3ROb2RlcyhyZXBlYXRlclZpZXcsIGZvckJsb2NrLmNoaWxkcmVuKTtcblxuICBsZXQgZW1wdHlWaWV3OiBWaWV3Q29tcGlsYXRpb25Vbml0IHwgbnVsbCA9IG51bGw7XG4gIGxldCBlbXB0eVRhZ05hbWU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBpZiAoZm9yQmxvY2suZW1wdHkgIT09IG51bGwpIHtcbiAgICBlbXB0eVZpZXcgPSB1bml0LmpvYi5hbGxvY2F0ZVZpZXcodW5pdC54cmVmKTtcbiAgICBpbmdlc3ROb2RlcyhlbXB0eVZpZXcsIGZvckJsb2NrLmVtcHR5LmNoaWxkcmVuKTtcbiAgICBlbXB0eVRhZ05hbWUgPSBpbmdlc3RDb250cm9sRmxvd0luc2VydGlvblBvaW50KHVuaXQsIGVtcHR5Vmlldy54cmVmLCBmb3JCbG9jay5lbXB0eSk7XG4gIH1cblxuICBjb25zdCB2YXJOYW1lczogaXIuUmVwZWF0ZXJWYXJOYW1lcyA9IHtcbiAgICAkaW5kZXg6IGluZGV4VmFyTmFtZXMsXG4gICAgJGltcGxpY2l0OiBmb3JCbG9jay5pdGVtLm5hbWUsXG4gIH07XG5cbiAgaWYgKGZvckJsb2NrLmkxOG4gIT09IHVuZGVmaW5lZCAmJiAhKGZvckJsb2NrLmkxOG4gaW5zdGFuY2VvZiBpMThuLkJsb2NrUGxhY2Vob2xkZXIpKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Fzc2VydGlvbkVycm9yOiBVbmhhbmRsZWQgaTE4biBtZXRhZGF0YSB0eXBlIG9yIEBmb3InKTtcbiAgfVxuICBpZiAoXG4gICAgZm9yQmxvY2suZW1wdHk/LmkxOG4gIT09IHVuZGVmaW5lZCAmJlxuICAgICEoZm9yQmxvY2suZW1wdHkuaTE4biBpbnN0YW5jZW9mIGkxOG4uQmxvY2tQbGFjZWhvbGRlcilcbiAgKSB7XG4gICAgdGhyb3cgRXJyb3IoJ0Fzc2VydGlvbkVycm9yOiBVbmhhbmRsZWQgaTE4biBtZXRhZGF0YSB0eXBlIG9yIEBlbXB0eScpO1xuICB9XG4gIGNvbnN0IGkxOG5QbGFjZWhvbGRlciA9IGZvckJsb2NrLmkxOG47XG4gIGNvbnN0IGVtcHR5STE4blBsYWNlaG9sZGVyID0gZm9yQmxvY2suZW1wdHk/LmkxOG47XG5cbiAgY29uc3QgdGFnTmFtZSA9IGluZ2VzdENvbnRyb2xGbG93SW5zZXJ0aW9uUG9pbnQodW5pdCwgcmVwZWF0ZXJWaWV3LnhyZWYsIGZvckJsb2NrKTtcbiAgY29uc3QgcmVwZWF0ZXJDcmVhdGUgPSBpci5jcmVhdGVSZXBlYXRlckNyZWF0ZU9wKFxuICAgIHJlcGVhdGVyVmlldy54cmVmLFxuICAgIGVtcHR5Vmlldz8ueHJlZiA/PyBudWxsLFxuICAgIHRhZ05hbWUsXG4gICAgdHJhY2ssXG4gICAgdmFyTmFtZXMsXG4gICAgZW1wdHlUYWdOYW1lLFxuICAgIGkxOG5QbGFjZWhvbGRlcixcbiAgICBlbXB0eUkxOG5QbGFjZWhvbGRlcixcbiAgICBmb3JCbG9jay5zdGFydFNvdXJjZVNwYW4sXG4gICAgZm9yQmxvY2suc291cmNlU3BhbixcbiAgKTtcbiAgdW5pdC5jcmVhdGUucHVzaChyZXBlYXRlckNyZWF0ZSk7XG5cbiAgY29uc3QgZXhwcmVzc2lvbiA9IGNvbnZlcnRBc3QoXG4gICAgZm9yQmxvY2suZXhwcmVzc2lvbixcbiAgICB1bml0LmpvYixcbiAgICBjb252ZXJ0U291cmNlU3Bhbihmb3JCbG9jay5leHByZXNzaW9uLnNwYW4sIGZvckJsb2NrLnNvdXJjZVNwYW4pLFxuICApO1xuICBjb25zdCByZXBlYXRlciA9IGlyLmNyZWF0ZVJlcGVhdGVyT3AoXG4gICAgcmVwZWF0ZXJDcmVhdGUueHJlZixcbiAgICByZXBlYXRlckNyZWF0ZS5oYW5kbGUsXG4gICAgZXhwcmVzc2lvbixcbiAgICBmb3JCbG9jay5zb3VyY2VTcGFuLFxuICApO1xuICB1bml0LnVwZGF0ZS5wdXNoKHJlcGVhdGVyKTtcbn1cblxuLyoqXG4gKiBHZXRzIGFuIGV4cHJlc3Npb24gdGhhdCByZXByZXNlbnRzIGEgdmFyaWFibGUgaW4gYW4gYEBmb3JgIGxvb3AuXG4gKiBAcGFyYW0gdmFyaWFibGUgQVNUIHJlcHJlc2VudGluZyB0aGUgdmFyaWFibGUuXG4gKiBAcGFyYW0gaW5kZXhOYW1lIExvb3Atc3BlY2lmaWMgbmFtZSBmb3IgYCRpbmRleGAuXG4gKiBAcGFyYW0gY291bnROYW1lIExvb3Atc3BlY2lmaWMgbmFtZSBmb3IgYCRjb3VudGAuXG4gKi9cbmZ1bmN0aW9uIGdldENvbXB1dGVkRm9yTG9vcFZhcmlhYmxlRXhwcmVzc2lvbihcbiAgdmFyaWFibGU6IHQuVmFyaWFibGUsXG4gIGluZGV4TmFtZTogc3RyaW5nLFxuICBjb3VudE5hbWU6IHN0cmluZyxcbik6IG8uRXhwcmVzc2lvbiB7XG4gIHN3aXRjaCAodmFyaWFibGUudmFsdWUpIHtcbiAgICBjYXNlICckaW5kZXgnOlxuICAgICAgcmV0dXJuIG5ldyBpci5MZXhpY2FsUmVhZEV4cHIoaW5kZXhOYW1lKTtcblxuICAgIGNhc2UgJyRjb3VudCc6XG4gICAgICByZXR1cm4gbmV3IGlyLkxleGljYWxSZWFkRXhwcihjb3VudE5hbWUpO1xuXG4gICAgY2FzZSAnJGZpcnN0JzpcbiAgICAgIHJldHVybiBuZXcgaXIuTGV4aWNhbFJlYWRFeHByKGluZGV4TmFtZSkuaWRlbnRpY2FsKG8ubGl0ZXJhbCgwKSk7XG5cbiAgICBjYXNlICckbGFzdCc6XG4gICAgICByZXR1cm4gbmV3IGlyLkxleGljYWxSZWFkRXhwcihpbmRleE5hbWUpLmlkZW50aWNhbChcbiAgICAgICAgbmV3IGlyLkxleGljYWxSZWFkRXhwcihjb3VudE5hbWUpLm1pbnVzKG8ubGl0ZXJhbCgxKSksXG4gICAgICApO1xuXG4gICAgY2FzZSAnJGV2ZW4nOlxuICAgICAgcmV0dXJuIG5ldyBpci5MZXhpY2FsUmVhZEV4cHIoaW5kZXhOYW1lKS5tb2R1bG8oby5saXRlcmFsKDIpKS5pZGVudGljYWwoby5saXRlcmFsKDApKTtcblxuICAgIGNhc2UgJyRvZGQnOlxuICAgICAgcmV0dXJuIG5ldyBpci5MZXhpY2FsUmVhZEV4cHIoaW5kZXhOYW1lKS5tb2R1bG8oby5saXRlcmFsKDIpKS5ub3RJZGVudGljYWwoby5saXRlcmFsKDApKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEFzc2VydGlvbkVycm9yOiB1bmtub3duIEBmb3IgbG9vcCB2YXJpYWJsZSAke3ZhcmlhYmxlLnZhbHVlfWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGluZ2VzdExldERlY2xhcmF0aW9uKHVuaXQ6IFZpZXdDb21waWxhdGlvblVuaXQsIG5vZGU6IHQuTGV0RGVjbGFyYXRpb24pIHtcbiAgY29uc3QgdGFyZ2V0ID0gdW5pdC5qb2IuYWxsb2NhdGVYcmVmSWQoKTtcblxuICB1bml0LmNyZWF0ZS5wdXNoKGlyLmNyZWF0ZURlY2xhcmVMZXRPcCh0YXJnZXQsIG5vZGUubmFtZSwgbm9kZS5zb3VyY2VTcGFuKSk7XG4gIHVuaXQudXBkYXRlLnB1c2goXG4gICAgaXIuY3JlYXRlU3RvcmVMZXRPcChcbiAgICAgIHRhcmdldCxcbiAgICAgIG5vZGUubmFtZSxcbiAgICAgIGNvbnZlcnRBc3Qobm9kZS52YWx1ZSwgdW5pdC5qb2IsIG5vZGUudmFsdWVTcGFuKSxcbiAgICAgIG5vZGUuc291cmNlU3BhbixcbiAgICApLFxuICApO1xufVxuXG4vKipcbiAqIENvbnZlcnQgYSB0ZW1wbGF0ZSBBU1QgZXhwcmVzc2lvbiBpbnRvIGFuIG91dHB1dCBBU1QgZXhwcmVzc2lvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEFzdChcbiAgYXN0OiBlLkFTVCxcbiAgam9iOiBDb21waWxhdGlvbkpvYixcbiAgYmFzZVNvdXJjZVNwYW46IFBhcnNlU291cmNlU3BhbiB8IG51bGwsXG4pOiBvLkV4cHJlc3Npb24ge1xuICBpZiAoYXN0IGluc3RhbmNlb2YgZS5BU1RXaXRoU291cmNlKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRBc3QoYXN0LmFzdCwgam9iLCBiYXNlU291cmNlU3Bhbik7XG4gIH0gZWxzZSBpZiAoYXN0IGluc3RhbmNlb2YgZS5Qcm9wZXJ0eVJlYWQpIHtcbiAgICBjb25zdCBpc1RoaXNSZWNlaXZlciA9IGFzdC5yZWNlaXZlciBpbnN0YW5jZW9mIGUuVGhpc1JlY2VpdmVyO1xuICAgIC8vIFdoZXRoZXIgdGhpcyBpcyBhbiBpbXBsaWNpdCByZWNlaXZlciwgKmV4Y2x1ZGluZyogZXhwbGljaXQgcmVhZHMgb2YgYHRoaXNgLlxuICAgIGNvbnN0IGlzSW1wbGljaXRSZWNlaXZlciA9XG4gICAgICBhc3QucmVjZWl2ZXIgaW5zdGFuY2VvZiBlLkltcGxpY2l0UmVjZWl2ZXIgJiYgIShhc3QucmVjZWl2ZXIgaW5zdGFuY2VvZiBlLlRoaXNSZWNlaXZlcik7XG4gICAgLy8gV2hldGhlciB0aGUgIG5hbWUgb2YgdGhlIHJlYWQgaXMgYSBub2RlIHRoYXQgc2hvdWxkIGJlIG5ldmVyIHJldGFpbiBpdHMgZXhwbGljaXQgdGhpc1xuICAgIC8vIHJlY2VpdmVyLlxuICAgIGNvbnN0IGlzU3BlY2lhbE5vZGUgPSBhc3QubmFtZSA9PT0gJyRhbnknIHx8IGFzdC5uYW1lID09PSAnJGV2ZW50JztcbiAgICAvLyBUT0RPOiBUaGUgbW9zdCBzZW5zaWJsZSBjb25kaXRpb24gaGVyZSB3b3VsZCBiZSBzaW1wbHkgYGlzSW1wbGljaXRSZWNlaXZlcmAsIHRvIGNvbnZlcnQgb25seVxuICAgIC8vIGFjdHVhbCBpbXBsaWNpdCBgdGhpc2AgcmVhZHMsIGFuZCBub3QgZXhwbGljaXQgb25lcy4gSG93ZXZlciwgVGVtcGxhdGVEZWZpbml0aW9uQnVpbGRlciAoYW5kXG4gICAgLy8gdGhlIFR5cGVjaGVjayBibG9jayEpIGJvdGggaGF2ZSB0aGUgc2FtZSBidWcsIGluIHdoaWNoIHRoZXkgYWxzbyBjb25zaWRlciBleHBsaWNpdCBgdGhpc2BcbiAgICAvLyByZWFkcyB0byBiZSBpbXBsaWNpdC4gVGhpcyBjYXVzZXMgcHJvYmxlbXMgd2hlbiB0aGUgZXhwbGljaXQgYHRoaXNgIHJlYWQgaXMgaW5zaWRlIGFcbiAgICAvLyB0ZW1wbGF0ZSB3aXRoIGEgY29udGV4dCB0aGF0IGFsc28gcHJvdmlkZXMgdGhlIHZhcmlhYmxlIG5hbWUgYmVpbmcgcmVhZDpcbiAgICAvLyBgYGBcbiAgICAvLyA8bmctdGVtcGxhdGUgbGV0LWE+e3t0aGlzLmF9fTwvbmctdGVtcGxhdGU+XG4gICAgLy8gYGBgXG4gICAgLy8gVGhlIHdob2xlIHBvaW50IG9mIHRoZSBleHBsaWNpdCBgdGhpc2Agd2FzIHRvIGFjY2VzcyB0aGUgY2xhc3MgcHJvcGVydHksIGJ1dCBUREIgYW5kIHRoZVxuICAgIC8vIGN1cnJlbnQgVENCIHRyZWF0IHRoZSByZWFkIGFzIGltcGxpY2l0LCBhbmQgZ2l2ZSB5b3UgdGhlIGNvbnRleHQgcHJvcGVydHkgaW5zdGVhZCFcbiAgICAvL1xuICAgIC8vIEZvciBub3csIHdlIGVtdWxhdGUgdGhpcyBvbGQgYmVoYXZpb3IgYnkgYWdncmVzc2l2ZWx5IGNvbnZlcnRpbmcgZXhwbGljaXQgcmVhZHMgdG8gdG9cbiAgICAvLyBpbXBsaWNpdCByZWFkcywgZXhjZXB0IGZvciB0aGUgc3BlY2lhbCBjYXNlcyB0aGF0IFREQiBhbmQgdGhlIGN1cnJlbnQgVENCIHByb3RlY3QuIEhvd2V2ZXIsXG4gICAgLy8gaXQgd291bGQgYmUgYW4gaW1wcm92ZW1lbnQgdG8gZml4IHRoaXMuXG4gICAgLy9cbiAgICAvLyBTZWUgYWxzbyB0aGUgY29ycmVzcG9uZGluZyBjb21tZW50IGZvciB0aGUgVENCLCBpbiBgdHlwZV9jaGVja19ibG9jay50c2AuXG4gICAgaWYgKGlzSW1wbGljaXRSZWNlaXZlciB8fCAoaXNUaGlzUmVjZWl2ZXIgJiYgIWlzU3BlY2lhbE5vZGUpKSB7XG4gICAgICByZXR1cm4gbmV3IGlyLkxleGljYWxSZWFkRXhwcihhc3QubmFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgby5SZWFkUHJvcEV4cHIoXG4gICAgICAgIGNvbnZlcnRBc3QoYXN0LnJlY2VpdmVyLCBqb2IsIGJhc2VTb3VyY2VTcGFuKSxcbiAgICAgICAgYXN0Lm5hbWUsXG4gICAgICAgIG51bGwsXG4gICAgICAgIGNvbnZlcnRTb3VyY2VTcGFuKGFzdC5zcGFuLCBiYXNlU291cmNlU3BhbiksXG4gICAgICApO1xuICAgIH1cbiAgfSBlbHNlIGlmIChhc3QgaW5zdGFuY2VvZiBlLlByb3BlcnR5V3JpdGUpIHtcbiAgICBpZiAoYXN0LnJlY2VpdmVyIGluc3RhbmNlb2YgZS5JbXBsaWNpdFJlY2VpdmVyKSB7XG4gICAgICByZXR1cm4gbmV3IG8uV3JpdGVQcm9wRXhwcihcbiAgICAgICAgLy8gVE9ETzogSXMgaXQgY29ycmVjdCB0byBhbHdheXMgdXNlIHRoZSByb290IGNvbnRleHQgaW4gcGxhY2Ugb2YgdGhlIGltcGxpY2l0IHJlY2VpdmVyP1xuICAgICAgICBuZXcgaXIuQ29udGV4dEV4cHIoam9iLnJvb3QueHJlZiksXG4gICAgICAgIGFzdC5uYW1lLFxuICAgICAgICBjb252ZXJ0QXN0KGFzdC52YWx1ZSwgam9iLCBiYXNlU291cmNlU3BhbiksXG4gICAgICAgIG51bGwsXG4gICAgICAgIGNvbnZlcnRTb3VyY2VTcGFuKGFzdC5zcGFuLCBiYXNlU291cmNlU3BhbiksXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IG8uV3JpdGVQcm9wRXhwcihcbiAgICAgIGNvbnZlcnRBc3QoYXN0LnJlY2VpdmVyLCBqb2IsIGJhc2VTb3VyY2VTcGFuKSxcbiAgICAgIGFzdC5uYW1lLFxuICAgICAgY29udmVydEFzdChhc3QudmFsdWUsIGpvYiwgYmFzZVNvdXJjZVNwYW4pLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgY29udmVydFNvdXJjZVNwYW4oYXN0LnNwYW4sIGJhc2VTb3VyY2VTcGFuKSxcbiAgICApO1xuICB9IGVsc2UgaWYgKGFzdCBpbnN0YW5jZW9mIGUuS2V5ZWRXcml0ZSkge1xuICAgIHJldHVybiBuZXcgby5Xcml0ZUtleUV4cHIoXG4gICAgICBjb252ZXJ0QXN0KGFzdC5yZWNlaXZlciwgam9iLCBiYXNlU291cmNlU3BhbiksXG4gICAgICBjb252ZXJ0QXN0KGFzdC5rZXksIGpvYiwgYmFzZVNvdXJjZVNwYW4pLFxuICAgICAgY29udmVydEFzdChhc3QudmFsdWUsIGpvYiwgYmFzZVNvdXJjZVNwYW4pLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgY29udmVydFNvdXJjZVNwYW4oYXN0LnNwYW4sIGJhc2VTb3VyY2VTcGFuKSxcbiAgICApO1xuICB9IGVsc2UgaWYgKGFzdCBpbnN0YW5jZW9mIGUuQ2FsbCkge1xuICAgIGlmIChhc3QucmVjZWl2ZXIgaW5zdGFuY2VvZiBlLkltcGxpY2l0UmVjZWl2ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBJbXBsaWNpdFJlY2VpdmVyYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgby5JbnZva2VGdW5jdGlvbkV4cHIoXG4gICAgICAgIGNvbnZlcnRBc3QoYXN0LnJlY2VpdmVyLCBqb2IsIGJhc2VTb3VyY2VTcGFuKSxcbiAgICAgICAgYXN0LmFyZ3MubWFwKChhcmcpID0+IGNvbnZlcnRBc3QoYXJnLCBqb2IsIGJhc2VTb3VyY2VTcGFuKSksXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgY29udmVydFNvdXJjZVNwYW4oYXN0LnNwYW4sIGJhc2VTb3VyY2VTcGFuKSxcbiAgICAgICk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGFzdCBpbnN0YW5jZW9mIGUuTGl0ZXJhbFByaW1pdGl2ZSkge1xuICAgIHJldHVybiBvLmxpdGVyYWwoYXN0LnZhbHVlLCB1bmRlZmluZWQsIGNvbnZlcnRTb3VyY2VTcGFuKGFzdC5zcGFuLCBiYXNlU291cmNlU3BhbikpO1xuICB9IGVsc2UgaWYgKGFzdCBpbnN0YW5jZW9mIGUuVW5hcnkpIHtcbiAgICBzd2l0Y2ggKGFzdC5vcGVyYXRvcikge1xuICAgICAgY2FzZSAnKyc6XG4gICAgICAgIHJldHVybiBuZXcgby5VbmFyeU9wZXJhdG9yRXhwcihcbiAgICAgICAgICBvLlVuYXJ5T3BlcmF0b3IuUGx1cyxcbiAgICAgICAgICBjb252ZXJ0QXN0KGFzdC5leHByLCBqb2IsIGJhc2VTb3VyY2VTcGFuKSxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgY29udmVydFNvdXJjZVNwYW4oYXN0LnNwYW4sIGJhc2VTb3VyY2VTcGFuKSxcbiAgICAgICAgKTtcbiAgICAgIGNhc2UgJy0nOlxuICAgICAgICByZXR1cm4gbmV3IG8uVW5hcnlPcGVyYXRvckV4cHIoXG4gICAgICAgICAgby5VbmFyeU9wZXJhdG9yLk1pbnVzLFxuICAgICAgICAgIGNvbnZlcnRBc3QoYXN0LmV4cHIsIGpvYiwgYmFzZVNvdXJjZVNwYW4pLFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICBjb252ZXJ0U291cmNlU3Bhbihhc3Quc3BhbiwgYmFzZVNvdXJjZVNwYW4pLFxuICAgICAgICApO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBc3NlcnRpb25FcnJvcjogdW5rbm93biB1bmFyeSBvcGVyYXRvciAke2FzdC5vcGVyYXRvcn1gKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoYXN0IGluc3RhbmNlb2YgZS5CaW5hcnkpIHtcbiAgICBjb25zdCBvcGVyYXRvciA9IEJJTkFSWV9PUEVSQVRPUlMuZ2V0KGFzdC5vcGVyYXRpb24pO1xuICAgIGlmIChvcGVyYXRvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEFzc2VydGlvbkVycm9yOiB1bmtub3duIGJpbmFyeSBvcGVyYXRvciAke2FzdC5vcGVyYXRpb259YCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgby5CaW5hcnlPcGVyYXRvckV4cHIoXG4gICAgICBvcGVyYXRvcixcbiAgICAgIGNvbnZlcnRBc3QoYXN0LmxlZnQsIGpvYiwgYmFzZVNvdXJjZVNwYW4pLFxuICAgICAgY29udmVydEFzdChhc3QucmlnaHQsIGpvYiwgYmFzZVNvdXJjZVNwYW4pLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgY29udmVydFNvdXJjZVNwYW4oYXN0LnNwYW4sIGJhc2VTb3VyY2VTcGFuKSxcbiAgICApO1xuICB9IGVsc2UgaWYgKGFzdCBpbnN0YW5jZW9mIGUuVGhpc1JlY2VpdmVyKSB7XG4gICAgLy8gVE9ETzogc2hvdWxkIGNvbnRleHQgZXhwcmVzc2lvbnMgaGF2ZSBzb3VyY2UgbWFwcz9cbiAgICByZXR1cm4gbmV3IGlyLkNvbnRleHRFeHByKGpvYi5yb290LnhyZWYpO1xuICB9IGVsc2UgaWYgKGFzdCBpbnN0YW5jZW9mIGUuS2V5ZWRSZWFkKSB7XG4gICAgcmV0dXJuIG5ldyBvLlJlYWRLZXlFeHByKFxuICAgICAgY29udmVydEFzdChhc3QucmVjZWl2ZXIsIGpvYiwgYmFzZVNvdXJjZVNwYW4pLFxuICAgICAgY29udmVydEFzdChhc3Qua2V5LCBqb2IsIGJhc2VTb3VyY2VTcGFuKSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIGNvbnZlcnRTb3VyY2VTcGFuKGFzdC5zcGFuLCBiYXNlU291cmNlU3BhbiksXG4gICAgKTtcbiAgfSBlbHNlIGlmIChhc3QgaW5zdGFuY2VvZiBlLkNoYWluKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBBc3NlcnRpb25FcnJvcjogQ2hhaW4gaW4gdW5rbm93biBjb250ZXh0YCk7XG4gIH0gZWxzZSBpZiAoYXN0IGluc3RhbmNlb2YgZS5MaXRlcmFsTWFwKSB7XG4gICAgY29uc3QgZW50cmllcyA9IGFzdC5rZXlzLm1hcCgoa2V5LCBpZHgpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gYXN0LnZhbHVlc1tpZHhdO1xuICAgICAgLy8gVE9ETzogc2hvdWxkIGxpdGVyYWxzIGhhdmUgc291cmNlIG1hcHMsIG9yIGRvIHdlIGp1c3QgbWFwIHRoZSB3aG9sZSBzdXJyb3VuZGluZ1xuICAgICAgLy8gZXhwcmVzc2lvbj9cbiAgICAgIHJldHVybiBuZXcgby5MaXRlcmFsTWFwRW50cnkoa2V5LmtleSwgY29udmVydEFzdCh2YWx1ZSwgam9iLCBiYXNlU291cmNlU3BhbiksIGtleS5xdW90ZWQpO1xuICAgIH0pO1xuICAgIHJldHVybiBuZXcgby5MaXRlcmFsTWFwRXhwcihlbnRyaWVzLCB1bmRlZmluZWQsIGNvbnZlcnRTb3VyY2VTcGFuKGFzdC5zcGFuLCBiYXNlU291cmNlU3BhbikpO1xuICB9IGVsc2UgaWYgKGFzdCBpbnN0YW5jZW9mIGUuTGl0ZXJhbEFycmF5KSB7XG4gICAgLy8gVE9ETzogc2hvdWxkIGxpdGVyYWxzIGhhdmUgc291cmNlIG1hcHMsIG9yIGRvIHdlIGp1c3QgbWFwIHRoZSB3aG9sZSBzdXJyb3VuZGluZyBleHByZXNzaW9uP1xuICAgIHJldHVybiBuZXcgby5MaXRlcmFsQXJyYXlFeHByKFxuICAgICAgYXN0LmV4cHJlc3Npb25zLm1hcCgoZXhwcikgPT4gY29udmVydEFzdChleHByLCBqb2IsIGJhc2VTb3VyY2VTcGFuKSksXG4gICAgKTtcbiAgfSBlbHNlIGlmIChhc3QgaW5zdGFuY2VvZiBlLkNvbmRpdGlvbmFsKSB7XG4gICAgcmV0dXJuIG5ldyBvLkNvbmRpdGlvbmFsRXhwcihcbiAgICAgIGNvbnZlcnRBc3QoYXN0LmNvbmRpdGlvbiwgam9iLCBiYXNlU291cmNlU3BhbiksXG4gICAgICBjb252ZXJ0QXN0KGFzdC50cnVlRXhwLCBqb2IsIGJhc2VTb3VyY2VTcGFuKSxcbiAgICAgIGNvbnZlcnRBc3QoYXN0LmZhbHNlRXhwLCBqb2IsIGJhc2VTb3VyY2VTcGFuKSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIGNvbnZlcnRTb3VyY2VTcGFuKGFzdC5zcGFuLCBiYXNlU291cmNlU3BhbiksXG4gICAgKTtcbiAgfSBlbHNlIGlmIChhc3QgaW5zdGFuY2VvZiBlLk5vbk51bGxBc3NlcnQpIHtcbiAgICAvLyBBIG5vbi1udWxsIGFzc2VydGlvbiBzaG91bGRuJ3QgaW1wYWN0IGdlbmVyYXRlZCBpbnN0cnVjdGlvbnMsIHNvIHdlIGNhbiBqdXN0IGRyb3AgaXQuXG4gICAgcmV0dXJuIGNvbnZlcnRBc3QoYXN0LmV4cHJlc3Npb24sIGpvYiwgYmFzZVNvdXJjZVNwYW4pO1xuICB9IGVsc2UgaWYgKGFzdCBpbnN0YW5jZW9mIGUuQmluZGluZ1BpcGUpIHtcbiAgICAvLyBUT0RPOiBwaXBlcyBzaG91bGQgcHJvYmFibHkgaGF2ZSBzb3VyY2UgbWFwczsgZmlndXJlIG91dCBkZXRhaWxzLlxuICAgIHJldHVybiBuZXcgaXIuUGlwZUJpbmRpbmdFeHByKGpvYi5hbGxvY2F0ZVhyZWZJZCgpLCBuZXcgaXIuU2xvdEhhbmRsZSgpLCBhc3QubmFtZSwgW1xuICAgICAgY29udmVydEFzdChhc3QuZXhwLCBqb2IsIGJhc2VTb3VyY2VTcGFuKSxcbiAgICAgIC4uLmFzdC5hcmdzLm1hcCgoYXJnKSA9PiBjb252ZXJ0QXN0KGFyZywgam9iLCBiYXNlU291cmNlU3BhbikpLFxuICAgIF0pO1xuICB9IGVsc2UgaWYgKGFzdCBpbnN0YW5jZW9mIGUuU2FmZUtleWVkUmVhZCkge1xuICAgIHJldHVybiBuZXcgaXIuU2FmZUtleWVkUmVhZEV4cHIoXG4gICAgICBjb252ZXJ0QXN0KGFzdC5yZWNlaXZlciwgam9iLCBiYXNlU291cmNlU3BhbiksXG4gICAgICBjb252ZXJ0QXN0KGFzdC5rZXksIGpvYiwgYmFzZVNvdXJjZVNwYW4pLFxuICAgICAgY29udmVydFNvdXJjZVNwYW4oYXN0LnNwYW4sIGJhc2VTb3VyY2VTcGFuKSxcbiAgICApO1xuICB9IGVsc2UgaWYgKGFzdCBpbnN0YW5jZW9mIGUuU2FmZVByb3BlcnR5UmVhZCkge1xuICAgIC8vIFRPRE86IHNvdXJjZSBzcGFuXG4gICAgcmV0dXJuIG5ldyBpci5TYWZlUHJvcGVydHlSZWFkRXhwcihjb252ZXJ0QXN0KGFzdC5yZWNlaXZlciwgam9iLCBiYXNlU291cmNlU3BhbiksIGFzdC5uYW1lKTtcbiAgfSBlbHNlIGlmIChhc3QgaW5zdGFuY2VvZiBlLlNhZmVDYWxsKSB7XG4gICAgLy8gVE9ETzogc291cmNlIHNwYW5cbiAgICByZXR1cm4gbmV3IGlyLlNhZmVJbnZva2VGdW5jdGlvbkV4cHIoXG4gICAgICBjb252ZXJ0QXN0KGFzdC5yZWNlaXZlciwgam9iLCBiYXNlU291cmNlU3BhbiksXG4gICAgICBhc3QuYXJncy5tYXAoKGEpID0+IGNvbnZlcnRBc3QoYSwgam9iLCBiYXNlU291cmNlU3BhbikpLFxuICAgICk7XG4gIH0gZWxzZSBpZiAoYXN0IGluc3RhbmNlb2YgZS5FbXB0eUV4cHIpIHtcbiAgICByZXR1cm4gbmV3IGlyLkVtcHR5RXhwcihjb252ZXJ0U291cmNlU3Bhbihhc3Quc3BhbiwgYmFzZVNvdXJjZVNwYW4pKTtcbiAgfSBlbHNlIGlmIChhc3QgaW5zdGFuY2VvZiBlLlByZWZpeE5vdCkge1xuICAgIHJldHVybiBvLm5vdChcbiAgICAgIGNvbnZlcnRBc3QoYXN0LmV4cHJlc3Npb24sIGpvYiwgYmFzZVNvdXJjZVNwYW4pLFxuICAgICAgY29udmVydFNvdXJjZVNwYW4oYXN0LnNwYW4sIGJhc2VTb3VyY2VTcGFuKSxcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBVbmhhbmRsZWQgZXhwcmVzc2lvbiB0eXBlIFwiJHthc3QuY29uc3RydWN0b3IubmFtZX1cIiBpbiBmaWxlIFwiJHtiYXNlU291cmNlU3Bhbj8uc3RhcnQuZmlsZS51cmx9XCJgLFxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29udmVydEFzdFdpdGhJbnRlcnBvbGF0aW9uKFxuICBqb2I6IENvbXBpbGF0aW9uSm9iLFxuICB2YWx1ZTogZS5BU1QgfCBzdHJpbmcsXG4gIGkxOG5NZXRhOiBpMThuLkkxOG5NZXRhIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgc291cmNlU3Bhbj86IFBhcnNlU291cmNlU3Bhbixcbik6IG8uRXhwcmVzc2lvbiB8IGlyLkludGVycG9sYXRpb24ge1xuICBsZXQgZXhwcmVzc2lvbjogby5FeHByZXNzaW9uIHwgaXIuSW50ZXJwb2xhdGlvbjtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgZS5JbnRlcnBvbGF0aW9uKSB7XG4gICAgZXhwcmVzc2lvbiA9IG5ldyBpci5JbnRlcnBvbGF0aW9uKFxuICAgICAgdmFsdWUuc3RyaW5ncyxcbiAgICAgIHZhbHVlLmV4cHJlc3Npb25zLm1hcCgoZSkgPT4gY29udmVydEFzdChlLCBqb2IsIHNvdXJjZVNwYW4gPz8gbnVsbCkpLFxuICAgICAgT2JqZWN0LmtleXMoYXNNZXNzYWdlKGkxOG5NZXRhKT8ucGxhY2Vob2xkZXJzID8/IHt9KSxcbiAgICApO1xuICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgZS5BU1QpIHtcbiAgICBleHByZXNzaW9uID0gY29udmVydEFzdCh2YWx1ZSwgam9iLCBzb3VyY2VTcGFuID8/IG51bGwpO1xuICB9IGVsc2Uge1xuICAgIGV4cHJlc3Npb24gPSBvLmxpdGVyYWwodmFsdWUpO1xuICB9XG4gIHJldHVybiBleHByZXNzaW9uO1xufVxuXG4vLyBUT0RPOiBDYW4gd2UgcG9wdWxhdGUgVGVtcGxhdGUgYmluZGluZyBraW5kcyBpbiBpbmdlc3Q/XG5jb25zdCBCSU5ESU5HX0tJTkRTID0gbmV3IE1hcDxlLkJpbmRpbmdUeXBlLCBpci5CaW5kaW5nS2luZD4oW1xuICBbZS5CaW5kaW5nVHlwZS5Qcm9wZXJ0eSwgaXIuQmluZGluZ0tpbmQuUHJvcGVydHldLFxuICBbZS5CaW5kaW5nVHlwZS5Ud29XYXksIGlyLkJpbmRpbmdLaW5kLlR3b1dheVByb3BlcnR5XSxcbiAgW2UuQmluZGluZ1R5cGUuQXR0cmlidXRlLCBpci5CaW5kaW5nS2luZC5BdHRyaWJ1dGVdLFxuICBbZS5CaW5kaW5nVHlwZS5DbGFzcywgaXIuQmluZGluZ0tpbmQuQ2xhc3NOYW1lXSxcbiAgW2UuQmluZGluZ1R5cGUuU3R5bGUsIGlyLkJpbmRpbmdLaW5kLlN0eWxlUHJvcGVydHldLFxuICBbZS5CaW5kaW5nVHlwZS5BbmltYXRpb24sIGlyLkJpbmRpbmdLaW5kLkFuaW1hdGlvbl0sXG5dKTtcblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gdGVtcGxhdGUgaXMgYSBwbGFpbiBuZy10ZW1wbGF0ZSAoYXMgb3Bwb3NlZCB0byBhbm90aGVyIGtpbmQgb2YgdGVtcGxhdGVcbiAqIHN1Y2ggYXMgYSBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZSB0ZW1wbGF0ZSBvciBjb250cm9sIGZsb3cgdGVtcGxhdGUpLiBUaGlzIGlzIGNoZWNrZWQgYmFzZWQgb24gdGhlXG4gKiB0YWdOYW1lLiBXZSBjYW4gZXhwZWN0IHRoYXQgb25seSBwbGFpbiBuZy10ZW1wbGF0ZXMgd2lsbCBjb21lIHRocm91Z2ggd2l0aCBhIHRhZ05hbWUgb2ZcbiAqICduZy10ZW1wbGF0ZScuXG4gKlxuICogSGVyZSBhcmUgc29tZSBvZiB0aGUgY2FzZXMgd2UgZXhwZWN0OlxuICpcbiAqIHwgQW5ndWxhciBIVE1MICAgICAgICAgICAgICAgICAgICAgICB8IFRlbXBsYXRlIHRhZ05hbWUgICB8XG4gKiB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gfCAtLS0tLS0tLS0tLS0tLS0tLS0gfFxuICogfCBgPG5nLXRlbXBsYXRlPmAgICAgICAgICAgICAgICAgICAgIHwgJ25nLXRlbXBsYXRlJyAgICAgIHxcbiAqIHwgYDxkaXYgKm5nSWY9XCJ0cnVlXCI+YCAgICAgICAgICAgICAgIHwgJ2RpdicgICAgICAgICAgICAgIHxcbiAqIHwgYDxzdmc+PG5nLXRlbXBsYXRlPmAgICAgICAgICAgICAgICB8ICdzdmc6bmctdGVtcGxhdGUnICB8XG4gKiB8IGBAaWYgKHRydWUpIHtgICAgICAgICAgICAgICAgICAgICAgfCAnQ29uZGl0aW9uYWwnICAgICAgfFxuICogfCBgPG5nLXRlbXBsYXRlICpuZ0lmPmAgKHBsYWluKSAgICAgIHwgJ25nLXRlbXBsYXRlJyAgICAgIHxcbiAqIHwgYDxuZy10ZW1wbGF0ZSAqbmdJZj5gIChzdHJ1Y3R1cmFsKSB8IG51bGwgICAgICAgICAgICAgICB8XG4gKi9cbmZ1bmN0aW9uIGlzUGxhaW5UZW1wbGF0ZSh0bXBsOiB0LlRlbXBsYXRlKSB7XG4gIHJldHVybiBzcGxpdE5zTmFtZSh0bXBsLnRhZ05hbWUgPz8gJycpWzFdID09PSBOR19URU1QTEFURV9UQUdfTkFNRTtcbn1cblxuLyoqXG4gKiBFbnN1cmVzIHRoYXQgdGhlIGkxOG5NZXRhLCBpZiBwcm92aWRlZCwgaXMgYW4gaTE4bi5NZXNzYWdlLlxuICovXG5mdW5jdGlvbiBhc01lc3NhZ2UoaTE4bk1ldGE6IGkxOG4uSTE4bk1ldGEgfCBudWxsIHwgdW5kZWZpbmVkKTogaTE4bi5NZXNzYWdlIHwgbnVsbCB7XG4gIGlmIChpMThuTWV0YSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgaWYgKCEoaTE4bk1ldGEgaW5zdGFuY2VvZiBpMThuLk1lc3NhZ2UpKSB7XG4gICAgdGhyb3cgRXJyb3IoYEV4cGVjdGVkIGkxOG4gbWV0YSB0byBiZSBhIE1lc3NhZ2UsIGJ1dCBnb3Q6ICR7aTE4bk1ldGEuY29uc3RydWN0b3IubmFtZX1gKTtcbiAgfVxuICByZXR1cm4gaTE4bk1ldGE7XG59XG5cbi8qKlxuICogUHJvY2VzcyBhbGwgb2YgdGhlIGJpbmRpbmdzIG9uIGFuIGVsZW1lbnQgaW4gdGhlIHRlbXBsYXRlIEFTVCBhbmQgY29udmVydCB0aGVtIHRvIHRoZWlyIElSXG4gKiByZXByZXNlbnRhdGlvbi5cbiAqL1xuZnVuY3Rpb24gaW5nZXN0RWxlbWVudEJpbmRpbmdzKFxuICB1bml0OiBWaWV3Q29tcGlsYXRpb25Vbml0LFxuICBvcDogaXIuRWxlbWVudE9wQmFzZSxcbiAgZWxlbWVudDogdC5FbGVtZW50LFxuKTogdm9pZCB7XG4gIGxldCBiaW5kaW5ncyA9IG5ldyBBcnJheTxpci5CaW5kaW5nT3AgfCBpci5FeHRyYWN0ZWRBdHRyaWJ1dGVPcCB8IG51bGw+KCk7XG5cbiAgbGV0IGkxOG5BdHRyaWJ1dGVCaW5kaW5nTmFtZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBmb3IgKGNvbnN0IGF0dHIgb2YgZWxlbWVudC5hdHRyaWJ1dGVzKSB7XG4gICAgLy8gQXR0cmlidXRlIGxpdGVyYWwgYmluZGluZ3MsIHN1Y2ggYXMgYGF0dHIuZm9vPVwiYmFyXCJgLlxuICAgIGNvbnN0IHNlY3VyaXR5Q29udGV4dCA9IGRvbVNjaGVtYS5zZWN1cml0eUNvbnRleHQoZWxlbWVudC5uYW1lLCBhdHRyLm5hbWUsIHRydWUpO1xuICAgIGJpbmRpbmdzLnB1c2goXG4gICAgICBpci5jcmVhdGVCaW5kaW5nT3AoXG4gICAgICAgIG9wLnhyZWYsXG4gICAgICAgIGlyLkJpbmRpbmdLaW5kLkF0dHJpYnV0ZSxcbiAgICAgICAgYXR0ci5uYW1lLFxuICAgICAgICBjb252ZXJ0QXN0V2l0aEludGVycG9sYXRpb24odW5pdC5qb2IsIGF0dHIudmFsdWUsIGF0dHIuaTE4biksXG4gICAgICAgIG51bGwsXG4gICAgICAgIHNlY3VyaXR5Q29udGV4dCxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICAgZmFsc2UsXG4gICAgICAgIG51bGwsXG4gICAgICAgIGFzTWVzc2FnZShhdHRyLmkxOG4pLFxuICAgICAgICBhdHRyLnNvdXJjZVNwYW4sXG4gICAgICApLFxuICAgICk7XG4gICAgaWYgKGF0dHIuaTE4bikge1xuICAgICAgaTE4bkF0dHJpYnV0ZUJpbmRpbmdOYW1lcy5hZGQoYXR0ci5uYW1lKTtcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IGlucHV0IG9mIGVsZW1lbnQuaW5wdXRzKSB7XG4gICAgaWYgKGkxOG5BdHRyaWJ1dGVCaW5kaW5nTmFtZXMuaGFzKGlucHV0Lm5hbWUpKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICBgT24gY29tcG9uZW50ICR7dW5pdC5qb2IuY29tcG9uZW50TmFtZX0sIHRoZSBiaW5kaW5nICR7aW5wdXQubmFtZX0gaXMgYm90aCBhbiBpMThuIGF0dHJpYnV0ZSBhbmQgYSBwcm9wZXJ0eS4gWW91IG1heSB3YW50IHRvIHJlbW92ZSB0aGUgcHJvcGVydHkgYmluZGluZy4gVGhpcyB3aWxsIGJlY29tZSBhIGNvbXBpbGF0aW9uIGVycm9yIGluIGZ1dHVyZSB2ZXJzaW9ucyBvZiBBbmd1bGFyLmAsXG4gICAgICApO1xuICAgIH1cbiAgICAvLyBBbGwgZHluYW1pYyBiaW5kaW5ncyAoYm90aCBhdHRyaWJ1dGUgYW5kIHByb3BlcnR5IGJpbmRpbmdzKS5cbiAgICBiaW5kaW5ncy5wdXNoKFxuICAgICAgaXIuY3JlYXRlQmluZGluZ09wKFxuICAgICAgICBvcC54cmVmLFxuICAgICAgICBCSU5ESU5HX0tJTkRTLmdldChpbnB1dC50eXBlKSEsXG4gICAgICAgIGlucHV0Lm5hbWUsXG4gICAgICAgIGNvbnZlcnRBc3RXaXRoSW50ZXJwb2xhdGlvbih1bml0LmpvYiwgYXN0T2YoaW5wdXQudmFsdWUpLCBpbnB1dC5pMThuKSxcbiAgICAgICAgaW5wdXQudW5pdCxcbiAgICAgICAgaW5wdXQuc2VjdXJpdHlDb250ZXh0LFxuICAgICAgICBmYWxzZSxcbiAgICAgICAgZmFsc2UsXG4gICAgICAgIG51bGwsXG4gICAgICAgIGFzTWVzc2FnZShpbnB1dC5pMThuKSA/PyBudWxsLFxuICAgICAgICBpbnB1dC5zb3VyY2VTcGFuLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgdW5pdC5jcmVhdGUucHVzaChcbiAgICBiaW5kaW5ncy5maWx0ZXIoKGIpOiBiIGlzIGlyLkV4dHJhY3RlZEF0dHJpYnV0ZU9wID0+IGI/LmtpbmQgPT09IGlyLk9wS2luZC5FeHRyYWN0ZWRBdHRyaWJ1dGUpLFxuICApO1xuICB1bml0LnVwZGF0ZS5wdXNoKGJpbmRpbmdzLmZpbHRlcigoYik6IGIgaXMgaXIuQmluZGluZ09wID0+IGI/LmtpbmQgPT09IGlyLk9wS2luZC5CaW5kaW5nKSk7XG5cbiAgZm9yIChjb25zdCBvdXRwdXQgb2YgZWxlbWVudC5vdXRwdXRzKSB7XG4gICAgaWYgKG91dHB1dC50eXBlID09PSBlLlBhcnNlZEV2ZW50VHlwZS5BbmltYXRpb24gJiYgb3V0cHV0LnBoYXNlID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBFcnJvcignQW5pbWF0aW9uIGxpc3RlbmVyIHNob3VsZCBoYXZlIGEgcGhhc2UnKTtcbiAgICB9XG5cbiAgICBpZiAob3V0cHV0LnR5cGUgPT09IGUuUGFyc2VkRXZlbnRUeXBlLlR3b1dheSkge1xuICAgICAgdW5pdC5jcmVhdGUucHVzaChcbiAgICAgICAgaXIuY3JlYXRlVHdvV2F5TGlzdGVuZXJPcChcbiAgICAgICAgICBvcC54cmVmLFxuICAgICAgICAgIG9wLmhhbmRsZSxcbiAgICAgICAgICBvdXRwdXQubmFtZSxcbiAgICAgICAgICBvcC50YWcsXG4gICAgICAgICAgbWFrZVR3b1dheUxpc3RlbmVySGFuZGxlck9wcyh1bml0LCBvdXRwdXQuaGFuZGxlciwgb3V0cHV0LmhhbmRsZXJTcGFuKSxcbiAgICAgICAgICBvdXRwdXQuc291cmNlU3BhbixcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVuaXQuY3JlYXRlLnB1c2goXG4gICAgICAgIGlyLmNyZWF0ZUxpc3RlbmVyT3AoXG4gICAgICAgICAgb3AueHJlZixcbiAgICAgICAgICBvcC5oYW5kbGUsXG4gICAgICAgICAgb3V0cHV0Lm5hbWUsXG4gICAgICAgICAgb3AudGFnLFxuICAgICAgICAgIG1ha2VMaXN0ZW5lckhhbmRsZXJPcHModW5pdCwgb3V0cHV0LmhhbmRsZXIsIG91dHB1dC5oYW5kbGVyU3BhbiksXG4gICAgICAgICAgb3V0cHV0LnBoYXNlLFxuICAgICAgICAgIG91dHB1dC50YXJnZXQsXG4gICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgb3V0cHV0LnNvdXJjZVNwYW4sXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIElmIGFueSBvZiB0aGUgYmluZGluZ3Mgb24gdGhpcyBlbGVtZW50IGhhdmUgYW4gaTE4biBtZXNzYWdlLCB0aGVuIGFuIGkxOG4gYXR0cnMgY29uZmlndXJhdGlvblxuICAvLyBvcCBpcyBhbHNvIHJlcXVpcmVkLlxuICBpZiAoYmluZGluZ3Muc29tZSgoYikgPT4gYj8uaTE4bk1lc3NhZ2UpICE9PSBudWxsKSB7XG4gICAgdW5pdC5jcmVhdGUucHVzaChcbiAgICAgIGlyLmNyZWF0ZUkxOG5BdHRyaWJ1dGVzT3AodW5pdC5qb2IuYWxsb2NhdGVYcmVmSWQoKSwgbmV3IGlyLlNsb3RIYW5kbGUoKSwgb3AueHJlZiksXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIFByb2Nlc3MgYWxsIG9mIHRoZSBiaW5kaW5ncyBvbiBhIHRlbXBsYXRlIGluIHRoZSB0ZW1wbGF0ZSBBU1QgYW5kIGNvbnZlcnQgdGhlbSB0byB0aGVpciBJUlxuICogcmVwcmVzZW50YXRpb24uXG4gKi9cbmZ1bmN0aW9uIGluZ2VzdFRlbXBsYXRlQmluZGluZ3MoXG4gIHVuaXQ6IFZpZXdDb21waWxhdGlvblVuaXQsXG4gIG9wOiBpci5FbGVtZW50T3BCYXNlLFxuICB0ZW1wbGF0ZTogdC5UZW1wbGF0ZSxcbiAgdGVtcGxhdGVLaW5kOiBpci5UZW1wbGF0ZUtpbmQgfCBudWxsLFxuKTogdm9pZCB7XG4gIGxldCBiaW5kaW5ncyA9IG5ldyBBcnJheTxpci5CaW5kaW5nT3AgfCBpci5FeHRyYWN0ZWRBdHRyaWJ1dGVPcCB8IG51bGw+KCk7XG5cbiAgZm9yIChjb25zdCBhdHRyIG9mIHRlbXBsYXRlLnRlbXBsYXRlQXR0cnMpIHtcbiAgICBpZiAoYXR0ciBpbnN0YW5jZW9mIHQuVGV4dEF0dHJpYnV0ZSkge1xuICAgICAgY29uc3Qgc2VjdXJpdHlDb250ZXh0ID0gZG9tU2NoZW1hLnNlY3VyaXR5Q29udGV4dChOR19URU1QTEFURV9UQUdfTkFNRSwgYXR0ci5uYW1lLCB0cnVlKTtcbiAgICAgIGJpbmRpbmdzLnB1c2goXG4gICAgICAgIGNyZWF0ZVRlbXBsYXRlQmluZGluZyhcbiAgICAgICAgICB1bml0LFxuICAgICAgICAgIG9wLnhyZWYsXG4gICAgICAgICAgZS5CaW5kaW5nVHlwZS5BdHRyaWJ1dGUsXG4gICAgICAgICAgYXR0ci5uYW1lLFxuICAgICAgICAgIGF0dHIudmFsdWUsXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgICBzZWN1cml0eUNvbnRleHQsXG4gICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICB0ZW1wbGF0ZUtpbmQsXG4gICAgICAgICAgYXNNZXNzYWdlKGF0dHIuaTE4biksXG4gICAgICAgICAgYXR0ci5zb3VyY2VTcGFuLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYmluZGluZ3MucHVzaChcbiAgICAgICAgY3JlYXRlVGVtcGxhdGVCaW5kaW5nKFxuICAgICAgICAgIHVuaXQsXG4gICAgICAgICAgb3AueHJlZixcbiAgICAgICAgICBhdHRyLnR5cGUsXG4gICAgICAgICAgYXR0ci5uYW1lLFxuICAgICAgICAgIGFzdE9mKGF0dHIudmFsdWUpLFxuICAgICAgICAgIGF0dHIudW5pdCxcbiAgICAgICAgICBhdHRyLnNlY3VyaXR5Q29udGV4dCxcbiAgICAgICAgICB0cnVlLFxuICAgICAgICAgIHRlbXBsYXRlS2luZCxcbiAgICAgICAgICBhc01lc3NhZ2UoYXR0ci5pMThuKSxcbiAgICAgICAgICBhdHRyLnNvdXJjZVNwYW4sXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgYXR0ciBvZiB0ZW1wbGF0ZS5hdHRyaWJ1dGVzKSB7XG4gICAgLy8gQXR0cmlidXRlIGxpdGVyYWwgYmluZGluZ3MsIHN1Y2ggYXMgYGF0dHIuZm9vPVwiYmFyXCJgLlxuICAgIGNvbnN0IHNlY3VyaXR5Q29udGV4dCA9IGRvbVNjaGVtYS5zZWN1cml0eUNvbnRleHQoTkdfVEVNUExBVEVfVEFHX05BTUUsIGF0dHIubmFtZSwgdHJ1ZSk7XG4gICAgYmluZGluZ3MucHVzaChcbiAgICAgIGNyZWF0ZVRlbXBsYXRlQmluZGluZyhcbiAgICAgICAgdW5pdCxcbiAgICAgICAgb3AueHJlZixcbiAgICAgICAgZS5CaW5kaW5nVHlwZS5BdHRyaWJ1dGUsXG4gICAgICAgIGF0dHIubmFtZSxcbiAgICAgICAgYXR0ci52YWx1ZSxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgc2VjdXJpdHlDb250ZXh0LFxuICAgICAgICBmYWxzZSxcbiAgICAgICAgdGVtcGxhdGVLaW5kLFxuICAgICAgICBhc01lc3NhZ2UoYXR0ci5pMThuKSxcbiAgICAgICAgYXR0ci5zb3VyY2VTcGFuLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgZm9yIChjb25zdCBpbnB1dCBvZiB0ZW1wbGF0ZS5pbnB1dHMpIHtcbiAgICAvLyBEeW5hbWljIGJpbmRpbmdzIChib3RoIGF0dHJpYnV0ZSBhbmQgcHJvcGVydHkgYmluZGluZ3MpLlxuICAgIGJpbmRpbmdzLnB1c2goXG4gICAgICBjcmVhdGVUZW1wbGF0ZUJpbmRpbmcoXG4gICAgICAgIHVuaXQsXG4gICAgICAgIG9wLnhyZWYsXG4gICAgICAgIGlucHV0LnR5cGUsXG4gICAgICAgIGlucHV0Lm5hbWUsXG4gICAgICAgIGFzdE9mKGlucHV0LnZhbHVlKSxcbiAgICAgICAgaW5wdXQudW5pdCxcbiAgICAgICAgaW5wdXQuc2VjdXJpdHlDb250ZXh0LFxuICAgICAgICBmYWxzZSxcbiAgICAgICAgdGVtcGxhdGVLaW5kLFxuICAgICAgICBhc01lc3NhZ2UoaW5wdXQuaTE4biksXG4gICAgICAgIGlucHV0LnNvdXJjZVNwYW4sXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICB1bml0LmNyZWF0ZS5wdXNoKFxuICAgIGJpbmRpbmdzLmZpbHRlcigoYik6IGIgaXMgaXIuRXh0cmFjdGVkQXR0cmlidXRlT3AgPT4gYj8ua2luZCA9PT0gaXIuT3BLaW5kLkV4dHJhY3RlZEF0dHJpYnV0ZSksXG4gICk7XG4gIHVuaXQudXBkYXRlLnB1c2goYmluZGluZ3MuZmlsdGVyKChiKTogYiBpcyBpci5CaW5kaW5nT3AgPT4gYj8ua2luZCA9PT0gaXIuT3BLaW5kLkJpbmRpbmcpKTtcblxuICBmb3IgKGNvbnN0IG91dHB1dCBvZiB0ZW1wbGF0ZS5vdXRwdXRzKSB7XG4gICAgaWYgKG91dHB1dC50eXBlID09PSBlLlBhcnNlZEV2ZW50VHlwZS5BbmltYXRpb24gJiYgb3V0cHV0LnBoYXNlID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBFcnJvcignQW5pbWF0aW9uIGxpc3RlbmVyIHNob3VsZCBoYXZlIGEgcGhhc2UnKTtcbiAgICB9XG5cbiAgICBpZiAodGVtcGxhdGVLaW5kID09PSBpci5UZW1wbGF0ZUtpbmQuTmdUZW1wbGF0ZSkge1xuICAgICAgaWYgKG91dHB1dC50eXBlID09PSBlLlBhcnNlZEV2ZW50VHlwZS5Ud29XYXkpIHtcbiAgICAgICAgdW5pdC5jcmVhdGUucHVzaChcbiAgICAgICAgICBpci5jcmVhdGVUd29XYXlMaXN0ZW5lck9wKFxuICAgICAgICAgICAgb3AueHJlZixcbiAgICAgICAgICAgIG9wLmhhbmRsZSxcbiAgICAgICAgICAgIG91dHB1dC5uYW1lLFxuICAgICAgICAgICAgb3AudGFnLFxuICAgICAgICAgICAgbWFrZVR3b1dheUxpc3RlbmVySGFuZGxlck9wcyh1bml0LCBvdXRwdXQuaGFuZGxlciwgb3V0cHV0LmhhbmRsZXJTcGFuKSxcbiAgICAgICAgICAgIG91dHB1dC5zb3VyY2VTcGFuLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1bml0LmNyZWF0ZS5wdXNoKFxuICAgICAgICAgIGlyLmNyZWF0ZUxpc3RlbmVyT3AoXG4gICAgICAgICAgICBvcC54cmVmLFxuICAgICAgICAgICAgb3AuaGFuZGxlLFxuICAgICAgICAgICAgb3V0cHV0Lm5hbWUsXG4gICAgICAgICAgICBvcC50YWcsXG4gICAgICAgICAgICBtYWtlTGlzdGVuZXJIYW5kbGVyT3BzKHVuaXQsIG91dHB1dC5oYW5kbGVyLCBvdXRwdXQuaGFuZGxlclNwYW4pLFxuICAgICAgICAgICAgb3V0cHV0LnBoYXNlLFxuICAgICAgICAgICAgb3V0cHV0LnRhcmdldCxcbiAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgb3V0cHV0LnNvdXJjZVNwYW4sXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKFxuICAgICAgdGVtcGxhdGVLaW5kID09PSBpci5UZW1wbGF0ZUtpbmQuU3RydWN0dXJhbCAmJlxuICAgICAgb3V0cHV0LnR5cGUgIT09IGUuUGFyc2VkRXZlbnRUeXBlLkFuaW1hdGlvblxuICAgICkge1xuICAgICAgLy8gQW5pbWF0aW9uIGJpbmRpbmdzIGFyZSBleGNsdWRlZCBmcm9tIHRoZSBzdHJ1Y3R1cmFsIHRlbXBsYXRlJ3MgY29uc3QgYXJyYXkuXG4gICAgICBjb25zdCBzZWN1cml0eUNvbnRleHQgPSBkb21TY2hlbWEuc2VjdXJpdHlDb250ZXh0KE5HX1RFTVBMQVRFX1RBR19OQU1FLCBvdXRwdXQubmFtZSwgZmFsc2UpO1xuICAgICAgdW5pdC5jcmVhdGUucHVzaChcbiAgICAgICAgaXIuY3JlYXRlRXh0cmFjdGVkQXR0cmlidXRlT3AoXG4gICAgICAgICAgb3AueHJlZixcbiAgICAgICAgICBpci5CaW5kaW5nS2luZC5Qcm9wZXJ0eSxcbiAgICAgICAgICBudWxsLFxuICAgICAgICAgIG91dHB1dC5uYW1lLFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgICBudWxsLFxuICAgICAgICAgIHNlY3VyaXR5Q29udGV4dCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gVE9ETzogUGVyaGFwcyB3ZSBjb3VsZCBkbyB0aGlzIGluIGEgcGhhc2U/IChJdCBsaWtlbHkgd291bGRuJ3QgY2hhbmdlIHRoZSBzbG90IGluZGljZXMuKVxuICBpZiAoYmluZGluZ3Muc29tZSgoYikgPT4gYj8uaTE4bk1lc3NhZ2UpICE9PSBudWxsKSB7XG4gICAgdW5pdC5jcmVhdGUucHVzaChcbiAgICAgIGlyLmNyZWF0ZUkxOG5BdHRyaWJ1dGVzT3AodW5pdC5qb2IuYWxsb2NhdGVYcmVmSWQoKSwgbmV3IGlyLlNsb3RIYW5kbGUoKSwgb3AueHJlZiksXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIEhlbHBlciB0byBpbmdlc3QgYW4gaW5kaXZpZHVhbCBiaW5kaW5nIG9uIGEgdGVtcGxhdGUsIGVpdGhlciBhbiBleHBsaWNpdCBgbmctdGVtcGxhdGVgLCBvciBhblxuICogaW1wbGljaXQgdGVtcGxhdGUgY3JlYXRlZCB2aWEgc3RydWN0dXJhbCBkaXJlY3RpdmUuXG4gKlxuICogQmluZGluZ3Mgb24gdGVtcGxhdGVzIGFyZSAqZXh0cmVtZWx5KiB0cmlja3kuIEkgaGF2ZSB0cmllZCB0byBpc29sYXRlIGFsbCBvZiB0aGUgY29uZnVzaW5nIGVkZ2VcbiAqIGNhc2VzIGludG8gdGhpcyBmdW5jdGlvbiwgYW5kIHRvIGNvbW1lbnQgaXQgd2VsbCB0byBkb2N1bWVudCB0aGUgYmVoYXZpb3IuXG4gKlxuICogU29tZSBvZiB0aGlzIGJlaGF2aW9yIGlzIGludHVpdGl2ZWx5IGluY29ycmVjdCwgYW5kIHdlIHNob3VsZCBjb25zaWRlciBjaGFuZ2luZyBpdCBpbiB0aGUgZnV0dXJlLlxuICpcbiAqIEBwYXJhbSB2aWV3IFRoZSBjb21waWxhdGlvbiB1bml0IGZvciB0aGUgdmlldyBjb250YWluaW5nIHRoZSB0ZW1wbGF0ZS5cbiAqIEBwYXJhbSB4cmVmIFRoZSB4cmVmIG9mIHRoZSB0ZW1wbGF0ZSBvcC5cbiAqIEBwYXJhbSB0eXBlIFRoZSBiaW5kaW5nIHR5cGUsIGFjY29yZGluZyB0byB0aGUgcGFyc2VyLiBUaGlzIGlzIGZhaXJseSByZWFzb25hYmxlLCBlLmcuIGJvdGhcbiAqICAgICBkeW5hbWljIGFuZCBzdGF0aWMgYXR0cmlidXRlcyBoYXZlIGUuQmluZGluZ1R5cGUuQXR0cmlidXRlLlxuICogQHBhcmFtIG5hbWUgVGhlIGJpbmRpbmcncyBuYW1lLlxuICogQHBhcmFtIHZhbHVlIFRoZSBiaW5kaW5ncydzIHZhbHVlLCB3aGljaCB3aWxsIGVpdGhlciBiZSBhbiBpbnB1dCBBU1QgZXhwcmVzc2lvbiwgb3IgYSBzdHJpbmdcbiAqICAgICBsaXRlcmFsLiBOb3RlIHRoYXQgdGhlIGlucHV0IEFTVCBleHByZXNzaW9uIG1heSBvciBtYXkgbm90IGJlIGNvbnN0IC0tIGl0IHdpbGwgb25seSBiZSBhXG4gKiAgICAgc3RyaW5nIGxpdGVyYWwgaWYgdGhlIHBhcnNlciBjb25zaWRlcmVkIGl0IGEgdGV4dCBiaW5kaW5nLlxuICogQHBhcmFtIHVuaXQgSWYgdGhlIGJpbmRpbmcgaGFzIGEgdW5pdCAoZS5nLiBgcHhgIGZvciBzdHlsZSBiaW5kaW5ncyksIHRoZW4gdGhpcyBpcyB0aGUgdW5pdC5cbiAqIEBwYXJhbSBzZWN1cml0eUNvbnRleHQgVGhlIHNlY3VyaXR5IGNvbnRleHQgb2YgdGhlIGJpbmRpbmcuXG4gKiBAcGFyYW0gaXNTdHJ1Y3R1cmFsVGVtcGxhdGVBdHRyaWJ1dGUgV2hldGhlciB0aGlzIGJpbmRpbmcgYWN0dWFsbHkgYXBwbGllcyB0byB0aGUgc3RydWN0dXJhbFxuICogICAgIG5nLXRlbXBsYXRlLiBGb3IgZXhhbXBsZSwgYW4gYG5nRm9yYCB3b3VsZCBhY3R1YWxseSBhcHBseSB0byB0aGUgc3RydWN0dXJhbCB0ZW1wbGF0ZS4gKE1vc3RcbiAqICAgICBiaW5kaW5ncyBvbiBzdHJ1Y3R1cmFsIGVsZW1lbnRzIHRhcmdldCB0aGUgaW5uZXIgZWxlbWVudCwgbm90IHRoZSB0ZW1wbGF0ZS4pXG4gKiBAcGFyYW0gdGVtcGxhdGVLaW5kIFdoZXRoZXIgdGhpcyBpcyBhbiBleHBsaWNpdCBgbmctdGVtcGxhdGVgIG9yIGFuIGltcGxpY2l0IHRlbXBsYXRlIGNyZWF0ZWQgYnlcbiAqICAgICBhIHN0cnVjdHVyYWwgZGlyZWN0aXZlLiBUaGlzIHNob3VsZCBuZXZlciBiZSBhIGJsb2NrIHRlbXBsYXRlLlxuICogQHBhcmFtIGkxOG5NZXNzYWdlIFRoZSBpMThuIG1ldGFkYXRhIGZvciB0aGUgYmluZGluZywgaWYgYW55LlxuICogQHBhcmFtIHNvdXJjZVNwYW4gVGhlIHNvdXJjZSBzcGFuIG9mIHRoZSBiaW5kaW5nLlxuICogQHJldHVybnMgQW4gSVIgYmluZGluZyBvcCwgb3IgbnVsbCBpZiB0aGUgYmluZGluZyBzaG91bGQgYmUgc2tpcHBlZC5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlVGVtcGxhdGVCaW5kaW5nKFxuICB2aWV3OiBWaWV3Q29tcGlsYXRpb25Vbml0LFxuICB4cmVmOiBpci5YcmVmSWQsXG4gIHR5cGU6IGUuQmluZGluZ1R5cGUsXG4gIG5hbWU6IHN0cmluZyxcbiAgdmFsdWU6IGUuQVNUIHwgc3RyaW5nLFxuICB1bml0OiBzdHJpbmcgfCBudWxsLFxuICBzZWN1cml0eUNvbnRleHQ6IFNlY3VyaXR5Q29udGV4dCxcbiAgaXNTdHJ1Y3R1cmFsVGVtcGxhdGVBdHRyaWJ1dGU6IGJvb2xlYW4sXG4gIHRlbXBsYXRlS2luZDogaXIuVGVtcGxhdGVLaW5kIHwgbnVsbCxcbiAgaTE4bk1lc3NhZ2U6IGkxOG4uTWVzc2FnZSB8IG51bGwsXG4gIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3Bhbixcbik6IGlyLkJpbmRpbmdPcCB8IGlyLkV4dHJhY3RlZEF0dHJpYnV0ZU9wIHwgbnVsbCB7XG4gIGNvbnN0IGlzVGV4dEJpbmRpbmcgPSB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnO1xuICAvLyBJZiB0aGlzIGlzIGEgc3RydWN0dXJhbCB0ZW1wbGF0ZSwgdGhlbiBzZXZlcmFsIGtpbmRzIG9mIGJpbmRpbmdzIHNob3VsZCBub3QgcmVzdWx0IGluIGFuXG4gIC8vIHVwZGF0ZSBpbnN0cnVjdGlvbi5cbiAgaWYgKHRlbXBsYXRlS2luZCA9PT0gaXIuVGVtcGxhdGVLaW5kLlN0cnVjdHVyYWwpIHtcbiAgICBpZiAoIWlzU3RydWN0dXJhbFRlbXBsYXRlQXR0cmlidXRlKSB7XG4gICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSBlLkJpbmRpbmdUeXBlLlByb3BlcnR5OlxuICAgICAgICBjYXNlIGUuQmluZGluZ1R5cGUuQ2xhc3M6XG4gICAgICAgIGNhc2UgZS5CaW5kaW5nVHlwZS5TdHlsZTpcbiAgICAgICAgICAvLyBCZWNhdXNlIHRoaXMgYmluZGluZyBkb2Vzbid0IHJlYWxseSB0YXJnZXQgdGhlIG5nLXRlbXBsYXRlLCBpdCBtdXN0IGJlIGEgYmluZGluZyBvbiBhblxuICAgICAgICAgIC8vIGlubmVyIG5vZGUgb2YgYSBzdHJ1Y3R1cmFsIHRlbXBsYXRlLiBXZSBjYW4ndCBza2lwIGl0IGVudGlyZWx5LCBiZWNhdXNlIHdlIHN0aWxsIG5lZWRcbiAgICAgICAgICAvLyBpdCBvbiB0aGUgbmctdGVtcGxhdGUncyBjb25zdHMgKGUuZy4gZm9yIHRoZSBwdXJwb3NlcyBvZiBkaXJlY3RpdmUgbWF0Y2hpbmcpLiBIb3dldmVyLFxuICAgICAgICAgIC8vIHdlIHNob3VsZCBub3QgZ2VuZXJhdGUgYW4gdXBkYXRlIGluc3RydWN0aW9uIGZvciBpdC5cbiAgICAgICAgICByZXR1cm4gaXIuY3JlYXRlRXh0cmFjdGVkQXR0cmlidXRlT3AoXG4gICAgICAgICAgICB4cmVmLFxuICAgICAgICAgICAgaXIuQmluZGluZ0tpbmQuUHJvcGVydHksXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgaTE4bk1lc3NhZ2UsXG4gICAgICAgICAgICBzZWN1cml0eUNvbnRleHQsXG4gICAgICAgICAgKTtcbiAgICAgICAgY2FzZSBlLkJpbmRpbmdUeXBlLlR3b1dheTpcbiAgICAgICAgICByZXR1cm4gaXIuY3JlYXRlRXh0cmFjdGVkQXR0cmlidXRlT3AoXG4gICAgICAgICAgICB4cmVmLFxuICAgICAgICAgICAgaXIuQmluZGluZ0tpbmQuVHdvV2F5UHJvcGVydHksXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgaTE4bk1lc3NhZ2UsXG4gICAgICAgICAgICBzZWN1cml0eUNvbnRleHQsXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWlzVGV4dEJpbmRpbmcgJiYgKHR5cGUgPT09IGUuQmluZGluZ1R5cGUuQXR0cmlidXRlIHx8IHR5cGUgPT09IGUuQmluZGluZ1R5cGUuQW5pbWF0aW9uKSkge1xuICAgICAgLy8gQWdhaW4sIHRoaXMgYmluZGluZyBkb2Vzbid0IHJlYWxseSB0YXJnZXQgdGhlIG5nLXRlbXBsYXRlOyBpdCBhY3R1YWxseSB0YXJnZXRzIHRoZSBlbGVtZW50XG4gICAgICAvLyBpbnNpZGUgdGhlIHN0cnVjdHVyYWwgdGVtcGxhdGUuIEluIHRoZSBjYXNlIG9mIG5vbi10ZXh0IGF0dHJpYnV0ZSBvciBhbmltYXRpb24gYmluZGluZ3MsXG4gICAgICAvLyB0aGUgYmluZGluZyBkb2Vzbid0IGV2ZW4gc2hvdyB1cCBvbiB0aGUgbmctdGVtcGxhdGUgY29uc3QgYXJyYXksIHNvIHdlIGp1c3Qgc2tpcCBpdFxuICAgICAgLy8gZW50aXJlbHkuXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBsZXQgYmluZGluZ1R5cGUgPSBCSU5ESU5HX0tJTkRTLmdldCh0eXBlKSE7XG5cbiAgaWYgKHRlbXBsYXRlS2luZCA9PT0gaXIuVGVtcGxhdGVLaW5kLk5nVGVtcGxhdGUpIHtcbiAgICAvLyBXZSBrbm93IHdlIGFyZSBkZWFsaW5nIHdpdGggYmluZGluZ3MgZGlyZWN0bHkgb24gYW4gZXhwbGljaXQgbmctdGVtcGxhdGUuXG4gICAgLy8gU3RhdGljIGF0dHJpYnV0ZSBiaW5kaW5ncyBzaG91bGQgYmUgY29sbGVjdGVkIGludG8gdGhlIGNvbnN0IGFycmF5IGFzIGsvdiBwYWlycy4gUHJvcGVydHlcbiAgICAvLyBiaW5kaW5ncyBzaG91bGQgcmVzdWx0IGluIGEgYHByb3BlcnR5YCBpbnN0cnVjdGlvbiwgYW5kIGBBdHRyaWJ1dGVNYXJrZXIuQmluZGluZ3NgIGNvbnN0XG4gICAgLy8gZW50cmllcy5cbiAgICAvL1xuICAgIC8vIFRoZSBkaWZmaWN1bHR5IGlzIHdpdGggZHluYW1pYyBhdHRyaWJ1dGUsIHN0eWxlLCBhbmQgY2xhc3MgYmluZGluZ3MuIFRoZXNlIGRvbid0IHJlYWxseSBtYWtlXG4gICAgLy8gc2Vuc2Ugb24gYW4gYG5nLXRlbXBsYXRlYCBhbmQgc2hvdWxkIHByb2JhYmx5IGJlIHBhcnNlciBlcnJvcnMuIEhvd2V2ZXIsXG4gICAgLy8gVGVtcGxhdGVEZWZpbml0aW9uQnVpbGRlciBnZW5lcmF0ZXMgYHByb3BlcnR5YCBpbnN0cnVjdGlvbnMgZm9yIHRoZW0sIGFuZCBzbyB3ZSBkbyB0aGF0IGFzXG4gICAgLy8gd2VsbC5cbiAgICAvL1xuICAgIC8vIE5vdGUgdGhhdCB3ZSBkbyBoYXZlIGEgc2xpZ2h0IGJlaGF2aW9yIGRpZmZlcmVuY2Ugd2l0aCBUZW1wbGF0ZURlZmluaXRpb25CdWlsZGVyOiBhbHRob3VnaFxuICAgIC8vIFREQiBlbWl0cyBgcHJvcGVydHlgIGluc3RydWN0aW9ucyBmb3IgZHluYW1pYyBhdHRyaWJ1dGVzLCBzdHlsZXMsIGFuZCBjbGFzc2VzLCBvbmx5IHN0eWxlc1xuICAgIC8vIGFuZCBjbGFzc2VzIGFsc28gZ2V0IGNvbnN0IGNvbGxlY3RlZCBpbnRvIHRoZSBgQXR0cmlidXRlTWFya2VyLkJpbmRpbmdzYCBmaWVsZC4gRHluYW1pY1xuICAgIC8vIGF0dHJpYnV0ZSBiaW5kaW5ncyBhcmUgbWlzc2luZyBmcm9tIHRoZSBjb25zdHMgZW50aXJlbHkuIFdlIGNob29zZSB0byBlbWl0IHRoZW0gaW50byB0aGVcbiAgICAvLyBjb25zdHMgZmllbGQgYW55d2F5LCB0byBhdm9pZCBjcmVhdGluZyBzcGVjaWFsIGNhc2VzIGZvciBzb21ldGhpbmcgc28gYXJjYW5lIGFuZCBub25zZW5zaWNhbC5cbiAgICBpZiAoXG4gICAgICB0eXBlID09PSBlLkJpbmRpbmdUeXBlLkNsYXNzIHx8XG4gICAgICB0eXBlID09PSBlLkJpbmRpbmdUeXBlLlN0eWxlIHx8XG4gICAgICAodHlwZSA9PT0gZS5CaW5kaW5nVHlwZS5BdHRyaWJ1dGUgJiYgIWlzVGV4dEJpbmRpbmcpXG4gICAgKSB7XG4gICAgICAvLyBUT0RPOiBUaGVzZSBjYXNlcyBzaG91bGQgYmUgcGFyc2UgZXJyb3JzLlxuICAgICAgYmluZGluZ1R5cGUgPSBpci5CaW5kaW5nS2luZC5Qcm9wZXJ0eTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaXIuY3JlYXRlQmluZGluZ09wKFxuICAgIHhyZWYsXG4gICAgYmluZGluZ1R5cGUsXG4gICAgbmFtZSxcbiAgICBjb252ZXJ0QXN0V2l0aEludGVycG9sYXRpb24odmlldy5qb2IsIHZhbHVlLCBpMThuTWVzc2FnZSksXG4gICAgdW5pdCxcbiAgICBzZWN1cml0eUNvbnRleHQsXG4gICAgaXNUZXh0QmluZGluZyxcbiAgICBpc1N0cnVjdHVyYWxUZW1wbGF0ZUF0dHJpYnV0ZSxcbiAgICB0ZW1wbGF0ZUtpbmQsXG4gICAgaTE4bk1lc3NhZ2UsXG4gICAgc291cmNlU3BhbixcbiAgKTtcbn1cblxuZnVuY3Rpb24gbWFrZUxpc3RlbmVySGFuZGxlck9wcyhcbiAgdW5pdDogQ29tcGlsYXRpb25Vbml0LFxuICBoYW5kbGVyOiBlLkFTVCxcbiAgaGFuZGxlclNwYW46IFBhcnNlU291cmNlU3Bhbixcbik6IGlyLlVwZGF0ZU9wW10ge1xuICBoYW5kbGVyID0gYXN0T2YoaGFuZGxlcik7XG4gIGNvbnN0IGhhbmRsZXJPcHMgPSBuZXcgQXJyYXk8aXIuVXBkYXRlT3A+KCk7XG4gIGxldCBoYW5kbGVyRXhwcnM6IGUuQVNUW10gPSBoYW5kbGVyIGluc3RhbmNlb2YgZS5DaGFpbiA/IGhhbmRsZXIuZXhwcmVzc2lvbnMgOiBbaGFuZGxlcl07XG4gIGlmIChoYW5kbGVyRXhwcnMubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBsaXN0ZW5lciB0byBoYXZlIG5vbi1lbXB0eSBleHByZXNzaW9uIGxpc3QuJyk7XG4gIH1cbiAgY29uc3QgZXhwcmVzc2lvbnMgPSBoYW5kbGVyRXhwcnMubWFwKChleHByKSA9PiBjb252ZXJ0QXN0KGV4cHIsIHVuaXQuam9iLCBoYW5kbGVyU3BhbikpO1xuICBjb25zdCByZXR1cm5FeHByID0gZXhwcmVzc2lvbnMucG9wKCkhO1xuICBoYW5kbGVyT3BzLnB1c2goXG4gICAgLi4uZXhwcmVzc2lvbnMubWFwKChlKSA9PlxuICAgICAgaXIuY3JlYXRlU3RhdGVtZW50T3A8aXIuVXBkYXRlT3A+KG5ldyBvLkV4cHJlc3Npb25TdGF0ZW1lbnQoZSwgZS5zb3VyY2VTcGFuKSksXG4gICAgKSxcbiAgKTtcbiAgaGFuZGxlck9wcy5wdXNoKGlyLmNyZWF0ZVN0YXRlbWVudE9wKG5ldyBvLlJldHVyblN0YXRlbWVudChyZXR1cm5FeHByLCByZXR1cm5FeHByLnNvdXJjZVNwYW4pKSk7XG4gIHJldHVybiBoYW5kbGVyT3BzO1xufVxuXG5mdW5jdGlvbiBtYWtlVHdvV2F5TGlzdGVuZXJIYW5kbGVyT3BzKFxuICB1bml0OiBDb21waWxhdGlvblVuaXQsXG4gIGhhbmRsZXI6IGUuQVNULFxuICBoYW5kbGVyU3BhbjogUGFyc2VTb3VyY2VTcGFuLFxuKTogaXIuVXBkYXRlT3BbXSB7XG4gIGhhbmRsZXIgPSBhc3RPZihoYW5kbGVyKTtcbiAgY29uc3QgaGFuZGxlck9wcyA9IG5ldyBBcnJheTxpci5VcGRhdGVPcD4oKTtcblxuICBpZiAoaGFuZGxlciBpbnN0YW5jZW9mIGUuQ2hhaW4pIHtcbiAgICBpZiAoaGFuZGxlci5leHByZXNzaW9ucy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGhhbmRsZXIgPSBoYW5kbGVyLmV4cHJlc3Npb25zWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBUaGlzIGlzIHZhbGlkYXRlZCBkdXJpbmcgcGFyc2luZyBhbHJlYWR5LCBidXQgd2UgZG8gaXQgaGVyZSBqdXN0IGluIGNhc2UuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHR3by13YXkgbGlzdGVuZXIgdG8gaGF2ZSBhIHNpbmdsZSBleHByZXNzaW9uLicpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGhhbmRsZXJFeHByID0gY29udmVydEFzdChoYW5kbGVyLCB1bml0LmpvYiwgaGFuZGxlclNwYW4pO1xuICBjb25zdCBldmVudFJlZmVyZW5jZSA9IG5ldyBpci5MZXhpY2FsUmVhZEV4cHIoJyRldmVudCcpO1xuICBjb25zdCB0d29XYXlTZXRFeHByID0gbmV3IGlyLlR3b1dheUJpbmRpbmdTZXRFeHByKGhhbmRsZXJFeHByLCBldmVudFJlZmVyZW5jZSk7XG5cbiAgaGFuZGxlck9wcy5wdXNoKGlyLmNyZWF0ZVN0YXRlbWVudE9wPGlyLlVwZGF0ZU9wPihuZXcgby5FeHByZXNzaW9uU3RhdGVtZW50KHR3b1dheVNldEV4cHIpKSk7XG4gIGhhbmRsZXJPcHMucHVzaChpci5jcmVhdGVTdGF0ZW1lbnRPcChuZXcgby5SZXR1cm5TdGF0ZW1lbnQoZXZlbnRSZWZlcmVuY2UpKSk7XG4gIHJldHVybiBoYW5kbGVyT3BzO1xufVxuXG5mdW5jdGlvbiBhc3RPZihhc3Q6IGUuQVNUIHwgZS5BU1RXaXRoU291cmNlKTogZS5BU1Qge1xuICByZXR1cm4gYXN0IGluc3RhbmNlb2YgZS5BU1RXaXRoU291cmNlID8gYXN0LmFzdCA6IGFzdDtcbn1cblxuLyoqXG4gKiBQcm9jZXNzIGFsbCBvZiB0aGUgbG9jYWwgcmVmZXJlbmNlcyBvbiBhbiBlbGVtZW50LWxpa2Ugc3RydWN0dXJlIGluIHRoZSB0ZW1wbGF0ZSBBU1QgYW5kXG4gKiBjb252ZXJ0IHRoZW0gdG8gdGhlaXIgSVIgcmVwcmVzZW50YXRpb24uXG4gKi9cbmZ1bmN0aW9uIGluZ2VzdFJlZmVyZW5jZXMob3A6IGlyLkVsZW1lbnRPcEJhc2UsIGVsZW1lbnQ6IHQuRWxlbWVudCB8IHQuVGVtcGxhdGUpOiB2b2lkIHtcbiAgYXNzZXJ0SXNBcnJheTxpci5Mb2NhbFJlZj4ob3AubG9jYWxSZWZzKTtcbiAgZm9yIChjb25zdCB7bmFtZSwgdmFsdWV9IG9mIGVsZW1lbnQucmVmZXJlbmNlcykge1xuICAgIG9wLmxvY2FsUmVmcy5wdXNoKHtcbiAgICAgIG5hbWUsXG4gICAgICB0YXJnZXQ6IHZhbHVlLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogQXNzZXJ0IHRoYXQgdGhlIGdpdmVuIHZhbHVlIGlzIGFuIGFycmF5LlxuICovXG5mdW5jdGlvbiBhc3NlcnRJc0FycmF5PFQ+KHZhbHVlOiBhbnkpOiBhc3NlcnRzIHZhbHVlIGlzIEFycmF5PFQ+IHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgQXNzZXJ0aW9uRXJyb3I6IGV4cGVjdGVkIGFuIGFycmF5YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFic29sdXRlIGBQYXJzZVNvdXJjZVNwYW5gIGZyb20gdGhlIHJlbGF0aXZlIGBQYXJzZVNwYW5gLlxuICpcbiAqIGBQYXJzZVNwYW5gIG9iamVjdHMgYXJlIHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0aGUgZXhwcmVzc2lvbi5cbiAqIFRoaXMgbWV0aG9kIGNvbnZlcnRzIHRoZXNlIHRvIGZ1bGwgYFBhcnNlU291cmNlU3BhbmAgb2JqZWN0cyB0aGF0XG4gKiBzaG93IHdoZXJlIHRoZSBzcGFuIGlzIHdpdGhpbiB0aGUgb3ZlcmFsbCBzb3VyY2UgZmlsZS5cbiAqXG4gKiBAcGFyYW0gc3BhbiB0aGUgcmVsYXRpdmUgc3BhbiB0byBjb252ZXJ0LlxuICogQHBhcmFtIGJhc2VTb3VyY2VTcGFuIGEgc3BhbiBjb3JyZXNwb25kaW5nIHRvIHRoZSBiYXNlIG9mIHRoZSBleHByZXNzaW9uIHRyZWUuXG4gKiBAcmV0dXJucyBhIGBQYXJzZVNvdXJjZVNwYW5gIGZvciB0aGUgZ2l2ZW4gc3BhbiBvciBudWxsIGlmIG5vIGBiYXNlU291cmNlU3BhbmAgd2FzIHByb3ZpZGVkLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0U291cmNlU3BhbihcbiAgc3BhbjogZS5QYXJzZVNwYW4sXG4gIGJhc2VTb3VyY2VTcGFuOiBQYXJzZVNvdXJjZVNwYW4gfCBudWxsLFxuKTogUGFyc2VTb3VyY2VTcGFuIHwgbnVsbCB7XG4gIGlmIChiYXNlU291cmNlU3BhbiA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGNvbnN0IHN0YXJ0ID0gYmFzZVNvdXJjZVNwYW4uc3RhcnQubW92ZUJ5KHNwYW4uc3RhcnQpO1xuICBjb25zdCBlbmQgPSBiYXNlU291cmNlU3Bhbi5zdGFydC5tb3ZlQnkoc3Bhbi5lbmQpO1xuICBjb25zdCBmdWxsU3RhcnQgPSBiYXNlU291cmNlU3Bhbi5mdWxsU3RhcnQubW92ZUJ5KHNwYW4uc3RhcnQpO1xuICByZXR1cm4gbmV3IFBhcnNlU291cmNlU3BhbihzdGFydCwgZW5kLCBmdWxsU3RhcnQpO1xufVxuXG4vKipcbiAqIFdpdGggdGhlIGRpcmVjdGl2ZS1iYXNlZCBjb250cm9sIGZsb3cgdXNlcnMgd2VyZSBhYmxlIHRvIGNvbmRpdGlvbmFsbHkgcHJvamVjdCBjb250ZW50IHVzaW5nXG4gKiB0aGUgYCpgIHN5bnRheC4gRS5nLiBgPGRpdiAqbmdJZj1cImV4cHJcIiBwcm9qZWN0TWU+PC9kaXY+YCB3aWxsIGJlIHByb2plY3RlZCBpbnRvXG4gKiBgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW3Byb2plY3RNZV1cIi8+YCwgYmVjYXVzZSB0aGUgYXR0cmlidXRlcyBhbmQgdGFnIG5hbWUgZnJvbSB0aGUgYGRpdmAgYXJlXG4gKiBjb3BpZWQgdG8gdGhlIHRlbXBsYXRlIHZpYSB0aGUgdGVtcGxhdGUgY3JlYXRpb24gaW5zdHJ1Y3Rpb24uIFdpdGggYEBpZmAgYW5kIGBAZm9yYCB0aGF0IGlzXG4gKiBub3QgdGhlIGNhc2UsIGJlY2F1c2UgdGhlIGNvbmRpdGlvbmFsIGlzIHBsYWNlZCAqYXJvdW5kKiBlbGVtZW50cywgcmF0aGVyIHRoYW4gKm9uKiB0aGVtLlxuICogVGhlIHJlc3VsdCBpcyB0aGF0IGNvbnRlbnQgcHJvamVjdGlvbiB3b24ndCB3b3JrIGluIHRoZSBzYW1lIHdheSBpZiBhIHVzZXIgY29udmVydHMgZnJvbVxuICogYCpuZ0lmYCB0byBgQGlmYC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGFpbXMgdG8gY292ZXIgdGhlIG1vc3QgY29tbW9uIGNhc2UgYnkgZG9pbmcgdGhlIHNhbWUgY29weWluZyB3aGVuIGEgY29udHJvbCBmbG93XG4gKiBub2RlIGhhcyAqb25lIGFuZCBvbmx5IG9uZSogcm9vdCBlbGVtZW50IG9yIHRlbXBsYXRlIG5vZGUuXG4gKlxuICogVGhpcyBhcHByb2FjaCBjb21lcyB3aXRoIHNvbWUgY2F2ZWF0czpcbiAqIDEuIEFzIHNvb24gYXMgYW55IG90aGVyIG5vZGUgaXMgYWRkZWQgdG8gdGhlIHJvb3QsIHRoZSBjb3B5aW5nIGJlaGF2aW9yIHdvbid0IHdvcmsgYW55bW9yZS5cbiAqICAgIEEgZGlhZ25vc3RpYyB3aWxsIGJlIGFkZGVkIHRvIGZsYWcgY2FzZXMgbGlrZSB0aGlzIGFuZCB0byBleHBsYWluIGhvdyB0byB3b3JrIGFyb3VuZCBpdC5cbiAqIDIuIElmIGBwcmVzZXJ2ZVdoaXRlc3BhY2VzYCBpcyBlbmFibGVkLCBpdCdzIHZlcnkgbGlrZWx5IHRoYXQgaW5kZW50YXRpb24gd2lsbCBicmVhayB0aGlzXG4gKiAgICB3b3JrYXJvdW5kLCBiZWNhdXNlIGl0J2xsIGluY2x1ZGUgYW4gYWRkaXRpb25hbCB0ZXh0IG5vZGUgYXMgdGhlIGZpcnN0IGNoaWxkLiBXZSBjYW4gd29ya1xuICogICAgYXJvdW5kIGl0IGhlcmUsIGJ1dCBpbiBhIGRpc2N1c3Npb24gaXQgd2FzIGRlY2lkZWQgbm90IHRvLCBiZWNhdXNlIHRoZSB1c2VyIGV4cGxpY2l0bHkgb3B0ZWRcbiAqICAgIGludG8gcHJlc2VydmluZyB0aGUgd2hpdGVzcGFjZSBhbmQgd2Ugd291bGQgaGF2ZSB0byBkcm9wIGl0IGZyb20gdGhlIGdlbmVyYXRlZCBjb2RlLlxuICogICAgVGhlIGRpYWdub3N0aWMgbWVudGlvbmVkIHBvaW50ICMxIHdpbGwgZmxhZyBzdWNoIGNhc2VzIHRvIHVzZXJzLlxuICpcbiAqIEByZXR1cm5zIFRhZyBuYW1lIHRvIGJlIHVzZWQgZm9yIHRoZSBjb250cm9sIGZsb3cgdGVtcGxhdGUuXG4gKi9cbmZ1bmN0aW9uIGluZ2VzdENvbnRyb2xGbG93SW5zZXJ0aW9uUG9pbnQoXG4gIHVuaXQ6IFZpZXdDb21waWxhdGlvblVuaXQsXG4gIHhyZWY6IGlyLlhyZWZJZCxcbiAgbm9kZTogdC5JZkJsb2NrQnJhbmNoIHwgdC5Td2l0Y2hCbG9ja0Nhc2UgfCB0LkZvckxvb3BCbG9jayB8IHQuRm9yTG9vcEJsb2NrRW1wdHksXG4pOiBzdHJpbmcgfCBudWxsIHtcbiAgbGV0IHJvb3Q6IHQuRWxlbWVudCB8IHQuVGVtcGxhdGUgfCBudWxsID0gbnVsbDtcblxuICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5vZGUuY2hpbGRyZW4pIHtcbiAgICAvLyBTa2lwIG92ZXIgY29tbWVudCBub2Rlcy5cbiAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiB0LkNvbW1lbnQpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIFdlIGNhbiBvbmx5IGluZmVyIHRoZSB0YWcgbmFtZS9hdHRyaWJ1dGVzIGlmIHRoZXJlJ3MgYSBzaW5nbGUgcm9vdCBub2RlLlxuICAgIGlmIChyb290ICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBSb290IG5vZGVzIGNhbiBvbmx5IGVsZW1lbnRzIG9yIHRlbXBsYXRlcyB3aXRoIGEgdGFnIG5hbWUgKGUuZy4gYDxkaXYgKmZvbz48L2Rpdj5gKS5cbiAgICBpZiAoY2hpbGQgaW5zdGFuY2VvZiB0LkVsZW1lbnQgfHwgKGNoaWxkIGluc3RhbmNlb2YgdC5UZW1wbGF0ZSAmJiBjaGlsZC50YWdOYW1lICE9PSBudWxsKSkge1xuICAgICAgcm9vdCA9IGNoaWxkO1xuICAgIH1cbiAgfVxuXG4gIC8vIElmIHdlJ3ZlIGZvdW5kIGEgc2luZ2xlIHJvb3Qgbm9kZSwgaXRzIHRhZyBuYW1lIGFuZCBhdHRyaWJ1dGVzIGNhbiBiZVxuICAvLyBjb3BpZWQgdG8gdGhlIHN1cnJvdW5kaW5nIHRlbXBsYXRlIHRvIGJlIHVzZWQgZm9yIGNvbnRlbnQgcHJvamVjdGlvbi5cbiAgaWYgKHJvb3QgIT09IG51bGwpIHtcbiAgICAvLyBDb2xsZWN0IHRoZSBzdGF0aWMgYXR0cmlidXRlcyBmb3IgY29udGVudCBwcm9qZWN0aW9uIHB1cnBvc2VzLlxuICAgIGZvciAoY29uc3QgYXR0ciBvZiByb290LmF0dHJpYnV0ZXMpIHtcbiAgICAgIGNvbnN0IHNlY3VyaXR5Q29udGV4dCA9IGRvbVNjaGVtYS5zZWN1cml0eUNvbnRleHQoTkdfVEVNUExBVEVfVEFHX05BTUUsIGF0dHIubmFtZSwgdHJ1ZSk7XG4gICAgICB1bml0LnVwZGF0ZS5wdXNoKFxuICAgICAgICBpci5jcmVhdGVCaW5kaW5nT3AoXG4gICAgICAgICAgeHJlZixcbiAgICAgICAgICBpci5CaW5kaW5nS2luZC5BdHRyaWJ1dGUsXG4gICAgICAgICAgYXR0ci5uYW1lLFxuICAgICAgICAgIG8ubGl0ZXJhbChhdHRyLnZhbHVlKSxcbiAgICAgICAgICBudWxsLFxuICAgICAgICAgIHNlY3VyaXR5Q29udGV4dCxcbiAgICAgICAgICB0cnVlLFxuICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICAgYXNNZXNzYWdlKGF0dHIuaTE4biksXG4gICAgICAgICAgYXR0ci5zb3VyY2VTcGFuLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBBbHNvIGNvbGxlY3QgdGhlIGlucHV0cyBzaW5jZSB0aGV5IHBhcnRpY2lwYXRlIGluIGNvbnRlbnQgcHJvamVjdGlvbiBhcyB3ZWxsLlxuICAgIC8vIE5vdGUgdGhhdCBUREIgdXNlZCB0byBjb2xsZWN0IHRoZSBvdXRwdXRzIGFzIHdlbGwsIGJ1dCBpdCB3YXNuJ3QgcGFzc2luZyB0aGVtIGludG9cbiAgICAvLyB0aGUgdGVtcGxhdGUgaW5zdHJ1Y3Rpb24uIEhlcmUgd2UganVzdCBkb24ndCBjb2xsZWN0IHRoZW0uXG4gICAgZm9yIChjb25zdCBhdHRyIG9mIHJvb3QuaW5wdXRzKSB7XG4gICAgICBpZiAoYXR0ci50eXBlICE9PSBlLkJpbmRpbmdUeXBlLkFuaW1hdGlvbiAmJiBhdHRyLnR5cGUgIT09IGUuQmluZGluZ1R5cGUuQXR0cmlidXRlKSB7XG4gICAgICAgIGNvbnN0IHNlY3VyaXR5Q29udGV4dCA9IGRvbVNjaGVtYS5zZWN1cml0eUNvbnRleHQoTkdfVEVNUExBVEVfVEFHX05BTUUsIGF0dHIubmFtZSwgdHJ1ZSk7XG4gICAgICAgIHVuaXQuY3JlYXRlLnB1c2goXG4gICAgICAgICAgaXIuY3JlYXRlRXh0cmFjdGVkQXR0cmlidXRlT3AoXG4gICAgICAgICAgICB4cmVmLFxuICAgICAgICAgICAgaXIuQmluZGluZ0tpbmQuUHJvcGVydHksXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgYXR0ci5uYW1lLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgc2VjdXJpdHlDb250ZXh0LFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgdGFnTmFtZSA9IHJvb3QgaW5zdGFuY2VvZiB0LkVsZW1lbnQgPyByb290Lm5hbWUgOiByb290LnRhZ05hbWU7XG5cbiAgICAvLyBEb24ndCBwYXNzIGFsb25nIGBuZy10ZW1wbGF0ZWAgdGFnIG5hbWUgc2luY2UgaXQgZW5hYmxlcyBkaXJlY3RpdmUgbWF0Y2hpbmcuXG4gICAgcmV0dXJuIHRhZ05hbWUgPT09IE5HX1RFTVBMQVRFX1RBR19OQU1FID8gbnVsbCA6IHRhZ05hbWU7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cbiJdfQ==