@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.
- package/LICENSE +21 -0
- package/fesm2022/compiler.mjs +5465 -4675
- package/fesm2022/compiler.mjs.map +1 -1
- package/index.d.ts +115 -15
- package/package.json +2 -4
- package/esm2022/compiler.mjs +0 -13
- package/esm2022/index.mjs +0 -13
- package/esm2022/public_api.mjs +0 -15
- package/esm2022/src/assertions.mjs +0 -31
- package/esm2022/src/chars.mjs +0 -90
- package/esm2022/src/compiler.mjs +0 -88
- package/esm2022/src/compiler_facade_interface.mjs +0 -29
- package/esm2022/src/config.mjs +0 -20
- package/esm2022/src/constant_pool.mjs +0 -285
- package/esm2022/src/core.mjs +0 -96
- package/esm2022/src/expression_parser/ast.mjs +0 -755
- package/esm2022/src/expression_parser/lexer.mjs +0 -421
- package/esm2022/src/expression_parser/parser.mjs +0 -1222
- package/esm2022/src/i18n/digest.mjs +0 -322
- package/esm2022/src/i18n/extractor_merger.mjs +0 -409
- package/esm2022/src/i18n/i18n_ast.mjs +0 -212
- package/esm2022/src/i18n/i18n_html_parser.mjs +0 -54
- package/esm2022/src/i18n/i18n_parser.mjs +0 -247
- package/esm2022/src/i18n/index.mjs +0 -16
- package/esm2022/src/i18n/message_bundle.mjs +0 -93
- package/esm2022/src/i18n/parse_util.mjs +0 -17
- package/esm2022/src/i18n/serializers/placeholder.mjs +0 -139
- package/esm2022/src/i18n/serializers/serializer.mjs +0 -77
- package/esm2022/src/i18n/serializers/xliff.mjs +0 -300
- package/esm2022/src/i18n/serializers/xliff2.mjs +0 -349
- package/esm2022/src/i18n/serializers/xmb.mjs +0 -188
- package/esm2022/src/i18n/serializers/xml_helper.mjs +0 -94
- package/esm2022/src/i18n/serializers/xtb.mjs +0 -186
- package/esm2022/src/i18n/translation_bundle.mjs +0 -164
- package/esm2022/src/injectable_compiler_2.mjs +0 -138
- package/esm2022/src/jit_compiler_facade.mjs +0 -681
- package/esm2022/src/ml_parser/ast.mjs +0 -167
- package/esm2022/src/ml_parser/defaults.mjs +0 -24
- package/esm2022/src/ml_parser/entities.mjs +0 -2144
- package/esm2022/src/ml_parser/html_parser.mjs +0 -18
- package/esm2022/src/ml_parser/html_tags.mjs +0 -156
- package/esm2022/src/ml_parser/html_whitespaces.mjs +0 -107
- package/esm2022/src/ml_parser/icu_ast_expander.mjs +0 -125
- package/esm2022/src/ml_parser/lexer.mjs +0 -1210
- package/esm2022/src/ml_parser/parser.mjs +0 -539
- package/esm2022/src/ml_parser/tags.mjs +0 -47
- package/esm2022/src/ml_parser/tokens.mjs +0 -9
- package/esm2022/src/ml_parser/xml_parser.mjs +0 -19
- package/esm2022/src/ml_parser/xml_tags.mjs +0 -32
- package/esm2022/src/output/abstract_emitter.mjs +0 -524
- package/esm2022/src/output/abstract_js_emitter.mjs +0 -130
- package/esm2022/src/output/map_util.mjs +0 -19
- package/esm2022/src/output/output_ast.mjs +0 -1301
- package/esm2022/src/output/output_jit.mjs +0 -138
- package/esm2022/src/output/output_jit_trusted_types.mjs +0 -100
- package/esm2022/src/output/source_map.mjs +0 -150
- package/esm2022/src/parse_util.mjs +0 -198
- package/esm2022/src/render3/partial/api.mjs +0 -9
- package/esm2022/src/render3/partial/class_metadata.mjs +0 -52
- package/esm2022/src/render3/partial/component.mjs +0 -197
- package/esm2022/src/render3/partial/directive.mjs +0 -264
- package/esm2022/src/render3/partial/factory.mjs +0 -35
- package/esm2022/src/render3/partial/injectable.mjs +0 -67
- package/esm2022/src/render3/partial/injector.mjs +0 -41
- package/esm2022/src/render3/partial/ng_module.mjs +0 -63
- package/esm2022/src/render3/partial/pipe.mjs +0 -50
- package/esm2022/src/render3/partial/util.mjs +0 -79
- package/esm2022/src/render3/r3_ast.mjs +0 -493
- package/esm2022/src/render3/r3_class_debug_info_compiler.mjs +0 -35
- package/esm2022/src/render3/r3_class_metadata_compiler.mjs +0 -92
- package/esm2022/src/render3/r3_control_flow.mjs +0 -421
- package/esm2022/src/render3/r3_deferred_blocks.mjs +0 -170
- package/esm2022/src/render3/r3_deferred_triggers.mjs +0 -316
- package/esm2022/src/render3/r3_factory.mjs +0 -200
- package/esm2022/src/render3/r3_identifiers.mjs +0 -480
- package/esm2022/src/render3/r3_injector_compiler.mjs +0 -28
- package/esm2022/src/render3/r3_jit.mjs +0 -29
- package/esm2022/src/render3/r3_module_compiler.mjs +0 -211
- package/esm2022/src/render3/r3_pipe_compiler.mjs +0 -35
- package/esm2022/src/render3/r3_template_transform.mjs +0 -560
- package/esm2022/src/render3/util.mjs +0 -90
- package/esm2022/src/render3/view/api.mjs +0 -14
- package/esm2022/src/render3/view/compiler.mjs +0 -546
- package/esm2022/src/render3/view/i18n/get_msg_utils.mjs +0 -113
- package/esm2022/src/render3/view/i18n/icu_serializer.mjs +0 -43
- package/esm2022/src/render3/view/i18n/localize_utils.mjs +0 -118
- package/esm2022/src/render3/view/i18n/meta.mjs +0 -259
- package/esm2022/src/render3/view/i18n/util.mjs +0 -70
- package/esm2022/src/render3/view/query_generation.mjs +0 -182
- package/esm2022/src/render3/view/t2_api.mjs +0 -9
- package/esm2022/src/render3/view/t2_binder.mjs +0 -823
- package/esm2022/src/render3/view/template.mjs +0 -113
- package/esm2022/src/render3/view/util.mjs +0 -192
- package/esm2022/src/resource_loader.mjs +0 -17
- package/esm2022/src/schema/dom_element_schema_registry.mjs +0 -471
- package/esm2022/src/schema/dom_security_schema.mjs +0 -96
- package/esm2022/src/schema/element_schema_registry.mjs +0 -10
- package/esm2022/src/schema/trusted_types_sinks.mjs +0 -41
- package/esm2022/src/selector.mjs +0 -400
- package/esm2022/src/shadow_css.mjs +0 -1053
- package/esm2022/src/style_url_resolver.mjs +0 -17
- package/esm2022/src/template/pipeline/ir/index.mjs +0 -18
- package/esm2022/src/template/pipeline/ir/src/enums.mjs +0 -503
- package/esm2022/src/template/pipeline/ir/src/expression.mjs +0 -997
- package/esm2022/src/template/pipeline/ir/src/handle.mjs +0 -13
- package/esm2022/src/template/pipeline/ir/src/operations.mjs +0 -261
- package/esm2022/src/template/pipeline/ir/src/ops/create.mjs +0 -405
- package/esm2022/src/template/pipeline/ir/src/ops/host.mjs +0 -25
- package/esm2022/src/template/pipeline/ir/src/ops/shared.mjs +0 -43
- package/esm2022/src/template/pipeline/ir/src/ops/update.mjs +0 -277
- package/esm2022/src/template/pipeline/ir/src/traits.mjs +0 -64
- package/esm2022/src/template/pipeline/ir/src/variable.mjs +0 -13
- package/esm2022/src/template/pipeline/src/compilation.mjs +0 -194
- package/esm2022/src/template/pipeline/src/conversion.mjs +0 -64
- package/esm2022/src/template/pipeline/src/emit.mjs +0 -238
- package/esm2022/src/template/pipeline/src/ingest.mjs +0 -1058
- package/esm2022/src/template/pipeline/src/instruction.mjs +0 -564
- package/esm2022/src/template/pipeline/src/phases/any_cast.mjs +0 -32
- package/esm2022/src/template/pipeline/src/phases/apply_i18n_expressions.mjs +0 -63
- package/esm2022/src/template/pipeline/src/phases/assign_i18n_slot_dependencies.mjs +0 -63
- package/esm2022/src/template/pipeline/src/phases/attribute_extraction.mjs +0 -138
- package/esm2022/src/template/pipeline/src/phases/binding_specialization.mjs +0 -75
- package/esm2022/src/template/pipeline/src/phases/chaining.mjs +0 -112
- package/esm2022/src/template/pipeline/src/phases/collapse_singleton_interpolations.mjs +0 -32
- package/esm2022/src/template/pipeline/src/phases/conditionals.mjs +0 -58
- package/esm2022/src/template/pipeline/src/phases/const_collection.mjs +0 -214
- package/esm2022/src/template/pipeline/src/phases/convert_i18n_bindings.mjs +0 -52
- package/esm2022/src/template/pipeline/src/phases/create_i18n_contexts.mjs +0 -105
- package/esm2022/src/template/pipeline/src/phases/deduplicate_text_bindings.mjs +0 -40
- package/esm2022/src/template/pipeline/src/phases/defer_configs.mjs +0 -29
- package/esm2022/src/template/pipeline/src/phases/defer_resolve_targets.mjs +0 -113
- package/esm2022/src/template/pipeline/src/phases/empty_elements.mjs +0 -47
- package/esm2022/src/template/pipeline/src/phases/expand_safe_reads.mjs +0 -192
- package/esm2022/src/template/pipeline/src/phases/extract_i18n_messages.mjs +0 -218
- package/esm2022/src/template/pipeline/src/phases/generate_advance.mjs +0 -66
- package/esm2022/src/template/pipeline/src/phases/generate_local_let_references.mjs +0 -29
- package/esm2022/src/template/pipeline/src/phases/generate_projection_def.mjs +0 -46
- package/esm2022/src/template/pipeline/src/phases/generate_variables.mjs +0 -170
- package/esm2022/src/template/pipeline/src/phases/has_const_expression_collection.mjs +0 -28
- package/esm2022/src/template/pipeline/src/phases/host_style_property_parsing.mjs +0 -81
- package/esm2022/src/template/pipeline/src/phases/i18n_const_collection.mjs +0 -309
- package/esm2022/src/template/pipeline/src/phases/i18n_text_extraction.mjs +0 -97
- package/esm2022/src/template/pipeline/src/phases/local_refs.mjs +0 -43
- package/esm2022/src/template/pipeline/src/phases/namespace.mjs +0 -26
- package/esm2022/src/template/pipeline/src/phases/naming.mjs +0 -179
- package/esm2022/src/template/pipeline/src/phases/next_context_merging.mjs +0 -75
- package/esm2022/src/template/pipeline/src/phases/ng_container.mjs +0 -29
- package/esm2022/src/template/pipeline/src/phases/nonbindable.mjs +0 -47
- package/esm2022/src/template/pipeline/src/phases/nullish_coalescing.mjs +0 -33
- package/esm2022/src/template/pipeline/src/phases/ordering.mjs +0 -140
- package/esm2022/src/template/pipeline/src/phases/parse_extracted_styles.mjs +0 -137
- package/esm2022/src/template/pipeline/src/phases/phase_remove_content_selectors.mjs +0 -42
- package/esm2022/src/template/pipeline/src/phases/pipe_creation.mjs +0 -74
- package/esm2022/src/template/pipeline/src/phases/pipe_variadic.mjs +0 -30
- package/esm2022/src/template/pipeline/src/phases/propagate_i18n_blocks.mjs +0 -81
- package/esm2022/src/template/pipeline/src/phases/pure_function_extraction.mjs +0 -55
- package/esm2022/src/template/pipeline/src/phases/pure_literal_structures.mjs +0 -58
- package/esm2022/src/template/pipeline/src/phases/reify.mjs +0 -433
- package/esm2022/src/template/pipeline/src/phases/remove_empty_bindings.mjs +0 -31
- package/esm2022/src/template/pipeline/src/phases/remove_i18n_contexts.mjs +0 -27
- package/esm2022/src/template/pipeline/src/phases/remove_illegal_let_references.mjs +0 -36
- package/esm2022/src/template/pipeline/src/phases/remove_unused_i18n_attrs.mjs +0 -33
- package/esm2022/src/template/pipeline/src/phases/resolve_contexts.mjs +0 -60
- package/esm2022/src/template/pipeline/src/phases/resolve_defer_deps_fns.mjs +0 -31
- package/esm2022/src/template/pipeline/src/phases/resolve_dollar_event.mjs +0 -36
- package/esm2022/src/template/pipeline/src/phases/resolve_i18n_element_placeholders.mjs +0 -266
- package/esm2022/src/template/pipeline/src/phases/resolve_i18n_expression_placeholders.mjs +0 -70
- package/esm2022/src/template/pipeline/src/phases/resolve_names.mjs +0 -124
- package/esm2022/src/template/pipeline/src/phases/resolve_sanitizers.mjs +0 -123
- package/esm2022/src/template/pipeline/src/phases/save_restore_view.mjs +0 -64
- package/esm2022/src/template/pipeline/src/phases/slot_allocation.mjs +0 -62
- package/esm2022/src/template/pipeline/src/phases/store_let_optimization.mjs +0 -35
- package/esm2022/src/template/pipeline/src/phases/style_binding_specialization.mjs +0 -42
- package/esm2022/src/template/pipeline/src/phases/temporary_variables.mjs +0 -87
- package/esm2022/src/template/pipeline/src/phases/track_fn_generation.mjs +0 -52
- package/esm2022/src/template/pipeline/src/phases/track_fn_optimization.mjs +0 -88
- package/esm2022/src/template/pipeline/src/phases/track_variables.mjs +0 -36
- package/esm2022/src/template/pipeline/src/phases/transform_two_way_binding_set.mjs +0 -43
- package/esm2022/src/template/pipeline/src/phases/var_counting.mjs +0 -155
- package/esm2022/src/template/pipeline/src/phases/variable_optimization.mjs +0 -423
- package/esm2022/src/template/pipeline/src/phases/wrap_icus.mjs +0 -41
- package/esm2022/src/template/pipeline/src/util/elements.mjs +0 -29
- package/esm2022/src/template_parser/binding_parser.mjs +0 -465
- package/esm2022/src/template_parser/template_preparser.mjs +0 -84
- package/esm2022/src/util.mjs +0 -124
- package/esm2022/src/version.mjs +0 -15
|
@@ -1,823 +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 { AST, ImplicitReceiver, RecursiveAstVisitor, ThisReceiver, } from '../../expression_parser/ast';
|
|
9
|
-
import { Comment, Content, DeferredBlock, DeferredBlockError, DeferredBlockLoading, DeferredBlockPlaceholder, Element, ForLoopBlock, ForLoopBlockEmpty, HoverDeferredTrigger, IfBlockBranch, InteractionDeferredTrigger, LetDeclaration, Reference, SwitchBlockCase, Template, ViewportDeferredTrigger, } from '../r3_ast';
|
|
10
|
-
import { createCssSelectorFromNode } from './util';
|
|
11
|
-
/**
|
|
12
|
-
* Processes `Target`s with a given set of directives and performs a binding operation, which
|
|
13
|
-
* returns an object similar to TypeScript's `ts.TypeChecker` that contains knowledge about the
|
|
14
|
-
* target.
|
|
15
|
-
*/
|
|
16
|
-
export class R3TargetBinder {
|
|
17
|
-
constructor(directiveMatcher) {
|
|
18
|
-
this.directiveMatcher = directiveMatcher;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Perform a binding operation on the given `Target` and return a `BoundTarget` which contains
|
|
22
|
-
* metadata about the types referenced in the template.
|
|
23
|
-
*/
|
|
24
|
-
bind(target) {
|
|
25
|
-
if (!target.template) {
|
|
26
|
-
// TODO(alxhub): handle targets which contain things like HostBindings, etc.
|
|
27
|
-
throw new Error('Binding without a template not yet supported');
|
|
28
|
-
}
|
|
29
|
-
// First, parse the template into a `Scope` structure. This operation captures the syntactic
|
|
30
|
-
// scopes in the template and makes them available for later use.
|
|
31
|
-
const scope = Scope.apply(target.template);
|
|
32
|
-
// Use the `Scope` to extract the entities present at every level of the template.
|
|
33
|
-
const scopedNodeEntities = extractScopedNodeEntities(scope);
|
|
34
|
-
// Next, perform directive matching on the template using the `DirectiveBinder`. This returns:
|
|
35
|
-
// - directives: Map of nodes (elements & ng-templates) to the directives on them.
|
|
36
|
-
// - bindings: Map of inputs, outputs, and attributes to the directive/element that claims
|
|
37
|
-
// them. TODO(alxhub): handle multiple directives claiming an input/output/etc.
|
|
38
|
-
// - references: Map of #references to their targets.
|
|
39
|
-
const { directives, eagerDirectives, bindings, references } = DirectiveBinder.apply(target.template, this.directiveMatcher);
|
|
40
|
-
// Finally, run the TemplateBinder to bind references, variables, and other entities within the
|
|
41
|
-
// template. This extracts all the metadata that doesn't depend on directive matching.
|
|
42
|
-
const { expressions, symbols, nestingLevel, usedPipes, eagerPipes, deferBlocks } = TemplateBinder.applyWithScope(target.template, scope);
|
|
43
|
-
return new R3BoundTarget(target, directives, eagerDirectives, bindings, references, expressions, symbols, nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, deferBlocks);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Represents a binding scope within a template.
|
|
48
|
-
*
|
|
49
|
-
* Any variables, references, or other named entities declared within the template will
|
|
50
|
-
* be captured and available by name in `namedEntities`. Additionally, child templates will
|
|
51
|
-
* be analyzed and have their child `Scope`s available in `childScopes`.
|
|
52
|
-
*/
|
|
53
|
-
class Scope {
|
|
54
|
-
constructor(parentScope, rootNode) {
|
|
55
|
-
this.parentScope = parentScope;
|
|
56
|
-
this.rootNode = rootNode;
|
|
57
|
-
/**
|
|
58
|
-
* Named members of the `Scope`, such as `Reference`s or `Variable`s.
|
|
59
|
-
*/
|
|
60
|
-
this.namedEntities = new Map();
|
|
61
|
-
/**
|
|
62
|
-
* Set of elements that belong to this scope.
|
|
63
|
-
*/
|
|
64
|
-
this.elementsInScope = new Set();
|
|
65
|
-
/**
|
|
66
|
-
* Child `Scope`s for immediately nested `ScopedNode`s.
|
|
67
|
-
*/
|
|
68
|
-
this.childScopes = new Map();
|
|
69
|
-
this.isDeferred =
|
|
70
|
-
parentScope !== null && parentScope.isDeferred ? true : rootNode instanceof DeferredBlock;
|
|
71
|
-
}
|
|
72
|
-
static newRootScope() {
|
|
73
|
-
return new Scope(null, null);
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Process a template (either as a `Template` sub-template with variables, or a plain array of
|
|
77
|
-
* template `Node`s) and construct its `Scope`.
|
|
78
|
-
*/
|
|
79
|
-
static apply(template) {
|
|
80
|
-
const scope = Scope.newRootScope();
|
|
81
|
-
scope.ingest(template);
|
|
82
|
-
return scope;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Internal method to process the scoped node and populate the `Scope`.
|
|
86
|
-
*/
|
|
87
|
-
ingest(nodeOrNodes) {
|
|
88
|
-
if (nodeOrNodes instanceof Template) {
|
|
89
|
-
// Variables on an <ng-template> are defined in the inner scope.
|
|
90
|
-
nodeOrNodes.variables.forEach((node) => this.visitVariable(node));
|
|
91
|
-
// Process the nodes of the template.
|
|
92
|
-
nodeOrNodes.children.forEach((node) => node.visit(this));
|
|
93
|
-
}
|
|
94
|
-
else if (nodeOrNodes instanceof IfBlockBranch) {
|
|
95
|
-
if (nodeOrNodes.expressionAlias !== null) {
|
|
96
|
-
this.visitVariable(nodeOrNodes.expressionAlias);
|
|
97
|
-
}
|
|
98
|
-
nodeOrNodes.children.forEach((node) => node.visit(this));
|
|
99
|
-
}
|
|
100
|
-
else if (nodeOrNodes instanceof ForLoopBlock) {
|
|
101
|
-
this.visitVariable(nodeOrNodes.item);
|
|
102
|
-
nodeOrNodes.contextVariables.forEach((v) => this.visitVariable(v));
|
|
103
|
-
nodeOrNodes.children.forEach((node) => node.visit(this));
|
|
104
|
-
}
|
|
105
|
-
else if (nodeOrNodes instanceof SwitchBlockCase ||
|
|
106
|
-
nodeOrNodes instanceof ForLoopBlockEmpty ||
|
|
107
|
-
nodeOrNodes instanceof DeferredBlock ||
|
|
108
|
-
nodeOrNodes instanceof DeferredBlockError ||
|
|
109
|
-
nodeOrNodes instanceof DeferredBlockPlaceholder ||
|
|
110
|
-
nodeOrNodes instanceof DeferredBlockLoading ||
|
|
111
|
-
nodeOrNodes instanceof Content) {
|
|
112
|
-
nodeOrNodes.children.forEach((node) => node.visit(this));
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
// No overarching `Template` instance, so process the nodes directly.
|
|
116
|
-
nodeOrNodes.forEach((node) => node.visit(this));
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
visitElement(element) {
|
|
120
|
-
// `Element`s in the template may have `Reference`s which are captured in the scope.
|
|
121
|
-
element.references.forEach((node) => this.visitReference(node));
|
|
122
|
-
// Recurse into the `Element`'s children.
|
|
123
|
-
element.children.forEach((node) => node.visit(this));
|
|
124
|
-
this.elementsInScope.add(element);
|
|
125
|
-
}
|
|
126
|
-
visitTemplate(template) {
|
|
127
|
-
// References on a <ng-template> are defined in the outer scope, so capture them before
|
|
128
|
-
// processing the template's child scope.
|
|
129
|
-
template.references.forEach((node) => this.visitReference(node));
|
|
130
|
-
// Next, create an inner scope and process the template within it.
|
|
131
|
-
this.ingestScopedNode(template);
|
|
132
|
-
}
|
|
133
|
-
visitVariable(variable) {
|
|
134
|
-
// Declare the variable if it's not already.
|
|
135
|
-
this.maybeDeclare(variable);
|
|
136
|
-
}
|
|
137
|
-
visitReference(reference) {
|
|
138
|
-
// Declare the variable if it's not already.
|
|
139
|
-
this.maybeDeclare(reference);
|
|
140
|
-
}
|
|
141
|
-
visitDeferredBlock(deferred) {
|
|
142
|
-
this.ingestScopedNode(deferred);
|
|
143
|
-
deferred.placeholder?.visit(this);
|
|
144
|
-
deferred.loading?.visit(this);
|
|
145
|
-
deferred.error?.visit(this);
|
|
146
|
-
}
|
|
147
|
-
visitDeferredBlockPlaceholder(block) {
|
|
148
|
-
this.ingestScopedNode(block);
|
|
149
|
-
}
|
|
150
|
-
visitDeferredBlockError(block) {
|
|
151
|
-
this.ingestScopedNode(block);
|
|
152
|
-
}
|
|
153
|
-
visitDeferredBlockLoading(block) {
|
|
154
|
-
this.ingestScopedNode(block);
|
|
155
|
-
}
|
|
156
|
-
visitSwitchBlock(block) {
|
|
157
|
-
block.cases.forEach((node) => node.visit(this));
|
|
158
|
-
}
|
|
159
|
-
visitSwitchBlockCase(block) {
|
|
160
|
-
this.ingestScopedNode(block);
|
|
161
|
-
}
|
|
162
|
-
visitForLoopBlock(block) {
|
|
163
|
-
this.ingestScopedNode(block);
|
|
164
|
-
block.empty?.visit(this);
|
|
165
|
-
}
|
|
166
|
-
visitForLoopBlockEmpty(block) {
|
|
167
|
-
this.ingestScopedNode(block);
|
|
168
|
-
}
|
|
169
|
-
visitIfBlock(block) {
|
|
170
|
-
block.branches.forEach((node) => node.visit(this));
|
|
171
|
-
}
|
|
172
|
-
visitIfBlockBranch(block) {
|
|
173
|
-
this.ingestScopedNode(block);
|
|
174
|
-
}
|
|
175
|
-
visitContent(content) {
|
|
176
|
-
this.ingestScopedNode(content);
|
|
177
|
-
}
|
|
178
|
-
visitLetDeclaration(decl) {
|
|
179
|
-
this.maybeDeclare(decl);
|
|
180
|
-
}
|
|
181
|
-
// Unused visitors.
|
|
182
|
-
visitBoundAttribute(attr) { }
|
|
183
|
-
visitBoundEvent(event) { }
|
|
184
|
-
visitBoundText(text) { }
|
|
185
|
-
visitText(text) { }
|
|
186
|
-
visitTextAttribute(attr) { }
|
|
187
|
-
visitIcu(icu) { }
|
|
188
|
-
visitDeferredTrigger(trigger) { }
|
|
189
|
-
visitUnknownBlock(block) { }
|
|
190
|
-
maybeDeclare(thing) {
|
|
191
|
-
// Declare something with a name, as long as that name isn't taken.
|
|
192
|
-
if (!this.namedEntities.has(thing.name)) {
|
|
193
|
-
this.namedEntities.set(thing.name, thing);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Look up a variable within this `Scope`.
|
|
198
|
-
*
|
|
199
|
-
* This can recurse into a parent `Scope` if it's available.
|
|
200
|
-
*/
|
|
201
|
-
lookup(name) {
|
|
202
|
-
if (this.namedEntities.has(name)) {
|
|
203
|
-
// Found in the local scope.
|
|
204
|
-
return this.namedEntities.get(name);
|
|
205
|
-
}
|
|
206
|
-
else if (this.parentScope !== null) {
|
|
207
|
-
// Not in the local scope, but there's a parent scope so check there.
|
|
208
|
-
return this.parentScope.lookup(name);
|
|
209
|
-
}
|
|
210
|
-
else {
|
|
211
|
-
// At the top level and it wasn't found.
|
|
212
|
-
return null;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
/**
|
|
216
|
-
* Get the child scope for a `ScopedNode`.
|
|
217
|
-
*
|
|
218
|
-
* This should always be defined.
|
|
219
|
-
*/
|
|
220
|
-
getChildScope(node) {
|
|
221
|
-
const res = this.childScopes.get(node);
|
|
222
|
-
if (res === undefined) {
|
|
223
|
-
throw new Error(`Assertion error: child scope for ${node} not found`);
|
|
224
|
-
}
|
|
225
|
-
return res;
|
|
226
|
-
}
|
|
227
|
-
ingestScopedNode(node) {
|
|
228
|
-
const scope = new Scope(this, node);
|
|
229
|
-
scope.ingest(node);
|
|
230
|
-
this.childScopes.set(node, scope);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Processes a template and matches directives on nodes (elements and templates).
|
|
235
|
-
*
|
|
236
|
-
* Usually used via the static `apply()` method.
|
|
237
|
-
*/
|
|
238
|
-
class DirectiveBinder {
|
|
239
|
-
constructor(matcher, directives, eagerDirectives, bindings, references) {
|
|
240
|
-
this.matcher = matcher;
|
|
241
|
-
this.directives = directives;
|
|
242
|
-
this.eagerDirectives = eagerDirectives;
|
|
243
|
-
this.bindings = bindings;
|
|
244
|
-
this.references = references;
|
|
245
|
-
// Indicates whether we are visiting elements within a `defer` block
|
|
246
|
-
this.isInDeferBlock = false;
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Process a template (list of `Node`s) and perform directive matching against each node.
|
|
250
|
-
*
|
|
251
|
-
* @param template the list of template `Node`s to match (recursively).
|
|
252
|
-
* @param selectorMatcher a `SelectorMatcher` containing the directives that are in scope for
|
|
253
|
-
* this template.
|
|
254
|
-
* @returns three maps which contain information about directives in the template: the
|
|
255
|
-
* `directives` map which lists directives matched on each node, the `bindings` map which
|
|
256
|
-
* indicates which directives claimed which bindings (inputs, outputs, etc), and the `references`
|
|
257
|
-
* map which resolves #references (`Reference`s) within the template to the named directive or
|
|
258
|
-
* template node.
|
|
259
|
-
*/
|
|
260
|
-
static apply(template, selectorMatcher) {
|
|
261
|
-
const directives = new Map();
|
|
262
|
-
const bindings = new Map();
|
|
263
|
-
const references = new Map();
|
|
264
|
-
const eagerDirectives = [];
|
|
265
|
-
const matcher = new DirectiveBinder(selectorMatcher, directives, eagerDirectives, bindings, references);
|
|
266
|
-
matcher.ingest(template);
|
|
267
|
-
return { directives, eagerDirectives, bindings, references };
|
|
268
|
-
}
|
|
269
|
-
ingest(template) {
|
|
270
|
-
template.forEach((node) => node.visit(this));
|
|
271
|
-
}
|
|
272
|
-
visitElement(element) {
|
|
273
|
-
this.visitElementOrTemplate(element);
|
|
274
|
-
}
|
|
275
|
-
visitTemplate(template) {
|
|
276
|
-
this.visitElementOrTemplate(template);
|
|
277
|
-
}
|
|
278
|
-
visitElementOrTemplate(node) {
|
|
279
|
-
// First, determine the HTML shape of the node for the purpose of directive matching.
|
|
280
|
-
// Do this by building up a `CssSelector` for the node.
|
|
281
|
-
const cssSelector = createCssSelectorFromNode(node);
|
|
282
|
-
// Next, use the `SelectorMatcher` to get the list of directives on the node.
|
|
283
|
-
const directives = [];
|
|
284
|
-
this.matcher.match(cssSelector, (_selector, results) => directives.push(...results));
|
|
285
|
-
if (directives.length > 0) {
|
|
286
|
-
this.directives.set(node, directives);
|
|
287
|
-
if (!this.isInDeferBlock) {
|
|
288
|
-
this.eagerDirectives.push(...directives);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
// Resolve any references that are created on this node.
|
|
292
|
-
node.references.forEach((ref) => {
|
|
293
|
-
let dirTarget = null;
|
|
294
|
-
// If the reference expression is empty, then it matches the "primary" directive on the node
|
|
295
|
-
// (if there is one). Otherwise it matches the host node itself (either an element or
|
|
296
|
-
// <ng-template> node).
|
|
297
|
-
if (ref.value.trim() === '') {
|
|
298
|
-
// This could be a reference to a component if there is one.
|
|
299
|
-
dirTarget = directives.find((dir) => dir.isComponent) || null;
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
// This should be a reference to a directive exported via exportAs.
|
|
303
|
-
dirTarget =
|
|
304
|
-
directives.find((dir) => dir.exportAs !== null && dir.exportAs.some((value) => value === ref.value)) || null;
|
|
305
|
-
// Check if a matching directive was found.
|
|
306
|
-
if (dirTarget === null) {
|
|
307
|
-
// No matching directive was found - this reference points to an unknown target. Leave it
|
|
308
|
-
// unmapped.
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
if (dirTarget !== null) {
|
|
313
|
-
// This reference points to a directive.
|
|
314
|
-
this.references.set(ref, { directive: dirTarget, node });
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
// This reference points to the node itself.
|
|
318
|
-
this.references.set(ref, node);
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
const setAttributeBinding = (attribute, ioType) => {
|
|
322
|
-
const dir = directives.find((dir) => dir[ioType].hasBindingPropertyName(attribute.name));
|
|
323
|
-
const binding = dir !== undefined ? dir : node;
|
|
324
|
-
this.bindings.set(attribute, binding);
|
|
325
|
-
};
|
|
326
|
-
// Node inputs (bound attributes) and text attributes can be bound to an
|
|
327
|
-
// input on a directive.
|
|
328
|
-
node.inputs.forEach((input) => setAttributeBinding(input, 'inputs'));
|
|
329
|
-
node.attributes.forEach((attr) => setAttributeBinding(attr, 'inputs'));
|
|
330
|
-
if (node instanceof Template) {
|
|
331
|
-
node.templateAttrs.forEach((attr) => setAttributeBinding(attr, 'inputs'));
|
|
332
|
-
}
|
|
333
|
-
// Node outputs (bound events) can be bound to an output on a directive.
|
|
334
|
-
node.outputs.forEach((output) => setAttributeBinding(output, 'outputs'));
|
|
335
|
-
// Recurse into the node's children.
|
|
336
|
-
node.children.forEach((child) => child.visit(this));
|
|
337
|
-
}
|
|
338
|
-
visitDeferredBlock(deferred) {
|
|
339
|
-
const wasInDeferBlock = this.isInDeferBlock;
|
|
340
|
-
this.isInDeferBlock = true;
|
|
341
|
-
deferred.children.forEach((child) => child.visit(this));
|
|
342
|
-
this.isInDeferBlock = wasInDeferBlock;
|
|
343
|
-
deferred.placeholder?.visit(this);
|
|
344
|
-
deferred.loading?.visit(this);
|
|
345
|
-
deferred.error?.visit(this);
|
|
346
|
-
}
|
|
347
|
-
visitDeferredBlockPlaceholder(block) {
|
|
348
|
-
block.children.forEach((child) => child.visit(this));
|
|
349
|
-
}
|
|
350
|
-
visitDeferredBlockError(block) {
|
|
351
|
-
block.children.forEach((child) => child.visit(this));
|
|
352
|
-
}
|
|
353
|
-
visitDeferredBlockLoading(block) {
|
|
354
|
-
block.children.forEach((child) => child.visit(this));
|
|
355
|
-
}
|
|
356
|
-
visitSwitchBlock(block) {
|
|
357
|
-
block.cases.forEach((node) => node.visit(this));
|
|
358
|
-
}
|
|
359
|
-
visitSwitchBlockCase(block) {
|
|
360
|
-
block.children.forEach((node) => node.visit(this));
|
|
361
|
-
}
|
|
362
|
-
visitForLoopBlock(block) {
|
|
363
|
-
block.item.visit(this);
|
|
364
|
-
block.contextVariables.forEach((v) => v.visit(this));
|
|
365
|
-
block.children.forEach((node) => node.visit(this));
|
|
366
|
-
block.empty?.visit(this);
|
|
367
|
-
}
|
|
368
|
-
visitForLoopBlockEmpty(block) {
|
|
369
|
-
block.children.forEach((node) => node.visit(this));
|
|
370
|
-
}
|
|
371
|
-
visitIfBlock(block) {
|
|
372
|
-
block.branches.forEach((node) => node.visit(this));
|
|
373
|
-
}
|
|
374
|
-
visitIfBlockBranch(block) {
|
|
375
|
-
block.expressionAlias?.visit(this);
|
|
376
|
-
block.children.forEach((node) => node.visit(this));
|
|
377
|
-
}
|
|
378
|
-
visitContent(content) {
|
|
379
|
-
content.children.forEach((child) => child.visit(this));
|
|
380
|
-
}
|
|
381
|
-
// Unused visitors.
|
|
382
|
-
visitVariable(variable) { }
|
|
383
|
-
visitReference(reference) { }
|
|
384
|
-
visitTextAttribute(attribute) { }
|
|
385
|
-
visitBoundAttribute(attribute) { }
|
|
386
|
-
visitBoundEvent(attribute) { }
|
|
387
|
-
visitBoundAttributeOrEvent(node) { }
|
|
388
|
-
visitText(text) { }
|
|
389
|
-
visitBoundText(text) { }
|
|
390
|
-
visitIcu(icu) { }
|
|
391
|
-
visitDeferredTrigger(trigger) { }
|
|
392
|
-
visitUnknownBlock(block) { }
|
|
393
|
-
visitLetDeclaration(decl) { }
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Processes a template and extract metadata about expressions and symbols within.
|
|
397
|
-
*
|
|
398
|
-
* This is a companion to the `DirectiveBinder` that doesn't require knowledge of directives matched
|
|
399
|
-
* within the template in order to operate.
|
|
400
|
-
*
|
|
401
|
-
* Expressions are visited by the superclass `RecursiveAstVisitor`, with custom logic provided
|
|
402
|
-
* by overridden methods from that visitor.
|
|
403
|
-
*/
|
|
404
|
-
class TemplateBinder extends RecursiveAstVisitor {
|
|
405
|
-
constructor(bindings, symbols, usedPipes, eagerPipes, deferBlocks, nestingLevel, scope, rootNode, level) {
|
|
406
|
-
super();
|
|
407
|
-
this.bindings = bindings;
|
|
408
|
-
this.symbols = symbols;
|
|
409
|
-
this.usedPipes = usedPipes;
|
|
410
|
-
this.eagerPipes = eagerPipes;
|
|
411
|
-
this.deferBlocks = deferBlocks;
|
|
412
|
-
this.nestingLevel = nestingLevel;
|
|
413
|
-
this.scope = scope;
|
|
414
|
-
this.rootNode = rootNode;
|
|
415
|
-
this.level = level;
|
|
416
|
-
// Save a bit of processing time by constructing this closure in advance.
|
|
417
|
-
this.visitNode = (node) => node.visit(this);
|
|
418
|
-
}
|
|
419
|
-
// This method is defined to reconcile the type of TemplateBinder since both
|
|
420
|
-
// RecursiveAstVisitor and Visitor define the visit() method in their
|
|
421
|
-
// interfaces.
|
|
422
|
-
visit(node, context) {
|
|
423
|
-
if (node instanceof AST) {
|
|
424
|
-
node.visit(this, context);
|
|
425
|
-
}
|
|
426
|
-
else {
|
|
427
|
-
node.visit(this);
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* Process a template and extract metadata about expressions and symbols within.
|
|
432
|
-
*
|
|
433
|
-
* @param nodes the nodes of the template to process
|
|
434
|
-
* @param scope the `Scope` of the template being processed.
|
|
435
|
-
* @returns three maps which contain metadata about the template: `expressions` which interprets
|
|
436
|
-
* special `AST` nodes in expressions as pointing to references or variables declared within the
|
|
437
|
-
* template, `symbols` which maps those variables and references to the nested `Template` which
|
|
438
|
-
* declares them, if any, and `nestingLevel` which associates each `Template` with a integer
|
|
439
|
-
* nesting level (how many levels deep within the template structure the `Template` is), starting
|
|
440
|
-
* at 1.
|
|
441
|
-
*/
|
|
442
|
-
static applyWithScope(nodes, scope) {
|
|
443
|
-
const expressions = new Map();
|
|
444
|
-
const symbols = new Map();
|
|
445
|
-
const nestingLevel = new Map();
|
|
446
|
-
const usedPipes = new Set();
|
|
447
|
-
const eagerPipes = new Set();
|
|
448
|
-
const template = nodes instanceof Template ? nodes : null;
|
|
449
|
-
const deferBlocks = [];
|
|
450
|
-
// The top-level template has nesting level 0.
|
|
451
|
-
const binder = new TemplateBinder(expressions, symbols, usedPipes, eagerPipes, deferBlocks, nestingLevel, scope, template, 0);
|
|
452
|
-
binder.ingest(nodes);
|
|
453
|
-
return { expressions, symbols, nestingLevel, usedPipes, eagerPipes, deferBlocks };
|
|
454
|
-
}
|
|
455
|
-
ingest(nodeOrNodes) {
|
|
456
|
-
if (nodeOrNodes instanceof Template) {
|
|
457
|
-
// For <ng-template>s, process only variables and child nodes. Inputs, outputs, templateAttrs,
|
|
458
|
-
// and references were all processed in the scope of the containing template.
|
|
459
|
-
nodeOrNodes.variables.forEach(this.visitNode);
|
|
460
|
-
nodeOrNodes.children.forEach(this.visitNode);
|
|
461
|
-
// Set the nesting level.
|
|
462
|
-
this.nestingLevel.set(nodeOrNodes, this.level);
|
|
463
|
-
}
|
|
464
|
-
else if (nodeOrNodes instanceof IfBlockBranch) {
|
|
465
|
-
if (nodeOrNodes.expressionAlias !== null) {
|
|
466
|
-
this.visitNode(nodeOrNodes.expressionAlias);
|
|
467
|
-
}
|
|
468
|
-
nodeOrNodes.children.forEach(this.visitNode);
|
|
469
|
-
this.nestingLevel.set(nodeOrNodes, this.level);
|
|
470
|
-
}
|
|
471
|
-
else if (nodeOrNodes instanceof ForLoopBlock) {
|
|
472
|
-
this.visitNode(nodeOrNodes.item);
|
|
473
|
-
nodeOrNodes.contextVariables.forEach((v) => this.visitNode(v));
|
|
474
|
-
nodeOrNodes.trackBy.visit(this);
|
|
475
|
-
nodeOrNodes.children.forEach(this.visitNode);
|
|
476
|
-
this.nestingLevel.set(nodeOrNodes, this.level);
|
|
477
|
-
}
|
|
478
|
-
else if (nodeOrNodes instanceof DeferredBlock) {
|
|
479
|
-
if (this.scope.rootNode !== nodeOrNodes) {
|
|
480
|
-
throw new Error(`Assertion error: resolved incorrect scope for deferred block ${nodeOrNodes}`);
|
|
481
|
-
}
|
|
482
|
-
this.deferBlocks.push([nodeOrNodes, this.scope]);
|
|
483
|
-
nodeOrNodes.children.forEach((node) => node.visit(this));
|
|
484
|
-
this.nestingLevel.set(nodeOrNodes, this.level);
|
|
485
|
-
}
|
|
486
|
-
else if (nodeOrNodes instanceof SwitchBlockCase ||
|
|
487
|
-
nodeOrNodes instanceof ForLoopBlockEmpty ||
|
|
488
|
-
nodeOrNodes instanceof DeferredBlockError ||
|
|
489
|
-
nodeOrNodes instanceof DeferredBlockPlaceholder ||
|
|
490
|
-
nodeOrNodes instanceof DeferredBlockLoading ||
|
|
491
|
-
nodeOrNodes instanceof Content) {
|
|
492
|
-
nodeOrNodes.children.forEach((node) => node.visit(this));
|
|
493
|
-
this.nestingLevel.set(nodeOrNodes, this.level);
|
|
494
|
-
}
|
|
495
|
-
else {
|
|
496
|
-
// Visit each node from the top-level template.
|
|
497
|
-
nodeOrNodes.forEach(this.visitNode);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
visitElement(element) {
|
|
501
|
-
// Visit the inputs, outputs, and children of the element.
|
|
502
|
-
element.inputs.forEach(this.visitNode);
|
|
503
|
-
element.outputs.forEach(this.visitNode);
|
|
504
|
-
element.children.forEach(this.visitNode);
|
|
505
|
-
element.references.forEach(this.visitNode);
|
|
506
|
-
}
|
|
507
|
-
visitTemplate(template) {
|
|
508
|
-
// First, visit inputs, outputs and template attributes of the template node.
|
|
509
|
-
template.inputs.forEach(this.visitNode);
|
|
510
|
-
template.outputs.forEach(this.visitNode);
|
|
511
|
-
template.templateAttrs.forEach(this.visitNode);
|
|
512
|
-
template.references.forEach(this.visitNode);
|
|
513
|
-
// Next, recurse into the template.
|
|
514
|
-
this.ingestScopedNode(template);
|
|
515
|
-
}
|
|
516
|
-
visitVariable(variable) {
|
|
517
|
-
// Register the `Variable` as a symbol in the current `Template`.
|
|
518
|
-
if (this.rootNode !== null) {
|
|
519
|
-
this.symbols.set(variable, this.rootNode);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
visitReference(reference) {
|
|
523
|
-
// Register the `Reference` as a symbol in the current `Template`.
|
|
524
|
-
if (this.rootNode !== null) {
|
|
525
|
-
this.symbols.set(reference, this.rootNode);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
// Unused template visitors
|
|
529
|
-
visitText(text) { }
|
|
530
|
-
visitTextAttribute(attribute) { }
|
|
531
|
-
visitUnknownBlock(block) { }
|
|
532
|
-
visitDeferredTrigger() { }
|
|
533
|
-
visitIcu(icu) {
|
|
534
|
-
Object.keys(icu.vars).forEach((key) => icu.vars[key].visit(this));
|
|
535
|
-
Object.keys(icu.placeholders).forEach((key) => icu.placeholders[key].visit(this));
|
|
536
|
-
}
|
|
537
|
-
// The remaining visitors are concerned with processing AST expressions within template bindings
|
|
538
|
-
visitBoundAttribute(attribute) {
|
|
539
|
-
attribute.value.visit(this);
|
|
540
|
-
}
|
|
541
|
-
visitBoundEvent(event) {
|
|
542
|
-
event.handler.visit(this);
|
|
543
|
-
}
|
|
544
|
-
visitDeferredBlock(deferred) {
|
|
545
|
-
this.ingestScopedNode(deferred);
|
|
546
|
-
deferred.triggers.when?.value.visit(this);
|
|
547
|
-
deferred.prefetchTriggers.when?.value.visit(this);
|
|
548
|
-
deferred.placeholder && this.visitNode(deferred.placeholder);
|
|
549
|
-
deferred.loading && this.visitNode(deferred.loading);
|
|
550
|
-
deferred.error && this.visitNode(deferred.error);
|
|
551
|
-
}
|
|
552
|
-
visitDeferredBlockPlaceholder(block) {
|
|
553
|
-
this.ingestScopedNode(block);
|
|
554
|
-
}
|
|
555
|
-
visitDeferredBlockError(block) {
|
|
556
|
-
this.ingestScopedNode(block);
|
|
557
|
-
}
|
|
558
|
-
visitDeferredBlockLoading(block) {
|
|
559
|
-
this.ingestScopedNode(block);
|
|
560
|
-
}
|
|
561
|
-
visitSwitchBlock(block) {
|
|
562
|
-
block.expression.visit(this);
|
|
563
|
-
block.cases.forEach(this.visitNode);
|
|
564
|
-
}
|
|
565
|
-
visitSwitchBlockCase(block) {
|
|
566
|
-
block.expression?.visit(this);
|
|
567
|
-
this.ingestScopedNode(block);
|
|
568
|
-
}
|
|
569
|
-
visitForLoopBlock(block) {
|
|
570
|
-
block.expression.visit(this);
|
|
571
|
-
this.ingestScopedNode(block);
|
|
572
|
-
block.empty?.visit(this);
|
|
573
|
-
}
|
|
574
|
-
visitForLoopBlockEmpty(block) {
|
|
575
|
-
this.ingestScopedNode(block);
|
|
576
|
-
}
|
|
577
|
-
visitIfBlock(block) {
|
|
578
|
-
block.branches.forEach((node) => node.visit(this));
|
|
579
|
-
}
|
|
580
|
-
visitIfBlockBranch(block) {
|
|
581
|
-
block.expression?.visit(this);
|
|
582
|
-
this.ingestScopedNode(block);
|
|
583
|
-
}
|
|
584
|
-
visitContent(content) {
|
|
585
|
-
this.ingestScopedNode(content);
|
|
586
|
-
}
|
|
587
|
-
visitBoundText(text) {
|
|
588
|
-
text.value.visit(this);
|
|
589
|
-
}
|
|
590
|
-
visitLetDeclaration(decl) {
|
|
591
|
-
decl.value.visit(this);
|
|
592
|
-
if (this.rootNode !== null) {
|
|
593
|
-
this.symbols.set(decl, this.rootNode);
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
visitPipe(ast, context) {
|
|
597
|
-
this.usedPipes.add(ast.name);
|
|
598
|
-
if (!this.scope.isDeferred) {
|
|
599
|
-
this.eagerPipes.add(ast.name);
|
|
600
|
-
}
|
|
601
|
-
return super.visitPipe(ast, context);
|
|
602
|
-
}
|
|
603
|
-
// These five types of AST expressions can refer to expression roots, which could be variables
|
|
604
|
-
// or references in the current scope.
|
|
605
|
-
visitPropertyRead(ast, context) {
|
|
606
|
-
this.maybeMap(ast, ast.name);
|
|
607
|
-
return super.visitPropertyRead(ast, context);
|
|
608
|
-
}
|
|
609
|
-
visitSafePropertyRead(ast, context) {
|
|
610
|
-
this.maybeMap(ast, ast.name);
|
|
611
|
-
return super.visitSafePropertyRead(ast, context);
|
|
612
|
-
}
|
|
613
|
-
visitPropertyWrite(ast, context) {
|
|
614
|
-
this.maybeMap(ast, ast.name);
|
|
615
|
-
return super.visitPropertyWrite(ast, context);
|
|
616
|
-
}
|
|
617
|
-
ingestScopedNode(node) {
|
|
618
|
-
const childScope = this.scope.getChildScope(node);
|
|
619
|
-
const binder = new TemplateBinder(this.bindings, this.symbols, this.usedPipes, this.eagerPipes, this.deferBlocks, this.nestingLevel, childScope, node, this.level + 1);
|
|
620
|
-
binder.ingest(node);
|
|
621
|
-
}
|
|
622
|
-
maybeMap(ast, name) {
|
|
623
|
-
// If the receiver of the expression isn't the `ImplicitReceiver`, this isn't the root of an
|
|
624
|
-
// `AST` expression that maps to a `Variable` or `Reference`.
|
|
625
|
-
if (!(ast.receiver instanceof ImplicitReceiver)) {
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
// Check whether the name exists in the current scope. If so, map it. Otherwise, the name is
|
|
629
|
-
// probably a property on the top-level component context.
|
|
630
|
-
const target = this.scope.lookup(name);
|
|
631
|
-
// It's not allowed to read template entities via `this`, however it previously worked by
|
|
632
|
-
// accident (see #55115). Since `@let` declarations are new, we can fix it from the beginning,
|
|
633
|
-
// whereas pre-existing template entities will be fixed in #55115.
|
|
634
|
-
if (target instanceof LetDeclaration && ast.receiver instanceof ThisReceiver) {
|
|
635
|
-
return;
|
|
636
|
-
}
|
|
637
|
-
if (target !== null) {
|
|
638
|
-
this.bindings.set(ast, target);
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
/**
|
|
643
|
-
* Metadata container for a `Target` that allows queries for specific bits of metadata.
|
|
644
|
-
*
|
|
645
|
-
* See `BoundTarget` for documentation on the individual methods.
|
|
646
|
-
*/
|
|
647
|
-
export class R3BoundTarget {
|
|
648
|
-
constructor(target, directives, eagerDirectives, bindings, references, exprTargets, symbols, nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, rawDeferred) {
|
|
649
|
-
this.target = target;
|
|
650
|
-
this.directives = directives;
|
|
651
|
-
this.eagerDirectives = eagerDirectives;
|
|
652
|
-
this.bindings = bindings;
|
|
653
|
-
this.references = references;
|
|
654
|
-
this.exprTargets = exprTargets;
|
|
655
|
-
this.symbols = symbols;
|
|
656
|
-
this.nestingLevel = nestingLevel;
|
|
657
|
-
this.scopedNodeEntities = scopedNodeEntities;
|
|
658
|
-
this.usedPipes = usedPipes;
|
|
659
|
-
this.eagerPipes = eagerPipes;
|
|
660
|
-
this.deferredBlocks = rawDeferred.map((current) => current[0]);
|
|
661
|
-
this.deferredScopes = new Map(rawDeferred);
|
|
662
|
-
}
|
|
663
|
-
getEntitiesInScope(node) {
|
|
664
|
-
return this.scopedNodeEntities.get(node) ?? new Set();
|
|
665
|
-
}
|
|
666
|
-
getDirectivesOfNode(node) {
|
|
667
|
-
return this.directives.get(node) || null;
|
|
668
|
-
}
|
|
669
|
-
getReferenceTarget(ref) {
|
|
670
|
-
return this.references.get(ref) || null;
|
|
671
|
-
}
|
|
672
|
-
getConsumerOfBinding(binding) {
|
|
673
|
-
return this.bindings.get(binding) || null;
|
|
674
|
-
}
|
|
675
|
-
getExpressionTarget(expr) {
|
|
676
|
-
return this.exprTargets.get(expr) || null;
|
|
677
|
-
}
|
|
678
|
-
getDefinitionNodeOfSymbol(symbol) {
|
|
679
|
-
return this.symbols.get(symbol) || null;
|
|
680
|
-
}
|
|
681
|
-
getNestingLevel(node) {
|
|
682
|
-
return this.nestingLevel.get(node) || 0;
|
|
683
|
-
}
|
|
684
|
-
getUsedDirectives() {
|
|
685
|
-
const set = new Set();
|
|
686
|
-
this.directives.forEach((dirs) => dirs.forEach((dir) => set.add(dir)));
|
|
687
|
-
return Array.from(set.values());
|
|
688
|
-
}
|
|
689
|
-
getEagerlyUsedDirectives() {
|
|
690
|
-
const set = new Set(this.eagerDirectives);
|
|
691
|
-
return Array.from(set.values());
|
|
692
|
-
}
|
|
693
|
-
getUsedPipes() {
|
|
694
|
-
return Array.from(this.usedPipes);
|
|
695
|
-
}
|
|
696
|
-
getEagerlyUsedPipes() {
|
|
697
|
-
return Array.from(this.eagerPipes);
|
|
698
|
-
}
|
|
699
|
-
getDeferBlocks() {
|
|
700
|
-
return this.deferredBlocks;
|
|
701
|
-
}
|
|
702
|
-
getDeferredTriggerTarget(block, trigger) {
|
|
703
|
-
// Only triggers that refer to DOM nodes can be resolved.
|
|
704
|
-
if (!(trigger instanceof InteractionDeferredTrigger) &&
|
|
705
|
-
!(trigger instanceof ViewportDeferredTrigger) &&
|
|
706
|
-
!(trigger instanceof HoverDeferredTrigger)) {
|
|
707
|
-
return null;
|
|
708
|
-
}
|
|
709
|
-
const name = trigger.reference;
|
|
710
|
-
if (name === null) {
|
|
711
|
-
let trigger = null;
|
|
712
|
-
if (block.placeholder !== null) {
|
|
713
|
-
for (const child of block.placeholder.children) {
|
|
714
|
-
// Skip over comment nodes. Currently by default the template parser doesn't capture
|
|
715
|
-
// comments, but we have a safeguard here just in case since it can be enabled.
|
|
716
|
-
if (child instanceof Comment) {
|
|
717
|
-
continue;
|
|
718
|
-
}
|
|
719
|
-
// We can only infer the trigger if there's one root element node. Any other
|
|
720
|
-
// nodes at the root make it so that we can't infer the trigger anymore.
|
|
721
|
-
if (trigger !== null) {
|
|
722
|
-
return null;
|
|
723
|
-
}
|
|
724
|
-
if (child instanceof Element) {
|
|
725
|
-
trigger = child;
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
return trigger;
|
|
730
|
-
}
|
|
731
|
-
const outsideRef = this.findEntityInScope(block, name);
|
|
732
|
-
// First try to resolve the target in the scope of the main deferred block. Note that we
|
|
733
|
-
// skip triggers defined inside the main block itself, because they might not exist yet.
|
|
734
|
-
if (outsideRef instanceof Reference && this.getDefinitionNodeOfSymbol(outsideRef) !== block) {
|
|
735
|
-
const target = this.getReferenceTarget(outsideRef);
|
|
736
|
-
if (target !== null) {
|
|
737
|
-
return this.referenceTargetToElement(target);
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
// If the trigger couldn't be found in the main block, check the
|
|
741
|
-
// placeholder block which is shown before the main block has loaded.
|
|
742
|
-
if (block.placeholder !== null) {
|
|
743
|
-
const refInPlaceholder = this.findEntityInScope(block.placeholder, name);
|
|
744
|
-
const targetInPlaceholder = refInPlaceholder instanceof Reference ? this.getReferenceTarget(refInPlaceholder) : null;
|
|
745
|
-
if (targetInPlaceholder !== null) {
|
|
746
|
-
return this.referenceTargetToElement(targetInPlaceholder);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
return null;
|
|
750
|
-
}
|
|
751
|
-
isDeferred(element) {
|
|
752
|
-
for (const block of this.deferredBlocks) {
|
|
753
|
-
if (!this.deferredScopes.has(block)) {
|
|
754
|
-
continue;
|
|
755
|
-
}
|
|
756
|
-
const stack = [this.deferredScopes.get(block)];
|
|
757
|
-
while (stack.length > 0) {
|
|
758
|
-
const current = stack.pop();
|
|
759
|
-
if (current.elementsInScope.has(element)) {
|
|
760
|
-
return true;
|
|
761
|
-
}
|
|
762
|
-
stack.push(...current.childScopes.values());
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
return false;
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* Finds an entity with a specific name in a scope.
|
|
769
|
-
* @param rootNode Root node of the scope.
|
|
770
|
-
* @param name Name of the entity.
|
|
771
|
-
*/
|
|
772
|
-
findEntityInScope(rootNode, name) {
|
|
773
|
-
const entities = this.getEntitiesInScope(rootNode);
|
|
774
|
-
for (const entity of entities) {
|
|
775
|
-
if (entity.name === name) {
|
|
776
|
-
return entity;
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
return null;
|
|
780
|
-
}
|
|
781
|
-
/** Coerces a `ReferenceTarget` to an `Element`, if possible. */
|
|
782
|
-
referenceTargetToElement(target) {
|
|
783
|
-
if (target instanceof Element) {
|
|
784
|
-
return target;
|
|
785
|
-
}
|
|
786
|
-
if (target instanceof Template) {
|
|
787
|
-
return null;
|
|
788
|
-
}
|
|
789
|
-
return this.referenceTargetToElement(target.node);
|
|
790
|
-
}
|
|
791
|
-
}
|
|
792
|
-
function extractScopedNodeEntities(rootScope) {
|
|
793
|
-
const entityMap = new Map();
|
|
794
|
-
function extractScopeEntities(scope) {
|
|
795
|
-
if (entityMap.has(scope.rootNode)) {
|
|
796
|
-
return entityMap.get(scope.rootNode);
|
|
797
|
-
}
|
|
798
|
-
const currentEntities = scope.namedEntities;
|
|
799
|
-
let entities;
|
|
800
|
-
if (scope.parentScope !== null) {
|
|
801
|
-
entities = new Map([...extractScopeEntities(scope.parentScope), ...currentEntities]);
|
|
802
|
-
}
|
|
803
|
-
else {
|
|
804
|
-
entities = new Map(currentEntities);
|
|
805
|
-
}
|
|
806
|
-
entityMap.set(scope.rootNode, entities);
|
|
807
|
-
return entities;
|
|
808
|
-
}
|
|
809
|
-
const scopesToProcess = [rootScope];
|
|
810
|
-
while (scopesToProcess.length > 0) {
|
|
811
|
-
const scope = scopesToProcess.pop();
|
|
812
|
-
for (const childScope of scope.childScopes.values()) {
|
|
813
|
-
scopesToProcess.push(childScope);
|
|
814
|
-
}
|
|
815
|
-
extractScopeEntities(scope);
|
|
816
|
-
}
|
|
817
|
-
const templateEntities = new Map();
|
|
818
|
-
for (const [template, entities] of entityMap) {
|
|
819
|
-
templateEntities.set(template, new Set(entities.values()));
|
|
820
|
-
}
|
|
821
|
-
return templateEntities;
|
|
822
|
-
}
|
|
823
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidDJfYmluZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3JlbmRlcjMvdmlldy90Ml9iaW5kZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUNMLEdBQUcsRUFFSCxnQkFBZ0IsRUFHaEIsbUJBQW1CLEVBRW5CLFlBQVksR0FDYixNQUFNLDZCQUE2QixDQUFDO0FBRXJDLE9BQU8sRUFJTCxPQUFPLEVBQ1AsT0FBTyxFQUNQLGFBQWEsRUFDYixrQkFBa0IsRUFDbEIsb0JBQW9CLEVBQ3BCLHdCQUF3QixFQUV4QixPQUFPLEVBQ1AsWUFBWSxFQUNaLGlCQUFpQixFQUNqQixvQkFBb0IsRUFHcEIsYUFBYSxFQUNiLDBCQUEwQixFQUMxQixjQUFjLEVBRWQsU0FBUyxFQUVULGVBQWUsRUFDZixRQUFRLEVBS1IsdUJBQXVCLEdBRXhCLE1BQU0sV0FBVyxDQUFDO0FBV25CLE9BQU8sRUFBQyx5QkFBeUIsRUFBQyxNQUFNLFFBQVEsQ0FBQztBQUVqRDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLGNBQWM7SUFDekIsWUFBb0IsZ0JBQStDO1FBQS9DLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBK0I7SUFBRyxDQUFDO0lBRXZFOzs7T0FHRztJQUNILElBQUksQ0FBQyxNQUFjO1FBQ2pCLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDckIsNEVBQTRFO1lBQzVFLE1BQU0sSUFBSSxLQUFLLENBQUMsOENBQThDLENBQUMsQ0FBQztRQUNsRSxDQUFDO1FBRUQsNEZBQTRGO1FBQzVGLGlFQUFpRTtRQUNqRSxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUUzQyxrRkFBa0Y7UUFDbEYsTUFBTSxrQkFBa0IsR0FBRyx5QkFBeUIsQ0FBQyxLQUFLLENB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QVEsRUFBRSxRQUFRLENBQUMsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUM3QyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUNELE9BQU8sZ0JBQWdCLENBQUM7QUFDMUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge1xuICBBU1QsXG4gIEJpbmRpbmdQaXBlLFxuICBJbXBsaWNpdFJlY2VpdmVyLFxuICBQcm9wZXJ0eVJlYWQsXG4gIFByb3BlcnR5V3JpdGUsXG4gIFJlY3Vyc2l2ZUFzdFZpc2l0b3IsXG4gIFNhZmVQcm9wZXJ0eVJlYWQsXG4gIFRoaXNSZWNlaXZlcixcbn0gZnJvbSAnLi4vLi4vZXhwcmVzc2lvbl9wYXJzZXIvYXN0JztcbmltcG9ydCB7U2VsZWN0b3JNYXRjaGVyfSBmcm9tICcuLi8uLi9zZWxlY3Rvcic7XG5pbXBvcnQge1xuICBCb3VuZEF0dHJpYnV0ZSxcbiAgQm91bmRFdmVudCxcbiAgQm91bmRUZXh0LFxuICBDb21tZW50LFxuICBDb250ZW50LFxuICBEZWZlcnJlZEJsb2NrLFxuICBEZWZlcnJlZEJsb2NrRXJyb3IsXG4gIERlZmVycmVkQmxvY2tMb2FkaW5nLFxuICBEZWZlcnJlZEJsb2NrUGxhY2Vob2xkZXIsXG4gIERlZmVycmVkVHJpZ2dlcixcbiAgRWxlbWVudCxcbiAgRm9yTG9vcEJsb2NrLFxuICBGb3JMb29wQmxvY2tFbXB0eSxcbiAgSG92ZXJEZWZlcnJlZFRyaWdnZXIsXG4gIEljdSxcbiAgSWZCbG9jayxcbiAgSWZCbG9ja0JyYW5jaCxcbiAgSW50ZXJhY3Rpb25EZWZlcnJlZFRyaWdnZXIsXG4gIExldERlY2xhcmF0aW9uLFxuICBOb2RlLFxuICBSZWZlcmVuY2UsXG4gIFN3aXRjaEJsb2NrLFxuICBTd2l0Y2hCbG9ja0Nhc2UsXG4gIFRlbXBsYXRlLFxuICBUZXh0LFxuICBUZXh0QXR0cmlidXRlLFxuICBVbmtub3duQmxvY2ssXG4gIFZhcmlhYmxlLFxuICBWaWV3cG9ydERlZmVycmVkVHJpZ2dlcixcbiAgVmlzaXRvcixcbn0gZnJvbSAnLi4vcjNfYXN0JztcblxuaW1wb3J0IHtcbiAgQm91bmRUYXJnZXQsXG4gIERpcmVjdGl2ZU1ldGEsXG4gIFJlZmVyZW5jZVRhcmdldCxcbiAgU2NvcGVkTm9kZSxcbiAgVGFyZ2V0LFxuICBUYXJnZXRCaW5kZXIsXG4gIFRlbXBsYXRlRW50aXR5LFxufSBmcm9tICcuL3QyX2FwaSc7XG5pbXBvcnQge2NyZWF0ZUNzc1NlbGVjdG9yRnJvbU5vZGV9IGZyb20gJy4vdXRpbCc7XG5cbi8qKlxuICogUHJvY2Vzc2VzIGBUYXJnZXRgcyB3aXRoIGEgZ2l2ZW4gc2V0IG9mIGRpcmVjdGl2ZXMgYW5kIHBlcmZvcm1zIGEgYmluZGluZyBvcGVyYXRpb24sIHdoaWNoXG4gKiByZXR1cm5zIGFuIG9iamVjdCBzaW1pbGFyIHRvIFR5cGVTY3JpcHQncyBgdHMuVHlwZUNoZWNrZXJgIHRoYXQgY29udGFpbnMga25vd2xlZGdlIGFib3V0IHRoZVxuICogdGFyZ2V0LlxuICovXG5leHBvcnQgY2xhc3MgUjNUYXJnZXRCaW5kZXI8RGlyZWN0aXZlVCBleHRlbmRzIERpcmVjdGl2ZU1ldGE+IGltcGxlbWVudHMgVGFyZ2V0QmluZGVyPERpcmVjdGl2ZVQ+IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBkaXJlY3RpdmVNYXRjaGVyOiBTZWxlY3Rvck1hdGNoZXI8RGlyZWN0aXZlVFtdPikge31cblxuICAvKipcbiAgICogUGVyZm9ybSBhIGJpbmRpbmcgb3BlcmF0aW9uIG9uIHRoZSBnaXZlbiBgVGFyZ2V0YCBhbmQgcmV0dXJuIGEgYEJvdW5kVGFyZ2V0YCB3aGljaCBjb250YWluc1xuICAgKiBtZXRhZGF0YSBhYm91dCB0aGUgdHlwZXMgcmVmZXJlbmNlZCBpbiB0aGUgdGVtcGxhdGUuXG4gICAqL1xuICBiaW5kKHRhcmdldDogVGFyZ2V0KTogQm91bmRUYXJnZXQ8RGlyZWN0aXZlVD4ge1xuICAgIGlmICghdGFyZ2V0LnRlbXBsYXRlKSB7XG4gICAgICAvLyBUT0RPKGFseGh1Yik6IGhhbmRsZSB0YXJnZXRzIHdoaWNoIGNvbnRhaW4gdGhpbmdzIGxpa2UgSG9zdEJpbmRpbmdzLCBldGMuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0JpbmRpbmcgd2l0aG91dCBhIHRlbXBsYXRlIG5vdCB5ZXQgc3VwcG9ydGVkJyk7XG4gICAgfVxuXG4gICAgLy8gRmlyc3QsIHBhcnNlIHRoZSB0ZW1wbGF0ZSBpbnRvIGEgYFNjb3BlYCBzdHJ1Y3R1cmUuIFRoaXMgb3BlcmF0aW9uIGNhcHR1cmVzIHRoZSBzeW50YWN0aWNcbiAgICAvLyBzY29wZXMgaW4gdGhlIHRlbXBsYXRlIGFuZCBtYWtlcyB0aGVtIGF2YWlsYWJsZSBmb3IgbGF0ZXIgdXNlLlxuICAgIGNvbnN0IHNjb3BlID0gU2NvcGUuYXBwbHkodGFyZ2V0LnRlbXBsYXRlKTtcblxuICAgIC8vIFVzZSB0aGUgYFNjb3BlYCB0byBleHRyYWN0IHRoZSBlbnRpdGllcyBwcmVzZW50IGF0IGV2ZXJ5IGxldmVsIG9mIHRoZSB0ZW1wbGF0ZS5cbiAgICBjb25zdCBzY29wZWROb2RlRW50aXRpZXMgPSBleHRyYWN0U2NvcGVkTm9kZUVudGl0aWVzKHNjb3BlKTtcblxuICAgIC8vIE5leHQsIHBlcmZvcm0gZGlyZWN0aXZlIG1hdGNoaW5nIG9uIHRoZSB0ZW1wbGF0ZSB1c2luZyB0aGUgYERpcmVjdGl2ZUJpbmRlcmAuIFRoaXMgcmV0dXJuczpcbiAgICAvLyAgIC0gZGlyZWN0aXZlczogTWFwIG9mIG5vZGVzIChlbGVtZW50cyAmIG5nLXRlbXBsYXRlcykgdG8gdGhlIGRpcmVjdGl2ZXMgb24gdGhlbS5cbiAgICAvLyAgIC0gYmluZGluZ3M6IE1hcCBvZiBpbnB1dHMsIG91dHB1dHMsIGFuZCBhdHRyaWJ1dGVzIHRvIHRoZSBkaXJlY3RpdmUvZWxlbWVudCB0aGF0IGNsYWltc1xuICAgIC8vICAgICB0aGVtLiBUT0RPKGFseGh1Yik6IGhhbmRsZSBtdWx0aXBsZSBkaXJlY3RpdmVzIGNsYWltaW5nIGFuIGlucHV0L291dHB1dC9ldGMuXG4gICAgLy8gICAtIHJlZmVyZW5jZXM6IE1hcCBvZiAjcmVmZXJlbmNlcyB0byB0aGVpciB0YXJnZXRzLlxuICAgIGNvbnN0IHtkaXJlY3RpdmVzLCBlYWdlckRpcmVjdGl2ZXMsIGJpbmRpbmdzLCByZWZlcmVuY2VzfSA9IERpcmVjdGl2ZUJpbmRlci5hcHBseShcbiAgICAgIHRhcmdldC50ZW1wbGF0ZSxcbiAgICAgIHRoaXMuZGlyZWN0aXZlTWF0Y2hlcixcbiAgICApO1xuICAgIC8vIEZpbmFsbHksIHJ1biB0aGUgVGVtcGxhdGVCaW5kZXIgdG8gYmluZCByZWZlcmVuY2VzLCB2YXJpYWJsZXMsIGFuZCBvdGhlciBlbnRpdGllcyB3aXRoaW4gdGhlXG4gICAgLy8gdGVtcGxhdGUuIFRoaXMgZXh0cmFjdHMgYWxsIHRoZSBtZXRhZGF0YSB0aGF0IGRvZXNuJ3QgZGVwZW5kIG9uIGRpcmVjdGl2ZSBtYXRjaGluZy5cbiAgICBjb25zdCB7ZXhwcmVzc2lvbnMsIHN5bWJvbHMsIG5lc3RpbmdMZXZlbCwgdXNlZFBpcGVzLCBlYWdlclBpcGVzLCBkZWZlckJsb2Nrc30gPVxuICAgICAgVGVtcGxhdGVCaW5kZXIuYXBwbHlXaXRoU2NvcGUodGFyZ2V0LnRlbXBsYXRlLCBzY29wZSk7XG4gICAgcmV0dXJuIG5ldyBSM0JvdW5kVGFyZ2V0KFxuICAgICAgdGFyZ2V0LFxuICAgICAgZGlyZWN0aXZlcyxcbiAgICAgIGVhZ2VyRGlyZWN0aXZlcyxcbiAgICAgIGJpbmRpbmdzLFxuICAgICAgcmVmZXJlbmNlcyxcbiAgICAgIGV4cHJlc3Npb25zLFxuICAgICAgc3ltYm9scyxcbiAgICAgIG5lc3RpbmdMZXZlbCxcbiAgICAgIHNjb3BlZE5vZGVFbnRpdGllcyxcbiAgICAgIHVzZWRQaXBlcyxcbiAgICAgIGVhZ2VyUGlwZXMsXG4gICAgICBkZWZlckJsb2NrcyxcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIGJpbmRpbmcgc2NvcGUgd2l0aGluIGEgdGVtcGxhdGUuXG4gKlxuICogQW55IHZhcmlhYmxlcywgcmVmZXJlbmNlcywgb3Igb3RoZXIgbmFtZWQgZW50aXRpZXMgZGVjbGFyZWQgd2l0aGluIHRoZSB0ZW1wbGF0ZSB3aWxsXG4gKiBiZSBjYXB0dXJlZCBhbmQgYXZhaWxhYmxlIGJ5IG5hbWUgaW4gYG5hbWVkRW50aXRpZXNgLiBBZGRpdGlvbmFsbHksIGNoaWxkIHRlbXBsYXRlcyB3aWxsXG4gKiBiZSBhbmFseXplZCBhbmQgaGF2ZSB0aGVpciBjaGlsZCBgU2NvcGVgcyBhdmFpbGFibGUgaW4gYGNoaWxkU2NvcGVzYC5cbiAqL1xuY2xhc3MgU2NvcGUgaW1wbGVtZW50cyBWaXNpdG9yIHtcbiAgLyoqXG4gICAqIE5hbWVkIG1lbWJlcnMgb2YgdGhlIGBTY29wZWAsIHN1Y2ggYXMgYFJlZmVyZW5jZWBzIG9yIGBWYXJpYWJsZWBzLlxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZWRFbnRpdGllcyA9IG5ldyBNYXA8c3RyaW5nLCBUZW1wbGF0ZUVudGl0eT4oKTtcblxuICAvKipcbiAgICogU2V0IG9mIGVsZW1lbnRzIHRoYXQgYmVsb25nIHRvIHRoaXMgc2NvcGUuXG4gICAqL1xuICByZWFkb25seSBlbGVtZW50c0luU2NvcGUgPSBuZXcgU2V0PEVsZW1lbnQ+KCk7XG5cbiAgLyoqXG4gICAqIENoaWxkIGBTY29wZWBzIGZvciBpbW1lZGlhdGVseSBuZXN0ZWQgYFNjb3BlZE5vZGVgcy5cbiAgICovXG4gIHJlYWRvbmx5IGNoaWxkU2NvcGVzID0gbmV3IE1hcDxTY29wZWROb2RlLCBTY29wZT4oKTtcblxuICAvKiogV2hldGhlciB0aGlzIHNjb3BlIGlzIGRlZmVycmVkIG9yIGlmIGFueSBvZiBpdHMgYW5jZXN0b3JzIGFyZSBkZWZlcnJlZC4gKi9cbiAgcmVhZG9ubHkgaXNEZWZlcnJlZDogYm9vbGVhbjtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKFxuICAgIHJlYWRvbmx5IHBhcmVudFNjb3BlOiBTY29wZSB8IG51bGwsXG4gICAgcmVhZG9ubHkgcm9vdE5vZGU6IFNjb3BlZE5vZGUgfCBudWxsLFxuICApIHtcbiAgICB0aGlzLmlzRGVmZXJyZWQgPVxuICAgICAgcGFyZW50U2NvcGUgIT09IG51bGwgJiYgcGFyZW50U2NvcGUuaXNEZWZlcnJlZCA/IHRydWUgOiByb290Tm9kZSBpbnN0YW5jZW9mIERlZmVycmVkQmxvY2s7XG4gIH1cblxuICBzdGF0aWMgbmV3Um9vdFNjb3BlKCk6IFNjb3BlIHtcbiAgICByZXR1cm4gbmV3IFNjb3BlKG51bGwsIG51bGwpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2Nlc3MgYSB0ZW1wbGF0ZSAoZWl0aGVyIGFzIGEgYFRlbXBsYXRlYCBzdWItdGVtcGxhdGUgd2l0aCB2YXJpYWJsZXMsIG9yIGEgcGxhaW4gYXJyYXkgb2ZcbiAgICogdGVtcGxhdGUgYE5vZGVgcykgYW5kIGNvbnN0cnVjdCBpdHMgYFNjb3BlYC5cbiAgICovXG4gIHN0YXRpYyBhcHBseSh0ZW1wbGF0ZTogTm9kZVtdKTogU2NvcGUge1xuICAgIGNvbnN0IHNjb3BlID0gU2NvcGUubmV3Um9vdFNjb3BlKCk7XG4gICAgc2NvcGUuaW5nZXN0KHRlbXBsYXRlKTtcbiAgICByZXR1cm4gc2NvcGU7XG4gIH1cblxuICAvKipcbiAgICogSW50ZXJuYWwgbWV0aG9kIHRvIHByb2Nlc3MgdGhlIHNjb3BlZCBub2RlIGFuZCBwb3B1bGF0ZSB0aGUgYFNjb3BlYC5cbiAgICovXG4gIHByaXZhdGUgaW5nZXN0KG5vZGVPck5vZGVzOiBTY29wZWROb2RlIHwgTm9kZVtdKTogdm9pZCB7XG4gICAgaWYgKG5vZGVPck5vZGVzIGluc3RhbmNlb2YgVGVtcGxhdGUpIHtcbiAgICAgIC8vIFZhcmlhYmxlcyBvbiBhbiA8bmctdGVtcGxhdGU+IGFyZSBkZWZpbmVkIGluIHRoZSBpbm5lciBzY29wZS5cbiAgICAgIG5vZGVPck5vZGVzLnZhcmlhYmxlcy5mb3JFYWNoKChub2RlKSA9PiB0aGlzLnZpc2l0VmFyaWFibGUobm9kZSkpO1xuXG4gICAgICAvLyBQcm9jZXNzIHRoZSBub2RlcyBvZiB0aGUgdGVtcGxhdGUuXG4gICAgICBub2RlT3JOb2Rlcy5jaGlsZHJlbi5mb3JFYWNoKChub2RlKSA9PiBub2RlLnZpc2l0KHRoaXMpKTtcbiAgICB9IGVsc2UgaWYgKG5vZGVPck5vZGVzIGluc3RhbmNlb2YgSWZCbG9ja0JyYW5jaCkge1xuICAgICAgaWYgKG5vZGVPck5vZGVzLmV4cHJlc3Npb25BbGlhcyAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLnZpc2l0VmFyaWFibGUobm9kZU9yTm9kZXMuZXhwcmVzc2lvbkFsaWFzKTtcbiAgICAgIH1cbiAgICAgIG5vZGVPck5vZGVzLmNoaWxkcmVuLmZvckVhY2goKG5vZGUpID0+IG5vZGUudmlzaXQodGhpcykpO1xuICAgIH0gZWxzZSBpZiAobm9kZU9yTm9kZXMgaW5zdGFuY2VvZiBGb3JMb29wQmxvY2spIHtcbiAgICAgIHRoaXMudmlzaXRWYXJpYWJsZShub2RlT3JOb2Rlcy5pdGVtKTtcbiAgICAgIG5vZGVPck5vZGVzLmNvbnRleHRWYXJpYWJsZXMuZm9yRWFjaCgodikgPT4gdGhpcy52aXNpdFZhcmlhYmxlKHYpKTtcbiAgICAgIG5vZGVPck5vZGVzLmNoaWxkcmVuLmZvckVhY2goKG5vZGUpID0+IG5vZGUudmlzaXQodGhpcykpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBub2RlT3JOb2RlcyBpbnN0YW5jZW9mIFN3aXRjaEJsb2NrQ2FzZSB8fFxuICAgICAgbm9kZU9yTm9kZXMgaW5zdGFuY2VvZiBGb3JMb29wQmxvY2tFbXB0eSB8fFxuICAgICAgbm9kZU9yTm9kZXMgaW5zdGFuY2VvZiBEZWZlcnJlZEJsb2NrIHx8XG4gICAgICBub2RlT3JOb2RlcyBpbnN0YW5jZW9mIERlZmVycmVkQmxvY2tFcnJvciB8fFxuICAgICAgbm9kZU9yTm9kZXMgaW5zdGFuY2VvZiBEZWZlcnJlZEJsb2NrUGxhY2Vob2xkZXIgfHxcbiAgICAgIG5vZGVPck5vZGVzIGluc3RhbmNlb2YgRGVmZXJyZWRCbG9ja0xvYWRpbmcgfHxcbiAgICAgIG5vZGVPck5vZGVzIGluc3RhbmNlb2YgQ29udGVudFxuICAgICkge1xuICAgICAgbm9kZU9yTm9kZXMuY2hpbGRyZW4uZm9yRWFjaCgobm9kZSkgPT4gbm9kZS52aXNpdCh0aGlzKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE5vIG92ZXJhcmNoaW5nIGBUZW1wbGF0ZWAgaW5zdGFuY2UsIHNvIHByb2Nlc3MgdGhlIG5vZGVzIGRpcmVjdGx5LlxuICAgICAgbm9kZU9yTm9kZXMuZm9yRWFjaCgobm9kZSkgPT4gbm9kZS52aXNpdCh0aGlzKSk7XG4gICAgfVxuICB9XG5cbiAgdmlzaXRFbGVtZW50KGVsZW1lbnQ6IEVsZW1lbnQpIHtcbiAgICAvLyBgRWxlbWVudGBzIGluIHRoZSB0ZW1wbGF0ZSBtYXkgaGF2ZSBgUmVmZXJlbmNlYHMgd2hpY2ggYXJlIGNhcHR1cmVkIGluIHRoZSBzY29wZS5cbiAgICBlbGVtZW50LnJlZmVyZW5jZXMuZm9yRWFjaCgobm9kZSkgPT4gdGhpcy52aXNpdFJlZmVyZW5jZShub2RlKSk7XG5cbiAgICAvLyBSZWN1cnNlIGludG8gdGhlIGBFbGVtZW50YCdzIGNoaWxkcmVuLlxuICAgIGVsZW1lbnQuY2hpbGRyZW4uZm9yRWFjaCgobm9kZSkgPT4gbm9kZS52aXNpdCh0aGlzKSk7XG5cbiAgICB0aGlzLmVsZW1lbnRzSW5TY29wZS5hZGQoZWxlbWVudCk7XG4gIH1cblxuICB2aXNpdFRlbXBsYXRlKHRlbXBsYXRlOiBUZW1wbGF0ZSkge1xuICAgIC8vIFJlZmVyZW5jZXMgb24gYSA8bmctdGVtcGxhdGU+IGFyZSBkZWZpbmVkIGluIHRoZSBvdXRlciBzY29wZSwgc28gY2FwdHVyZSB0aGVtIGJlZm9yZVxuICAgIC8vIHByb2Nlc3NpbmcgdGhlIHRlbXBsYXRlJ3MgY2hpbGQgc2NvcGUuXG4gICAgdGVtcGxhdGUucmVmZXJlbmNlcy5mb3JFYWNoKChub2RlKSA9PiB0aGlzLnZpc2l0UmVmZXJlbmNlKG5vZGUpKTtcblxuICAgIC8vIE5leHQsIGNyZWF0ZSBhbiBpbm5lciBzY29wZSBhbmQgcHJvY2VzcyB0aGUgdGVtcGxhdGUgd2l0aGluIGl0LlxuICAgIHRoaXMuaW5nZXN0U2NvcGVkTm9kZSh0ZW1wbGF0ZSk7XG4gIH1cblxuICB2aXNpdFZhcmlhYmxlKHZhcmlhYmxlOiBWYXJpYWJsZSkge1xuICAgIC8vIERlY2xhcmUgdGhlIHZhcmlhYmxlIGlmIGl0J3Mgbm90IGFscmVhZHkuXG4gICAgdGhpcy5tYXliZURlY2xhcmUodmFyaWFibGUpO1xuICB9XG5cbiAgdmlzaXRSZWZlcmVuY2UocmVmZXJlbmNlOiBSZWZlcmVuY2UpIHtcbiAgICAvLyBEZWNsYXJlIHRoZSB2YXJpYWJsZSBpZiBpdCdzIG5vdCBhbHJlYWR5LlxuICAgIHRoaXMubWF5YmVEZWNsYXJlKHJlZmVyZW5jZSk7XG4gIH1cblxuICB2aXNpdERlZmVycmVkQmxvY2soZGVmZXJyZWQ6IERlZmVycmVkQmxvY2spIHtcbiAgICB0aGlzLmluZ2VzdFNjb3BlZE5vZGUoZGVmZXJyZWQpO1xuICAgIGRlZmVycmVkLnBsYWNlaG9sZGVyPy52aXNpdCh0aGlzKTtcbiAgICBkZWZlcnJlZC5sb2FkaW5nPy52aXNpdCh0aGlzKTtcbiAgICBkZWZlcnJlZC5lcnJvcj8udmlzaXQodGhpcyk7XG4gIH1cblxuICB2aXNpdERlZmVycmVkQmxvY2tQbGFjZWhvbGRlcihibG9jazogRGVmZXJyZWRCbG9ja1BsYWNlaG9sZGVyKSB7XG4gICAgdGhpcy5pbmdlc3RTY29wZWROb2RlKGJsb2NrKTtcbiAgfVxuXG4gIHZpc2l0RGVmZXJyZWRCbG9ja0Vycm9yKGJsb2NrOiBEZWZlcnJlZEJsb2NrRXJyb3IpIHtcbiAgICB0aGlzLmluZ2VzdFNjb3BlZE5vZGUoYmxvY2spO1xuICB9XG5cbiAgdmlzaXREZWZlcnJlZEJsb2NrTG9hZGluZyhibG9jazogRGVmZXJyZWRCbG9ja0xvYWRpbmcpIHtcbiAgICB0aGlzLmluZ2VzdFNjb3BlZE5vZGUoYmxvY2spO1xuICB9XG5cbiAgdmlzaXRTd2l0Y2hCbG9jayhibG9jazogU3dpdGNoQmxvY2spIHtcbiAgICBibG9jay5jYXNlcy5mb3JFYWNoKChub2RlKSA9PiBub2RlLnZpc2l0KHRoaXMpKTtcbiAgfVxuXG4gIHZpc2l0U3dpdGNoQmxvY2tDYXNlKGJsb2NrOiBTd2l0Y2hCbG9ja0Nhc2UpIHtcbiAgICB0aGlzLmluZ2VzdFNjb3BlZE5vZGUoYmxvY2spO1xuICB9XG5cbiAgdmlzaXRGb3JMb29wQmxvY2soYmxvY2s6IEZvckxvb3BCbG9jaykge1xuICAgIHRoaXMuaW5nZXN0U2NvcGVkTm9kZShibG9jayk7XG4gICAgYmxvY2suZW1wdHk/LnZpc2l0KHRoaXMpO1xuICB9XG5cbiAgdmlzaXRGb3JMb29wQmxvY2tFbXB0eShibG9jazogRm9yTG9vcEJsb2NrRW1wdHkpIHtcbiAgICB0aGlzLmluZ2VzdFNjb3BlZE5vZGUoYmxvY2spO1xuICB9XG5cbiAgdmlzaXRJZkJsb2NrKGJsb2NrOiBJZkJsb2NrKSB7XG4gICAgYmxvY2suYnJhbmNoZXMuZm9yRWFjaCgobm9kZSkgPT4gbm9kZS52aXNpdCh0aGlzKSk7XG4gIH1cblxuICB2aXNpdElmQmxvY2tCcmFuY2goYmxvY2s6IElmQmxvY2tCcmFuY2gpIHtcbiAgICB0aGlzLmluZ2VzdFNjb3BlZE5vZGUoYmxvY2spO1xuICB9XG5cbiAgdmlzaXRDb250ZW50KGNvbnRlbnQ6IENvbnRlbnQpIHtcbiAgICB0aGlzLmluZ2VzdFNjb3BlZE5vZGUoY29udGVudCk7XG4gIH1cblxuICB2aXNpdExldERlY2xhcmF0aW9uKGRlY2w6IExldERlY2xhcmF0aW9uKSB7XG4gICAgdGhpcy5tYXliZURlY2xhcmUoZGVjbCk7XG4gIH1cblxuICAvLyBVbnVzZWQgdmlzaXRvcnMuXG4gIHZpc2l0Qm91bmRBdHRyaWJ1dGUoYXR0cjogQm91bmRBdHRyaWJ1dGUpIHt9XG4gIHZpc2l0Qm91bmRFdmVudChldmVudDogQm91bmRFdmVudCkge31cbiAgdmlzaXRCb3VuZFRleHQodGV4dDogQm91bmRUZXh0KSB7fVxuICB2aXNpdFRleHQodGV4dDogVGV4dCkge31cbiAgdmlzaXRUZXh0QXR0cmlidXRlKGF0dHI6IFRleHRBdHRyaWJ1dGUpIHt9XG4gIHZpc2l0SWN1KGljdTogSWN1KSB7fVxuICB2aXNpdERlZmVycmVkVHJpZ2dlcih0cmlnZ2VyOiBEZWZlcnJlZFRyaWdnZXIpIHt9XG4gIHZpc2l0VW5rbm93bkJsb2NrKGJsb2NrOiBVbmtub3duQmxvY2spIHt9XG5cbiAgcHJpdmF0ZSBtYXliZURlY2xhcmUodGhpbmc6IFRlbXBsYXRlRW50aXR5KSB7XG4gICAgLy8gRGVjbGFyZSBzb21ldGhpbmcgd2l0aCBhIG5hbWUsIGFzIGxvbmcgYXMgdGhhdCBuYW1lIGlzbid0IHRha2VuLlxuICAgIGlmICghdGhpcy5uYW1lZEVudGl0aWVzLmhhcyh0aGluZy5uYW1lKSkge1xuICAgICAgdGhpcy5uYW1lZEVudGl0aWVzLnNldCh0aGluZy5uYW1lLCB0aGluZyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExvb2sgdXAgYSB2YXJpYWJsZSB3aXRoaW4gdGhpcyBgU2NvcGVgLlxuICAgKlxuICAgKiBUaGlzIGNhbiByZWN1cnNlIGludG8gYSBwYXJlbnQgYFNjb3BlYCBpZiBpdCdzIGF2YWlsYWJsZS5cbiAgICovXG4gIGxvb2t1cChuYW1lOiBzdHJpbmcpOiBUZW1wbGF0ZUVudGl0eSB8IG51bGwge1xuICAgIGlmICh0aGlzLm5hbWVkRW50aXRpZXMuaGFzKG5hbWUpKSB7XG4gICAgICAvLyBGb3VuZCBpbiB0aGUgbG9jYWwgc2NvcGUuXG4gICAgICByZXR1cm4gdGhpcy5uYW1lZEVudGl0aWVzLmdldChuYW1lKSE7XG4gICAgfSBlbHNlIGlmICh0aGlzLnBhcmVudFNjb3BlICE9PSBudWxsKSB7XG4gICAgICAvLyBOb3QgaW4gdGhlIGxvY2FsIHNjb3BlLCBidXQgdGhlcmUncyBhIHBhcmVudCBzY29wZSBzbyBjaGVjayB0aGVyZS5cbiAgICAgIHJldHVybiB0aGlzLnBhcmVudFNjb3BlLmxvb2t1cChuYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQXQgdGhlIHRvcCBsZXZlbCBhbmQgaXQgd2Fzbid0IGZvdW5kLlxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgY2hpbGQgc2NvcGUgZm9yIGEgYFNjb3BlZE5vZGVgLlxuICAgKlxuICAgKiBUaGlzIHNob3VsZCBhbHdheXMgYmUgZGVmaW5lZC5cbiAgICovXG4gIGdldENoaWxkU2NvcGUobm9kZTogU2NvcGVkTm9kZSk6IFNjb3BlIHtcbiAgICBjb25zdCByZXMgPSB0aGlzLmNoaWxkU2NvcGVzLmdldChub2RlKTtcbiAgICBpZiAocmVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQXNzZXJ0aW9uIGVycm9yOiBjaGlsZCBzY29wZSBmb3IgJHtub2RlfSBub3QgZm91bmRgKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIHByaXZhdGUgaW5nZXN0U2NvcGVkTm9kZShub2RlOiBTY29wZWROb2RlKSB7XG4gICAgY29uc3Qgc2NvcGUgPSBuZXcgU2NvcGUodGhpcywgbm9kZSk7XG4gICAgc2NvcGUuaW5nZXN0KG5vZGUpO1xuICAgIHRoaXMuY2hpbGRTY29wZXMuc2V0KG5vZGUsIHNjb3BlKTtcbiAgfVxufVxuXG4vKipcbiAqIFByb2Nlc3NlcyBhIHRlbXBsYXRlIGFuZCBtYXRjaGVzIGRpcmVjdGl2ZXMgb24gbm9kZXMgKGVsZW1lbnRzIGFuZCB0ZW1wbGF0ZXMpLlxuICpcbiAqIFVzdWFsbHkgdXNlZCB2aWEgdGhlIHN0YXRpYyBgYXBwbHkoKWAgbWV0aG9kLlxuICovXG5jbGFzcyBEaXJlY3RpdmVCaW5kZXI8RGlyZWN0aXZlVCBleHRlbmRzIERpcmVjdGl2ZU1ldGE+IGltcGxlbWVudHMgVmlzaXRvciB7XG4gIC8vIEluZGljYXRlcyB3aGV0aGVyIHdlIGFyZSB2aXNpdGluZyBlbGVtZW50cyB3aXRoaW4gYSBgZGVmZXJgIGJsb2NrXG4gIHByaXZhdGUgaXNJbkRlZmVyQmxvY2sgPSBmYWxzZTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbWF0Y2hlcjogU2VsZWN0b3JNYXRjaGVyPERpcmVjdGl2ZVRbXT4sXG4gICAgcHJpdmF0ZSBkaXJlY3RpdmVzOiBNYXA8RWxlbWVudCB8IFRlbXBsYXRlLCBEaXJlY3RpdmVUW10+LFxuICAgIHByaXZhdGUgZWFnZXJEaXJlY3RpdmVzOiBEaXJlY3RpdmVUW10sXG4gICAgcHJpdmF0ZSBiaW5kaW5nczogTWFwPFxuICAgICAgQm91bmRBdHRyaWJ1dGUgfCBCb3VuZEV2ZW50IHwgVGV4dEF0dHJpYnV0ZSxcbiAgICAgIERpcmVjdGl2ZVQgfCBFbGVtZW50IHwgVGVtcGxhdGVcbiAgICA+LFxuICAgIHByaXZhdGUgcmVmZXJlbmNlczogTWFwPFxuICAgICAgUmVmZXJlbmNlLFxuICAgICAge2RpcmVjdGl2ZTogRGlyZWN0aXZlVDsgbm9kZTogRWxlbWVudCB8IFRlbXBsYXRlfSB8IEVsZW1lbnQgfCBUZW1wbGF0ZVxuICAgID4sXG4gICkge31cblxuICAvKipcbiAgICogUHJvY2VzcyBhIHRlbXBsYXRlIChsaXN0IG9mIGBOb2RlYHMpIGFuZCBwZXJmb3JtIGRpcmVjdGl2ZSBtYXRjaGluZyBhZ2FpbnN0IGVhY2ggbm9kZS5cbiAgICpcbiAgICogQHBhcmFtIHRlbXBsYXRlIHRoZSBsaXN0IG9mIHRlbXBsYXRlIGBOb2RlYHMgdG8gbWF0Y2ggKHJlY3Vyc2l2ZWx5KS5cbiAgICogQHBhcmFtIHNlbGVjdG9yTWF0Y2hlciBhIGBTZWxlY3Rvck1hdGNoZXJgIGNvbnRhaW5pbmcgdGhlIGRpcmVjdGl2ZXMgdGhhdCBhcmUgaW4gc2NvcGUgZm9yXG4gICAqIHRoaXMgdGVtcGxhdGUuXG4gICAqIEByZXR1cm5zIHRocmVlIG1hcHMgd2hpY2ggY29udGFpbiBpbmZvcm1hdGlvbiBhYm91dCBkaXJlY3RpdmVzIGluIHRoZSB0ZW1wbGF0ZTogdGhlXG4gICAqIGBkaXJlY3RpdmVzYCBtYXAgd2hpY2ggbGlzdHMgZGlyZWN0aXZlcyBtYXRjaGVkIG9uIGVhY2ggbm9kZSwgdGhlIGBiaW5kaW5nc2AgbWFwIHdoaWNoXG4gICAqIGluZGljYXRlcyB3aGljaCBkaXJlY3RpdmVzIGNsYWltZWQgd2hpY2ggYmluZGluZ3MgKGlucHV0cywgb3V0cHV0cywgZXRjKSwgYW5kIHRoZSBgcmVmZXJlbmNlc2BcbiAgICogbWFwIHdoaWNoIHJlc29sdmVzICNyZWZlcmVuY2VzIChgUmVmZXJlbmNlYHMpIHdpdGhpbiB0aGUgdGVtcGxhdGUgdG8gdGhlIG5hbWVkIGRpcmVjdGl2ZSBvclxuICAgKiB0ZW1wbGF0ZSBub2RlLlxuICAgKi9cbiAgc3RhdGljIGFwcGx5PERpcmVjdGl2ZVQgZXh0ZW5kcyBEaXJlY3RpdmVNZXRhPihcbiAgICB0ZW1wbGF0ZTogTm9kZVtdLFxuICAgIHNlbGVjdG9yTWF0Y2hlcjogU2VsZWN0b3JNYXRjaGVyPERpcmVjdGl2ZVRbXT4sXG4gICk6IHtcbiAgICBkaXJlY3RpdmVzOiBNYXA8RWxlbWVudCB8IFRlbXBsYXRlLCBEaXJlY3RpdmVUW10+O1xuICAgIGVhZ2VyRGlyZWN0aXZlczogRGlyZWN0aXZlVFtdO1xuICAgIGJpbmRpbmdzOiBNYXA8Qm91bmRBdHRyaWJ1dGUgfCBCb3VuZEV2ZW50IHwgVGV4dEF0dHJpYnV0ZSwgRGlyZWN0aXZlVCB8IEVsZW1lbnQgfCBUZW1wbGF0ZT47XG4gICAgcmVmZXJlbmNlczogTWFwPFxuICAgICAgUmVmZXJlbmNlLFxuICAgICAge2RpcmVjdGl2ZTogRGlyZWN0aXZlVDsgbm9kZTogRWxlbWVudCB8IFRlbXBsYXRlfSB8IEVsZW1lbnQgfCBUZW1wbGF0ZVxuICAgID47XG4gIH0ge1xuICAgIGNvbnN0IGRpcmVjdGl2ZXMgPSBuZXcgTWFwPEVsZW1lbnQgfCBUZW1wbGF0ZSwgRGlyZWN0aXZlVFtdPigpO1xuICAgIGNvbnN0IGJpbmRpbmdzID0gbmV3IE1hcDxcbiAgICAgIEJvdW5kQXR0cmlidXRlIHwgQm91bmRFdmVudCB8IFRleHRBdHRyaWJ1dGUsXG4gICAgICBEaXJlY3RpdmVUIHwgRWxlbWVudCB8IFRlbXBsYXRlXG4gICAgPigpO1xuICAgIGNvbnN0IHJlZmVyZW5jZXMgPSBuZXcgTWFwPFxuICAgICAgUmVmZXJlbmNlLFxuICAgICAge2RpcmVjdGl2ZTogRGlyZWN0aXZlVDsgbm9kZTogRWxlbWVudCB8IFRlbXBsYXRlfSB8IEVsZW1lbnQgfCBUZW1wbGF0ZVxuICAgID4oKTtcbiAgICBjb25zdCBlYWdlckRpcmVjdGl2ZXM6IERpcmVjdGl2ZVRbXSA9IFtdO1xuICAgIGNvbnN0IG1hdGNoZXIgPSBuZXcgRGlyZWN0aXZlQmluZGVyKFxuICAgICAgc2VsZWN0b3JNYXRjaGVyLFxuICAgICAgZGlyZWN0aXZlcyxcbiAgICAgIGVhZ2VyRGlyZWN0aXZlcyxcbiAgICAgIGJpbmRpbmdzLFxuICAgICAgcmVmZXJlbmNlcyxcbiAgICApO1xuICAgIG1hdGNoZXIuaW5nZXN0KHRlbXBsYXRlKTtcbiAgICByZXR1cm4ge2RpcmVjdGl2ZXMsIGVhZ2VyRGlyZWN0aXZlcywgYmluZGluZ3MsIHJlZmVyZW5jZXN9O1xuICB9XG5cbiAgcHJpdmF0ZSBpbmdlc3QodGVtcGxhdGU6IE5vZGVbXSk6IHZvaWQge1xuICAgIHRlbXBsYXRlLmZvckVhY2goKG5vZGUpID0+IG5vZGUudmlzaXQodGhpcykpO1xuICB9XG5cbiAgdmlzaXRFbGVtZW50KGVsZW1lbnQ6IEVsZW1lbnQpOiB2b2lkIHtcbiAgICB0aGlzLnZpc2l0RWxlbWVudE9yVGVtcGxhdGUoZWxlbWVudCk7XG4gIH1cblxuICB2aXNpdFRlbXBsYXRlKHRlbXBsYXRlOiBUZW1wbGF0ZSk6IHZvaWQge1xuICAgIHRoaXMudmlzaXRFbGVtZW50T3JUZW1wbGF0ZSh0ZW1wbGF0ZSk7XG4gIH1cblxuICB2aXNpdEVsZW1lbnRPclRlbXBsYXRlKG5vZGU6IEVsZW1lbnQgfCBUZW1wbGF0ZSk6IHZvaWQge1xuICAgIC8vIEZpcnN0LCBkZXRlcm1pbmUgdGhlIEhUTUwgc2hhcGUgb2YgdGhlIG5vZGUgZm9yIHRoZSBwdXJwb3NlIG9mIGRpcmVjdGl2ZSBtYXRjaGluZy5cbiAgICAvLyBEbyB0aGlzIGJ5IGJ1aWxkaW5nIHVwIGEgYENzc1NlbGVjdG9yYCBmb3IgdGhlIG5vZGUuXG4gICAgY29uc3QgY3NzU2VsZWN0b3IgPSBjcmVhdGVDc3NTZWxlY3RvckZyb21Ob2RlKG5vZGUpO1xuXG4gICAgLy8gTmV4dCwgdXNlIHRoZSBgU2VsZWN0b3JNYXRjaGVyYCB0byBnZXQgdGhlIGxpc3Qgb2YgZGlyZWN0aXZlcyBvbiB0aGUgbm9kZS5cbiAgICBjb25zdCBkaXJlY3RpdmVzOiBEaXJlY3RpdmVUW10gPSBbXTtcbiAgICB0aGlzLm1hdGNoZXIubWF0Y2goY3NzU2VsZWN0b3IsIChfc2VsZWN0b3IsIHJlc3VsdHMpID0+IGRpcmVjdGl2ZXMucHVzaCguLi5yZXN1bHRzKSk7XG4gICAgaWYgKGRpcmVjdGl2ZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5kaXJlY3RpdmVzLnNldChub2RlLCBkaXJlY3RpdmVzKTtcbiAgICAgIGlmICghdGhpcy5pc0luRGVmZXJCbG9jaykge1xuICAgICAgICB0aGlzLmVhZ2VyRGlyZWN0aXZlcy5wdXNoKC4uLmRpcmVjdGl2ZXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlc29sdmUgYW55IHJlZmVyZW5jZXMgdGhhdCBhcmUgY3JlYXRlZCBvbiB0aGlzIG5vZGUuXG4gICAgbm9kZS5yZWZlcmVuY2VzLmZvckVhY2goKHJlZikgPT4ge1xuICAgICAgbGV0IGRpclRhcmdldDogRGlyZWN0aXZlVCB8IG51bGwgPSBudWxsO1xuXG4gICAgICAvLyBJZiB0aGUgcmVmZXJlbmNlIGV4cHJlc3Npb24gaXMgZW1wdHksIHRoZW4gaXQgbWF0Y2hlcyB0aGUgXCJwcmltYXJ5XCIgZGlyZWN0aXZlIG9uIHRoZSBub2RlXG4gICAgICAvLyAoaWYgdGhlcmUgaXMgb25lKS4gT3RoZXJ3aXNlIGl0IG1hdGNoZXMgdGhlIGhvc3Qgbm9kZSBpdHNlbGYgKGVpdGhlciBhbiBlbGVtZW50IG9yXG4gICAgICAvLyA8bmctdGVtcGxhdGU+IG5vZGUpLlxuICAgICAgaWYgKHJlZi52YWx1ZS50cmltKCkgPT09ICcnKSB7XG4gICAgICAgIC8vIFRoaXMgY291bGQgYmUgYSByZWZlcmVuY2UgdG8gYSBjb21wb25lbnQgaWYgdGhlcmUgaXMgb25lLlxuICAgICAgICBkaXJUYXJnZXQgPSBkaXJlY3RpdmVzLmZpbmQoKGRpcikgPT4gZGlyLmlzQ29tcG9uZW50KSB8fCBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVGhpcyBzaG91bGQgYmUgYSByZWZlcmVuY2UgdG8gYSBkaXJlY3RpdmUgZXhwb3J0ZWQgdmlhIGV4cG9ydEFzLlxuICAgICAgICBkaXJUYXJnZXQgPVxuICAgICAgICAgIGRpcmVjdGl2ZXMuZmluZChcbiAgICAgICAgICAgIChkaXIpID0+IGRpci5leHBvcnRBcyAhPT0gbnVsbCAmJiBkaXIuZXhwb3J0QXMuc29tZSgodmFsdWUpID0+IHZhbHVlID09PSByZWYudmFsdWUpLFxuICAgICAgICAgICkgfHwgbnVsbDtcbiAgICAgICAgLy8gQ2hlY2sgaWYgYSBtYXRjaGluZyBkaXJlY3RpdmUgd2FzIGZvdW5kLlxuICAgICAgICBpZiAoZGlyVGFyZ2V0ID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gTm8gbWF0Y2hpbmcgZGlyZWN0aXZlIHdhcyBmb3VuZCAtIHRoaXMgcmVmZXJlbmNlIHBvaW50cyB0byBhbiB1bmtub3duIHRhcmdldC4gTGVhdmUgaXRcbiAgICAgICAgICAvLyB1bm1hcHBlZC5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGRpclRhcmdldCAhPT0gbnVsbCkge1xuICAgICAgICAvLyBUaGlzIHJlZmVyZW5jZSBwb2ludHMgdG8gYSBkaXJlY3RpdmUuXG4gICAgICAgIHRoaXMucmVmZXJlbmNlcy5zZXQocmVmLCB7ZGlyZWN0aXZlOiBkaXJUYXJnZXQsIG5vZGV9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRoaXMgcmVmZXJlbmNlIHBvaW50cyB0byB0aGUgbm9kZSBpdHNlbGYuXG4gICAgICAgIHRoaXMucmVmZXJlbmNlcy5zZXQocmVmLCBub2RlKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIEFzc29jaWF0ZSBhdHRyaWJ1dGVzL2JpbmRpbmdzIG9uIHRoZSBub2RlIHdpdGggZGlyZWN0aXZlcyBvciB3aXRoIHRoZSBub2RlIGl0c2VsZi5cbiAgICB0eXBlIEJvdW5kTm9kZSA9IEJvdW5kQXR0cmlidXRlIHwgQm91bmRFdmVudCB8IFRleHRBdHRyaWJ1dGU7XG4gICAgY29uc3Qgc2V0QXR0cmlidXRlQmluZGluZyA9IChcbiAgICAgIGF0dHJpYnV0ZTogQm91bmROb2RlLFxuICAgICAgaW9UeXBlOiBrZXlvZiBQaWNrPERpcmVjdGl2ZU1ldGEsICdpbnB1dHMnIHwgJ291dHB1dHMnPixcbiAgICApID0+IHtcbiAgICAgIGNvbnN0IGRpciA9IGRpcmVjdGl2ZXMuZmluZCgoZGlyKSA9PiBkaXJbaW9UeXBlXS5oYXNCaW5kaW5nUHJvcGVydHlOYW1lKGF0dHJpYnV0ZS5uYW1lKSk7XG4gICAgICBjb25zdCBiaW5kaW5nID0gZGlyICE9PSB1bmRlZmluZWQgPyBkaXIgOiBub2RlO1xuICAgICAgdGhpcy5iaW5kaW5ncy5zZXQoYXR0cmlidXRlLCBiaW5kaW5nKTtcbiAgICB9O1xuXG4gICAgLy8gTm9kZSBpbnB1dHMgKGJvdW5kIGF0dHJpYnV0ZXMpIGFuZCB0ZXh0IGF0dHJpYnV0ZXMgY2FuIGJlIGJvdW5kIHRvIGFuXG4gICAgLy8gaW5wdXQgb24gYSBkaXJlY3RpdmUuXG4gICAgbm9kZS5pbnB1dHMuZm9yRWFjaCgoaW5wdXQpID0+IHNldEF0dHJpYnV0ZUJpbmRpbmcoaW5wdXQsICdpbnB1dHMnKSk7XG4gICAgbm9kZS5hdHRyaWJ1dGVzLmZvckVhY2goKGF0dHIpID0+IHNldEF0dHJpYnV0ZUJpbmRpbmcoYXR0ciwgJ2lucHV0cycpKTtcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFRlbXBsYXRlKSB7XG4gICAgICBub2RlLnRlbXBsYXRlQXR0cnMuZm9yRWFjaCgoYXR0cikgPT4gc2V0QXR0cmlidXRlQmluZGluZyhhdHRyLCAnaW5wdXRzJykpO1xuICAgIH1cbiAgICAvLyBOb2RlIG91dHB1dHMgKGJvdW5kIGV2ZW50cykgY2FuIGJlIGJvdW5kIHRvIGFuIG91dHB1dCBvbiBhIGRpcmVjdGl2ZS5cbiAgICBub2RlLm91dHB1dHMuZm9yRWFjaCgob3V0cHV0KSA9PiBzZXRBdHRyaWJ1dGVCaW5kaW5nKG91dHB1dCwgJ291dHB1dHMnKSk7XG5cbiAgICAvLyBSZWN1cnNlIGludG8gdGhlIG5vZGUncyBjaGlsZHJlbi5cbiAgICBub2RlLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkKSA9PiBjaGlsZC52aXNpdCh0aGlzKSk7XG4gIH1cblxuICB2aXNpdERlZmVycmVkQmxvY2soZGVmZXJyZWQ6IERlZmVycmVkQmxvY2spOiB2b2lkIHtcbiAgICBjb25zdCB3YXNJbkRlZmVyQmxvY2sgPSB0aGlzLmlzSW5EZWZlckJsb2NrO1xuICAgIHRoaXMuaXNJbkRlZmVyQmxvY2sgPSB0cnVlO1xuICAgIGRlZmVycmVkLmNoaWxkcmVuLmZvckVhY2goKGNoaWxkKSA9PiBjaGlsZC52aXNpdCh0aGlzKSk7XG4gICAgdGhpcy5pc0luRGVmZXJCbG9jayA9IHdhc0luRGVmZXJCbG9jaztcblxuICAgIGRlZmVycmVkLnBsYWNlaG9sZGVyPy52aXNpdCh0aGlzKTtcbiAgICBkZWZlcnJlZC5sb2FkaW5nPy52aXNpdCh0aGlzKTtcbiAgICBkZWZlcnJlZC5lcnJvcj8udmlzaXQodGhpcyk7XG4gIH1cblxuICB2aXNpdERlZmVycmVkQmxvY2tQbGFjZWhvbGRlcihibG9jazogRGVmZXJyZWRCbG9ja1BsYWNlaG9sZGVyKTogdm9pZCB7XG4gICAgYmxvY2suY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQpID0+IGNoaWxkLnZpc2l0KHRoaXMpKTtcbiAgfVxuXG4gIHZpc2l0RGVmZXJyZWRCbG9ja0Vycm9yKGJsb2NrOiBEZWZlcnJlZEJsb2NrRXJyb3IpOiB2b2lkIHtcbiAgICBibG9jay5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZCkgPT4gY2hpbGQudmlzaXQodGhpcykpO1xuICB9XG5cbiAgdmlzaXREZWZlcnJlZEJsb2NrTG9hZGluZyhibG9jazogRGVmZXJyZWRCbG9ja0xvYWRpbmcpOiB2b2lkIHtcbiAgICBibG9jay5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZCkgPT4gY2hpbGQudmlzaXQodGhpcykpO1xuICB9XG5cbiAgdmlzaXRTd2l0Y2hCbG9jayhibG9jazogU3dpdGNoQmxvY2spIHtcbiAgICBibG9jay5jYXNlcy5mb3JFYWNoKChub2RlKSA9PiBub2RlLnZpc2l0KHRoaXMpKTtcbiAgfVxuXG4gIHZpc2l0U3dpdGNoQmxvY2tDYXNlKGJsb2NrOiBTd2l0Y2hCbG9ja0Nhc2UpIHtcbiAgICBibG9jay5jaGlsZHJlbi5mb3JFYWNoKChub2RlKSA9PiBub2RlLnZpc2l0KHRoaXMpKTtcbiAgfVxuXG4gIHZpc2l0Rm9yTG9vcEJsb2NrKGJsb2NrOiBGb3JMb29wQmxvY2spIHtcbiAgICBibG9jay5pdGVtLnZpc2l0KHRoaXMpO1xuICAgIGJsb2NrLmNvbnRleHRWYXJpYWJsZXMuZm9yRWFjaCgodikgPT4gdi52aXNpdCh0aGlzKSk7XG4gICAgYmxvY2suY2hpbGRyZW4uZm9yRWFjaCgobm9kZSkgPT4gbm9kZS52aXNpdCh0aGlzKSk7XG4gICAgYmxvY2suZW1wdHk/LnZpc2l0KHRoaXMpO1xuICB9XG5cbiAgdmlzaXRGb3JMb29wQmxvY2tFbXB0eShibG9jazogRm9yTG9vcEJsb2NrRW1wdHkpIHtcbiAgICBibG9jay5jaGlsZHJlbi5mb3JFYWNoKChub2RlKSA9PiBub2RlLnZpc2l0KHRoaXMpKTtcbiAgfVxuXG4gIHZpc2l0SWZCbG9jayhibG9jazogSWZCbG9jaykge1xuICAgIGJsb2NrLmJyYW5jaGVzLmZvckVhY2goKG5vZGUpID0+IG5vZGUudmlzaXQodGhpcykpO1xuICB9XG5cbiAgdmlzaXRJZkJsb2NrQnJhbmNoKGJsb2NrOiBJZkJsb2NrQnJhbmNoKSB7XG4gICAgYmxvY2suZXhwcmVzc2lvbkFsaWFzPy52aXNpdCh0aGlzKTtcbiAgICBibG9jay5jaGlsZHJlbi5mb3JFYWNoKChub2RlKSA9PiBub2RlLnZpc2l0KHRoaXMpKTtcbiAgfVxuXG4gIHZpc2l0Q29udGVudChjb250ZW50OiBDb250ZW50KTogdm9pZCB7XG4gICAgY29udGVudC5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZCkgPT4gY2hpbGQudmlzaXQodGhpcykpO1xuICB9XG5cbiAgLy8gVW51c2VkIHZpc2l0b3JzLlxuICB2aXNpdFZhcmlhYmxlKHZhcmlhYmxlOiBWYXJpYWJsZSk6IHZvaWQge31cbiAgdmlzaXRSZWZlcmVuY2UocmVmZXJlbmNlOiBSZWZlcmVuY2UpOiB2b2lkIHt9XG4gIHZpc2l0VGV4dEF0dHJpYnV0ZShhdHRyaWJ1dGU6IFRleHRBdHRyaWJ1dGUpOiB2b2lkIHt9XG4gIHZpc2l0Qm91bmRBdHRyaWJ1dGUoYXR0cmlidXRlOiBCb3VuZEF0dHJpYnV0ZSk6IHZvaWQge31cbiAgdmlzaXRCb3VuZEV2ZW50KGF0dHJpYnV0ZTogQm91bmRFdmVudCk6IHZvaWQge31cbiAgdmlzaXRCb3VuZEF0dHJpYnV0ZU9yRXZlbnQobm9kZTogQm91bmRBdHRyaWJ1dGUgfCBCb3VuZEV2ZW50KSB7fVxuICB2aXNpdFRleHQodGV4dDogVGV4dCk6IHZvaWQge31cbiAgdmlzaXRCb3VuZFRleHQodGV4dDogQm91bmRUZXh0KTogdm9pZCB7fVxuICB2aXNpdEljdShpY3U6IEljdSk6IHZvaWQge31cbiAgdmlzaXREZWZlcnJlZFRyaWdnZXIodHJpZ2dlcjogRGVmZXJyZWRUcmlnZ2VyKTogdm9pZCB7fVxuICB2aXNpdFVua25vd25CbG9jayhibG9jazogVW5rbm93bkJsb2NrKSB7fVxuICB2aXNpdExldERlY2xhcmF0aW9uKGRlY2w6IExldERlY2xhcmF0aW9uKSB7fVxufVxuXG4vKipcbiAqIFByb2Nlc3NlcyBhIHRlbXBsYXRlIGFuZCBleHRyYWN0IG1ldGFkYXRhIGFib3V0IGV4cHJlc3Npb25zIGFuZCBzeW1ib2xzIHdpdGhpbi5cbiAqXG4gKiBUaGlzIGlzIGEgY29tcGFuaW9uIHRvIHRoZSBgRGlyZWN0aXZlQmluZGVyYCB0aGF0IGRvZXNuJ3QgcmVxdWlyZSBrbm93bGVkZ2Ugb2YgZGlyZWN0aXZlcyBtYXRjaGVkXG4gKiB3aXRoaW4gdGhlIHRlbXBsYXRlIGluIG9yZGVyIHRvIG9wZXJhdGUuXG4gKlxuICogRXhwcmVzc2lvbnMgYXJlIHZpc2l0ZWQgYnkgdGhlIHN1cGVyY2xhc3MgYFJlY3Vyc2l2ZUFzdFZpc2l0b3JgLCB3aXRoIGN1c3RvbSBsb2dpYyBwcm92aWRlZFxuICogYnkgb3ZlcnJpZGRlbiBtZXRob2RzIGZyb20gdGhhdCB2aXNpdG9yLlxuICovXG5jbGFzcyBUZW1wbGF0ZUJpbmRlciBleHRlbmRzIFJlY3Vyc2l2ZUFzdFZpc2l0b3IgaW1wbGVtZW50cyBWaXNpdG9yIHtcbiAgcHJpdmF0ZSB2aXNpdE5vZGU6IChub2RlOiBOb2RlKSA9PiB2b2lkO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBiaW5kaW5nczogTWFwPEFTVCwgVGVtcGxhdGVFbnRpdHk+LFxuICAgIHByaXZhdGUgc3ltYm9sczogTWFwPFRlbXBsYXRlRW50aXR5LCBTY29wZWROb2RlPixcbiAgICBwcml2YXRlIHVzZWRQaXBlczogU2V0PHN0cmluZz4sXG4gICAgcHJpdmF0ZSBlYWdlclBpcGVzOiBTZXQ8c3RyaW5nPixcbiAgICBwcml2YXRlIGRlZmVyQmxvY2tzOiBbRGVmZXJyZWRCbG9jaywgU2NvcGVdW10sXG4gICAgcHJpdmF0ZSBuZXN0aW5nTGV2ZWw6IE1hcDxTY29wZWROb2RlLCBudW1iZXI+LFxuICAgIHByaXZhdGUgc2NvcGU6IFNjb3BlLFxuICAgIHByaXZhdGUgcm9vdE5vZGU6IFNjb3BlZE5vZGUgfCBudWxsLFxuICAgIHByaXZhdGUgbGV2ZWw6IG51bWJlcixcbiAgKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIC8vIFNhdmUgYSBiaXQgb2YgcHJvY2Vzc2luZyB0aW1lIGJ5IGNvbnN0cnVjdGluZyB0aGlzIGNsb3N1cmUgaW4gYWR2YW5jZS5cbiAgICB0aGlzLnZpc2l0Tm9kZSA9IChub2RlOiBOb2RlKSA9PiBub2RlLnZpc2l0KHRoaXMpO1xuICB9XG5cbiAgLy8gVGhpcyBtZXRob2QgaXMgZGVmaW5lZCB0byByZWNvbmNpbGUgdGhlIHR5cGUgb2YgVGVtcGxhdGVCaW5kZXIgc2luY2UgYm90aFxuICAvLyBSZWN1cnNpdmVBc3RWaXNpdG9yIGFuZCBWaXNpdG9yIGRlZmluZSB0aGUgdmlzaXQoKSBtZXRob2QgaW4gdGhlaXJcbiAgLy8gaW50ZXJmYWNlcy5cbiAgb3ZlcnJpZGUgdmlzaXQobm9kZTogQVNUIHwgTm9kZSwgY29udGV4dD86IGFueSkge1xuICAgIGlmIChub2RlIGluc3RhbmNlb2YgQVNUKSB7XG4gICAgICBub2RlLnZpc2l0KHRoaXMsIGNvbnRleHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBub2RlLnZpc2l0KHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzIGEgdGVtcGxhdGUgYW5kIGV4dHJhY3QgbWV0YWRhdGEgYWJvdXQgZXhwcmVzc2lvbnMgYW5kIHN5bWJvbHMgd2l0aGluLlxuICAgKlxuICAgKiBAcGFyYW0gbm9kZXMgdGhlIG5vZGVzIG9mIHRoZSB0ZW1wbGF0ZSB0byBwcm9jZXNzXG4gICAqIEBwYXJhbSBzY29wZSB0aGUgYFNjb3BlYCBvZiB0aGUgdGVtcGxhdGUgYmVpbmcgcHJvY2Vzc2VkLlxuICAgKiBAcmV0dXJucyB0aHJlZSBtYXBzIHdoaWNoIGNvbnRhaW4gbWV0YWRhdGEgYWJvdXQgdGhlIHRlbXBsYXRlOiBgZXhwcmVzc2lvbnNgIHdoaWNoIGludGVycHJldHNcbiAgICogc3BlY2lhbCBgQVNUYCBub2RlcyBpbiBleHByZXNzaW9ucyBhcyBwb2ludGluZyB0byByZWZlcmVuY2VzIG9yIHZhcmlhYmxlcyBkZWNsYXJlZCB3aXRoaW4gdGhlXG4gICAqIHRlbXBsYXRlLCBgc3ltYm9sc2Agd2hpY2ggbWFwcyB0aG9zZSB2YXJpYWJsZXMgYW5kIHJlZmVyZW5jZXMgdG8gdGhlIG5lc3RlZCBgVGVtcGxhdGVgIHdoaWNoXG4gICAqIGRlY2xhcmVzIHRoZW0sIGlmIGFueSwgYW5kIGBuZXN0aW5nTGV2ZWxgIHdoaWNoIGFzc29jaWF0ZXMgZWFjaCBgVGVtcGxhdGVgIHdpdGggYSBpbnRlZ2VyXG4gICAqIG5lc3RpbmcgbGV2ZWwgKGhvdyBtYW55IGxldmVscyBkZWVwIHdpdGhpbiB0aGUgdGVtcGxhdGUgc3RydWN0dXJlIHRoZSBgVGVtcGxhdGVgIGlzKSwgc3RhcnRpbmdcbiAgICogYXQgMS5cbiAgICovXG4gIHN0YXRpYyBhcHBseVdpdGhTY29wZShcbiAgICBub2RlczogTm9kZVtdLFxuICAgIHNjb3BlOiBTY29wZSxcbiAgKToge1xuICAgIGV4cHJlc3Npb25zOiBNYXA8QVNULCBUZW1wbGF0ZUVudGl0eT47XG4gICAgc3ltYm9sczogTWFwPFRlbXBsYXRlRW50aXR5LCBUZW1wbGF0ZT47XG4gICAgbmVzdGluZ0xldmVsOiBNYXA8U2NvcGVkTm9kZSwgbnVtYmVyPjtcbiAgICB1c2VkUGlwZXM6IFNldDxzdHJpbmc+O1xuICAgIGVhZ2VyUGlwZXM6IFNldDxzdHJpbmc+O1xuICAgIGRlZmVyQmxvY2tzOiBbRGVmZXJyZWRCbG9jaywgU2NvcGVdW107XG4gIH0ge1xuICAgIGNvbnN0IGV4cHJlc3Npb25zID0gbmV3IE1hcDxBU1QsIFRlbXBsYXRlRW50aXR5PigpO1xuICAgIGNvbnN0IHN5bWJvbHMgPSBuZXcgTWFwPFRlbXBsYXRlRW50aXR5LCBUZW1wbGF0ZT4oKTtcbiAgICBjb25zdCBuZXN0aW5nTGV2ZWwgPSBuZXcgTWFwPFNjb3BlZE5vZGUsIG51bWJlcj4oKTtcbiAgICBjb25zdCB1c2VkUGlwZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCBlYWdlclBpcGVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgY29uc3QgdGVtcGxhdGUgPSBub2RlcyBpbnN0YW5jZW9mIFRlbXBsYXRlID8gbm9kZXMgOiBudWxsO1xuICAgIGNvbnN0IGRlZmVyQmxvY2tzOiBbRGVmZXJyZWRCbG9jaywgU2NvcGVdW10gPSBbXTtcbiAgICAvLyBUaGUgdG9wLWxldmVsIHRlbXBsYXRlIGhhcyBuZXN0aW5nIGxldmVsIDAuXG4gICAgY29uc3QgYmluZGVyID0gbmV3IFRlbXBsYXRlQmluZGVyKFxuICAgICAgZXhwcmVzc2lvbnMsXG4gICAgICBzeW1ib2xzLFxuICAgICAgdXNlZFBpcGVzLFxuICAgICAgZWFnZXJQaXBlcyxcbiAgICAgIGRlZmVyQmxvY2tzLFxuICAgICAgbmVzdGluZ0xldmVsLFxuICAgICAgc2NvcGUsXG4gICAgICB0ZW1wbGF0ZSxcbiAgICAgIDAsXG4gICAgKTtcbiAgICBiaW5kZXIuaW5nZXN0KG5vZGVzKTtcbiAgICByZXR1cm4ge2V4cHJlc3Npb25zLCBzeW1ib2xzLCBuZXN0aW5nTGV2ZWwsIHVzZWRQaXBlcywgZWFnZXJQaXBlcywgZGVmZXJCbG9ja3N9O1xuICB9XG5cbiAgcHJpdmF0ZSBpbmdlc3Qobm9kZU9yTm9kZXM6IFNjb3BlZE5vZGUgfCBOb2RlW10pOiB2b2lkIHtcbiAgICBpZiAobm9kZU9yTm9kZXMgaW5zdGFuY2VvZiBUZW1wbGF0ZSkge1xuICAgICAgLy8gRm9yIDxuZy10ZW1wbGF0ZT5zLCBwcm9jZXNzIG9ubHkgdmFyaWFibGVzIGFuZCBjaGlsZCBub2Rlcy4gSW5wdXRzLCBvdXRwdXRzLCB0ZW1wbGF0ZUF0dHJzLFxuICAgICAgLy8gYW5kIHJlZmVyZW5jZXMgd2VyZSBhbGwgcHJvY2Vzc2VkIGluIHRoZSBzY29wZSBvZiB0aGUgY29udGFpbmluZyB0ZW1wbGF0ZS5cbiAgICAgIG5vZGVPck5vZGVzLnZhcmlhYmxlcy5mb3JFYWNoKHRoaXMudmlzaXROb2RlKTtcbiAgICAgIG5vZGVPck5vZGVzLmNoaWxkcmVuLmZvckVhY2godGhpcy52aXNpdE5vZGUpO1xuXG4gICAgICAvLyBTZXQgdGhlIG5lc3RpbmcgbGV2ZWwuXG4gICAgICB0aGlzLm5lc3RpbmdMZXZlbC5zZXQobm9kZU9yTm9kZXMsIHRoaXMubGV2ZWwpO1xuICAgIH0gZWxzZSBpZiAobm9kZU9yTm9kZXMgaW5zdGFuY2VvZiBJZkJsb2NrQnJhbmNoKSB7XG4gICAgICBpZiAobm9kZU9yTm9kZXMuZXhwcmVzc2lvbkFsaWFzICE9PSBudWxsKSB7XG4gICAgICAgIHRoaXMudmlzaXROb2RlKG5vZGVPck5vZGVzLmV4cHJlc3Npb25BbGlhcyk7XG4gICAgICB9XG4gICAgICBub2RlT3JOb2Rlcy5jaGlsZHJlbi5mb3JFYWNoKHRoaXMudmlzaXROb2RlKTtcbiAgICAgIHRoaXMubmVzdGluZ0xldmVsLnNldChub2RlT3JOb2RlcywgdGhpcy5sZXZlbCk7XG4gICAgfSBlbHNlIGlmIChub2RlT3JOb2RlcyBpbnN0YW5jZW9mIEZvckxvb3BCbG9jaykge1xuICAgICAgdGhpcy52aXNpdE5vZGUobm9kZU9yTm9kZXMuaXRlbSk7XG4gICAgICBub2RlT3JOb2Rlcy5jb250ZXh0VmFyaWFibGVzLmZvckVhY2goKHYpID0+IHRoaXMudmlzaXROb2RlKHYpKTtcbiAgICAgIG5vZGVPck5vZGVzLnRyYWNrQnkudmlzaXQodGhpcyk7XG4gICAgICBub2RlT3JOb2Rlcy5jaGlsZHJlbi5mb3JFYWNoKHRoaXMudmlzaXROb2RlKTtcbiAgICAgIHRoaXMubmVzdGluZ0xldmVsLnNldChub2RlT3JOb2RlcywgdGhpcy5sZXZlbCk7XG4gICAgfSBlbHNlIGlmIChub2RlT3JOb2RlcyBpbnN0YW5jZW9mIERlZmVycmVkQmxvY2spIHtcbiAgICAgIGlmICh0aGlzLnNjb3BlLnJvb3ROb2RlICE9PSBub2RlT3JOb2Rlcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYEFzc2VydGlvbiBlcnJvcjogcmVzb2x2ZWQgaW5jb3JyZWN0IHNjb3BlIGZvciBkZWZlcnJlZCBibG9jayAke25vZGVPck5vZGVzfWAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlZmVyQmxvY2tzLnB1c2goW25vZGVPck5vZGVzLCB0aGlzLnNjb3BlXSk7XG4gICAgICBub2RlT3JOb2Rlcy5jaGlsZHJlbi5mb3JFYWNoKChub2RlKSA9PiBub2RlLnZpc2l0KHRoaXMpKTtcbiAgICAgIHRoaXMubmVzdGluZ0xldmVsLnNldChub2RlT3JOb2RlcywgdGhpcy5sZXZlbCk7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIG5vZGVPck5vZGVzIGluc3RhbmNlb2YgU3dpdGNoQmxvY2tDYXNlIHx8XG4gICAgICBub2RlT3JOb2RlcyBpbnN0YW5jZW9mIEZvckxvb3BCbG9ja0VtcHR5IHx8XG4gICAgICBub2RlT3JOb2RlcyBpbnN0YW5jZW9mIERlZmVycmVkQmxvY2tFcnJvciB8fFxuICAgICAgbm9kZU9yTm9kZXMgaW5zdGFuY2VvZiBEZWZlcnJlZEJsb2NrUGxhY2Vob2xkZXIgfHxcbiAgICAgIG5vZGVPck5vZGVzIGluc3RhbmNlb2YgRGVmZXJyZWRCbG9ja0xvYWRpbmcgfHxcbiAgICAgIG5vZGVPck5vZGVzIGluc3RhbmNlb2YgQ29udGVudFxuICAgICkge1xuICAgICAgbm9kZU9yTm9kZXMuY2hpbGRyZW4uZm9yRWFjaCgobm9kZSkgPT4gbm9kZS52aXNpdCh0aGlzKSk7XG4gICAgICB0aGlzLm5lc3RpbmdMZXZlbC5zZXQobm9kZU9yTm9kZXMsIHRoaXMubGV2ZWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBWaXNpdCBlYWNoIG5vZGUgZnJvbSB0aGUgdG9wLWxldmVsIHRlbXBsYXRlLlxuICAgICAgbm9kZU9yTm9kZXMuZm9yRWFjaCh0aGlzLnZpc2l0Tm9kZSk7XG4gICAgfVxuICB9XG5cbiAgdmlzaXRFbGVtZW50KGVsZW1lbnQ6IEVsZW1lbnQpIHtcbiAgICAvLyBWaXNpdCB0aGUgaW5wdXRzLCBvdXRwdXRzLCBhbmQgY2hpbGRyZW4gb2YgdGhlIGVsZW1lbnQuXG4gICAgZWxlbWVudC5pbnB1dHMuZm9yRWFjaCh0aGlzLnZpc2l0Tm9kZSk7XG4gICAgZWxlbWVudC5vdXRwdXRzLmZvckVhY2godGhpcy52aXNpdE5vZGUpO1xuICAgIGVsZW1lbnQuY2hpbGRyZW4uZm9yRWFjaCh0aGlzLnZpc2l0Tm9kZSk7XG4gICAgZWxlbWVudC5yZWZlcmVuY2VzLmZvckVhY2godGhpcy52aXNpdE5vZGUpO1xuICB9XG5cbiAgdmlzaXRUZW1wbGF0ZSh0ZW1wbGF0ZTogVGVtcGxhdGUpIHtcbiAgICAvLyBGaXJzdCwgdmlzaXQgaW5wdXRzLCBvdXRwdXRzIGFuZCB0ZW1wbGF0ZSBhdHRyaWJ1dGVzIG9mIHRoZSB0ZW1wbGF0ZSBub2RlLlxuICAgIHRlbXBsYXRlLmlucHV0cy5mb3JFYWNoKHRoaXMudmlzaXROb2RlKTtcbiAgICB0ZW1wbGF0ZS5vdXRwdXRzLmZvckVhY2godGhpcy52aXNpdE5vZGUpO1xuICAgIHRlbXBsYXRlLnRlbXBsYXRlQXR0cnMuZm9yRWFjaCh0aGlzLnZpc2l0Tm9kZSk7XG4gICAgdGVtcGxhdGUucmVmZXJlbmNlcy5mb3JFYWNoKHRoaXMudmlzaXROb2RlKTtcblxuICAgIC8vIE5leHQsIHJlY3Vyc2UgaW50byB0aGUgdGVtcGxhdGUuXG4gICAgdGhpcy5pbmdlc3RTY29wZWROb2RlKHRlbXBsYXRlKTtcbiAgfVxuXG4gIHZpc2l0VmFyaWFibGUodmFyaWFibGU6IFZhcmlhYmxlKSB7XG4gICAgLy8gUmVnaXN0ZXIgdGhlIGBWYXJpYWJsZWAgYXMgYSBzeW1ib2wgaW4gdGhlIGN1cnJlbnQgYFRlbXBsYXRlYC5cbiAgICBpZiAodGhpcy5yb290Tm9kZSAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5zeW1ib2xzLnNldCh2YXJpYWJsZSwgdGhpcy5yb290Tm9kZSk7XG4gICAgfVxuICB9XG5cbiAgdmlzaXRSZWZlcmVuY2UocmVmZXJlbmNlOiBSZWZlcmVuY2UpIHtcbiAgICAvLyBSZWdpc3RlciB0aGUgYFJlZmVyZW5jZWAgYXMgYSBzeW1ib2wgaW4gdGhlIGN1cnJlbnQgYFRlbXBsYXRlYC5cbiAgICBpZiAodGhpcy5yb290Tm9kZSAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5zeW1ib2xzLnNldChyZWZlcmVuY2UsIHRoaXMucm9vdE5vZGUpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFVudXNlZCB0ZW1wbGF0ZSB2aXNpdG9yc1xuICB2aXNpdFRleHQodGV4dDogVGV4dCkge31cbiAgdmlzaXRUZXh0QXR0cmlidXRlKGF0dHJpYnV0ZTogVGV4dEF0dHJpYnV0ZSkge31cbiAgdmlzaXRVbmtub3duQmxvY2soYmxvY2s6IFVua25vd25CbG9jaykge31cbiAgdmlzaXREZWZlcnJlZFRyaWdnZXIoKTogdm9pZCB7fVxuICB2aXNpdEljdShpY3U6IEljdSk6IHZvaWQge1xuICAgIE9iamVjdC5rZXlzKGljdS52YXJzKS5mb3JFYWNoKChrZXkpID0+IGljdS52YXJzW2tleV0udmlzaXQodGhpcykpO1xuICAgIE9iamVjdC5rZXlzKGljdS5wbGFjZWhvbGRlcnMpLmZvckVhY2goKGtleSkgPT4gaWN1LnBsYWNlaG9sZGVyc1trZXldLnZpc2l0KHRoaXMpKTtcbiAgfVxuXG4gIC8vIFRoZSByZW1haW5pbmcgdmlzaXRvcnMgYXJlIGNvbmNlcm5lZCB3aXRoIHByb2Nlc3NpbmcgQVNUIGV4cHJlc3Npb25zIHdpdGhpbiB0ZW1wbGF0ZSBiaW5kaW5nc1xuXG4gIHZpc2l0Qm91bmRBdHRyaWJ1dGUoYXR0cmlidXRlOiBCb3VuZEF0dHJpYnV0ZSkge1xuICAgIGF0dHJpYnV0ZS52YWx1ZS52aXNpdCh0aGlzKTtcbiAgfVxuXG4gIHZpc2l0Qm91bmRFdmVudChldmVudDogQm91bmRFdmVudCkge1xuICAgIGV2ZW50LmhhbmRsZXIudmlzaXQodGhpcyk7XG4gIH1cblxuICB2aXNpdERlZmVycmVkQmxvY2soZGVmZXJyZWQ6IERlZmVycmVkQmxvY2spIHtcbiAgICB0aGlzLmluZ2VzdFNjb3BlZE5vZGUoZGVmZXJyZWQpO1xuICAgIGRlZmVycmVkLnRyaWdnZXJzLndoZW4/LnZhbHVlLnZpc2l0KHRoaXMpO1xuICAgIGRlZmVycmVkLnByZWZldGNoVHJpZ2dlcnMud2hlbj8udmFsdWUudmlzaXQodGhpcyk7XG4gICAgZGVmZXJyZWQucGxhY2Vob2xkZXIgJiYgdGhpcy52aXNpdE5vZGUoZGVmZXJyZWQucGxhY2Vob2xkZXIpO1xuICAgIGRlZmVycmVkLmxvYWRpbmcgJiYgdGhpcy52aXNpdE5vZGUoZGVmZXJyZWQubG9hZGluZyk7XG4gICAgZGVmZXJyZWQuZXJyb3IgJiYgdGhpcy52aXNpdE5vZGUoZGVmZXJyZWQuZXJyb3IpO1xuICB9XG5cbiAgdmlzaXREZWZlcnJlZEJsb2NrUGxhY2Vob2xkZXIoYmxvY2s6IERlZmVycmVkQmxvY2tQbGFjZWhvbGRlcikge1xuICAgIHRoaXMuaW5nZXN0U2NvcGVkTm9kZShibG9jayk7XG4gIH1cblxuICB2aXNpdERlZmVycmVkQmxvY2tFcnJvcihibG9jazogRGVmZXJyZWRCbG9ja0Vycm9yKSB7XG4gICAgdGhpcy5pbmdlc3RTY29wZWROb2RlKGJsb2NrKTtcbiAgfVxuXG4gIHZpc2l0RGVmZXJyZWRCbG9ja0xvYWRpbmcoYmxvY2s6IERlZmVycmVkQmxvY2tMb2FkaW5nKSB7XG4gICAgdGhpcy5pbmdlc3RTY29wZWROb2RlKGJsb2NrKTtcbiAgfVxuXG4gIHZpc2l0U3dpdGNoQmxvY2soYmxvY2s6IFN3aXRjaEJsb2NrKSB7XG4gICAgYmxvY2suZXhwcmVzc2lvbi52aXNpdCh0aGlzKTtcbiAgICBibG9jay5jYXNlcy5mb3JFYWNoKHRoaXMudmlzaXROb2RlKTtcbiAgfVxuXG4gIHZpc2l0U3dpdGNoQmxvY2tDYXNlKGJsb2NrOiBTd2l0Y2hCbG9ja0Nhc2UpIHtcbiAgICBibG9jay5leHByZXNzaW9uPy52aXNpdCh0aGlzKTtcbiAgICB0aGlzLmluZ2VzdFNjb3BlZE5vZGUoYmxvY2spO1xuICB9XG5cbiAgdmlzaXRGb3JMb29wQmxvY2soYmxvY2s6IEZvckxvb3BCbG9jaykge1xuICAgIGJsb2NrLmV4cHJlc3Npb24udmlzaXQodGhpcyk7XG4gICAgdGhpcy5pbmdlc3RTY29wZWROb2RlKGJsb2NrKTtcbiAgICBibG9jay5lbXB0eT8udmlzaXQodGhpcyk7XG4gIH1cblxuICB2aXNpdEZvckxvb3BCbG9ja0VtcHR5KGJsb2NrOiBGb3JMb29wQmxvY2tFbXB0eSkge1xuICAgIHRoaXMuaW5nZXN0U2NvcGVkTm9kZShibG9jayk7XG4gIH1cblxuICB2aXNpdElmQmxvY2soYmxvY2s6IElmQmxvY2spIHtcbiAgICBibG9jay5icmFuY2hlcy5mb3JFYWNoKChub2RlKSA9PiBub2RlLnZpc2l0KHRoaXMpKTtcbiAgfVxuXG4gIHZpc2l0SWZCbG9ja0JyYW5jaChibG9jazogSWZCbG9ja0JyYW5jaCkge1xuICAgIGJsb2NrLmV4cHJlc3Npb24/LnZpc2l0KHRoaXMpO1xuICAgIHRoaXMuaW5nZXN0U2NvcGVkTm9kZShibG9jayk7XG4gIH1cblxuICB2aXNpdENvbnRlbnQoY29udGVudDogQ29udGVudCkge1xuICAgIHRoaXMuaW5nZXN0U2NvcGVkTm9kZShjb250ZW50KTtcbiAgfVxuXG4gIHZpc2l0Qm91bmRUZXh0KHRleHQ6IEJvdW5kVGV4dCkge1xuICAgIHRleHQudmFsdWUudmlzaXQodGhpcyk7XG4gIH1cblxuICB2aXNpdExldERlY2xhcmF0aW9uKGRlY2w6IExldERlY2xhcmF0aW9uKSB7XG4gICAgZGVjbC52YWx1ZS52aXNpdCh0aGlzKTtcblxuICAgIGlmICh0aGlzLnJvb3ROb2RlICE9PSBudWxsKSB7XG4gICAgICB0aGlzLnN5bWJvbHMuc2V0KGRlY2wsIHRoaXMucm9vdE5vZGUpO1xuICAgIH1cbiAgfVxuXG4gIG92ZXJyaWRlIHZpc2l0UGlwZShhc3Q6IEJpbmRpbmdQaXBlLCBjb250ZXh0OiBhbnkpOiBhbnkge1xuICAgIHRoaXMudXNlZFBpcGVzLmFkZChhc3QubmFtZSk7XG4gICAgaWYgKCF0aGlzLnNjb3BlLmlzRGVmZXJyZWQpIHtcbiAgICAgIHRoaXMuZWFnZXJQaXBlcy5hZGQoYXN0Lm5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gc3VwZXIudmlzaXRQaXBlKGFzdCwgY29udGV4dCk7XG4gIH1cblxuICAvLyBUaGVzZSBmaXZlIHR5cGVzIG9mIEFTVCBleHByZXNzaW9ucyBjYW4gcmVmZXIgdG8gZXhwcmVzc2lvbiByb290cywgd2hpY2ggY291bGQgYmUgdmFyaWFibGVzXG4gIC8vIG9yIHJlZmVyZW5jZXMgaW4gdGhlIGN1cnJlbnQgc2NvcGUuXG5cbiAgb3ZlcnJpZGUgdmlzaXRQcm9wZXJ0eVJlYWQoYXN0OiBQcm9wZXJ0eVJlYWQsIGNvbnRleHQ6IGFueSk6IGFueSB7XG4gICAgdGhpcy5tYXliZU1hcChhc3QsIGFzdC5uYW1lKTtcbiAgICByZXR1cm4gc3VwZXIudmlzaXRQcm9wZXJ0eVJlYWQoYXN0LCBjb250ZXh0KTtcbiAgfVxuXG4gIG92ZXJyaWRlIHZpc2l0U2FmZVByb3BlcnR5UmVhZChhc3Q6IFNhZmVQcm9wZXJ0eVJlYWQsIGNvbnRleHQ6IGFueSk6IGFueSB7XG4gICAgdGhpcy5tYXliZU1hcChhc3QsIGFzdC5uYW1lKTtcbiAgICByZXR1cm4gc3VwZXIudmlzaXRTYWZlUHJvcGVydHlSZWFkKGFzdCwgY29udGV4dCk7XG4gIH1cblxuICBvdmVycmlkZSB2aXNpdFByb3BlcnR5V3JpdGUoYXN0OiBQcm9wZXJ0eVdyaXRlLCBjb250ZXh0OiBhbnkpOiBhbnkge1xuICAgIHRoaXMubWF5YmVNYXAoYXN0LCBhc3QubmFtZSk7XG4gICAgcmV0dXJuIHN1cGVyLnZpc2l0UHJvcGVydHlXcml0ZShhc3QsIGNvbnRleHQpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbmdlc3RTY29wZWROb2RlKG5vZGU6IFNjb3BlZE5vZGUpIHtcbiAgICBjb25zdCBjaGlsZFNjb3BlID0gdGhpcy5zY29wZS5nZXRDaGlsZFNjb3BlKG5vZGUpO1xuICAgIGNvbnN0IGJpbmRlciA9IG5ldyBUZW1wbGF0ZUJpbmRlcihcbiAgICAgIHRoaXMuYmluZGluZ3MsXG4gICAgICB0aGlzLnN5bWJvbHMsXG4gICAgICB0aGlzLnVzZWRQaXBlcyxcbiAgICAgIHRoaXMuZWFnZXJQaXBlcyxcbiAgICAgIHRoaXMuZGVmZXJCbG9ja3MsXG4gICAgICB0aGlzLm5lc3RpbmdMZXZlbCxcbiAgICAgIGNoaWxkU2NvcGUsXG4gICAgICBub2RlLFxuICAgICAgdGhpcy5sZXZlbCArIDEsXG4gICAgKTtcbiAgICBiaW5kZXIuaW5nZXN0KG5vZGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBtYXliZU1hcChhc3Q6IFByb3BlcnR5UmVhZCB8IFNhZmVQcm9wZXJ0eVJlYWQgfCBQcm9wZXJ0eVdyaXRlLCBuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAvLyBJZiB0aGUgcmVjZWl2ZXIgb2YgdGhlIGV4cHJlc3Npb24gaXNuJ3QgdGhlIGBJbXBsaWNpdFJlY2VpdmVyYCwgdGhpcyBpc24ndCB0aGUgcm9vdCBvZiBhblxuICAgIC8vIGBBU1RgIGV4cHJlc3Npb24gdGhhdCBtYXBzIHRvIGEgYFZhcmlhYmxlYCBvciBgUmVmZXJlbmNlYC5cbiAgICBpZiAoIShhc3QucmVjZWl2ZXIgaW5zdGFuY2VvZiBJbXBsaWNpdFJlY2VpdmVyKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIG5hbWUgZXhpc3RzIGluIHRoZSBjdXJyZW50IHNjb3BlLiBJZiBzbywgbWFwIGl0LiBPdGhlcndpc2UsIHRoZSBuYW1lIGlzXG4gICAgLy8gcHJvYmFibHkgYSBwcm9wZXJ0eSBvbiB0aGUgdG9wLWxldmVsIGNvbXBvbmVudCBjb250ZXh0LlxuICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuc2NvcGUubG9va3VwKG5hbWUpO1xuXG4gICAgLy8gSXQncyBub3QgYWxsb3dlZCB0byByZWFkIHRlbXBsYXRlIGVudGl0aWVzIHZpYSBgdGhpc2AsIGhvd2V2ZXIgaXQgcHJldmlvdXNseSB3b3JrZWQgYnlcbiAgICAvLyBhY2NpZGVudCAoc2VlICM1NTExNSkuIFNpbmNlIGBAbGV0YCBkZWNsYXJhdGlvbnMgYXJlIG5ldywgd2UgY2FuIGZpeCBpdCBmcm9tIHRoZSBiZWdpbm5pbmcsXG4gICAgLy8gd2hlcmVhcyBwcmUtZXhpc3RpbmcgdGVtcGxhdGUgZW50aXRpZXMgd2lsbCBiZSBmaXhlZCBpbiAjNTUxMTUuXG4gICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIExldERlY2xhcmF0aW9uICYmIGFzdC5yZWNlaXZlciBpbnN0YW5jZW9mIFRoaXNSZWNlaXZlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0YXJnZXQgIT09IG51bGwpIHtcbiAgICAgIHRoaXMuYmluZGluZ3Muc2V0KGFzdCwgdGFyZ2V0KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBNZXRhZGF0YSBjb250YWluZXIgZm9yIGEgYFRhcmdldGAgdGhhdCBhbGxvd3MgcXVlcmllcyBmb3Igc3BlY2lmaWMgYml0cyBvZiBtZXRhZGF0YS5cbiAqXG4gKiBTZWUgYEJvdW5kVGFyZ2V0YCBmb3IgZG9jdW1lbnRhdGlvbiBvbiB0aGUgaW5kaXZpZHVhbCBtZXRob2RzLlxuICovXG5leHBvcnQgY2xhc3MgUjNCb3VuZFRhcmdldDxEaXJlY3RpdmVUIGV4dGVuZHMgRGlyZWN0aXZlTWV0YT4gaW1wbGVtZW50cyBCb3VuZFRhcmdldDxEaXJlY3RpdmVUPiB7XG4gIC8qKiBEZWZlcnJlZCBibG9ja3MsIG9yZGVyZWQgYXMgdGhleSBhcHBlYXIgaW4gdGhlIHRlbXBsYXRlLiAqL1xuICBwcml2YXRlIGRlZmVycmVkQmxvY2tzOiBEZWZlcnJlZEJsb2NrW107XG5cbiAgLyoqIE1hcCBvZiBkZWZlcnJlZCBibG9ja3MgdG8gdGhlaXIgc2NvcGUuICovXG4gIHByaXZhdGUgZGVmZXJyZWRTY29wZXM6IE1hcDxEZWZlcnJlZEJsb2NrLCBTY29wZT47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkgdGFyZ2V0OiBUYXJnZXQsXG4gICAgcHJpdmF0ZSBkaXJlY3RpdmVzOiBNYXA8RWxlbWVudCB8IFRlbXBsYXRlLCBEaXJlY3RpdmVUW10+LFxuICAgIHByaXZhdGUgZWFnZXJEaXJlY3RpdmVzOiBEaXJlY3RpdmVUW10sXG4gICAgcHJpdmF0ZSBiaW5kaW5nczogTWFwPFxuICAgICAgQm91bmRBdHRyaWJ1dGUgfCBCb3VuZEV2ZW50IHwgVGV4dEF0dHJpYnV0ZSxcbiAgICAgIERpcmVjdGl2ZVQgfCBFbGVtZW50IHwgVGVtcGxhdGVcbiAgICA+LFxuICAgIHByaXZhdGUgcmVmZXJlbmNlczogTWFwPFxuICAgICAgQm91bmRBdHRyaWJ1dGUgfCBCb3VuZEV2ZW50IHwgUmVmZXJlbmNlIHwgVGV4dEF0dHJpYnV0ZSxcbiAgICAgIHtkaXJlY3RpdmU6IERpcmVjdGl2ZVQ7IG5vZGU6IEVsZW1lbnQgfCBUZW1wbGF0ZX0gfCBFbGVtZW50IHwgVGVtcGxhdGVcbiAgICA+LFxuICAgIHByaXZhdGUgZXhwclRhcmdldHM6IE1hcDxBU1QsIFRlbXBsYXRlRW50aXR5PixcbiAgICBwcml2YXRlIHN5bWJvbHM6IE1hcDxUZW1wbGF0ZUVudGl0eSwgVGVtcGxhdGU+LFxuICAgIHByaXZhdGUgbmVzdGluZ0xldmVsOiBNYXA8U2NvcGVkTm9kZSwgbnVtYmVyPixcbiAgICBwcml2YXRlIHNjb3BlZE5vZGVFbnRpdGllczogTWFwPFNjb3BlZE5vZGUgfCBudWxsLCBSZWFkb25seVNldDxUZW1wbGF0ZUVudGl0eT4+LFxuICAgIHByaXZhdGUgdXNlZFBpcGVzOiBTZXQ8c3RyaW5nPixcbiAgICBwcml2YXRlIGVhZ2VyUGlwZXM6IFNldDxzdHJpbmc+LFxuICAgIHJhd0RlZmVycmVkOiBbRGVmZXJyZWRCbG9jaywgU2NvcGVdW10sXG4gICkge1xuICAgIHRoaXMuZGVmZXJyZWRCbG9ja3MgPSByYXdEZWZlcnJlZC5tYXAoKGN1cnJlbnQpID0+IGN1cnJlbnRbMF0pO1xuICAgIHRoaXMuZGVmZXJyZWRTY29wZXMgPSBuZXcgTWFwKHJhd0RlZmVycmVkKTtcbiAgfVxuXG4gIGdldEVudGl0aWVzSW5TY29wZShub2RlOiBTY29wZWROb2RlIHwgbnVsbCk6IFJlYWRvbmx5U2V0PFRlbXBsYXRlRW50aXR5PiB7XG4gICAgcmV0dXJuIHRoaXMuc2NvcGVkTm9kZUVudGl0aWVzLmdldChub2RlKSA/PyBuZXcgU2V0KCk7XG4gIH1cblxuICBnZXREaXJlY3RpdmVzT2ZOb2RlKG5vZGU6IEVsZW1lbnQgfCBUZW1wbGF0ZSk6IERpcmVjdGl2ZVRbXSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmRpcmVjdGl2ZXMuZ2V0KG5vZGUpIHx8IG51bGw7XG4gIH1cblxuICBnZXRSZWZlcmVuY2VUYXJnZXQocmVmOiBSZWZlcmVuY2UpOiBSZWZlcmVuY2VUYXJnZXQ8RGlyZWN0aXZlVD4gfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5yZWZlcmVuY2VzLmdldChyZWYpIHx8IG51bGw7XG4gIH1cblxuICBnZXRDb25zdW1lck9mQmluZGluZyhcbiAgICBiaW5kaW5nOiBCb3VuZEF0dHJpYnV0ZSB8IEJvdW5kRXZlbnQgfCBUZXh0QXR0cmlidXRlLFxuICApOiBEaXJlY3RpdmVUIHwgRWxlbWVudCB8IFRlbXBsYXRlIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuYmluZGluZ3MuZ2V0KGJpbmRpbmcpIHx8IG51bGw7XG4gIH1cblxuICBnZXRFeHByZXNzaW9uVGFyZ2V0KGV4cHI6IEFTVCk6IFRlbXBsYXRlRW50aXR5IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZXhwclRhcmdldHMuZ2V0KGV4cHIpIHx8IG51bGw7XG4gIH1cblxuICBnZXREZWZpbml0aW9uTm9kZU9mU3ltYm9sKHN5bWJvbDogVGVtcGxhdGVFbnRpdHkpOiBTY29wZWROb2RlIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuc3ltYm9scy5nZXQoc3ltYm9sKSB8fCBudWxsO1xuICB9XG5cbiAgZ2V0TmVzdGluZ0xldmVsKG5vZGU6IFNjb3BlZE5vZGUpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm5lc3RpbmdMZXZlbC5nZXQobm9kZSkgfHwgMDtcbiAgfVxuXG4gIGdldFVzZWREaXJlY3RpdmVzKCk6IERpcmVjdGl2ZVRbXSB7XG4gICAgY29uc3Qgc2V0ID0gbmV3IFNldDxEaXJlY3RpdmVUPigpO1xuICAgIHRoaXMuZGlyZWN0aXZlcy5mb3JFYWNoKChkaXJzKSA9PiBkaXJzLmZvckVhY2goKGRpcikgPT4gc2V0LmFkZChkaXIpKSk7XG4gICAgcmV0dXJuIEFycmF5LmZyb20oc2V0LnZhbHVlcygpKTtcbiAgfVxuXG4gIGdldEVhZ2VybHlVc2VkRGlyZWN0aXZlcygpOiBEaXJlY3RpdmVUW10ge1xuICAgIGNvbnN0IHNldCA9IG5ldyBTZXQ8RGlyZWN0aXZlVD4odGhpcy5lYWdlckRpcmVjdGl2ZXMpO1xuICAgIHJldHVybiBBcnJheS5mcm9tKHNldC52YWx1ZXMoKSk7XG4gIH1cblxuICBnZXRVc2VkUGlwZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMudXNlZFBpcGVzKTtcbiAgfVxuXG4gIGdldEVhZ2VybHlVc2VkUGlwZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuZWFnZXJQaXBlcyk7XG4gIH1cblxuICBnZXREZWZlckJsb2NrcygpOiBEZWZlcnJlZEJsb2NrW10ge1xuICAgIHJldHVybiB0aGlzLmRlZmVycmVkQmxvY2tzO1xuICB9XG5cbiAgZ2V0RGVmZXJyZWRUcmlnZ2VyVGFyZ2V0KGJsb2NrOiBEZWZlcnJlZEJsb2NrLCB0cmlnZ2VyOiBEZWZlcnJlZFRyaWdnZXIpOiBFbGVtZW50IHwgbnVsbCB7XG4gICAgLy8gT25seSB0cmlnZ2VycyB0aGF0IHJlZmVyIHRvIERPTSBub2RlcyBjYW4gYmUgcmVzb2x2ZWQuXG4gICAgaWYgKFxuICAgICAgISh0cmlnZ2VyIGluc3RhbmNlb2YgSW50ZXJhY3Rpb25EZWZlcnJlZFRyaWdnZXIpICYmXG4gICAgICAhKHRyaWdnZXIgaW5zdGFuY2VvZiBWaWV3cG9ydERlZmVycmVkVHJpZ2dlcikgJiZcbiAgICAgICEodHJpZ2dlciBpbnN0YW5jZW9mIEhvdmVyRGVmZXJyZWRUcmlnZ2VyKVxuICAgICkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgbmFtZSA9IHRyaWdnZXIucmVmZXJlbmNlO1xuXG4gICAgaWYgKG5hbWUgPT09IG51bGwpIHtcbiAgICAgIGxldCB0cmlnZ2VyOiBFbGVtZW50IHwgbnVsbCA9IG51bGw7XG5cbiAgICAgIGlmIChibG9jay5wbGFjZWhvbGRlciAhPT0gbnVsbCkge1xuICAgICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIGJsb2NrLnBsYWNlaG9sZGVyLmNoaWxkcmVuKSB7XG4gICAgICAgICAgLy8gU2tpcCBvdmVyIGNvbW1lbnQgbm9kZXMuIEN1cnJlbnRseSBieSBkZWZhdWx0IHRoZSB0ZW1wbGF0ZSBwYXJzZXIgZG9lc24ndCBjYXB0dXJlXG4gICAgICAgICAgLy8gY29tbWVudHMsIGJ1dCB3ZSBoYXZlIGEgc2FmZWd1YXJkIGhlcmUganVzdCBpbiBjYXNlIHNpbmNlIGl0IGNhbiBiZSBlbmFibGVkLlxuICAgICAgICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIENvbW1lbnQpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFdlIGNhbiBvbmx5IGluZmVyIHRoZSB0cmlnZ2VyIGlmIHRoZXJlJ3Mgb25lIHJvb3QgZWxlbWVudCBub2RlLiBBbnkgb3RoZXJcbiAgICAgICAgICAvLyBub2RlcyBhdCB0aGUgcm9vdCBtYWtlIGl0IHNvIHRoYXQgd2UgY2FuJ3QgaW5mZXIgdGhlIHRyaWdnZXIgYW55bW9yZS5cbiAgICAgICAgICBpZiAodHJpZ2dlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgICAgICAgdHJpZ2dlciA9IGNoaWxkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJpZ2dlcjtcbiAgICB9XG5cbiAgICBjb25zdCBvdXRzaWRlUmVmID0gdGhpcy5maW5kRW50aXR5SW5TY29wZShibG9jaywgbmFtZSk7XG5cbiAgICAvLyBGaXJzdCB0cnkgdG8gcmVzb2x2ZSB0aGUgdGFyZ2V0IGluIHRoZSBzY29wZSBvZiB0aGUgbWFpbiBkZWZlcnJlZCBibG9jay4gTm90ZSB0aGF0IHdlXG4gICAgLy8gc2tpcCB0cmlnZ2VycyBkZWZpbmVkIGluc2lkZSB0aGUgbWFpbiBibG9jayBpdHNlbGYsIGJlY2F1c2UgdGhleSBtaWdodCBub3QgZXhpc3QgeWV0LlxuICAgIGlmIChvdXRzaWRlUmVmIGluc3RhbmNlb2YgUmVmZXJlbmNlICYmIHRoaXMuZ2V0RGVmaW5pdGlvbk5vZGVPZlN5bWJvbChvdXRzaWRlUmVmKSAhPT0gYmxvY2spIHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuZ2V0UmVmZXJlbmNlVGFyZ2V0KG91dHNpZGVSZWYpO1xuXG4gICAgICBpZiAodGFyZ2V0ICE9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlZmVyZW5jZVRhcmdldFRvRWxlbWVudCh0YXJnZXQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIHRoZSB0cmlnZ2VyIGNvdWxkbid0IGJlIGZvdW5kIGluIHRoZSBtYWluIGJsb2NrLCBjaGVjayB0aGVcbiAgICAvLyBwbGFjZWhvbGRlciBibG9jayB3aGljaCBpcyBzaG93biBiZWZvcmUgdGhlIG1haW4gYmxvY2sgaGFzIGxvYWRlZC5cbiAgICBpZiAoYmxvY2sucGxhY2Vob2xkZXIgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IHJlZkluUGxhY2Vob2xkZXIgPSB0aGlzLmZpbmRFbnRpdHlJblNjb3BlKGJsb2NrLnBsYWNlaG9sZGVyLCBuYW1lKTtcbiAgICAgIGNvbnN0IHRhcmdldEluUGxhY2Vob2xkZXIgPVxuICAgICAgICByZWZJblBsYWNlaG9sZGVyIGluc3RhbmNlb2YgUmVmZXJlbmNlID8gdGhpcy5nZXRSZWZlcmVuY2VUYXJnZXQocmVmSW5QbGFjZWhvbGRlcikgOiBudWxsO1xuXG4gICAgICBpZiAodGFyZ2V0SW5QbGFjZWhvbGRlciAhPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWZlcmVuY2VUYXJnZXRUb0VsZW1lbnQodGFyZ2V0SW5QbGFjZWhvbGRlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpc0RlZmVycmVkKGVsZW1lbnQ6IEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICBmb3IgKGNvbnN0IGJsb2NrIG9mIHRoaXMuZGVmZXJyZWRCbG9ja3MpIHtcbiAgICAgIGlmICghdGhpcy5kZWZlcnJlZFNjb3Blcy5oYXMoYmxvY2spKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdGFjazogU2NvcGVbXSA9IFt0aGlzLmRlZmVycmVkU2NvcGVzLmdldChibG9jaykhXTtcblxuICAgICAgd2hpbGUgKHN0YWNrLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgY3VycmVudCA9IHN0YWNrLnBvcCgpITtcblxuICAgICAgICBpZiAoY3VycmVudC5lbGVtZW50c0luU2NvcGUuaGFzKGVsZW1lbnQpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBzdGFjay5wdXNoKC4uLmN1cnJlbnQuY2hpbGRTY29wZXMudmFsdWVzKCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyBhbiBlbnRpdHkgd2l0aCBhIHNwZWNpZmljIG5hbWUgaW4gYSBzY29wZS5cbiAgICogQHBhcmFtIHJvb3ROb2RlIFJvb3Qgbm9kZSBvZiB0aGUgc2NvcGUuXG4gICAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgdGhlIGVudGl0eS5cbiAgICovXG4gIHByaXZhdGUgZmluZEVudGl0eUluU2NvcGUocm9vdE5vZGU6IFNjb3BlZE5vZGUsIG5hbWU6IHN0cmluZyk6IFRlbXBsYXRlRW50aXR5IHwgbnVsbCB7XG4gICAgY29uc3QgZW50aXRpZXMgPSB0aGlzLmdldEVudGl0aWVzSW5TY29wZShyb290Tm9kZSk7XG5cbiAgICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlbnRpdGllcykge1xuICAgICAgaWYgKGVudGl0eS5uYW1lID09PSBuYW1lKSB7XG4gICAgICAgIHJldHVybiBlbnRpdHk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKiogQ29lcmNlcyBhIGBSZWZlcmVuY2VUYXJnZXRgIHRvIGFuIGBFbGVtZW50YCwgaWYgcG9zc2libGUuICovXG4gIHByaXZhdGUgcmVmZXJlbmNlVGFyZ2V0VG9FbGVtZW50KHRhcmdldDogUmVmZXJlbmNlVGFyZ2V0PERpcmVjdGl2ZVQ+KTogRWxlbWVudCB8IG51bGwge1xuICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cblxuICAgIGlmICh0YXJnZXQgaW5zdGFuY2VvZiBUZW1wbGF0ZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVmZXJlbmNlVGFyZ2V0VG9FbGVtZW50KHRhcmdldC5ub2RlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBleHRyYWN0U2NvcGVkTm9kZUVudGl0aWVzKHJvb3RTY29wZTogU2NvcGUpOiBNYXA8U2NvcGVkTm9kZSB8IG51bGwsIFNldDxUZW1wbGF0ZUVudGl0eT4+IHtcbiAgY29uc3QgZW50aXR5TWFwID0gbmV3IE1hcDxTY29wZWROb2RlIHwgbnVsbCwgTWFwPHN0cmluZywgVGVtcGxhdGVFbnRpdHk+PigpO1xuXG4gIGZ1bmN0aW9uIGV4dHJhY3RTY29wZUVudGl0aWVzKHNjb3BlOiBTY29wZSk6IE1hcDxzdHJpbmcsIFRlbXBsYXRlRW50aXR5PiB7XG4gICAgaWYgKGVudGl0eU1hcC5oYXMoc2NvcGUucm9vdE5vZGUpKSB7XG4gICAgICByZXR1cm4gZW50aXR5TWFwLmdldChzY29wZS5yb290Tm9kZSkhO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnRFbnRpdGllcyA9IHNjb3BlLm5hbWVkRW50aXRpZXM7XG5cbiAgICBsZXQgZW50aXRpZXM6IE1hcDxzdHJpbmcsIFRlbXBsYXRlRW50aXR5PjtcbiAgICBpZiAoc2NvcGUucGFyZW50U2NvcGUgIT09IG51bGwpIHtcbiAgICAgIGVudGl0aWVzID0gbmV3IE1hcChbLi4uZXh0cmFjdFNjb3BlRW50aXRpZXMoc2NvcGUucGFyZW50U2NvcGUpLCAuLi5jdXJyZW50RW50aXRpZXNdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW50aXRpZXMgPSBuZXcgTWFwKGN1cnJlbnRFbnRpdGllcyk7XG4gICAgfVxuXG4gICAgZW50aXR5TWFwLnNldChzY29wZS5yb290Tm9kZSwgZW50aXRpZXMpO1xuICAgIHJldHVybiBlbnRpdGllcztcbiAgfVxuXG4gIGNvbnN0IHNjb3Blc1RvUHJvY2VzczogU2NvcGVbXSA9IFtyb290U2NvcGVdO1xuICB3aGlsZSAoc2NvcGVzVG9Qcm9jZXNzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBzY29wZSA9IHNjb3Blc1RvUHJvY2Vzcy5wb3AoKSE7XG4gICAgZm9yIChjb25zdCBjaGlsZFNjb3BlIG9mIHNjb3BlLmNoaWxkU2NvcGVzLnZhbHVlcygpKSB7XG4gICAgICBzY29wZXNUb1Byb2Nlc3MucHVzaChjaGlsZFNjb3BlKTtcbiAgICB9XG4gICAgZXh0cmFjdFNjb3BlRW50aXRpZXMoc2NvcGUpO1xuICB9XG5cbiAgY29uc3QgdGVtcGxhdGVFbnRpdGllcyA9IG5ldyBNYXA8U2NvcGVkTm9kZSB8IG51bGwsIFNldDxUZW1wbGF0ZUVudGl0eT4+KCk7XG4gIGZvciAoY29uc3QgW3RlbXBsYXRlLCBlbnRpdGllc10gb2YgZW50aXR5TWFwKSB7XG4gICAgdGVtcGxhdGVFbnRpdGllcy5zZXQodGVtcGxhdGUsIG5ldyBTZXQoZW50aXRpZXMudmFsdWVzKCkpKTtcbiAgfVxuICByZXR1cm4gdGVtcGxhdGVFbnRpdGllcztcbn1cbiJdfQ==
|