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