@angular/compiler 19.0.0-next.1 → 19.0.0-next.11
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,421 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7
|
-
*/
|
|
8
|
-
import { EmptyExpr } from '../expression_parser/ast';
|
|
9
|
-
import * as html from '../ml_parser/ast';
|
|
10
|
-
import { ParseError, ParseSourceSpan } from '../parse_util';
|
|
11
|
-
import * as t from './r3_ast';
|
|
12
|
-
/** Pattern for the expression in a for loop block. */
|
|
13
|
-
const FOR_LOOP_EXPRESSION_PATTERN = /^\s*([0-9A-Za-z_$]*)\s+of\s+([\S\s]*)/;
|
|
14
|
-
/** Pattern for the tracking expression in a for loop block. */
|
|
15
|
-
const FOR_LOOP_TRACK_PATTERN = /^track\s+([\S\s]*)/;
|
|
16
|
-
/** Pattern for the `as` expression in a conditional block. */
|
|
17
|
-
const CONDITIONAL_ALIAS_PATTERN = /^(as\s)+(.*)/;
|
|
18
|
-
/** Pattern used to identify an `else if` block. */
|
|
19
|
-
const ELSE_IF_PATTERN = /^else[^\S\r\n]+if/;
|
|
20
|
-
/** Pattern used to identify a `let` parameter. */
|
|
21
|
-
const FOR_LOOP_LET_PATTERN = /^let\s+([\S\s]*)/;
|
|
22
|
-
/**
|
|
23
|
-
* Pattern to group a string into leading whitespace, non whitespace, and trailing whitespace.
|
|
24
|
-
* Useful for getting the variable name span when a span can contain leading and trailing space.
|
|
25
|
-
*/
|
|
26
|
-
const CHARACTERS_IN_SURROUNDING_WHITESPACE_PATTERN = /(\s*)(\S+)(\s*)/;
|
|
27
|
-
/** Names of variables that are allowed to be used in the `let` expression of a `for` loop. */
|
|
28
|
-
const ALLOWED_FOR_LOOP_LET_VARIABLES = new Set([
|
|
29
|
-
'$index',
|
|
30
|
-
'$first',
|
|
31
|
-
'$last',
|
|
32
|
-
'$even',
|
|
33
|
-
'$odd',
|
|
34
|
-
'$count',
|
|
35
|
-
]);
|
|
36
|
-
/**
|
|
37
|
-
* Predicate function that determines if a block with
|
|
38
|
-
* a specific name cam be connected to a `for` block.
|
|
39
|
-
*/
|
|
40
|
-
export function isConnectedForLoopBlock(name) {
|
|
41
|
-
return name === 'empty';
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Predicate function that determines if a block with
|
|
45
|
-
* a specific name cam be connected to an `if` block.
|
|
46
|
-
*/
|
|
47
|
-
export function isConnectedIfLoopBlock(name) {
|
|
48
|
-
return name === 'else' || ELSE_IF_PATTERN.test(name);
|
|
49
|
-
}
|
|
50
|
-
/** Creates an `if` loop block from an HTML AST node. */
|
|
51
|
-
export function createIfBlock(ast, connectedBlocks, visitor, bindingParser) {
|
|
52
|
-
const errors = validateIfConnectedBlocks(connectedBlocks);
|
|
53
|
-
const branches = [];
|
|
54
|
-
const mainBlockParams = parseConditionalBlockParameters(ast, errors, bindingParser);
|
|
55
|
-
if (mainBlockParams !== null) {
|
|
56
|
-
branches.push(new t.IfBlockBranch(mainBlockParams.expression, html.visitAll(visitor, ast.children, ast.children), mainBlockParams.expressionAlias, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan, ast.nameSpan, ast.i18n));
|
|
57
|
-
}
|
|
58
|
-
for (const block of connectedBlocks) {
|
|
59
|
-
if (ELSE_IF_PATTERN.test(block.name)) {
|
|
60
|
-
const params = parseConditionalBlockParameters(block, errors, bindingParser);
|
|
61
|
-
if (params !== null) {
|
|
62
|
-
const children = html.visitAll(visitor, block.children, block.children);
|
|
63
|
-
branches.push(new t.IfBlockBranch(params.expression, children, params.expressionAlias, block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan, block.i18n));
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
else if (block.name === 'else') {
|
|
67
|
-
const children = html.visitAll(visitor, block.children, block.children);
|
|
68
|
-
branches.push(new t.IfBlockBranch(null, children, null, block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan, block.i18n));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// The outer IfBlock should have a span that encapsulates all branches.
|
|
72
|
-
const ifBlockStartSourceSpan = branches.length > 0 ? branches[0].startSourceSpan : ast.startSourceSpan;
|
|
73
|
-
const ifBlockEndSourceSpan = branches.length > 0 ? branches[branches.length - 1].endSourceSpan : ast.endSourceSpan;
|
|
74
|
-
let wholeSourceSpan = ast.sourceSpan;
|
|
75
|
-
const lastBranch = branches[branches.length - 1];
|
|
76
|
-
if (lastBranch !== undefined) {
|
|
77
|
-
wholeSourceSpan = new ParseSourceSpan(ifBlockStartSourceSpan.start, lastBranch.sourceSpan.end);
|
|
78
|
-
}
|
|
79
|
-
return {
|
|
80
|
-
node: new t.IfBlock(branches, wholeSourceSpan, ast.startSourceSpan, ifBlockEndSourceSpan, ast.nameSpan),
|
|
81
|
-
errors,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
/** Creates a `for` loop block from an HTML AST node. */
|
|
85
|
-
export function createForLoop(ast, connectedBlocks, visitor, bindingParser) {
|
|
86
|
-
const errors = [];
|
|
87
|
-
const params = parseForLoopParameters(ast, errors, bindingParser);
|
|
88
|
-
let node = null;
|
|
89
|
-
let empty = null;
|
|
90
|
-
for (const block of connectedBlocks) {
|
|
91
|
-
if (block.name === 'empty') {
|
|
92
|
-
if (empty !== null) {
|
|
93
|
-
errors.push(new ParseError(block.sourceSpan, '@for loop can only have one @empty block'));
|
|
94
|
-
}
|
|
95
|
-
else if (block.parameters.length > 0) {
|
|
96
|
-
errors.push(new ParseError(block.sourceSpan, '@empty block cannot have parameters'));
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
empty = new t.ForLoopBlockEmpty(html.visitAll(visitor, block.children, block.children), block.sourceSpan, block.startSourceSpan, block.endSourceSpan, block.nameSpan, block.i18n);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
errors.push(new ParseError(block.sourceSpan, `Unrecognized @for loop block "${block.name}"`));
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (params !== null) {
|
|
107
|
-
if (params.trackBy === null) {
|
|
108
|
-
// TODO: We should not fail here, and instead try to produce some AST for the language
|
|
109
|
-
// service.
|
|
110
|
-
errors.push(new ParseError(ast.sourceSpan, '@for loop must have a "track" expression'));
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
// The `for` block has a main span that includes the `empty` branch. For only the span of the
|
|
114
|
-
// main `for` body, use `mainSourceSpan`.
|
|
115
|
-
const endSpan = empty?.endSourceSpan ?? ast.endSourceSpan;
|
|
116
|
-
const sourceSpan = new ParseSourceSpan(ast.sourceSpan.start, endSpan?.end ?? ast.sourceSpan.end);
|
|
117
|
-
node = new t.ForLoopBlock(params.itemName, params.expression, params.trackBy.expression, params.trackBy.keywordSpan, params.context, html.visitAll(visitor, ast.children, ast.children), empty, sourceSpan, ast.sourceSpan, ast.startSourceSpan, endSpan, ast.nameSpan, ast.i18n);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return { node, errors };
|
|
121
|
-
}
|
|
122
|
-
/** Creates a switch block from an HTML AST node. */
|
|
123
|
-
export function createSwitchBlock(ast, visitor, bindingParser) {
|
|
124
|
-
const errors = validateSwitchBlock(ast);
|
|
125
|
-
const primaryExpression = ast.parameters.length > 0
|
|
126
|
-
? parseBlockParameterToBinding(ast.parameters[0], bindingParser)
|
|
127
|
-
: bindingParser.parseBinding('', false, ast.sourceSpan, 0);
|
|
128
|
-
const cases = [];
|
|
129
|
-
const unknownBlocks = [];
|
|
130
|
-
let defaultCase = null;
|
|
131
|
-
// Here we assume that all the blocks are valid given that we validated them above.
|
|
132
|
-
for (const node of ast.children) {
|
|
133
|
-
if (!(node instanceof html.Block)) {
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
if ((node.name !== 'case' || node.parameters.length === 0) && node.name !== 'default') {
|
|
137
|
-
unknownBlocks.push(new t.UnknownBlock(node.name, node.sourceSpan, node.nameSpan));
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
const expression = node.name === 'case' ? parseBlockParameterToBinding(node.parameters[0], bindingParser) : null;
|
|
141
|
-
const ast = new t.SwitchBlockCase(expression, html.visitAll(visitor, node.children, node.children), node.sourceSpan, node.startSourceSpan, node.endSourceSpan, node.nameSpan, node.i18n);
|
|
142
|
-
if (expression === null) {
|
|
143
|
-
defaultCase = ast;
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
cases.push(ast);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
// Ensure that the default case is last in the array.
|
|
150
|
-
if (defaultCase !== null) {
|
|
151
|
-
cases.push(defaultCase);
|
|
152
|
-
}
|
|
153
|
-
return {
|
|
154
|
-
node: new t.SwitchBlock(primaryExpression, cases, unknownBlocks, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan, ast.nameSpan),
|
|
155
|
-
errors,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
/** Parses the parameters of a `for` loop block. */
|
|
159
|
-
function parseForLoopParameters(block, errors, bindingParser) {
|
|
160
|
-
if (block.parameters.length === 0) {
|
|
161
|
-
errors.push(new ParseError(block.sourceSpan, '@for loop does not have an expression'));
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
164
|
-
const [expressionParam, ...secondaryParams] = block.parameters;
|
|
165
|
-
const match = stripOptionalParentheses(expressionParam, errors)?.match(FOR_LOOP_EXPRESSION_PATTERN);
|
|
166
|
-
if (!match || match[2].trim().length === 0) {
|
|
167
|
-
errors.push(new ParseError(expressionParam.sourceSpan, 'Cannot parse expression. @for loop expression must match the pattern "<identifier> of <expression>"'));
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
const [, itemName, rawExpression] = match;
|
|
171
|
-
if (ALLOWED_FOR_LOOP_LET_VARIABLES.has(itemName)) {
|
|
172
|
-
errors.push(new ParseError(expressionParam.sourceSpan, `@for loop item name cannot be one of ${Array.from(ALLOWED_FOR_LOOP_LET_VARIABLES).join(', ')}.`));
|
|
173
|
-
}
|
|
174
|
-
// `expressionParam.expression` contains the variable declaration and the expression of the
|
|
175
|
-
// for...of statement, i.e. 'user of users' The variable of a ForOfStatement is _only_ the "const
|
|
176
|
-
// user" part and does not include "of x".
|
|
177
|
-
const variableName = expressionParam.expression.split(' ')[0];
|
|
178
|
-
const variableSpan = new ParseSourceSpan(expressionParam.sourceSpan.start, expressionParam.sourceSpan.start.moveBy(variableName.length));
|
|
179
|
-
const result = {
|
|
180
|
-
itemName: new t.Variable(itemName, '$implicit', variableSpan, variableSpan),
|
|
181
|
-
trackBy: null,
|
|
182
|
-
expression: parseBlockParameterToBinding(expressionParam, bindingParser, rawExpression),
|
|
183
|
-
context: Array.from(ALLOWED_FOR_LOOP_LET_VARIABLES, (variableName) => {
|
|
184
|
-
// Give ambiently-available context variables empty spans at the end of
|
|
185
|
-
// the start of the `for` block, since they are not explicitly defined.
|
|
186
|
-
const emptySpanAfterForBlockStart = new ParseSourceSpan(block.startSourceSpan.end, block.startSourceSpan.end);
|
|
187
|
-
return new t.Variable(variableName, variableName, emptySpanAfterForBlockStart, emptySpanAfterForBlockStart);
|
|
188
|
-
}),
|
|
189
|
-
};
|
|
190
|
-
for (const param of secondaryParams) {
|
|
191
|
-
const letMatch = param.expression.match(FOR_LOOP_LET_PATTERN);
|
|
192
|
-
if (letMatch !== null) {
|
|
193
|
-
const variablesSpan = new ParseSourceSpan(param.sourceSpan.start.moveBy(letMatch[0].length - letMatch[1].length), param.sourceSpan.end);
|
|
194
|
-
parseLetParameter(param.sourceSpan, letMatch[1], variablesSpan, itemName, result.context, errors);
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
const trackMatch = param.expression.match(FOR_LOOP_TRACK_PATTERN);
|
|
198
|
-
if (trackMatch !== null) {
|
|
199
|
-
if (result.trackBy !== null) {
|
|
200
|
-
errors.push(new ParseError(param.sourceSpan, '@for loop can only have one "track" expression'));
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
const expression = parseBlockParameterToBinding(param, bindingParser, trackMatch[1]);
|
|
204
|
-
if (expression.ast instanceof EmptyExpr) {
|
|
205
|
-
errors.push(new ParseError(param.sourceSpan, '@for loop must have a "track" expression'));
|
|
206
|
-
}
|
|
207
|
-
const keywordSpan = new ParseSourceSpan(param.sourceSpan.start, param.sourceSpan.start.moveBy('track'.length));
|
|
208
|
-
result.trackBy = { expression, keywordSpan };
|
|
209
|
-
}
|
|
210
|
-
continue;
|
|
211
|
-
}
|
|
212
|
-
errors.push(new ParseError(param.sourceSpan, `Unrecognized @for loop paramater "${param.expression}"`));
|
|
213
|
-
}
|
|
214
|
-
return result;
|
|
215
|
-
}
|
|
216
|
-
/** Parses the `let` parameter of a `for` loop block. */
|
|
217
|
-
function parseLetParameter(sourceSpan, expression, span, loopItemName, context, errors) {
|
|
218
|
-
const parts = expression.split(',');
|
|
219
|
-
let startSpan = span.start;
|
|
220
|
-
for (const part of parts) {
|
|
221
|
-
const expressionParts = part.split('=');
|
|
222
|
-
const name = expressionParts.length === 2 ? expressionParts[0].trim() : '';
|
|
223
|
-
const variableName = expressionParts.length === 2 ? expressionParts[1].trim() : '';
|
|
224
|
-
if (name.length === 0 || variableName.length === 0) {
|
|
225
|
-
errors.push(new ParseError(sourceSpan, `Invalid @for loop "let" parameter. Parameter should match the pattern "<name> = <variable name>"`));
|
|
226
|
-
}
|
|
227
|
-
else if (!ALLOWED_FOR_LOOP_LET_VARIABLES.has(variableName)) {
|
|
228
|
-
errors.push(new ParseError(sourceSpan, `Unknown "let" parameter variable "${variableName}". The allowed variables are: ${Array.from(ALLOWED_FOR_LOOP_LET_VARIABLES).join(', ')}`));
|
|
229
|
-
}
|
|
230
|
-
else if (name === loopItemName) {
|
|
231
|
-
errors.push(new ParseError(sourceSpan, `Invalid @for loop "let" parameter. Variable cannot be called "${loopItemName}"`));
|
|
232
|
-
}
|
|
233
|
-
else if (context.some((v) => v.name === name)) {
|
|
234
|
-
errors.push(new ParseError(sourceSpan, `Duplicate "let" parameter variable "${variableName}"`));
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
const [, keyLeadingWhitespace, keyName] = expressionParts[0].match(CHARACTERS_IN_SURROUNDING_WHITESPACE_PATTERN) ?? [];
|
|
238
|
-
const keySpan = keyLeadingWhitespace !== undefined && expressionParts.length === 2
|
|
239
|
-
? new ParseSourceSpan(
|
|
240
|
-
/* strip leading spaces */
|
|
241
|
-
startSpan.moveBy(keyLeadingWhitespace.length),
|
|
242
|
-
/* advance to end of the variable name */
|
|
243
|
-
startSpan.moveBy(keyLeadingWhitespace.length + keyName.length))
|
|
244
|
-
: span;
|
|
245
|
-
let valueSpan = undefined;
|
|
246
|
-
if (expressionParts.length === 2) {
|
|
247
|
-
const [, valueLeadingWhitespace, implicit] = expressionParts[1].match(CHARACTERS_IN_SURROUNDING_WHITESPACE_PATTERN) ?? [];
|
|
248
|
-
valueSpan =
|
|
249
|
-
valueLeadingWhitespace !== undefined
|
|
250
|
-
? new ParseSourceSpan(startSpan.moveBy(expressionParts[0].length + 1 + valueLeadingWhitespace.length), startSpan.moveBy(expressionParts[0].length + 1 + valueLeadingWhitespace.length + implicit.length))
|
|
251
|
-
: undefined;
|
|
252
|
-
}
|
|
253
|
-
const sourceSpan = new ParseSourceSpan(keySpan.start, valueSpan?.end ?? keySpan.end);
|
|
254
|
-
context.push(new t.Variable(name, variableName, sourceSpan, keySpan, valueSpan));
|
|
255
|
-
}
|
|
256
|
-
startSpan = startSpan.moveBy(part.length + 1 /* add 1 to move past the comma */);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Checks that the shape of the blocks connected to an
|
|
261
|
-
* `@if` block is correct. Returns an array of errors.
|
|
262
|
-
*/
|
|
263
|
-
function validateIfConnectedBlocks(connectedBlocks) {
|
|
264
|
-
const errors = [];
|
|
265
|
-
let hasElse = false;
|
|
266
|
-
for (let i = 0; i < connectedBlocks.length; i++) {
|
|
267
|
-
const block = connectedBlocks[i];
|
|
268
|
-
if (block.name === 'else') {
|
|
269
|
-
if (hasElse) {
|
|
270
|
-
errors.push(new ParseError(block.sourceSpan, 'Conditional can only have one @else block'));
|
|
271
|
-
}
|
|
272
|
-
else if (connectedBlocks.length > 1 && i < connectedBlocks.length - 1) {
|
|
273
|
-
errors.push(new ParseError(block.sourceSpan, '@else block must be last inside the conditional'));
|
|
274
|
-
}
|
|
275
|
-
else if (block.parameters.length > 0) {
|
|
276
|
-
errors.push(new ParseError(block.sourceSpan, '@else block cannot have parameters'));
|
|
277
|
-
}
|
|
278
|
-
hasElse = true;
|
|
279
|
-
}
|
|
280
|
-
else if (!ELSE_IF_PATTERN.test(block.name)) {
|
|
281
|
-
errors.push(new ParseError(block.sourceSpan, `Unrecognized conditional block @${block.name}`));
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
return errors;
|
|
285
|
-
}
|
|
286
|
-
/** Checks that the shape of a `switch` block is valid. Returns an array of errors. */
|
|
287
|
-
function validateSwitchBlock(ast) {
|
|
288
|
-
const errors = [];
|
|
289
|
-
let hasDefault = false;
|
|
290
|
-
if (ast.parameters.length !== 1) {
|
|
291
|
-
errors.push(new ParseError(ast.sourceSpan, '@switch block must have exactly one parameter'));
|
|
292
|
-
return errors;
|
|
293
|
-
}
|
|
294
|
-
for (const node of ast.children) {
|
|
295
|
-
// Skip over comments and empty text nodes inside the switch block.
|
|
296
|
-
// Empty text nodes can be used for formatting while comments don't affect the runtime.
|
|
297
|
-
if (node instanceof html.Comment ||
|
|
298
|
-
(node instanceof html.Text && node.value.trim().length === 0)) {
|
|
299
|
-
continue;
|
|
300
|
-
}
|
|
301
|
-
if (!(node instanceof html.Block) || (node.name !== 'case' && node.name !== 'default')) {
|
|
302
|
-
errors.push(new ParseError(node.sourceSpan, '@switch block can only contain @case and @default blocks'));
|
|
303
|
-
continue;
|
|
304
|
-
}
|
|
305
|
-
if (node.name === 'default') {
|
|
306
|
-
if (hasDefault) {
|
|
307
|
-
errors.push(new ParseError(node.sourceSpan, '@switch block can only have one @default block'));
|
|
308
|
-
}
|
|
309
|
-
else if (node.parameters.length > 0) {
|
|
310
|
-
errors.push(new ParseError(node.sourceSpan, '@default block cannot have parameters'));
|
|
311
|
-
}
|
|
312
|
-
hasDefault = true;
|
|
313
|
-
}
|
|
314
|
-
else if (node.name === 'case' && node.parameters.length !== 1) {
|
|
315
|
-
errors.push(new ParseError(node.sourceSpan, '@case block must have exactly one parameter'));
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
return errors;
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Parses a block parameter into a binding AST.
|
|
322
|
-
* @param ast Block parameter that should be parsed.
|
|
323
|
-
* @param bindingParser Parser that the expression should be parsed with.
|
|
324
|
-
* @param part Specific part of the expression that should be parsed.
|
|
325
|
-
*/
|
|
326
|
-
function parseBlockParameterToBinding(ast, bindingParser, part) {
|
|
327
|
-
let start;
|
|
328
|
-
let end;
|
|
329
|
-
if (typeof part === 'string') {
|
|
330
|
-
// Note: `lastIndexOf` here should be enough to know the start index of the expression,
|
|
331
|
-
// because we know that it'll be at the end of the param. Ideally we could use the `d`
|
|
332
|
-
// flag when matching via regex and get the index from `match.indices`, but it's unclear
|
|
333
|
-
// if we can use it yet since it's a relatively new feature. See:
|
|
334
|
-
// https://github.com/tc39/proposal-regexp-match-indices
|
|
335
|
-
start = Math.max(0, ast.expression.lastIndexOf(part));
|
|
336
|
-
end = start + part.length;
|
|
337
|
-
}
|
|
338
|
-
else {
|
|
339
|
-
start = 0;
|
|
340
|
-
end = ast.expression.length;
|
|
341
|
-
}
|
|
342
|
-
return bindingParser.parseBinding(ast.expression.slice(start, end), false, ast.sourceSpan, ast.sourceSpan.start.offset + start);
|
|
343
|
-
}
|
|
344
|
-
/** Parses the parameter of a conditional block (`if` or `else if`). */
|
|
345
|
-
function parseConditionalBlockParameters(block, errors, bindingParser) {
|
|
346
|
-
if (block.parameters.length === 0) {
|
|
347
|
-
errors.push(new ParseError(block.sourceSpan, 'Conditional block does not have an expression'));
|
|
348
|
-
return null;
|
|
349
|
-
}
|
|
350
|
-
const expression = parseBlockParameterToBinding(block.parameters[0], bindingParser);
|
|
351
|
-
let expressionAlias = null;
|
|
352
|
-
// Start from 1 since we processed the first parameter already.
|
|
353
|
-
for (let i = 1; i < block.parameters.length; i++) {
|
|
354
|
-
const param = block.parameters[i];
|
|
355
|
-
const aliasMatch = param.expression.match(CONDITIONAL_ALIAS_PATTERN);
|
|
356
|
-
// For now conditionals can only have an `as` parameter.
|
|
357
|
-
// We may want to rework this later if we add more.
|
|
358
|
-
if (aliasMatch === null) {
|
|
359
|
-
errors.push(new ParseError(param.sourceSpan, `Unrecognized conditional paramater "${param.expression}"`));
|
|
360
|
-
}
|
|
361
|
-
else if (block.name !== 'if') {
|
|
362
|
-
errors.push(new ParseError(param.sourceSpan, '"as" expression is only allowed on the primary @if block'));
|
|
363
|
-
}
|
|
364
|
-
else if (expressionAlias !== null) {
|
|
365
|
-
errors.push(new ParseError(param.sourceSpan, 'Conditional can only have one "as" expression'));
|
|
366
|
-
}
|
|
367
|
-
else {
|
|
368
|
-
const name = aliasMatch[2].trim();
|
|
369
|
-
const variableStart = param.sourceSpan.start.moveBy(aliasMatch[1].length);
|
|
370
|
-
const variableSpan = new ParseSourceSpan(variableStart, variableStart.moveBy(name.length));
|
|
371
|
-
expressionAlias = new t.Variable(name, name, variableSpan, variableSpan);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
return { expression, expressionAlias };
|
|
375
|
-
}
|
|
376
|
-
/** Strips optional parentheses around from a control from expression parameter. */
|
|
377
|
-
function stripOptionalParentheses(param, errors) {
|
|
378
|
-
const expression = param.expression;
|
|
379
|
-
const spaceRegex = /^\s$/;
|
|
380
|
-
let openParens = 0;
|
|
381
|
-
let start = 0;
|
|
382
|
-
let end = expression.length - 1;
|
|
383
|
-
for (let i = 0; i < expression.length; i++) {
|
|
384
|
-
const char = expression[i];
|
|
385
|
-
if (char === '(') {
|
|
386
|
-
start = i + 1;
|
|
387
|
-
openParens++;
|
|
388
|
-
}
|
|
389
|
-
else if (spaceRegex.test(char)) {
|
|
390
|
-
continue;
|
|
391
|
-
}
|
|
392
|
-
else {
|
|
393
|
-
break;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
if (openParens === 0) {
|
|
397
|
-
return expression;
|
|
398
|
-
}
|
|
399
|
-
for (let i = expression.length - 1; i > -1; i--) {
|
|
400
|
-
const char = expression[i];
|
|
401
|
-
if (char === ')') {
|
|
402
|
-
end = i;
|
|
403
|
-
openParens--;
|
|
404
|
-
if (openParens === 0) {
|
|
405
|
-
break;
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
else if (spaceRegex.test(char)) {
|
|
409
|
-
continue;
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
break;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
if (openParens !== 0) {
|
|
416
|
-
errors.push(new ParseError(param.sourceSpan, 'Unclosed parentheses in expression'));
|
|
417
|
-
return null;
|
|
418
|
-
}
|
|
419
|
-
return expression.slice(start, end);
|
|
420
|
-
}
|
|
421
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicjNfY29udHJvbF9mbG93LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3JlbmRlcjMvcjNfY29udHJvbF9mbG93LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBZ0IsU0FBUyxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDbEUsT0FBTyxLQUFLLElBQUksTUFBTSxrQkFBa0IsQ0FBQztBQUN6QyxPQUFPLEVBQUMsVUFBVSxFQUFFLGVBQWUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUcxRCxPQUFPLEtBQUssQ0FBQyxNQUFNLFVBQVUsQ0FBQztBQUU5QixzREFBc0Q7QUFDdEQsTUFBTSwyQkFBMkIsR0FBRyx1Q0FBdUMsQ0FBQztBQUU1RSwrREFBK0Q7QUFDL0QsTUFBTSxzQkFBc0IsR0FBRyxvQkFBb0IsQ0FBQztBQUVwRCw4REFBOEQ7QUFDOUQsTUFBTSx5QkFBeUIsR0FBRyxjQUFjLENBQUM7QUFFakQsbURBQW1EO0FBQ25ELE1BQU0sZUFBZSxHQUFHLG1CQUFtQixDQUFDO0FBRTVDLGtEQUFrRDtBQUNsRCxNQUFNLG9CQUFvQixHQUFHLGtCQUFrQixDQUFDO0FBRWhEOzs7R0FHRztBQUNILE1BQU0sNENBQTRDLEdBQUcsaUJBQWlCLENBQUM7QUFFdkUsOEZBQThGO0FBQzlGLE1BQU0sOEJBQThCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDN0MsUUFBUTtJQUNSLFFBQVE7SUFDUixPQUFPO0lBQ1AsT0FBTztJQUNQLE1BQU07SUFDTixRQUFRO0NBQ1QsQ0FBQyxDQUFDO0FBRUg7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLHVCQUF1QixDQUFDLElBQVk7SUFDbEQsT0FBTyxJQUFJLEtBQUssT0FBTyxDQUFDO0FBQzFCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsc0JBQXNCLENBQUMsSUFBWTtJQUNqRCxPQUFPLElB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QyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ2hELE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUzQixJQUFJLElBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNqQixHQUFHLEdBQUcsQ0FBQyxDQUFDO1lBQ1IsVUFBVSxFQUFFLENBQUM7WUFDYixJQUFJLFVBQVUsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDckIsTUFBTTtZQUNSLENBQUM7UUFDSCxDQUFDO2FBQU0sSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDakMsU0FBUztRQUNYLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTTtRQUNSLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxVQUFVLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDckIsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLFVBQVUsQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLG9DQUFvQyxDQUFDLENBQUMsQ0FBQztRQUNwRixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLFVBQVUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3RDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtBU1RXaXRoU291cmNlLCBFbXB0eUV4cHJ9IGZyb20gJy4uL2V4cHJlc3Npb25fcGFyc2VyL2FzdCc7XG5pbXBvcnQgKiBhcyBodG1sIGZyb20gJy4uL21sX3BhcnNlci9hc3QnO1xuaW1wb3J0IHtQYXJzZUVycm9yLCBQYXJzZVNvdXJjZVNwYW59IGZyb20gJy4uL3BhcnNlX3V0aWwnO1xuaW1wb3J0IHtCaW5kaW5nUGFyc2VyfSBmcm9tICcuLi90ZW1wbGF0ZV9wYXJzZXIvYmluZGluZ19wYXJzZXInO1xuXG5pbXBvcnQgKiBhcyB0IGZyb20gJy4vcjNfYXN0JztcblxuLyoqIFBhdHRlcm4gZm9yIHRoZSBleHByZXNzaW9uIGluIGEgZm9yIGxvb3AgYmxvY2suICovXG5jb25zdCBGT1JfTE9PUF9FWFBSRVNTSU9OX1BBVFRFUk4gPSAvXlxccyooWzAtOUEtWmEtel8kXSopXFxzK29mXFxzKyhbXFxTXFxzXSopLztcblxuLyoqIFBhdHRlcm4gZm9yIHRoZSB0cmFja2luZyBleHByZXNzaW9uIGluIGEgZm9yIGxvb3AgYmxvY2suICovXG5jb25zdCBGT1JfTE9PUF9UUkFDS19QQVRURVJOID0gL150cmFja1xccysoW1xcU1xcc10qKS87XG5cbi8qKiBQYXR0ZXJuIGZvciB0aGUgYGFzYCBleHByZXNzaW9uIGluIGEgY29uZGl0aW9uYWwgYmxvY2suICovXG5jb25zdCBDT05ESVRJT05BTF9BTElBU19QQVRURVJOID0gL14oYXNcXHMpKyguKikvO1xuXG4vKiogUGF0dGVybiB1c2VkIHRvIGlkZW50aWZ5IGFuIGBlbHNlIGlmYCBibG9jay4gKi9cbmNvbnN0IEVMU0VfSUZfUEFUVEVSTiA9IC9eZWxzZVteXFxTXFxyXFxuXStpZi87XG5cbi8qKiBQYXR0ZXJuIHVzZWQgdG8gaWRlbnRpZnkgYSBgbGV0YCBwYXJhbWV0ZXIuICovXG5jb25zdCBGT1JfTE9PUF9MRVRfUEFUVEVSTiA9IC9ebGV0XFxzKyhbXFxTXFxzXSopLztcblxuLyoqXG4gKiBQYXR0ZXJuIHRvIGdyb3VwIGEgc3RyaW5nIGludG8gbGVhZGluZyB3aGl0ZXNwYWNlLCBub24gd2hpdGVzcGFjZSwgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UuXG4gKiBVc2VmdWwgZm9yIGdldHRpbmcgdGhlIHZhcmlhYmxlIG5hbWUgc3BhbiB3aGVuIGEgc3BhbiBjYW4gY29udGFpbiBsZWFkaW5nIGFuZCB0cmFpbGluZyBzcGFjZS5cbiAqL1xuY29uc3QgQ0hBUkFDVEVSU19JTl9TVVJST1VORElOR19XSElURVNQQUNFX1BBVFRFUk4gPSAvKFxccyopKFxcUyspKFxccyopLztcblxuLyoqIE5hbWVzIG9mIHZhcmlhYmxlcyB0aGF0IGFyZSBhbGxvd2VkIHRvIGJlIHVzZWQgaW4gdGhlIGBsZXRgIGV4cHJlc3Npb24gb2YgYSBgZm9yYCBsb29wLiAqL1xuY29uc3QgQUxMT1dFRF9GT1JfTE9PUF9MRVRfVkFSSUFCTEVTID0gbmV3IFNldChbXG4gICckaW5kZXgnLFxuICAnJGZpcnN0JyxcbiAgJyRsYXN0JyxcbiAgJyRldmVuJyxcbiAgJyRvZGQnLFxuICAnJGNvdW50Jyxcbl0pO1xuXG4vKipcbiAqIFByZWRpY2F0ZSBmdW5jdGlvbiB0aGF0IGRldGVybWluZXMgaWYgYSBibG9jayB3aXRoXG4gKiBhIHNwZWNpZmljIG5hbWUgY2FtIGJlIGNvbm5lY3RlZCB0byBhIGBmb3JgIGJsb2NrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb25uZWN0ZWRGb3JMb29wQmxvY2sobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBuYW1lID09PSAnZW1wdHknO1xufVxuXG4vKipcbiAqIFByZWRpY2F0ZSBmdW5jdGlvbiB0aGF0IGRldGVybWluZXMgaWYgYSBibG9jayB3aXRoXG4gKiBhIHNwZWNpZmljIG5hbWUgY2FtIGJlIGNvbm5lY3RlZCB0byBhbiBgaWZgIGJsb2NrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb25uZWN0ZWRJZkxvb3BCbG9jayhuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIG5hbWUgPT09ICdlbHNlJyB8fCBFTFNFX0lGX1BBVFRFUk4udGVzdChuYW1lKTtcbn1cblxuLyoqIENyZWF0ZXMgYW4gYGlmYCBsb29wIGJsb2NrIGZyb20gYW4gSFRNTCBBU1Qgbm9kZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVJZkJsb2NrKFxuICBhc3Q6IGh0bWwuQmxvY2ssXG4gIGNvbm5lY3RlZEJsb2NrczogaHRtbC5CbG9ja1tdLFxuICB2aXNpdG9yOiBodG1sLlZpc2l0b3IsXG4gIGJpbmRpbmdQYXJzZXI6IEJpbmRpbmdQYXJzZXIsXG4pOiB7bm9kZTogdC5JZkJsb2NrIHwgbnVsbDsgZXJyb3JzOiBQYXJzZUVycm9yW119IHtcbiAgY29uc3QgZXJyb3JzOiBQYXJzZUVycm9yW10gPSB2YWxpZGF0ZUlmQ29ubmVjdGVkQmxvY2tzKGNvbm5lY3RlZEJsb2Nrcyk7XG4gIGNvbnN0IGJyYW5jaGVzOiB0LklmQmxvY2tCcmFuY2hbXSA9IFtdO1xuICBjb25zdCBtYWluQmxvY2tQYXJhbXMgPSBwYXJzZUNvbmRpdGlvbmFsQmxvY2tQYXJhbWV0ZXJzKGFzdCwgZXJyb3JzLCBiaW5kaW5nUGFyc2VyKTtcblxuICBpZiAobWFpbkJsb2NrUGFyYW1zICE9PSBudWxsKSB7XG4gICAgYnJhbmNoZXMucHVzaChcbiAgICAgIG5ldyB0LklmQmxvY2tCcmFuY2goXG4gICAgICAgIG1haW5CbG9ja1BhcmFtcy5leHByZXNzaW9uLFxuICAgICAgICBodG1sLnZpc2l0QWxsKHZpc2l0b3IsIGFzdC5jaGlsZHJlbiwgYXN0LmNoaWxkcmVuKSxcbiAgICAgICAgbWFpbkJsb2NrUGFyYW1zLmV4cHJlc3Npb25BbGlhcyxcbiAgICAgICAgYXN0LnNvdXJjZVNwYW4sXG4gICAgICAgIGFzdC5zdGFydFNvdXJjZVNwYW4sXG4gICAgICAgIGFzdC5lbmRTb3VyY2VTcGFuLFxuICAgICAgICBhc3QubmFtZVNwYW4sXG4gICAgICAgIGFzdC5pMThuLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgZm9yIChjb25zdCBibG9jayBvZiBjb25uZWN0ZWRCbG9ja3MpIHtcbiAgICBpZiAoRUxTRV9JRl9QQVRURVJOLnRlc3QoYmxvY2submFtZSkpIHtcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHBhcnNlQ29uZGl0aW9uYWxCbG9ja1BhcmFtZXRlcnMoYmxvY2ssIGVycm9ycywgYmluZGluZ1BhcnNlcik7XG5cbiAgICAgIGlmIChwYXJhbXMgIT09IG51bGwpIHtcbiAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBodG1sLnZpc2l0QWxsKHZpc2l0b3IsIGJsb2NrLmNoaWxkcmVuLCBibG9jay5jaGlsZHJlbik7XG4gICAgICAgIGJyYW5jaGVzLnB1c2goXG4gICAgICAgICAgbmV3IHQuSWZCbG9ja0JyYW5jaChcbiAgICAgICAgICAgIHBhcmFtcy5leHByZXNzaW9uLFxuICAgICAgICAgICAgY2hpbGRyZW4sXG4gICAgICAgICAgICBwYXJhbXMuZXhwcmVzc2lvbkFsaWFzLFxuICAgICAgICAgICAgYmxvY2suc291cmNlU3BhbixcbiAgICAgICAgICAgIGJsb2NrLnN0YXJ0U291cmNlU3BhbixcbiAgICAgICAgICAgIGJsb2NrLmVuZFNvdXJjZVNwYW4sXG4gICAgICAgICAgICBibG9jay5uYW1lU3BhbixcbiAgICAgICAgICAgIGJsb2NrLmkxOG4sXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGJsb2NrLm5hbWUgPT09ICdlbHNlJykge1xuICAgICAgY29uc3QgY2hpbGRyZW4gPSBodG1sLnZpc2l0QWxsKHZpc2l0b3IsIGJsb2NrLmNoaWxkcmVuLCBibG9jay5jaGlsZHJlbik7XG4gICAgICBicmFuY2hlcy5wdXNoKFxuICAgICAgICBuZXcgdC5JZkJsb2NrQnJhbmNoKFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICAgY2hpbGRyZW4sXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgICBibG9jay5zb3VyY2VTcGFuLFxuICAgICAgICAgIGJsb2NrLnN0YXJ0U291cmNlU3BhbixcbiAgICAgICAgICBibG9jay5lbmRTb3VyY2VTcGFuLFxuICAgICAgICAgIGJsb2NrLm5hbWVTcGFuLFxuICAgICAgICAgIGJsb2NrLmkxOG4sXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRoZSBvdXRlciBJZkJsb2NrIHNob3VsZCBoYXZlIGEgc3BhbiB0aGF0IGVuY2Fwc3VsYXRlcyBhbGwgYnJhbmNoZXMuXG4gIGNvbnN0IGlmQmxvY2tTdGFydFNvdXJjZVNwYW4gPVxuICAgIGJyYW5jaGVzLmxlbmd0aCA+IDAgPyBicmFuY2hlc1swXS5zdGFydFNvdXJjZVNwYW4gOiBhc3Quc3RhcnRTb3VyY2VTcGFuO1xuICBjb25zdCBpZkJsb2NrRW5kU291cmNlU3BhbiA9XG4gICAgYnJhbmNoZXMubGVuZ3RoID4gMCA/IGJyYW5jaGVzW2JyYW5jaGVzLmxlbmd0aCAtIDFdLmVuZFNvdXJjZVNwYW4gOiBhc3QuZW5kU291cmNlU3BhbjtcblxuICBsZXQgd2hvbGVTb3VyY2VTcGFuID0gYXN0LnNvdXJjZVNwYW47XG4gIGNvbnN0IGxhc3RCcmFuY2ggPSBicmFuY2hlc1ticmFuY2hlcy5sZW5ndGggLSAxXTtcbiAgaWYgKGxhc3RCcmFuY2ggIT09IHVuZGVmaW5lZCkge1xuICAgIHdob2xlU291cmNlU3BhbiA9IG5ldyBQYXJzZVNvdXJjZVNwYW4oaWZCbG9ja1N0YXJ0U291cmNlU3Bhbi5zdGFydCwgbGFzdEJyYW5jaC5zb3VyY2VTcGFuLmVuZCk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5vZGU6IG5ldyB0LklmQmxvY2soXG4gICAgICBicmFuY2hlcyxcbiAgICAgIHdob2xlU291cmNlU3BhbixcbiAgICAgIGFzdC5zdGFydFNvdXJjZVNwYW4sXG4gICAgICBpZkJsb2NrRW5kU291cmNlU3BhbixcbiAgICAgIGFzdC5uYW1lU3BhbixcbiAgICApLFxuICAgIGVycm9ycyxcbiAgfTtcbn1cblxuLyoqIENyZWF0ZXMgYSBgZm9yYCBsb29wIGJsb2NrIGZyb20gYW4gSFRNTCBBU1Qgbm9kZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVGb3JMb29wKFxuICBhc3Q6IGh0bWwuQmxvY2ssXG4gIGNvbm5lY3RlZEJsb2NrczogaHRtbC5CbG9ja1tdLFxuICB2aXNpdG9yOiBodG1sLlZpc2l0b3IsXG4gIGJpbmRpbmdQYXJzZXI6IEJpbmRpbmdQYXJzZXIsXG4pOiB7bm9kZTogdC5Gb3JMb29wQmxvY2sgfCBudWxsOyBlcnJvcnM6IFBhcnNlRXJyb3JbXX0ge1xuICBjb25zdCBlcnJvcnM6IFBhcnNlRXJyb3JbXSA9IFtdO1xuICBjb25zdCBwYXJhbXMgPSBwYXJzZUZvckxvb3BQYXJhbWV0ZXJzKGFzdCwgZXJyb3JzLCBiaW5kaW5nUGFyc2VyKTtcbiAgbGV0IG5vZGU6IHQuRm9yTG9vcEJsb2NrIHwgbnVsbCA9IG51bGw7XG4gIGxldCBlbXB0eTogdC5Gb3JMb29wQmxvY2tFbXB0eSB8IG51bGwgPSBudWxsO1xuXG4gIGZvciAoY29uc3QgYmxvY2sgb2YgY29ubmVjdGVkQmxvY2tzKSB7XG4gICAgaWYgKGJsb2NrLm5hbWUgPT09ICdlbXB0eScpIHtcbiAgICAgIGlmIChlbXB0eSAhPT0gbnVsbCkge1xuICAgICAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihibG9jay5zb3VyY2VTcGFuLCAnQGZvciBsb29wIGNhbiBvbmx5IGhhdmUgb25lIEBlbXB0eSBibG9jaycpKTtcbiAgICAgIH0gZWxzZSBpZiAoYmxvY2sucGFyYW1ldGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKGJsb2NrLnNvdXJjZVNwYW4sICdAZW1wdHkgYmxvY2sgY2Fubm90IGhhdmUgcGFyYW1ldGVycycpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVtcHR5ID0gbmV3IHQuRm9yTG9vcEJsb2NrRW1wdHkoXG4gICAgICAgICAgaHRtbC52aXNpdEFsbCh2aXNpdG9yLCBibG9jay5jaGlsZHJlbiwgYmxvY2suY2hpbGRyZW4pLFxuICAgICAgICAgIGJsb2NrLnNvdXJjZVNwYW4sXG4gICAgICAgICAgYmxvY2suc3RhcnRTb3VyY2VTcGFuLFxuICAgICAgICAgIGJsb2NrLmVuZFNvdXJjZVNwYW4sXG4gICAgICAgICAgYmxvY2submFtZVNwYW4sXG4gICAgICAgICAgYmxvY2suaTE4bixcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZXJyb3JzLnB1c2gobmV3IFBhcnNlRXJyb3IoYmxvY2suc291cmNlU3BhbiwgYFVucmVjb2duaXplZCBAZm9yIGxvb3AgYmxvY2sgXCIke2Jsb2NrLm5hbWV9XCJgKSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHBhcmFtcyAhPT0gbnVsbCkge1xuICAgIGlmIChwYXJhbXMudHJhY2tCeSA9PT0gbnVsbCkge1xuICAgICAgLy8gVE9ETzogV2Ugc2hvdWxkIG5vdCBmYWlsIGhlcmUsIGFuZCBpbnN0ZWFkIHRyeSB0byBwcm9kdWNlIHNvbWUgQVNUIGZvciB0aGUgbGFuZ3VhZ2VcbiAgICAgIC8vIHNlcnZpY2UuXG4gICAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihhc3Quc291cmNlU3BhbiwgJ0Bmb3IgbG9vcCBtdXN0IGhhdmUgYSBcInRyYWNrXCIgZXhwcmVzc2lvbicpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhlIGBmb3JgIGJsb2NrIGhhcyBhIG1haW4gc3BhbiB0aGF0IGluY2x1ZGVzIHRoZSBgZW1wdHlgIGJyYW5jaC4gRm9yIG9ubHkgdGhlIHNwYW4gb2YgdGhlXG4gICAgICAvLyBtYWluIGBmb3JgIGJvZHksIHVzZSBgbWFpblNvdXJjZVNwYW5gLlxuICAgICAgY29uc3QgZW5kU3BhbiA9IGVtcHR5Py5lbmRTb3VyY2VTcGFuID8/IGFzdC5lbmRTb3VyY2VTcGFuO1xuICAgICAgY29uc3Qgc291cmNlU3BhbiA9IG5ldyBQYXJzZVNvdXJjZVNwYW4oXG4gICAgICAgIGFzdC5zb3VyY2VTcGFuLnN0YXJ0LFxuICAgICAgICBlbmRTcGFuPy5lbmQgPz8gYXN0LnNvdXJjZVNwYW4uZW5kLFxuICAgICAgKTtcbiAgICAgIG5vZGUgPSBuZXcgdC5Gb3JMb29wQmxvY2soXG4gICAgICAgIHBhcmFtcy5pdGVtTmFtZSxcbiAgICAgICAgcGFyYW1zLmV4cHJlc3Npb24sXG4gICAgICAgIHBhcmFtcy50cmFja0J5LmV4cHJlc3Npb24sXG4gICAgICAgIHBhcmFtcy50cmFja0J5LmtleXdvcmRTcGFuLFxuICAgICAgICBwYXJhbXMuY29udGV4dCxcbiAgICAgICAgaHRtbC52aXNpdEFsbCh2aXNpdG9yLCBhc3QuY2hpbGRyZW4sIGFzdC5jaGlsZHJlbiksXG4gICAgICAgIGVtcHR5LFxuICAgICAgICBzb3VyY2VTcGFuLFxuICAgICAgICBhc3Quc291cmNlU3BhbixcbiAgICAgICAgYXN0LnN0YXJ0U291cmNlU3BhbixcbiAgICAgICAgZW5kU3BhbixcbiAgICAgICAgYXN0Lm5hbWVTcGFuLFxuICAgICAgICBhc3QuaTE4bixcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtub2RlLCBlcnJvcnN9O1xufVxuXG4vKiogQ3JlYXRlcyBhIHN3aXRjaCBibG9jayBmcm9tIGFuIEhUTUwgQVNUIG5vZGUuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU3dpdGNoQmxvY2soXG4gIGFzdDogaHRtbC5CbG9jayxcbiAgdmlzaXRvcjogaHRtbC5WaXNpdG9yLFxuICBiaW5kaW5nUGFyc2VyOiBCaW5kaW5nUGFyc2VyLFxuKToge25vZGU6IHQuU3dpdGNoQmxvY2sgfCBudWxsOyBlcnJvcnM6IFBhcnNlRXJyb3JbXX0ge1xuICBjb25zdCBlcnJvcnMgPSB2YWxpZGF0ZVN3aXRjaEJsb2NrKGFzdCk7XG4gIGNvbnN0IHByaW1hcnlFeHByZXNzaW9uID1cbiAgICBhc3QucGFyYW1ldGVycy5sZW5ndGggPiAwXG4gICAgICA/IHBhcnNlQmxvY2tQYXJhbWV0ZXJUb0JpbmRpbmcoYXN0LnBhcmFtZXRlcnNbMF0sIGJpbmRpbmdQYXJzZXIpXG4gICAgICA6IGJpbmRpbmdQYXJzZXIucGFyc2VCaW5kaW5nKCcnLCBmYWxzZSwgYXN0LnNvdXJjZVNwYW4sIDApO1xuICBjb25zdCBjYXNlczogdC5Td2l0Y2hCbG9ja0Nhc2VbXSA9IFtdO1xuICBjb25zdCB1bmtub3duQmxvY2tzOiB0LlVua25vd25CbG9ja1tdID0gW107XG4gIGxldCBkZWZhdWx0Q2FzZTogdC5Td2l0Y2hCbG9ja0Nhc2UgfCBudWxsID0gbnVsbDtcblxuICAvLyBIZXJlIHdlIGFzc3VtZSB0aGF0IGFsbCB0aGUgYmxvY2tzIGFyZSB2YWxpZCBnaXZlbiB0aGF0IHdlIHZhbGlkYXRlZCB0aGVtIGFib3ZlLlxuICBmb3IgKGNvbnN0IG5vZGUgb2YgYXN0LmNoaWxkcmVuKSB7XG4gICAgaWYgKCEobm9kZSBpbnN0YW5jZW9mIGh0bWwuQmxvY2spKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoKG5vZGUubmFtZSAhPT0gJ2Nhc2UnIHx8IG5vZGUucGFyYW1ldGVycy5sZW5ndGggPT09IDApICYmIG5vZGUubmFtZSAhPT0gJ2RlZmF1bHQnKSB7XG4gICAgICB1bmtub3duQmxvY2tzLnB1c2gobmV3IHQuVW5rbm93bkJsb2NrKG5vZGUubmFtZSwgbm9kZS5zb3VyY2VTcGFuLCBub2RlLm5hbWVTcGFuKSk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBleHByZXNzaW9uID1cbiAgICAgIG5vZGUubmFtZSA9PT0gJ2Nhc2UnID8gcGFyc2VCbG9ja1BhcmFtZXRlclRvQmluZGluZyhub2RlLnBhcmFtZXRlcnNbMF0sIGJpbmRpbmdQYXJzZXIpIDogbnVsbDtcbiAgICBjb25zdCBhc3QgPSBuZXcgdC5Td2l0Y2hCbG9ja0Nhc2UoXG4gICAgICBleHByZXNzaW9uLFxuICAgICAgaHRtbC52aXNpdEFsbCh2aXNpdG9yLCBub2RlLmNoaWxkcmVuLCBub2RlLmNoaWxkcmVuKSxcbiAgICAgIG5vZGUuc291cmNlU3BhbixcbiAgICAgIG5vZGUuc3RhcnRTb3VyY2VTcGFuLFxuICAgICAgbm9kZS5lbmRTb3VyY2VTcGFuLFxuICAgICAgbm9kZS5uYW1lU3BhbixcbiAgICAgIG5vZGUuaTE4bixcbiAgICApO1xuXG4gICAgaWYgKGV4cHJlc3Npb24gPT09IG51bGwpIHtcbiAgICAgIGRlZmF1bHRDYXNlID0gYXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBjYXNlcy5wdXNoKGFzdCk7XG4gICAgfVxuICB9XG5cbiAgLy8gRW5zdXJlIHRoYXQgdGhlIGRlZmF1bHQgY2FzZSBpcyBsYXN0IGluIHRoZSBhcnJheS5cbiAgaWYgKGRlZmF1bHRDYXNlICE9PSBudWxsKSB7XG4gICAgY2FzZXMucHVzaChkZWZhdWx0Q2FzZSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIG5vZGU6IG5ldyB0LlN3aXRjaEJsb2NrKFxuICAgICAgcHJpbWFyeUV4cHJlc3Npb24sXG4gICAgICBjYXNlcyxcbiAgICAgIHVua25vd25CbG9ja3MsXG4gICAgICBhc3Quc291cmNlU3BhbixcbiAgICAgIGFzdC5zdGFydFNvdXJjZVNwYW4sXG4gICAgICBhc3QuZW5kU291cmNlU3BhbixcbiAgICAgIGFzdC5uYW1lU3BhbixcbiAgICApLFxuICAgIGVycm9ycyxcbiAgfTtcbn1cblxuLyoqIFBhcnNlcyB0aGUgcGFyYW1ldGVycyBvZiBhIGBmb3JgIGxvb3AgYmxvY2suICovXG5mdW5jdGlvbiBwYXJzZUZvckxvb3BQYXJhbWV0ZXJzKFxuICBibG9jazogaHRtbC5CbG9jayxcbiAgZXJyb3JzOiBQYXJzZUVycm9yW10sXG4gIGJpbmRpbmdQYXJzZXI6IEJpbmRpbmdQYXJzZXIsXG4pIHtcbiAgaWYgKGJsb2NrLnBhcmFtZXRlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgZXJyb3JzLnB1c2gobmV3IFBhcnNlRXJyb3IoYmxvY2suc291cmNlU3BhbiwgJ0Bmb3IgbG9vcCBkb2VzIG5vdCBoYXZlIGFuIGV4cHJlc3Npb24nKSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBbZXhwcmVzc2lvblBhcmFtLCAuLi5zZWNvbmRhcnlQYXJhbXNdID0gYmxvY2sucGFyYW1ldGVycztcbiAgY29uc3QgbWF0Y2ggPSBzdHJpcE9wdGlvbmFsUGFyZW50aGVzZXMoZXhwcmVzc2lvblBhcmFtLCBlcnJvcnMpPy5tYXRjaChcbiAgICBGT1JfTE9PUF9FWFBSRVNTSU9OX1BBVFRFUk4sXG4gICk7XG5cbiAgaWYgKCFtYXRjaCB8fCBtYXRjaFsyXS50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgZXJyb3JzLnB1c2goXG4gICAgICBuZXcgUGFyc2VFcnJvcihcbiAgICAgICAgZXhwcmVzc2lvblBhcmFtLnNvdXJjZVNwYW4sXG4gICAgICAgICdDYW5ub3QgcGFyc2UgZXhwcmVzc2lvbi4gQGZvciBsb29wIGV4cHJlc3Npb24gbXVzdCBtYXRjaCB0aGUgcGF0dGVybiBcIjxpZGVudGlmaWVyPiBvZiA8ZXhwcmVzc2lvbj5cIicsXG4gICAgICApLFxuICAgICk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBbLCBpdGVtTmFtZSwgcmF3RXhwcmVzc2lvbl0gPSBtYXRjaDtcbiAgaWYgKEFMTE9XRURfRk9SX0xPT1BfTEVUX1ZBUklBQkxFUy5oYXMoaXRlbU5hbWUpKSB7XG4gICAgZXJyb3JzLnB1c2goXG4gICAgICBuZXcgUGFyc2VFcnJvcihcbiAgICAgICAgZXhwcmVzc2lvblBhcmFtLnNvdXJjZVNwYW4sXG4gICAgICAgIGBAZm9yIGxvb3AgaXRlbSBuYW1lIGNhbm5vdCBiZSBvbmUgb2YgJHtBcnJheS5mcm9tKEFMTE9XRURfRk9SX0xPT1BfTEVUX1ZBUklBQkxFUykuam9pbihcbiAgICAgICAgICAnLCAnLFxuICAgICAgICApfS5gLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgLy8gYGV4cHJlc3Npb25QYXJhbS5leHByZXNzaW9uYCBjb250YWlucyB0aGUgdmFyaWFibGUgZGVjbGFyYXRpb24gYW5kIHRoZSBleHByZXNzaW9uIG9mIHRoZVxuICAvLyBmb3IuLi5vZiBzdGF0ZW1lbnQsIGkuZS4gJ3VzZXIgb2YgdXNlcnMnIFRoZSB2YXJpYWJsZSBvZiBhIEZvck9mU3RhdGVtZW50IGlzIF9vbmx5XyB0aGUgXCJjb25zdFxuICAvLyB1c2VyXCIgcGFydCBhbmQgZG9lcyBub3QgaW5jbHVkZSBcIm9mIHhcIi5cbiAgY29uc3QgdmFyaWFibGVOYW1lID0gZXhwcmVzc2lvblBhcmFtLmV4cHJlc3Npb24uc3BsaXQoJyAnKVswXTtcbiAgY29uc3QgdmFyaWFibGVTcGFuID0gbmV3IFBhcnNlU291cmNlU3BhbihcbiAgICBleHByZXNzaW9uUGFyYW0uc291cmNlU3Bhbi5zdGFydCxcbiAgICBleHByZXNzaW9uUGFyYW0uc291cmNlU3Bhbi5zdGFydC5tb3ZlQnkodmFyaWFibGVOYW1lLmxlbmd0aCksXG4gICk7XG4gIGNvbnN0IHJlc3VsdCA9IHtcbiAgICBpdGVtTmFtZTogbmV3IHQuVmFyaWFibGUoaXRlbU5hbWUsICckaW1wbGljaXQnLCB2YXJpYWJsZVNwYW4sIHZhcmlhYmxlU3BhbiksXG4gICAgdHJhY2tCeTogbnVsbCBhcyB7ZXhwcmVzc2lvbjogQVNUV2l0aFNvdXJjZTsga2V5d29yZFNwYW46IFBhcnNlU291cmNlU3Bhbn0gfCBudWxsLFxuICAgIGV4cHJlc3Npb246IHBhcnNlQmxvY2tQYXJhbWV0ZXJUb0JpbmRpbmcoZXhwcmVzc2lvblBhcmFtLCBiaW5kaW5nUGFyc2VyLCByYXdFeHByZXNzaW9uKSxcbiAgICBjb250ZXh0OiBBcnJheS5mcm9tKEFMTE9XRURfRk9SX0xPT1BfTEVUX1ZBUklBQkxFUywgKHZhcmlhYmxlTmFtZSkgPT4ge1xuICAgICAgLy8gR2l2ZSBhbWJpZW50bHktYXZhaWxhYmxlIGNvbnRleHQgdmFyaWFibGVzIGVtcHR5IHNwYW5zIGF0IHRoZSBlbmQgb2ZcbiAgICAgIC8vIHRoZSBzdGFydCBvZiB0aGUgYGZvcmAgYmxvY2ssIHNpbmNlIHRoZXkgYXJlIG5vdCBleHBsaWNpdGx5IGRlZmluZWQuXG4gICAgICBjb25zdCBlbXB0eVNwYW5BZnRlckZvckJsb2NrU3RhcnQgPSBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgICBibG9jay5zdGFydFNvdXJjZVNwYW4uZW5kLFxuICAgICAgICBibG9jay5zdGFydFNvdXJjZVNwYW4uZW5kLFxuICAgICAgKTtcbiAgICAgIHJldHVybiBuZXcgdC5WYXJpYWJsZShcbiAgICAgICAgdmFyaWFibGVOYW1lLFxuICAgICAgICB2YXJpYWJsZU5hbWUsXG4gICAgICAgIGVtcHR5U3BhbkFmdGVyRm9yQmxvY2tTdGFydCxcbiAgICAgICAgZW1wdHlTcGFuQWZ0ZXJGb3JCbG9ja1N0YXJ0LFxuICAgICAgKTtcbiAgICB9KSxcbiAgfTtcblxuICBmb3IgKGNvbnN0IHBhcmFtIG9mIHNlY29uZGFyeVBhcmFtcykge1xuICAgIGNvbnN0IGxldE1hdGNoID0gcGFyYW0uZXhwcmVzc2lvbi5tYXRjaChGT1JfTE9PUF9MRVRfUEFUVEVSTik7XG5cbiAgICBpZiAobGV0TWF0Y2ggIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IHZhcmlhYmxlc1NwYW4gPSBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgICBwYXJhbS5zb3VyY2VTcGFuLnN0YXJ0Lm1vdmVCeShsZXRNYXRjaFswXS5sZW5ndGggLSBsZXRNYXRjaFsxXS5sZW5ndGgpLFxuICAgICAgICBwYXJhbS5zb3VyY2VTcGFuLmVuZCxcbiAgICAgICk7XG4gICAgICBwYXJzZUxldFBhcmFtZXRlcihcbiAgICAgICAgcGFyYW0uc291cmNlU3BhbixcbiAgICAgICAgbGV0TWF0Y2hbMV0sXG4gICAgICAgIHZhcmlhYmxlc1NwYW4sXG4gICAgICAgIGl0ZW1OYW1lLFxuICAgICAgICByZXN1bHQuY29udGV4dCxcbiAgICAgICAgZXJyb3JzLFxuICAgICAgKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHRyYWNrTWF0Y2ggPSBwYXJhbS5leHByZXNzaW9uLm1hdGNoKEZPUl9MT09QX1RSQUNLX1BBVFRFUk4pO1xuXG4gICAgaWYgKHRyYWNrTWF0Y2ggIT09IG51bGwpIHtcbiAgICAgIGlmIChyZXN1bHQudHJhY2tCeSAhPT0gbnVsbCkge1xuICAgICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgICBuZXcgUGFyc2VFcnJvcihwYXJhbS5zb3VyY2VTcGFuLCAnQGZvciBsb29wIGNhbiBvbmx5IGhhdmUgb25lIFwidHJhY2tcIiBleHByZXNzaW9uJyksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBleHByZXNzaW9uID0gcGFyc2VCbG9ja1BhcmFtZXRlclRvQmluZGluZyhwYXJhbSwgYmluZGluZ1BhcnNlciwgdHJhY2tNYXRjaFsxXSk7XG4gICAgICAgIGlmIChleHByZXNzaW9uLmFzdCBpbnN0YW5jZW9mIEVtcHR5RXhwcikge1xuICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKHBhcmFtLnNvdXJjZVNwYW4sICdAZm9yIGxvb3AgbXVzdCBoYXZlIGEgXCJ0cmFja1wiIGV4cHJlc3Npb24nKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qga2V5d29yZFNwYW4gPSBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgICAgIHBhcmFtLnNvdXJjZVNwYW4uc3RhcnQsXG4gICAgICAgICAgcGFyYW0uc291cmNlU3Bhbi5zdGFydC5tb3ZlQnkoJ3RyYWNrJy5sZW5ndGgpLFxuICAgICAgICApO1xuICAgICAgICByZXN1bHQudHJhY2tCeSA9IHtleHByZXNzaW9uLCBrZXl3b3JkU3Bhbn07XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBlcnJvcnMucHVzaChcbiAgICAgIG5ldyBQYXJzZUVycm9yKHBhcmFtLnNvdXJjZVNwYW4sIGBVbnJlY29nbml6ZWQgQGZvciBsb29wIHBhcmFtYXRlciBcIiR7cGFyYW0uZXhwcmVzc2lvbn1cImApLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKiogUGFyc2VzIHRoZSBgbGV0YCBwYXJhbWV0ZXIgb2YgYSBgZm9yYCBsb29wIGJsb2NrLiAqL1xuZnVuY3Rpb24gcGFyc2VMZXRQYXJhbWV0ZXIoXG4gIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3BhbixcbiAgZXhwcmVzc2lvbjogc3RyaW5nLFxuICBzcGFuOiBQYXJzZVNvdXJjZVNwYW4sXG4gIGxvb3BJdGVtTmFtZTogc3RyaW5nLFxuICBjb250ZXh0OiB0LlZhcmlhYmxlW10sXG4gIGVycm9yczogUGFyc2VFcnJvcltdLFxuKTogdm9pZCB7XG4gIGNvbnN0IHBhcnRzID0gZXhwcmVzc2lvbi5zcGxpdCgnLCcpO1xuICBsZXQgc3RhcnRTcGFuID0gc3Bhbi5zdGFydDtcbiAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgY29uc3QgZXhwcmVzc2lvblBhcnRzID0gcGFydC5zcGxpdCgnPScpO1xuICAgIGNvbnN0IG5hbWUgPSBleHByZXNzaW9uUGFydHMubGVuZ3RoID09PSAyID8gZXhwcmVzc2lvblBhcnRzWzBdLnRyaW0oKSA6ICcnO1xuICAgIGNvbnN0IHZhcmlhYmxlTmFtZSA9IGV4cHJlc3Npb25QYXJ0cy5sZW5ndGggPT09IDIgPyBleHByZXNzaW9uUGFydHNbMV0udHJpbSgpIDogJyc7XG5cbiAgICBpZiAobmFtZS5sZW5ndGggPT09IDAgfHwgdmFyaWFibGVOYW1lLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgIG5ldyBQYXJzZUVycm9yKFxuICAgICAgICAgIHNvdXJjZVNwYW4sXG4gICAgICAgICAgYEludmFsaWQgQGZvciBsb29wIFwibGV0XCIgcGFyYW1ldGVyLiBQYXJhbWV0ZXIgc2hvdWxkIG1hdGNoIHRoZSBwYXR0ZXJuIFwiPG5hbWU+ID0gPHZhcmlhYmxlIG5hbWU+XCJgLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKCFBTExPV0VEX0ZPUl9MT09QX0xFVF9WQVJJQUJMRVMuaGFzKHZhcmlhYmxlTmFtZSkpIHtcbiAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICBuZXcgUGFyc2VFcnJvcihcbiAgICAgICAgICBzb3VyY2VTcGFuLFxuICAgICAgICAgIGBVbmtub3duIFwibGV0XCIgcGFyYW1ldGVyIHZhcmlhYmxlIFwiJHt2YXJpYWJsZU5hbWV9XCIuIFRoZSBhbGxvd2VkIHZhcmlhYmxlcyBhcmU6ICR7QXJyYXkuZnJvbShcbiAgICAgICAgICAgIEFMTE9XRURfRk9SX0xPT1BfTEVUX1ZBUklBQkxFUyxcbiAgICAgICAgICApLmpvaW4oJywgJyl9YCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChuYW1lID09PSBsb29wSXRlbU5hbWUpIHtcbiAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICBuZXcgUGFyc2VFcnJvcihcbiAgICAgICAgICBzb3VyY2VTcGFuLFxuICAgICAgICAgIGBJbnZhbGlkIEBmb3IgbG9vcCBcImxldFwiIHBhcmFtZXRlci4gVmFyaWFibGUgY2Fubm90IGJlIGNhbGxlZCBcIiR7bG9vcEl0ZW1OYW1lfVwiYCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChjb250ZXh0LnNvbWUoKHYpID0+IHYubmFtZSA9PT0gbmFtZSkpIHtcbiAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICBuZXcgUGFyc2VFcnJvcihzb3VyY2VTcGFuLCBgRHVwbGljYXRlIFwibGV0XCIgcGFyYW1ldGVyIHZhcmlhYmxlIFwiJHt2YXJpYWJsZU5hbWV9XCJgKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IFssIGtleUxlYWRpbmdXaGl0ZXNwYWNlLCBrZXlOYW1lXSA9XG4gICAgICAgIGV4cHJlc3Npb25QYXJ0c1swXS5tYXRjaChDSEFSQUNURVJTX0lOX1NVUlJPVU5ESU5HX1dISVRFU1BBQ0VfUEFUVEVSTikgPz8gW107XG4gICAgICBjb25zdCBrZXlTcGFuID1cbiAgICAgICAga2V5TGVhZGluZ1doaXRlc3BhY2UgIT09IHVuZGVmaW5lZCAmJiBleHByZXNzaW9uUGFydHMubGVuZ3RoID09PSAyXG4gICAgICAgICAgPyBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgICAgICAgICAvKiBzdHJpcCBsZWFkaW5nIHNwYWNlcyAqL1xuICAgICAgICAgICAgICBzdGFydFNwYW4ubW92ZUJ5KGtleUxlYWRpbmdXaGl0ZXNwYWNlLmxlbmd0aCksXG4gICAgICAgICAgICAgIC8qIGFkdmFuY2UgdG8gZW5kIG9mIHRoZSB2YXJpYWJsZSBuYW1lICovXG4gICAgICAgICAgICAgIHN0YXJ0U3Bhbi5tb3ZlQnkoa2V5TGVhZGluZ1doaXRlc3BhY2UubGVuZ3RoICsga2V5TmFtZS5sZW5ndGgpLFxuICAgICAgICAgICAgKVxuICAgICAgICAgIDogc3BhbjtcblxuICAgICAgbGV0IHZhbHVlU3BhbjogUGFyc2VTb3VyY2VTcGFuIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKGV4cHJlc3Npb25QYXJ0cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgY29uc3QgWywgdmFsdWVMZWFkaW5nV2hpdGVzcGFjZSwgaW1wbGljaXRdID1cbiAgICAgICAgICBleHByZXNzaW9uUGFydHNbMV0ubWF0Y2goQ0hBUkFDVEVSU19JTl9TVVJST1VORElOR19XSElURVNQQUNFX1BBVFRFUk4pID8/IFtdO1xuICAgICAgICB2YWx1ZVNwYW4gPVxuICAgICAgICAgIHZhbHVlTGVhZGluZ1doaXRlc3BhY2UgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBuZXcgUGFyc2VTb3VyY2VTcGFuKFxuICAgICAgICAgICAgICAgIHN0YXJ0U3Bhbi5tb3ZlQnkoZXhwcmVzc2lvblBhcnRzWzBdLmxlbmd0aCArIDEgKyB2YWx1ZUxlYWRpbmdXaGl0ZXNwYWNlLmxlbmd0aCksXG4gICAgICAgICAgICAgICAgc3RhcnRTcGFuLm1vdmVCeShcbiAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb25QYXJ0c1swXS5sZW5ndGggKyAxICsgdmFsdWVMZWFkaW5nV2hpdGVzcGFjZS5sZW5ndGggKyBpbXBsaWNpdC5sZW5ndGgsXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IFBhcnNlU291cmNlU3BhbihrZXlTcGFuLnN0YXJ0LCB2YWx1ZVNwYW4/LmVuZCA/PyBrZXlTcGFuLmVuZCk7XG4gICAgICBjb250ZXh0LnB1c2gobmV3IHQuVmFyaWFibGUobmFtZSwgdmFyaWFibGVOYW1lLCBzb3VyY2VTcGFuLCBrZXlTcGFuLCB2YWx1ZVNwYW4pKTtcbiAgICB9XG4gICAgc3RhcnRTcGFuID0gc3RhcnRTcGFuLm1vdmVCeShwYXJ0Lmxlbmd0aCArIDEgLyogYWRkIDEgdG8gbW92ZSBwYXN0IHRoZSBjb21tYSAqLyk7XG4gIH1cbn1cblxuLyoqXG4gKiBDaGVja3MgdGhhdCB0aGUgc2hhcGUgb2YgdGhlIGJsb2NrcyBjb25uZWN0ZWQgdG8gYW5cbiAqIGBAaWZgIGJsb2NrIGlzIGNvcnJlY3QuIFJldHVybnMgYW4gYXJyYXkgb2YgZXJyb3JzLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUlmQ29ubmVjdGVkQmxvY2tzKGNvbm5lY3RlZEJsb2NrczogaHRtbC5CbG9ja1tdKTogUGFyc2VFcnJvcltdIHtcbiAgY29uc3QgZXJyb3JzOiBQYXJzZUVycm9yW10gPSBbXTtcbiAgbGV0IGhhc0Vsc2UgPSBmYWxzZTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbm5lY3RlZEJsb2Nrcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGJsb2NrID0gY29ubmVjdGVkQmxvY2tzW2ldO1xuXG4gICAgaWYgKGJsb2NrLm5hbWUgPT09ICdlbHNlJykge1xuICAgICAgaWYgKGhhc0Vsc2UpIHtcbiAgICAgICAgZXJyb3JzLnB1c2gobmV3IFBhcnNlRXJyb3IoYmxvY2suc291cmNlU3BhbiwgJ0NvbmRpdGlvbmFsIGNhbiBvbmx5IGhhdmUgb25lIEBlbHNlIGJsb2NrJykpO1xuICAgICAgfSBlbHNlIGlmIChjb25uZWN0ZWRCbG9ja3MubGVuZ3RoID4gMSAmJiBpIDwgY29ubmVjdGVkQmxvY2tzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgICAgbmV3IFBhcnNlRXJyb3IoYmxvY2suc291cmNlU3BhbiwgJ0BlbHNlIGJsb2NrIG11c3QgYmUgbGFzdCBpbnNpZGUgdGhlIGNvbmRpdGlvbmFsJyksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKGJsb2NrLnBhcmFtZXRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihibG9jay5zb3VyY2VTcGFuLCAnQGVsc2UgYmxvY2sgY2Fubm90IGhhdmUgcGFyYW1ldGVycycpKTtcbiAgICAgIH1cbiAgICAgIGhhc0Vsc2UgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoIUVMU0VfSUZfUEFUVEVSTi50ZXN0KGJsb2NrLm5hbWUpKSB7XG4gICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgbmV3IFBhcnNlRXJyb3IoYmxvY2suc291cmNlU3BhbiwgYFVucmVjb2duaXplZCBjb25kaXRpb25hbCBibG9jayBAJHtibG9jay5uYW1lfWApLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXJyb3JzO1xufVxuXG4vKiogQ2hlY2tzIHRoYXQgdGhlIHNoYXBlIG9mIGEgYHN3aXRjaGAgYmxvY2sgaXMgdmFsaWQuIFJldHVybnMgYW4gYXJyYXkgb2YgZXJyb3JzLiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVTd2l0Y2hCbG9jayhhc3Q6IGh0bWwuQmxvY2spOiBQYXJzZUVycm9yW10ge1xuICBjb25zdCBlcnJvcnM6IFBhcnNlRXJyb3JbXSA9IFtdO1xuICBsZXQgaGFzRGVmYXVsdCA9IGZhbHNlO1xuXG4gIGlmIChhc3QucGFyYW1ldGVycy5sZW5ndGggIT09IDEpIHtcbiAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihhc3Quc291cmNlU3BhbiwgJ0Bzd2l0Y2ggYmxvY2sgbXVzdCBoYXZlIGV4YWN0bHkgb25lIHBhcmFtZXRlcicpKTtcbiAgICByZXR1cm4gZXJyb3JzO1xuICB9XG5cbiAgZm9yIChjb25zdCBub2RlIG9mIGFzdC5jaGlsZHJlbikge1xuICAgIC8vIFNraXAgb3ZlciBjb21tZW50cyBhbmQgZW1wdHkgdGV4dCBub2RlcyBpbnNpZGUgdGhlIHN3aXRjaCBibG9jay5cbiAgICAvLyBFbXB0eSB0ZXh0IG5vZGVzIGNhbiBiZSB1c2VkIGZvciBmb3JtYXR0aW5nIHdoaWxlIGNvbW1lbnRzIGRvbid0IGFmZmVjdCB0aGUgcnVudGltZS5cbiAgICBpZiAoXG4gICAgICBub2RlIGluc3RhbmNlb2YgaHRtbC5Db21tZW50IHx8XG4gICAgICAobm9kZSBpbnN0YW5jZW9mIGh0bWwuVGV4dCAmJiBub2RlLnZhbHVlLnRyaW0oKS5sZW5ndGggPT09IDApXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoIShub2RlIGluc3RhbmNlb2YgaHRtbC5CbG9jaykgfHwgKG5vZGUubmFtZSAhPT0gJ2Nhc2UnICYmIG5vZGUubmFtZSAhPT0gJ2RlZmF1bHQnKSkge1xuICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgIG5ldyBQYXJzZUVycm9yKG5vZGUuc291cmNlU3BhbiwgJ0Bzd2l0Y2ggYmxvY2sgY2FuIG9ubHkgY29udGFpbiBAY2FzZSBhbmQgQGRlZmF1bHQgYmxvY2tzJyksXG4gICAgICApO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG5vZGUubmFtZSA9PT0gJ2RlZmF1bHQnKSB7XG4gICAgICBpZiAoaGFzRGVmYXVsdCkge1xuICAgICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgICBuZXcgUGFyc2VFcnJvcihub2RlLnNvdXJjZVNwYW4sICdAc3dpdGNoIGJsb2NrIGNhbiBvbmx5IGhhdmUgb25lIEBkZWZhdWx0IGJsb2NrJyksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKG5vZGUucGFyYW1ldGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKG5vZGUuc291cmNlU3BhbiwgJ0BkZWZhdWx0IGJsb2NrIGNhbm5vdCBoYXZlIHBhcmFtZXRlcnMnKSk7XG4gICAgICB9XG4gICAgICBoYXNEZWZhdWx0ID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKG5vZGUubmFtZSA9PT0gJ2Nhc2UnICYmIG5vZGUucGFyYW1ldGVycy5sZW5ndGggIT09IDEpIHtcbiAgICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKG5vZGUuc291cmNlU3BhbiwgJ0BjYXNlIGJsb2NrIG11c3QgaGF2ZSBleGFjdGx5IG9uZSBwYXJhbWV0ZXInKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVycm9ycztcbn1cblxuLyoqXG4gKiBQYXJzZXMgYSBibG9jayBwYXJhbWV0ZXIgaW50byBhIGJpbmRpbmcgQVNULlxuICogQHBhcmFtIGFzdCBCbG9jayBwYXJhbWV0ZXIgdGhhdCBzaG91bGQgYmUgcGFyc2VkLlxuICogQHBhcmFtIGJpbmRpbmdQYXJzZXIgUGFyc2VyIHRoYXQgdGhlIGV4cHJlc3Npb24gc2hvdWxkIGJlIHBhcnNlZCB3aXRoLlxuICogQHBhcmFtIHBhcnQgU3BlY2lmaWMgcGFydCBvZiB0aGUgZXhwcmVzc2lvbiB0aGF0IHNob3VsZCBiZSBwYXJzZWQuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlQmxvY2tQYXJhbWV0ZXJUb0JpbmRpbmcoXG4gIGFzdDogaHRtbC5CbG9ja1BhcmFtZXRlcixcbiAgYmluZGluZ1BhcnNlcjogQmluZGluZ1BhcnNlcixcbiAgcGFydD86IHN0cmluZyxcbik6IEFTVFdpdGhTb3VyY2Uge1xuICBsZXQgc3RhcnQ6IG51bWJlcjtcbiAgbGV0IGVuZDogbnVtYmVyO1xuXG4gIGlmICh0eXBlb2YgcGFydCA9PT0gJ3N0cmluZycpIHtcbiAgICAvLyBOb3RlOiBgbGFzdEluZGV4T2ZgIGhlcmUgc2hvdWxkIGJlIGVub3VnaCB0byBrbm93IHRoZSBzdGFydCBpbmRleCBvZiB0aGUgZXhwcmVzc2lvbixcbiAgICAvLyBiZWNhdXNlIHdlIGtub3cgdGhhdCBpdCdsbCBiZSBhdCB0aGUgZW5kIG9mIHRoZSBwYXJhbS4gSWRlYWxseSB3ZSBjb3VsZCB1c2UgdGhlIGBkYFxuICAgIC8vIGZsYWcgd2hlbiBtYXRjaGluZyB2aWEgcmVnZXggYW5kIGdldCB0aGUgaW5kZXggZnJvbSBgbWF0Y2guaW5kaWNlc2AsIGJ1dCBpdCdzIHVuY2xlYXJcbiAgICAvLyBpZiB3ZSBjYW4gdXNlIGl0IHlldCBzaW5jZSBpdCdzIGEgcmVsYXRpdmVseSBuZXcgZmVhdHVyZS4gU2VlOlxuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLXJlZ2V4cC1tYXRjaC1pbmRpY2VzXG4gICAgc3RhcnQgPSBNYXRoLm1heCgwLCBhc3QuZXhwcmVzc2lvbi5sYXN0SW5kZXhPZihwYXJ0KSk7XG4gICAgZW5kID0gc3RhcnQgKyBwYXJ0Lmxlbmd0aDtcbiAgfSBlbHNlIHtcbiAgICBzdGFydCA9IDA7XG4gICAgZW5kID0gYXN0LmV4cHJlc3Npb24ubGVuZ3RoO1xuICB9XG5cbiAgcmV0dXJuIGJpbmRpbmdQYXJzZXIucGFyc2VCaW5kaW5nKFxuICAgIGFzdC5leHByZXNzaW9uLnNsaWNlKHN0YXJ0LCBlbmQpLFxuICAgIGZhbHNlLFxuICAgIGFzdC5zb3VyY2VTcGFuLFxuICAgIGFzdC5zb3VyY2VTcGFuLnN0YXJ0Lm9mZnNldCArIHN0YXJ0LFxuICApO1xufVxuXG4vKiogUGFyc2VzIHRoZSBwYXJhbWV0ZXIgb2YgYSBjb25kaXRpb25hbCBibG9jayAoYGlmYCBvciBgZWxzZSBpZmApLiAqL1xuZnVuY3Rpb24gcGFyc2VDb25kaXRpb25hbEJsb2NrUGFyYW1ldGVycyhcbiAgYmxvY2s6IGh0bWwuQmxvY2ssXG4gIGVycm9yczogUGFyc2VFcnJvcltdLFxuICBiaW5kaW5nUGFyc2VyOiBCaW5kaW5nUGFyc2VyLFxuKSB7XG4gIGlmIChibG9jay5wYXJhbWV0ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKGJsb2NrLnNvdXJjZVNwYW4sICdDb25kaXRpb25hbCBibG9jayBkb2VzIG5vdCBoYXZlIGFuIGV4cHJlc3Npb24nKSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBleHByZXNzaW9uID0gcGFyc2VCbG9ja1BhcmFtZXRlclRvQmluZGluZyhibG9jay5wYXJhbWV0ZXJzWzBdLCBiaW5kaW5nUGFyc2VyKTtcbiAgbGV0IGV4cHJlc3Npb25BbGlhczogdC5WYXJpYWJsZSB8IG51bGwgPSBudWxsO1xuXG4gIC8vIFN0YXJ0IGZyb20gMSBzaW5jZSB3ZSBwcm9jZXNzZWQgdGhlIGZpcnN0IHBhcmFtZXRlciBhbHJlYWR5LlxuICBmb3IgKGxldCBpID0gMTsgaSA8IGJsb2NrLnBhcmFtZXRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBwYXJhbSA9IGJsb2NrLnBhcmFtZXRlcnNbaV07XG4gICAgY29uc3QgYWxpYXNNYXRjaCA9IHBhcmFtLmV4cHJlc3Npb24ubWF0Y2goQ09ORElUSU9OQUxfQUxJQVNfUEFUVEVSTik7XG5cbiAgICAvLyBGb3Igbm93IGNvbmRpdGlvbmFscyBjYW4gb25seSBoYXZlIGFuIGBhc2AgcGFyYW1ldGVyLlxuICAgIC8vIFdlIG1heSB3YW50IHRvIHJld29yayB0aGlzIGxhdGVyIGlmIHdlIGFkZCBtb3JlLlxuICAgIGlmIChhbGlhc01hdGNoID09PSBudWxsKSB7XG4gICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgbmV3IFBhcnNlRXJyb3IoXG4gICAgICAgICAgcGFyYW0uc291cmNlU3BhbixcbiAgICAgICAgICBgVW5yZWNvZ25pemVkIGNvbmRpdGlvbmFsIHBhcmFtYXRlciBcIiR7cGFyYW0uZXhwcmVzc2lvbn1cImAsXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoYmxvY2submFtZSAhPT0gJ2lmJykge1xuICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgIG5ldyBQYXJzZUVycm9yKFxuICAgICAgICAgIHBhcmFtLnNvdXJjZVNwYW4sXG4gICAgICAgICAgJ1wiYXNcIiBleHByZXNzaW9uIGlzIG9ubHkgYWxsb3dlZCBvbiB0aGUgcHJpbWFyeSBAaWYgYmxvY2snLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKGV4cHJlc3Npb25BbGlhcyAhPT0gbnVsbCkge1xuICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgIG5ldyBQYXJzZUVycm9yKHBhcmFtLnNvdXJjZVNwYW4sICdDb25kaXRpb25hbCBjYW4gb25seSBoYXZlIG9uZSBcImFzXCIgZXhwcmVzc2lvbicpLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbmFtZSA9IGFsaWFzTWF0Y2hbMl0udHJpbSgpO1xuICAgICAgY29uc3QgdmFyaWFibGVTdGFydCA9IHBhcmFtLnNvdXJjZVNwYW4uc3RhcnQubW92ZUJ5KGFsaWFzTWF0Y2hbMV0ubGVuZ3RoKTtcbiAgICAgIGNvbnN0IHZhcmlhYmxlU3BhbiA9IG5ldyBQYXJzZVNvdXJjZVNwYW4odmFyaWFibGVTdGFydCwgdmFyaWFibGVTdGFydC5tb3ZlQnkobmFtZS5sZW5ndGgpKTtcbiAgICAgIGV4cHJlc3Npb25BbGlhcyA9IG5ldyB0LlZhcmlhYmxlKG5hbWUsIG5hbWUsIHZhcmlhYmxlU3BhbiwgdmFyaWFibGVTcGFuKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge2V4cHJlc3Npb24sIGV4cHJlc3Npb25BbGlhc307XG59XG5cbi8qKiBTdHJpcHMgb3B0aW9uYWwgcGFyZW50aGVzZXMgYXJvdW5kIGZyb20gYSBjb250cm9sIGZyb20gZXhwcmVzc2lvbiBwYXJhbWV0ZXIuICovXG5mdW5jdGlvbiBzdHJpcE9wdGlvbmFsUGFyZW50aGVzZXMocGFyYW06IGh0bWwuQmxvY2tQYXJhbWV0ZXIsIGVycm9yczogUGFyc2VFcnJvcltdKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IGV4cHJlc3Npb24gPSBwYXJhbS5leHByZXNzaW9uO1xuICBjb25zdCBzcGFjZVJlZ2V4ID0gL15cXHMkLztcbiAgbGV0IG9wZW5QYXJlbnMgPSAwO1xuICBsZXQgc3RhcnQgPSAwO1xuICBsZXQgZW5kID0gZXhwcmVzc2lvbi5sZW5ndGggLSAxO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwcmVzc2lvbi5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGNoYXIgPSBleHByZXNzaW9uW2ldO1xuXG4gICAgaWYgKGNoYXIgPT09ICcoJykge1xuICAgICAgc3RhcnQgPSBpICsgMTtcbiAgICAgIG9wZW5QYXJlbnMrKztcbiAgICB9IGVsc2UgaWYgKHNwYWNlUmVnZXgudGVzdChjaGFyKSkge1xuICAgICAgY29udGludWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChvcGVuUGFyZW5zID09PSAwKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb247XG4gIH1cblxuICBmb3IgKGxldCBpID0gZXhwcmVzc2lvbi5sZW5ndGggLSAxOyBpID4gLTE7IGktLSkge1xuICAgIGNvbnN0IGNoYXIgPSBleHByZXNzaW9uW2ldO1xuXG4gICAgaWYgKGNoYXIgPT09ICcpJykge1xuICAgICAgZW5kID0gaTtcbiAgICAgIG9wZW5QYXJlbnMtLTtcbiAgICAgIGlmIChvcGVuUGFyZW5zID09PSAwKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc3BhY2VSZWdleC50ZXN0KGNoYXIpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKG9wZW5QYXJlbnMgIT09IDApIHtcbiAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihwYXJhbS5zb3VyY2VTcGFuLCAnVW5jbG9zZWQgcGFyZW50aGVzZXMgaW4gZXhwcmVzc2lvbicpKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBleHByZXNzaW9uLnNsaWNlKHN0YXJ0LCBlbmQpO1xufVxuIl19
|