@angular/compiler 19.0.0-next.1 → 19.0.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/fesm2022/compiler.mjs +5465 -4675
- package/fesm2022/compiler.mjs.map +1 -1
- package/index.d.ts +115 -15
- package/package.json +2 -4
- package/esm2022/compiler.mjs +0 -13
- package/esm2022/index.mjs +0 -13
- package/esm2022/public_api.mjs +0 -15
- package/esm2022/src/assertions.mjs +0 -31
- package/esm2022/src/chars.mjs +0 -90
- package/esm2022/src/compiler.mjs +0 -88
- package/esm2022/src/compiler_facade_interface.mjs +0 -29
- package/esm2022/src/config.mjs +0 -20
- package/esm2022/src/constant_pool.mjs +0 -285
- package/esm2022/src/core.mjs +0 -96
- package/esm2022/src/expression_parser/ast.mjs +0 -755
- package/esm2022/src/expression_parser/lexer.mjs +0 -421
- package/esm2022/src/expression_parser/parser.mjs +0 -1222
- package/esm2022/src/i18n/digest.mjs +0 -322
- package/esm2022/src/i18n/extractor_merger.mjs +0 -409
- package/esm2022/src/i18n/i18n_ast.mjs +0 -212
- package/esm2022/src/i18n/i18n_html_parser.mjs +0 -54
- package/esm2022/src/i18n/i18n_parser.mjs +0 -247
- package/esm2022/src/i18n/index.mjs +0 -16
- package/esm2022/src/i18n/message_bundle.mjs +0 -93
- package/esm2022/src/i18n/parse_util.mjs +0 -17
- package/esm2022/src/i18n/serializers/placeholder.mjs +0 -139
- package/esm2022/src/i18n/serializers/serializer.mjs +0 -77
- package/esm2022/src/i18n/serializers/xliff.mjs +0 -300
- package/esm2022/src/i18n/serializers/xliff2.mjs +0 -349
- package/esm2022/src/i18n/serializers/xmb.mjs +0 -188
- package/esm2022/src/i18n/serializers/xml_helper.mjs +0 -94
- package/esm2022/src/i18n/serializers/xtb.mjs +0 -186
- package/esm2022/src/i18n/translation_bundle.mjs +0 -164
- package/esm2022/src/injectable_compiler_2.mjs +0 -138
- package/esm2022/src/jit_compiler_facade.mjs +0 -681
- package/esm2022/src/ml_parser/ast.mjs +0 -167
- package/esm2022/src/ml_parser/defaults.mjs +0 -24
- package/esm2022/src/ml_parser/entities.mjs +0 -2144
- package/esm2022/src/ml_parser/html_parser.mjs +0 -18
- package/esm2022/src/ml_parser/html_tags.mjs +0 -156
- package/esm2022/src/ml_parser/html_whitespaces.mjs +0 -107
- package/esm2022/src/ml_parser/icu_ast_expander.mjs +0 -125
- package/esm2022/src/ml_parser/lexer.mjs +0 -1210
- package/esm2022/src/ml_parser/parser.mjs +0 -539
- package/esm2022/src/ml_parser/tags.mjs +0 -47
- package/esm2022/src/ml_parser/tokens.mjs +0 -9
- package/esm2022/src/ml_parser/xml_parser.mjs +0 -19
- package/esm2022/src/ml_parser/xml_tags.mjs +0 -32
- package/esm2022/src/output/abstract_emitter.mjs +0 -524
- package/esm2022/src/output/abstract_js_emitter.mjs +0 -130
- package/esm2022/src/output/map_util.mjs +0 -19
- package/esm2022/src/output/output_ast.mjs +0 -1301
- package/esm2022/src/output/output_jit.mjs +0 -138
- package/esm2022/src/output/output_jit_trusted_types.mjs +0 -100
- package/esm2022/src/output/source_map.mjs +0 -150
- package/esm2022/src/parse_util.mjs +0 -198
- package/esm2022/src/render3/partial/api.mjs +0 -9
- package/esm2022/src/render3/partial/class_metadata.mjs +0 -52
- package/esm2022/src/render3/partial/component.mjs +0 -197
- package/esm2022/src/render3/partial/directive.mjs +0 -264
- package/esm2022/src/render3/partial/factory.mjs +0 -35
- package/esm2022/src/render3/partial/injectable.mjs +0 -67
- package/esm2022/src/render3/partial/injector.mjs +0 -41
- package/esm2022/src/render3/partial/ng_module.mjs +0 -63
- package/esm2022/src/render3/partial/pipe.mjs +0 -50
- package/esm2022/src/render3/partial/util.mjs +0 -79
- package/esm2022/src/render3/r3_ast.mjs +0 -493
- package/esm2022/src/render3/r3_class_debug_info_compiler.mjs +0 -35
- package/esm2022/src/render3/r3_class_metadata_compiler.mjs +0 -92
- package/esm2022/src/render3/r3_control_flow.mjs +0 -421
- package/esm2022/src/render3/r3_deferred_blocks.mjs +0 -170
- package/esm2022/src/render3/r3_deferred_triggers.mjs +0 -316
- package/esm2022/src/render3/r3_factory.mjs +0 -200
- package/esm2022/src/render3/r3_identifiers.mjs +0 -480
- package/esm2022/src/render3/r3_injector_compiler.mjs +0 -28
- package/esm2022/src/render3/r3_jit.mjs +0 -29
- package/esm2022/src/render3/r3_module_compiler.mjs +0 -211
- package/esm2022/src/render3/r3_pipe_compiler.mjs +0 -35
- package/esm2022/src/render3/r3_template_transform.mjs +0 -560
- package/esm2022/src/render3/util.mjs +0 -90
- package/esm2022/src/render3/view/api.mjs +0 -14
- package/esm2022/src/render3/view/compiler.mjs +0 -546
- package/esm2022/src/render3/view/i18n/get_msg_utils.mjs +0 -113
- package/esm2022/src/render3/view/i18n/icu_serializer.mjs +0 -43
- package/esm2022/src/render3/view/i18n/localize_utils.mjs +0 -118
- package/esm2022/src/render3/view/i18n/meta.mjs +0 -259
- package/esm2022/src/render3/view/i18n/util.mjs +0 -70
- package/esm2022/src/render3/view/query_generation.mjs +0 -182
- package/esm2022/src/render3/view/t2_api.mjs +0 -9
- package/esm2022/src/render3/view/t2_binder.mjs +0 -823
- package/esm2022/src/render3/view/template.mjs +0 -113
- package/esm2022/src/render3/view/util.mjs +0 -192
- package/esm2022/src/resource_loader.mjs +0 -17
- package/esm2022/src/schema/dom_element_schema_registry.mjs +0 -471
- package/esm2022/src/schema/dom_security_schema.mjs +0 -96
- package/esm2022/src/schema/element_schema_registry.mjs +0 -10
- package/esm2022/src/schema/trusted_types_sinks.mjs +0 -41
- package/esm2022/src/selector.mjs +0 -400
- package/esm2022/src/shadow_css.mjs +0 -1053
- package/esm2022/src/style_url_resolver.mjs +0 -17
- package/esm2022/src/template/pipeline/ir/index.mjs +0 -18
- package/esm2022/src/template/pipeline/ir/src/enums.mjs +0 -503
- package/esm2022/src/template/pipeline/ir/src/expression.mjs +0 -997
- package/esm2022/src/template/pipeline/ir/src/handle.mjs +0 -13
- package/esm2022/src/template/pipeline/ir/src/operations.mjs +0 -261
- package/esm2022/src/template/pipeline/ir/src/ops/create.mjs +0 -405
- package/esm2022/src/template/pipeline/ir/src/ops/host.mjs +0 -25
- package/esm2022/src/template/pipeline/ir/src/ops/shared.mjs +0 -43
- package/esm2022/src/template/pipeline/ir/src/ops/update.mjs +0 -277
- package/esm2022/src/template/pipeline/ir/src/traits.mjs +0 -64
- package/esm2022/src/template/pipeline/ir/src/variable.mjs +0 -13
- package/esm2022/src/template/pipeline/src/compilation.mjs +0 -194
- package/esm2022/src/template/pipeline/src/conversion.mjs +0 -64
- package/esm2022/src/template/pipeline/src/emit.mjs +0 -238
- package/esm2022/src/template/pipeline/src/ingest.mjs +0 -1058
- package/esm2022/src/template/pipeline/src/instruction.mjs +0 -564
- package/esm2022/src/template/pipeline/src/phases/any_cast.mjs +0 -32
- package/esm2022/src/template/pipeline/src/phases/apply_i18n_expressions.mjs +0 -63
- package/esm2022/src/template/pipeline/src/phases/assign_i18n_slot_dependencies.mjs +0 -63
- package/esm2022/src/template/pipeline/src/phases/attribute_extraction.mjs +0 -138
- package/esm2022/src/template/pipeline/src/phases/binding_specialization.mjs +0 -75
- package/esm2022/src/template/pipeline/src/phases/chaining.mjs +0 -112
- package/esm2022/src/template/pipeline/src/phases/collapse_singleton_interpolations.mjs +0 -32
- package/esm2022/src/template/pipeline/src/phases/conditionals.mjs +0 -58
- package/esm2022/src/template/pipeline/src/phases/const_collection.mjs +0 -214
- package/esm2022/src/template/pipeline/src/phases/convert_i18n_bindings.mjs +0 -52
- package/esm2022/src/template/pipeline/src/phases/create_i18n_contexts.mjs +0 -105
- package/esm2022/src/template/pipeline/src/phases/deduplicate_text_bindings.mjs +0 -40
- package/esm2022/src/template/pipeline/src/phases/defer_configs.mjs +0 -29
- package/esm2022/src/template/pipeline/src/phases/defer_resolve_targets.mjs +0 -113
- package/esm2022/src/template/pipeline/src/phases/empty_elements.mjs +0 -47
- package/esm2022/src/template/pipeline/src/phases/expand_safe_reads.mjs +0 -192
- package/esm2022/src/template/pipeline/src/phases/extract_i18n_messages.mjs +0 -218
- package/esm2022/src/template/pipeline/src/phases/generate_advance.mjs +0 -66
- package/esm2022/src/template/pipeline/src/phases/generate_local_let_references.mjs +0 -29
- package/esm2022/src/template/pipeline/src/phases/generate_projection_def.mjs +0 -46
- package/esm2022/src/template/pipeline/src/phases/generate_variables.mjs +0 -170
- package/esm2022/src/template/pipeline/src/phases/has_const_expression_collection.mjs +0 -28
- package/esm2022/src/template/pipeline/src/phases/host_style_property_parsing.mjs +0 -81
- package/esm2022/src/template/pipeline/src/phases/i18n_const_collection.mjs +0 -309
- package/esm2022/src/template/pipeline/src/phases/i18n_text_extraction.mjs +0 -97
- package/esm2022/src/template/pipeline/src/phases/local_refs.mjs +0 -43
- package/esm2022/src/template/pipeline/src/phases/namespace.mjs +0 -26
- package/esm2022/src/template/pipeline/src/phases/naming.mjs +0 -179
- package/esm2022/src/template/pipeline/src/phases/next_context_merging.mjs +0 -75
- package/esm2022/src/template/pipeline/src/phases/ng_container.mjs +0 -29
- package/esm2022/src/template/pipeline/src/phases/nonbindable.mjs +0 -47
- package/esm2022/src/template/pipeline/src/phases/nullish_coalescing.mjs +0 -33
- package/esm2022/src/template/pipeline/src/phases/ordering.mjs +0 -140
- package/esm2022/src/template/pipeline/src/phases/parse_extracted_styles.mjs +0 -137
- package/esm2022/src/template/pipeline/src/phases/phase_remove_content_selectors.mjs +0 -42
- package/esm2022/src/template/pipeline/src/phases/pipe_creation.mjs +0 -74
- package/esm2022/src/template/pipeline/src/phases/pipe_variadic.mjs +0 -30
- package/esm2022/src/template/pipeline/src/phases/propagate_i18n_blocks.mjs +0 -81
- package/esm2022/src/template/pipeline/src/phases/pure_function_extraction.mjs +0 -55
- package/esm2022/src/template/pipeline/src/phases/pure_literal_structures.mjs +0 -58
- package/esm2022/src/template/pipeline/src/phases/reify.mjs +0 -433
- package/esm2022/src/template/pipeline/src/phases/remove_empty_bindings.mjs +0 -31
- package/esm2022/src/template/pipeline/src/phases/remove_i18n_contexts.mjs +0 -27
- package/esm2022/src/template/pipeline/src/phases/remove_illegal_let_references.mjs +0 -36
- package/esm2022/src/template/pipeline/src/phases/remove_unused_i18n_attrs.mjs +0 -33
- package/esm2022/src/template/pipeline/src/phases/resolve_contexts.mjs +0 -60
- package/esm2022/src/template/pipeline/src/phases/resolve_defer_deps_fns.mjs +0 -31
- package/esm2022/src/template/pipeline/src/phases/resolve_dollar_event.mjs +0 -36
- package/esm2022/src/template/pipeline/src/phases/resolve_i18n_element_placeholders.mjs +0 -266
- package/esm2022/src/template/pipeline/src/phases/resolve_i18n_expression_placeholders.mjs +0 -70
- package/esm2022/src/template/pipeline/src/phases/resolve_names.mjs +0 -124
- package/esm2022/src/template/pipeline/src/phases/resolve_sanitizers.mjs +0 -123
- package/esm2022/src/template/pipeline/src/phases/save_restore_view.mjs +0 -64
- package/esm2022/src/template/pipeline/src/phases/slot_allocation.mjs +0 -62
- package/esm2022/src/template/pipeline/src/phases/store_let_optimization.mjs +0 -35
- package/esm2022/src/template/pipeline/src/phases/style_binding_specialization.mjs +0 -42
- package/esm2022/src/template/pipeline/src/phases/temporary_variables.mjs +0 -87
- package/esm2022/src/template/pipeline/src/phases/track_fn_generation.mjs +0 -52
- package/esm2022/src/template/pipeline/src/phases/track_fn_optimization.mjs +0 -88
- package/esm2022/src/template/pipeline/src/phases/track_variables.mjs +0 -36
- package/esm2022/src/template/pipeline/src/phases/transform_two_way_binding_set.mjs +0 -43
- package/esm2022/src/template/pipeline/src/phases/var_counting.mjs +0 -155
- package/esm2022/src/template/pipeline/src/phases/variable_optimization.mjs +0 -423
- package/esm2022/src/template/pipeline/src/phases/wrap_icus.mjs +0 -41
- package/esm2022/src/template/pipeline/src/util/elements.mjs +0 -29
- package/esm2022/src/template_parser/binding_parser.mjs +0 -465
- package/esm2022/src/template_parser/template_preparser.mjs +0 -84
- package/esm2022/src/util.mjs +0 -124
- package/esm2022/src/version.mjs +0 -15
|
@@ -1,409 +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 * as html from '../ml_parser/ast';
|
|
9
|
-
import { DEFAULT_CONTAINER_BLOCKS } from '../ml_parser/defaults';
|
|
10
|
-
import { ParseTreeResult } from '../ml_parser/parser';
|
|
11
|
-
import * as i18n from './i18n_ast';
|
|
12
|
-
import { createI18nMessageFactory } from './i18n_parser';
|
|
13
|
-
import { I18nError } from './parse_util';
|
|
14
|
-
const _I18N_ATTR = 'i18n';
|
|
15
|
-
const _I18N_ATTR_PREFIX = 'i18n-';
|
|
16
|
-
const _I18N_COMMENT_PREFIX_REGEXP = /^i18n:?/;
|
|
17
|
-
const MEANING_SEPARATOR = '|';
|
|
18
|
-
const ID_SEPARATOR = '@@';
|
|
19
|
-
let i18nCommentsWarned = false;
|
|
20
|
-
/**
|
|
21
|
-
* Extract translatable messages from an html AST
|
|
22
|
-
*/
|
|
23
|
-
export function extractMessages(nodes, interpolationConfig, implicitTags, implicitAttrs) {
|
|
24
|
-
const visitor = new _Visitor(implicitTags, implicitAttrs);
|
|
25
|
-
return visitor.extract(nodes, interpolationConfig);
|
|
26
|
-
}
|
|
27
|
-
export function mergeTranslations(nodes, translations, interpolationConfig, implicitTags, implicitAttrs) {
|
|
28
|
-
const visitor = new _Visitor(implicitTags, implicitAttrs);
|
|
29
|
-
return visitor.merge(nodes, translations, interpolationConfig);
|
|
30
|
-
}
|
|
31
|
-
export class ExtractionResult {
|
|
32
|
-
constructor(messages, errors) {
|
|
33
|
-
this.messages = messages;
|
|
34
|
-
this.errors = errors;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
var _VisitorMode;
|
|
38
|
-
(function (_VisitorMode) {
|
|
39
|
-
_VisitorMode[_VisitorMode["Extract"] = 0] = "Extract";
|
|
40
|
-
_VisitorMode[_VisitorMode["Merge"] = 1] = "Merge";
|
|
41
|
-
})(_VisitorMode || (_VisitorMode = {}));
|
|
42
|
-
/**
|
|
43
|
-
* This Visitor is used:
|
|
44
|
-
* 1. to extract all the translatable strings from an html AST (see `extract()`),
|
|
45
|
-
* 2. to replace the translatable strings with the actual translations (see `merge()`)
|
|
46
|
-
*
|
|
47
|
-
* @internal
|
|
48
|
-
*/
|
|
49
|
-
class _Visitor {
|
|
50
|
-
constructor(_implicitTags, _implicitAttrs) {
|
|
51
|
-
this._implicitTags = _implicitTags;
|
|
52
|
-
this._implicitAttrs = _implicitAttrs;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Extracts the messages from the tree
|
|
56
|
-
*/
|
|
57
|
-
extract(nodes, interpolationConfig) {
|
|
58
|
-
this._init(_VisitorMode.Extract, interpolationConfig);
|
|
59
|
-
nodes.forEach((node) => node.visit(this, null));
|
|
60
|
-
if (this._inI18nBlock) {
|
|
61
|
-
this._reportError(nodes[nodes.length - 1], 'Unclosed block');
|
|
62
|
-
}
|
|
63
|
-
return new ExtractionResult(this._messages, this._errors);
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Returns a tree where all translatable nodes are translated
|
|
67
|
-
*/
|
|
68
|
-
merge(nodes, translations, interpolationConfig) {
|
|
69
|
-
this._init(_VisitorMode.Merge, interpolationConfig);
|
|
70
|
-
this._translations = translations;
|
|
71
|
-
// Construct a single fake root element
|
|
72
|
-
const wrapper = new html.Element('wrapper', [], nodes, undefined, undefined, undefined);
|
|
73
|
-
const translatedNode = wrapper.visit(this, null);
|
|
74
|
-
if (this._inI18nBlock) {
|
|
75
|
-
this._reportError(nodes[nodes.length - 1], 'Unclosed block');
|
|
76
|
-
}
|
|
77
|
-
return new ParseTreeResult(translatedNode.children, this._errors);
|
|
78
|
-
}
|
|
79
|
-
visitExpansionCase(icuCase, context) {
|
|
80
|
-
// Parse cases for translatable html attributes
|
|
81
|
-
const expression = html.visitAll(this, icuCase.expression, context);
|
|
82
|
-
if (this._mode === _VisitorMode.Merge) {
|
|
83
|
-
return new html.ExpansionCase(icuCase.value, expression, icuCase.sourceSpan, icuCase.valueSourceSpan, icuCase.expSourceSpan);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
visitExpansion(icu, context) {
|
|
87
|
-
this._mayBeAddBlockChildren(icu);
|
|
88
|
-
const wasInIcu = this._inIcu;
|
|
89
|
-
if (!this._inIcu) {
|
|
90
|
-
// nested ICU messages should not be extracted but top-level translated as a whole
|
|
91
|
-
if (this._isInTranslatableSection) {
|
|
92
|
-
this._addMessage([icu]);
|
|
93
|
-
}
|
|
94
|
-
this._inIcu = true;
|
|
95
|
-
}
|
|
96
|
-
const cases = html.visitAll(this, icu.cases, context);
|
|
97
|
-
if (this._mode === _VisitorMode.Merge) {
|
|
98
|
-
icu = new html.Expansion(icu.switchValue, icu.type, cases, icu.sourceSpan, icu.switchValueSourceSpan);
|
|
99
|
-
}
|
|
100
|
-
this._inIcu = wasInIcu;
|
|
101
|
-
return icu;
|
|
102
|
-
}
|
|
103
|
-
visitComment(comment, context) {
|
|
104
|
-
const isOpening = _isOpeningComment(comment);
|
|
105
|
-
if (isOpening && this._isInTranslatableSection) {
|
|
106
|
-
this._reportError(comment, 'Could not start a block inside a translatable section');
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const isClosing = _isClosingComment(comment);
|
|
110
|
-
if (isClosing && !this._inI18nBlock) {
|
|
111
|
-
this._reportError(comment, 'Trying to close an unopened block');
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
if (!this._inI18nNode && !this._inIcu) {
|
|
115
|
-
if (!this._inI18nBlock) {
|
|
116
|
-
if (isOpening) {
|
|
117
|
-
// deprecated from v5 you should use <ng-container i18n> instead of i18n comments
|
|
118
|
-
if (!i18nCommentsWarned && console && console.warn) {
|
|
119
|
-
i18nCommentsWarned = true;
|
|
120
|
-
const details = comment.sourceSpan.details ? `, ${comment.sourceSpan.details}` : '';
|
|
121
|
-
// TODO(ocombe): use a log service once there is a public one available
|
|
122
|
-
console.warn(`I18n comments are deprecated, use an <ng-container> element instead (${comment.sourceSpan.start}${details})`);
|
|
123
|
-
}
|
|
124
|
-
this._inI18nBlock = true;
|
|
125
|
-
this._blockStartDepth = this._depth;
|
|
126
|
-
this._blockChildren = [];
|
|
127
|
-
this._blockMeaningAndDesc = comment
|
|
128
|
-
.value.replace(_I18N_COMMENT_PREFIX_REGEXP, '')
|
|
129
|
-
.trim();
|
|
130
|
-
this._openTranslatableSection(comment);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
if (isClosing) {
|
|
135
|
-
if (this._depth == this._blockStartDepth) {
|
|
136
|
-
this._closeTranslatableSection(comment, this._blockChildren);
|
|
137
|
-
this._inI18nBlock = false;
|
|
138
|
-
const message = this._addMessage(this._blockChildren, this._blockMeaningAndDesc);
|
|
139
|
-
// merge attributes in sections
|
|
140
|
-
const nodes = this._translateMessage(comment, message);
|
|
141
|
-
return html.visitAll(this, nodes);
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
this._reportError(comment, 'I18N blocks should not cross element boundaries');
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
visitText(text, context) {
|
|
152
|
-
if (this._isInTranslatableSection) {
|
|
153
|
-
this._mayBeAddBlockChildren(text);
|
|
154
|
-
}
|
|
155
|
-
return text;
|
|
156
|
-
}
|
|
157
|
-
visitElement(el, context) {
|
|
158
|
-
this._mayBeAddBlockChildren(el);
|
|
159
|
-
this._depth++;
|
|
160
|
-
const wasInI18nNode = this._inI18nNode;
|
|
161
|
-
const wasInImplicitNode = this._inImplicitNode;
|
|
162
|
-
let childNodes = [];
|
|
163
|
-
let translatedChildNodes = undefined;
|
|
164
|
-
// Extract:
|
|
165
|
-
// - top level nodes with the (implicit) "i18n" attribute if not already in a section
|
|
166
|
-
// - ICU messages
|
|
167
|
-
const i18nAttr = _getI18nAttr(el);
|
|
168
|
-
const i18nMeta = i18nAttr ? i18nAttr.value : '';
|
|
169
|
-
const isImplicit = this._implicitTags.some((tag) => el.name === tag) &&
|
|
170
|
-
!this._inIcu &&
|
|
171
|
-
!this._isInTranslatableSection;
|
|
172
|
-
const isTopLevelImplicit = !wasInImplicitNode && isImplicit;
|
|
173
|
-
this._inImplicitNode = wasInImplicitNode || isImplicit;
|
|
174
|
-
if (!this._isInTranslatableSection && !this._inIcu) {
|
|
175
|
-
if (i18nAttr || isTopLevelImplicit) {
|
|
176
|
-
this._inI18nNode = true;
|
|
177
|
-
const message = this._addMessage(el.children, i18nMeta);
|
|
178
|
-
translatedChildNodes = this._translateMessage(el, message);
|
|
179
|
-
}
|
|
180
|
-
if (this._mode == _VisitorMode.Extract) {
|
|
181
|
-
const isTranslatable = i18nAttr || isTopLevelImplicit;
|
|
182
|
-
if (isTranslatable)
|
|
183
|
-
this._openTranslatableSection(el);
|
|
184
|
-
html.visitAll(this, el.children);
|
|
185
|
-
if (isTranslatable)
|
|
186
|
-
this._closeTranslatableSection(el, el.children);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
else {
|
|
190
|
-
if (i18nAttr || isTopLevelImplicit) {
|
|
191
|
-
this._reportError(el, 'Could not mark an element as translatable inside a translatable section');
|
|
192
|
-
}
|
|
193
|
-
if (this._mode == _VisitorMode.Extract) {
|
|
194
|
-
// Descend into child nodes for extraction
|
|
195
|
-
html.visitAll(this, el.children);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
if (this._mode === _VisitorMode.Merge) {
|
|
199
|
-
const visitNodes = translatedChildNodes || el.children;
|
|
200
|
-
visitNodes.forEach((child) => {
|
|
201
|
-
const visited = child.visit(this, context);
|
|
202
|
-
if (visited && !this._isInTranslatableSection) {
|
|
203
|
-
// Do not add the children from translatable sections (= i18n blocks here)
|
|
204
|
-
// They will be added later in this loop when the block closes (i.e. on `<!-- /i18n -->`)
|
|
205
|
-
childNodes = childNodes.concat(visited);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
this._visitAttributesOf(el);
|
|
210
|
-
this._depth--;
|
|
211
|
-
this._inI18nNode = wasInI18nNode;
|
|
212
|
-
this._inImplicitNode = wasInImplicitNode;
|
|
213
|
-
if (this._mode === _VisitorMode.Merge) {
|
|
214
|
-
const translatedAttrs = this._translateAttributes(el);
|
|
215
|
-
return new html.Element(el.name, translatedAttrs, childNodes, el.sourceSpan, el.startSourceSpan, el.endSourceSpan);
|
|
216
|
-
}
|
|
217
|
-
return null;
|
|
218
|
-
}
|
|
219
|
-
visitAttribute(attribute, context) {
|
|
220
|
-
throw new Error('unreachable code');
|
|
221
|
-
}
|
|
222
|
-
visitBlock(block, context) {
|
|
223
|
-
html.visitAll(this, block.children, context);
|
|
224
|
-
}
|
|
225
|
-
visitBlockParameter(parameter, context) { }
|
|
226
|
-
visitLetDeclaration(decl, context) { }
|
|
227
|
-
_init(mode, interpolationConfig) {
|
|
228
|
-
this._mode = mode;
|
|
229
|
-
this._inI18nBlock = false;
|
|
230
|
-
this._inI18nNode = false;
|
|
231
|
-
this._depth = 0;
|
|
232
|
-
this._inIcu = false;
|
|
233
|
-
this._msgCountAtSectionStart = undefined;
|
|
234
|
-
this._errors = [];
|
|
235
|
-
this._messages = [];
|
|
236
|
-
this._inImplicitNode = false;
|
|
237
|
-
this._createI18nMessage = createI18nMessageFactory(interpolationConfig, DEFAULT_CONTAINER_BLOCKS);
|
|
238
|
-
}
|
|
239
|
-
// looks for translatable attributes
|
|
240
|
-
_visitAttributesOf(el) {
|
|
241
|
-
const explicitAttrNameToValue = {};
|
|
242
|
-
const implicitAttrNames = this._implicitAttrs[el.name] || [];
|
|
243
|
-
el.attrs
|
|
244
|
-
.filter((attr) => attr.name.startsWith(_I18N_ATTR_PREFIX))
|
|
245
|
-
.forEach((attr) => (explicitAttrNameToValue[attr.name.slice(_I18N_ATTR_PREFIX.length)] = attr.value));
|
|
246
|
-
el.attrs.forEach((attr) => {
|
|
247
|
-
if (attr.name in explicitAttrNameToValue) {
|
|
248
|
-
this._addMessage([attr], explicitAttrNameToValue[attr.name]);
|
|
249
|
-
}
|
|
250
|
-
else if (implicitAttrNames.some((name) => attr.name === name)) {
|
|
251
|
-
this._addMessage([attr]);
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
// add a translatable message
|
|
256
|
-
_addMessage(ast, msgMeta) {
|
|
257
|
-
if (ast.length == 0 ||
|
|
258
|
-
(ast.length == 1 && ast[0] instanceof html.Attribute && !ast[0].value)) {
|
|
259
|
-
// Do not create empty messages
|
|
260
|
-
return null;
|
|
261
|
-
}
|
|
262
|
-
const { meaning, description, id } = _parseMessageMeta(msgMeta);
|
|
263
|
-
const message = this._createI18nMessage(ast, meaning, description, id);
|
|
264
|
-
this._messages.push(message);
|
|
265
|
-
return message;
|
|
266
|
-
}
|
|
267
|
-
// Translates the given message given the `TranslationBundle`
|
|
268
|
-
// This is used for translating elements / blocks - see `_translateAttributes` for attributes
|
|
269
|
-
// no-op when called in extraction mode (returns [])
|
|
270
|
-
_translateMessage(el, message) {
|
|
271
|
-
if (message && this._mode === _VisitorMode.Merge) {
|
|
272
|
-
const nodes = this._translations.get(message);
|
|
273
|
-
if (nodes) {
|
|
274
|
-
return nodes;
|
|
275
|
-
}
|
|
276
|
-
this._reportError(el, `Translation unavailable for message id="${this._translations.digest(message)}"`);
|
|
277
|
-
}
|
|
278
|
-
return [];
|
|
279
|
-
}
|
|
280
|
-
// translate the attributes of an element and remove i18n specific attributes
|
|
281
|
-
_translateAttributes(el) {
|
|
282
|
-
const attributes = el.attrs;
|
|
283
|
-
const i18nParsedMessageMeta = {};
|
|
284
|
-
attributes.forEach((attr) => {
|
|
285
|
-
if (attr.name.startsWith(_I18N_ATTR_PREFIX)) {
|
|
286
|
-
i18nParsedMessageMeta[attr.name.slice(_I18N_ATTR_PREFIX.length)] = _parseMessageMeta(attr.value);
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
const translatedAttributes = [];
|
|
290
|
-
attributes.forEach((attr) => {
|
|
291
|
-
if (attr.name === _I18N_ATTR || attr.name.startsWith(_I18N_ATTR_PREFIX)) {
|
|
292
|
-
// strip i18n specific attributes
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
if (attr.value && attr.value != '' && i18nParsedMessageMeta.hasOwnProperty(attr.name)) {
|
|
296
|
-
const { meaning, description, id } = i18nParsedMessageMeta[attr.name];
|
|
297
|
-
const message = this._createI18nMessage([attr], meaning, description, id);
|
|
298
|
-
const nodes = this._translations.get(message);
|
|
299
|
-
if (nodes) {
|
|
300
|
-
if (nodes.length == 0) {
|
|
301
|
-
translatedAttributes.push(new html.Attribute(attr.name, '', attr.sourceSpan, undefined /* keySpan */, undefined /* valueSpan */, undefined /* valueTokens */, undefined /* i18n */));
|
|
302
|
-
}
|
|
303
|
-
else if (nodes[0] instanceof html.Text) {
|
|
304
|
-
const value = nodes[0].value;
|
|
305
|
-
translatedAttributes.push(new html.Attribute(attr.name, value, attr.sourceSpan, undefined /* keySpan */, undefined /* valueSpan */, undefined /* valueTokens */, undefined /* i18n */));
|
|
306
|
-
}
|
|
307
|
-
else {
|
|
308
|
-
this._reportError(el, `Unexpected translation for attribute "${attr.name}" (id="${id || this._translations.digest(message)}")`);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
this._reportError(el, `Translation unavailable for attribute "${attr.name}" (id="${id || this._translations.digest(message)}")`);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
translatedAttributes.push(attr);
|
|
317
|
-
}
|
|
318
|
-
});
|
|
319
|
-
return translatedAttributes;
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Add the node as a child of the block when:
|
|
323
|
-
* - we are in a block,
|
|
324
|
-
* - we are not inside a ICU message (those are handled separately),
|
|
325
|
-
* - the node is a "direct child" of the block
|
|
326
|
-
*/
|
|
327
|
-
_mayBeAddBlockChildren(node) {
|
|
328
|
-
if (this._inI18nBlock && !this._inIcu && this._depth == this._blockStartDepth) {
|
|
329
|
-
this._blockChildren.push(node);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Marks the start of a section, see `_closeTranslatableSection`
|
|
334
|
-
*/
|
|
335
|
-
_openTranslatableSection(node) {
|
|
336
|
-
if (this._isInTranslatableSection) {
|
|
337
|
-
this._reportError(node, 'Unexpected section start');
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
this._msgCountAtSectionStart = this._messages.length;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
/**
|
|
344
|
-
* A translatable section could be:
|
|
345
|
-
* - the content of translatable element,
|
|
346
|
-
* - nodes between `<!-- i18n -->` and `<!-- /i18n -->` comments
|
|
347
|
-
*/
|
|
348
|
-
get _isInTranslatableSection() {
|
|
349
|
-
return this._msgCountAtSectionStart !== void 0;
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Terminates a section.
|
|
353
|
-
*
|
|
354
|
-
* If a section has only one significant children (comments not significant) then we should not
|
|
355
|
-
* keep the message from this children:
|
|
356
|
-
*
|
|
357
|
-
* `<p i18n="meaning|description">{ICU message}</p>` would produce two messages:
|
|
358
|
-
* - one for the <p> content with meaning and description,
|
|
359
|
-
* - another one for the ICU message.
|
|
360
|
-
*
|
|
361
|
-
* In this case the last message is discarded as it contains less information (the AST is
|
|
362
|
-
* otherwise identical).
|
|
363
|
-
*
|
|
364
|
-
* Note that we should still keep messages extracted from attributes inside the section (ie in the
|
|
365
|
-
* ICU message here)
|
|
366
|
-
*/
|
|
367
|
-
_closeTranslatableSection(node, directChildren) {
|
|
368
|
-
if (!this._isInTranslatableSection) {
|
|
369
|
-
this._reportError(node, 'Unexpected section end');
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
const startIndex = this._msgCountAtSectionStart;
|
|
373
|
-
const significantChildren = directChildren.reduce((count, node) => count + (node instanceof html.Comment ? 0 : 1), 0);
|
|
374
|
-
if (significantChildren == 1) {
|
|
375
|
-
for (let i = this._messages.length - 1; i >= startIndex; i--) {
|
|
376
|
-
const ast = this._messages[i].nodes;
|
|
377
|
-
if (!(ast.length == 1 && ast[0] instanceof i18n.Text)) {
|
|
378
|
-
this._messages.splice(i, 1);
|
|
379
|
-
break;
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
this._msgCountAtSectionStart = undefined;
|
|
384
|
-
}
|
|
385
|
-
_reportError(node, msg) {
|
|
386
|
-
this._errors.push(new I18nError(node.sourceSpan, msg));
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
function _isOpeningComment(n) {
|
|
390
|
-
return !!(n instanceof html.Comment && n.value && n.value.startsWith('i18n'));
|
|
391
|
-
}
|
|
392
|
-
function _isClosingComment(n) {
|
|
393
|
-
return !!(n instanceof html.Comment && n.value && n.value === '/i18n');
|
|
394
|
-
}
|
|
395
|
-
function _getI18nAttr(p) {
|
|
396
|
-
return p.attrs.find((attr) => attr.name === _I18N_ATTR) || null;
|
|
397
|
-
}
|
|
398
|
-
function _parseMessageMeta(i18n) {
|
|
399
|
-
if (!i18n)
|
|
400
|
-
return { meaning: '', description: '', id: '' };
|
|
401
|
-
const idIndex = i18n.indexOf(ID_SEPARATOR);
|
|
402
|
-
const descIndex = i18n.indexOf(MEANING_SEPARATOR);
|
|
403
|
-
const [meaningAndDesc, id] = idIndex > -1 ? [i18n.slice(0, idIndex), i18n.slice(idIndex + 2)] : [i18n, ''];
|
|
404
|
-
const [meaning, description] = descIndex > -1
|
|
405
|
-
? [meaningAndDesc.slice(0, descIndex), meaningAndDesc.slice(descIndex + 1)]
|
|
406
|
-
: ['', meaningAndDesc];
|
|
407
|
-
return { meaning, description, id: id.trim() };
|
|
408
|
-
}
|
|
409
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0cmFjdG9yX21lcmdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbXBpbGVyL3NyYy9pMThuL2V4dHJhY3Rvcl9tZXJnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxLQUFLLElBQUksTUFBTSxrQkFBa0IsQ0FBQztBQUN6QyxPQUFPLEVBQUMsd0JBQXdCLEVBQXNCLE1BQU0sdUJBQXVCLENBQUM7QUFDcEYsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBRXBELE9BQU8sS0FBSyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQ25DLE9BQU8sRUFBQyx3QkFBd0IsRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFDM0UsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUd2QyxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUM7QUFDMUIsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUM7QUFDbEMsTUFBTSwyQkFBMkIsR0FBRyxTQUFTLENBQUM7QUFDOUMsTUFBTSxpQkFBaUIsR0FBRyxHQUFHLENBQUM7QUFDOUIsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDO0FBQzFCLElBQUksa0JBQWtCLEdBQUcsS0FBSyxDQUFDO0FBRS9COztHQUVHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FDN0IsS0FBa0IsRUFDbEIsbUJBQXdDLEVBQ3hDLFlBQXNCLEVBQ3RCLGFBQXNDO0lBRXRDLE1BQU0sT0FBTyxHQUFHLElBQUksUUFBUSxDQUFDLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQztJQUMxRCxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLG1CQUFtQixDQUFDLENBQUM7QUFDckQsQ0FBQztBQUVELE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsS0FBa0IsRUFDbEIsWUFBK0IsRUFDL0IsbUJBQXdDLEVBQ3hDLFlBQXNC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LENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNoRixNQUFNLENBQUMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxHQUMxQixTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ1osQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDM0UsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBRTNCLE9BQU8sRUFBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUMsQ0FBQztBQUMvQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCAqIGFzIGh0bWwgZnJvbSAnLi4vbWxfcGFyc2VyL2FzdCc7XG5pbXBvcnQge0RFRkFVTFRfQ09OVEFJTkVSX0JMT0NLUywgSW50ZXJwb2xhdGlvbkNvbmZpZ30gZnJvbSAnLi4vbWxfcGFyc2VyL2RlZmF1bHRzJztcbmltcG9ydCB7UGFyc2VUcmVlUmVzdWx0fSBmcm9tICcuLi9tbF9wYXJzZXIvcGFyc2VyJztcblxuaW1wb3J0ICogYXMgaTE4biBmcm9tICcuL2kxOG5fYXN0JztcbmltcG9ydCB7Y3JlYXRlSTE4bk1lc3NhZ2VGYWN0b3J5LCBJMThuTWVzc2FnZUZhY3Rvcnl9IGZyb20gJy4vaTE4bl9wYXJzZXInO1xuaW1wb3J0IHtJMThuRXJyb3J9IGZyb20gJy4vcGFyc2VfdXRpbCc7XG5pbXBvcnQge1RyYW5zbGF0aW9uQnVuZGxlfSBmcm9tICcuL3RyYW5zbGF0aW9uX2J1bmRsZSc7XG5cbmNvbnN0IF9JMThOX0FUVFIgPSAnaTE4bic7XG5jb25zdCBfSTE4Tl9BVFRSX1BSRUZJWCA9ICdpMThuLSc7XG5jb25zdCBfSTE4Tl9DT01NRU5UX1BSRUZJWF9SRUdFWFAgPSAvXmkxOG46Py87XG5jb25zdCBNRUFOSU5HX1NFUEFSQVRPUiA9ICd8JztcbmNvbnN0IElEX1NFUEFSQVRPUiA9ICdAQCc7XG5sZXQgaTE4bkNvbW1lbnRzV2FybmVkID0gZmFsc2U7XG5cbi8qKlxuICogRXh0cmFjdCB0cmFuc2xhdGFibGUgbWVzc2FnZXMgZnJvbSBhbiBodG1sIEFTVFxuICovXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdE1lc3NhZ2VzKFxuICBub2RlczogaHRtbC5Ob2RlW10sXG4gIGludGVycG9sYXRpb25Db25maWc6IEludGVycG9sYXRpb25Db25maWcsXG4gIGltcGxpY2l0VGFnczogc3RyaW5nW10sXG4gIGltcGxpY2l0QXR0cnM6IHtbazogc3RyaW5nXTogc3RyaW5nW119LFxuKTogRXh0cmFjdGlvblJlc3VsdCB7XG4gIGNvbnN0IHZpc2l0b3IgPSBuZXcgX1Zpc2l0b3IoaW1wbGljaXRUYWdzLCBpbXBsaWNpdEF0dHJzKTtcbiAgcmV0dXJuIHZpc2l0b3IuZXh0cmFjdChub2RlcywgaW50ZXJwb2xhdGlvbkNvbmZpZyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZVRyYW5zbGF0aW9ucyhcbiAgbm9kZXM6IGh0bWwuTm9kZVtdLFxuICB0cmFuc2xhdGlvbnM6IFRyYW5zbGF0aW9uQnVuZGxlLFxuICBpbnRlcnBvbGF0aW9uQ29uZmlnOiBJbnRlcnBvbGF0aW9uQ29uZmlnLFxuICBpbXBsaWNpdFRhZ3M6IHN0cmluZ1tdLFxuICBpbXBsaWNpdEF0dHJzOiB7W2s6IHN0cmluZ106IHN0cmluZ1tdfSxcbik6IFBhcnNlVHJlZVJlc3VsdCB7XG4gIGNvbnN0IHZpc2l0b3IgPSBuZXcgX1Zpc2l0b3IoaW1wbGljaXRUYWdzLCBpbXBsaWNpdEF0dHJzKTtcbiAgcmV0dXJuIHZpc2l0b3IubWVyZ2Uobm9kZXMsIHRyYW5zbGF0aW9ucywgaW50ZXJwb2xhdGlvbkNvbmZpZyk7XG59XG5cbmV4cG9ydCBjbGFzcyBFeHRyYWN0aW9uUmVzdWx0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIG1lc3NhZ2VzOiBpMThuLk1lc3NhZ2VbXSxcbiAgICBwdWJsaWMgZXJyb3JzOiBJMThuRXJyb3JbXSxcbiAgKSB7fVxufVxuXG5lbnVtIF9WaXNpdG9yTW9kZSB7XG4gIEV4dHJhY3QsXG4gIE1lcmdlLFxufVxuXG4vKipcbiAqIFRoaXMgVmlzaXRvciBpcyB1c2VkOlxuICogMS4gdG8gZXh0cmFjdCBhbGwgdGhlIHRyYW5zbGF0YWJsZSBzdHJpbmdzIGZyb20gYW4gaHRtbCBBU1QgKHNlZSBgZXh0cmFjdCgpYCksXG4gKiAyLiB0byByZXBsYWNlIHRoZSB0cmFuc2xhdGFibGUgc3RyaW5ncyB3aXRoIHRoZSBhY3R1YWwgdHJhbnNsYXRpb25zIChzZWUgYG1lcmdlKClgKVxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5jbGFzcyBfVmlzaXRvciBpbXBsZW1lbnRzIGh0bWwuVmlzaXRvciB7XG4gIC8vIFVzaW5nIG5vbi1udWxsIGFzc2VydGlvbnMgYmVjYXVzZSBhbGwgdmFyaWFibGVzIGFyZSAocmUpc2V0IGluIGluaXQoKVxuXG4gIHByaXZhdGUgX2RlcHRoITogbnVtYmVyO1xuXG4gIC8vIDxlbCBpMThuPi4uLjwvZWw+XG4gIHByaXZhdGUgX2luSTE4bk5vZGUhOiBib29sZWFuO1xuICBwcml2YXRlIF9pbkltcGxpY2l0Tm9kZSE6IGJvb2xlYW47XG5cbiAgLy8gPCEtLWkxOG4tLT4uLi48IS0tL2kxOG4tLT5cbiAgcHJpdmF0ZSBfaW5JMThuQmxvY2shOiBib29sZWFuO1xuICBwcml2YXRlIF9ibG9ja01lYW5pbmdBbmREZXNjITogc3RyaW5nO1xuICBwcml2YXRlIF9ibG9ja0NoaWxkcmVuITogaHRtbC5Ob2RlW107XG4gIHByaXZhdGUgX2Jsb2NrU3RhcnREZXB0aCE6IG51bWJlcjtcblxuICAvLyB7PGljdSBtZXNzYWdlPn1cbiAgcHJpdmF0ZSBfaW5JY3UhOiBib29sZWFuO1xuXG4gIC8vIHNldCB0byB2b2lkIDAgd2hlbiBub3QgaW4gYSBzZWN0aW9uXG4gIHByaXZhdGUgX21zZ0NvdW50QXRTZWN0aW9uU3RhcnQ6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBfZXJyb3JzITogSTE4bkVycm9yW107XG4gIHByaXZhdGUgX21vZGUhOiBfVmlzaXRvck1vZGU7XG5cbiAgLy8gX1Zpc2l0b3JNb2RlLkV4dHJhY3Qgb25seVxuICBwcml2YXRlIF9tZXNzYWdlcyE6IGkxOG4uTWVzc2FnZVtdO1xuXG4gIC8vIF9WaXNpdG9yTW9kZS5NZXJnZSBvbmx5XG4gIHByaXZhdGUgX3RyYW5zbGF0aW9ucyE6IFRyYW5zbGF0aW9uQnVuZGxlO1xuICBwcml2YXRlIF9jcmVhdGVJMThuTWVzc2FnZSE6IEkxOG5NZXNzYWdlRmFjdG9yeTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIF9pbXBsaWNpdFRhZ3M6IHN0cmluZ1tdLFxuICAgIHByaXZhdGUgX2ltcGxpY2l0QXR0cnM6IHtbazogc3RyaW5nXTogc3RyaW5nW119LFxuICApIHt9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3RzIHRoZSBtZXNzYWdlcyBmcm9tIHRoZSB0cmVlXG4gICAqL1xuICBleHRyYWN0KG5vZGVzOiBodG1sLk5vZGVbXSwgaW50ZXJwb2xhdGlvbkNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyk6IEV4dHJhY3Rpb25SZXN1bHQge1xuICAgIHRoaXMuX2luaXQoX1Zpc2l0b3JNb2RlLkV4dHJhY3QsIGludGVycG9sYXRpb25Db25maWcpO1xuXG4gICAgbm9kZXMuZm9yRWFjaCgobm9kZSkgPT4gbm9kZS52aXNpdCh0aGlzLCBudWxsKSk7XG5cbiAgICBpZiAodGhpcy5faW5JMThuQmxvY2spIHtcbiAgICAgIHRoaXMuX3JlcG9ydEVycm9yKG5vZGVzW25vZGVzLmxlbmd0aCAtIDFdLCAnVW5jbG9zZWQgYmxvY2snKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEV4dHJhY3Rpb25SZXN1bHQodGhpcy5fbWVzc2FnZXMsIHRoaXMuX2Vycm9ycyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHRyZWUgd2hlcmUgYWxsIHRyYW5zbGF0YWJsZSBub2RlcyBhcmUgdHJhbnNsYXRlZFxuICAgKi9cbiAgbWVyZ2UoXG4gICAgbm9kZXM6IGh0bWwuTm9kZVtdLFxuICAgIHRyYW5zbGF0aW9uczogVHJhbnNsYXRpb25CdW5kbGUsXG4gICAgaW50ZXJwb2xhdGlvbkNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyxcbiAgKTogUGFyc2VUcmVlUmVzdWx0IHtcbiAgICB0aGlzLl9pbml0KF9WaXNpdG9yTW9kZS5NZXJnZSwgaW50ZXJwb2xhdGlvbkNvbmZpZyk7XG4gICAgdGhpcy5fdHJhbnNsYXRpb25zID0gdHJhbnNsYXRpb25zO1xuXG4gICAgLy8gQ29uc3RydWN0IGEgc2luZ2xlIGZha2Ugcm9vdCBlbGVtZW50XG4gICAgY29uc3Qgd3JhcHBlciA9IG5ldyBodG1sLkVsZW1lbnQoJ3dyYXBwZXInLCBbXSwgbm9kZXMsIHVuZGVmaW5lZCEsIHVuZGVmaW5lZCEsIHVuZGVmaW5lZCk7XG5cbiAgICBjb25zdCB0cmFuc2xhdGVkTm9kZSA9IHdyYXBwZXIudmlzaXQodGhpcywgbnVsbCk7XG5cbiAgICBpZiAodGhpcy5faW5JMThuQmxvY2spIHtcbiAgICAgIHRoaXMuX3JlcG9ydEVycm9yKG5vZGVzW25vZGVzLmxlbmd0aCAtIDFdLCAnVW5jbG9zZWQgYmxvY2snKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFBhcnNlVHJlZVJlc3VsdCh0cmFuc2xhdGVkTm9kZS5jaGlsZHJlbiwgdGhpcy5fZXJyb3JzKTtcbiAgfVxuXG4gIHZpc2l0RXhwYW5zaW9uQ2FzZShpY3VDYXNlOiBodG1sLkV4cGFuc2lvbkNhc2UsIGNvbnRleHQ6IGFueSk6IGFueSB7XG4gICAgLy8gUGFyc2UgY2FzZXMgZm9yIHRyYW5zbGF0YWJsZSBodG1sIGF0dHJpYnV0ZXNcbiAgICBjb25zdCBleHByZXNzaW9uID0gaHRtbC52aXNpdEFsbCh0aGlzLCBpY3VDYXNlLmV4cHJlc3Npb24sIGNvbnRleHQpO1xuXG4gICAgaWYgKHRoaXMuX21vZGUgPT09IF9WaXNpdG9yTW9kZS5NZXJnZSkge1xuICAgICAgcmV0dXJuIG5ldyBodG1sLkV4cGFuc2lvbkNhc2UoXG4gICAgICAgIGljdUNhc2UudmFsdWUsXG4gICAgICAgIGV4cHJlc3Npb24sXG4gICAgICAgIGljdUNhc2Uuc291cmNlU3BhbixcbiAgICAgICAgaWN1Q2FzZS52YWx1ZVNvdXJjZVNwYW4sXG4gICAgICAgIGljdUNhc2UuZXhwU291cmNlU3BhbixcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgdmlzaXRFeHBhbnNpb24oaWN1OiBodG1sLkV4cGFuc2lvbiwgY29udGV4dDogYW55KTogaHRtbC5FeHBhbnNpb24ge1xuICAgIHRoaXMuX21heUJlQWRkQmxvY2tDaGlsZHJlbihpY3UpO1xuXG4gICAgY29uc3Qgd2FzSW5JY3UgPSB0aGlzLl9pbkljdTtcblxuICAgIGlmICghdGhpcy5faW5JY3UpIHtcbiAgICAgIC8vIG5lc3RlZCBJQ1UgbWVzc2FnZXMgc2hvdWxkIG5vdCBiZSBleHRyYWN0ZWQgYnV0IHRvcC1sZXZlbCB0cmFuc2xhdGVkIGFzIGEgd2hvbGVcbiAgICAgIGlmICh0aGlzLl9pc0luVHJhbnNsYXRhYmxlU2VjdGlvbikge1xuICAgICAgICB0aGlzLl9hZGRNZXNzYWdlKFtpY3VdKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2luSWN1ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjYXNlcyA9IGh0bWwudmlzaXRBbGwodGhpcywgaWN1LmNhc2VzLCBjb250ZXh0KTtcblxuICAgIGlmICh0aGlzLl9tb2RlID09PSBfVmlzaXRvck1vZGUuTWVyZ2UpIHtcbiAgICAgIGljdSA9IG5ldyBodG1sLkV4cGFuc2lvbihcbiAgICAgICAgaWN1LnN3aXRjaFZhbHVlLFxuICAgICAgICBpY3UudHlwZSxcbiAgICAgICAgY2FzZXMsXG4gICAgICAgIGljdS5zb3VyY2VTcGFuLFxuICAgICAgICBpY3Uuc3dpdGNoVmFsdWVTb3VyY2VTcGFuLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLl9pbkljdSA9IHdhc0luSWN1O1xuXG4gICAgcmV0dXJuIGljdTtcbiAgfVxuXG4gIHZpc2l0Q29tbWVudChjb21tZW50OiBodG1sLkNvbW1lbnQsIGNvbnRleHQ6IGFueSk6IGFueSB7XG4gICAgY29uc3QgaXNPcGVuaW5nID0gX2lzT3BlbmluZ0NvbW1lbnQoY29tbWVudCk7XG5cbiAgICBpZiAoaXNPcGVuaW5nICYmIHRoaXMuX2lzSW5UcmFuc2xhdGFibGVTZWN0aW9uKSB7XG4gICAgICB0aGlzLl9yZXBvcnRFcnJvcihjb21tZW50LCAnQ291bGQgbm90IHN0YXJ0IGEgYmxvY2sgaW5zaWRlIGEgdHJhbnNsYXRhYmxlIHNlY3Rpb24nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpc0Nsb3NpbmcgPSBfaXNDbG9zaW5nQ29tbWVudChjb21tZW50KTtcblxuICAgIGlmIChpc0Nsb3NpbmcgJiYgIXRoaXMuX2luSTE4bkJsb2NrKSB7XG4gICAgICB0aGlzLl9yZXBvcnRFcnJvcihjb21tZW50LCAnVHJ5aW5nIHRvIGNsb3NlIGFuIHVub3BlbmVkIGJsb2NrJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLl9pbkkxOG5Ob2RlICYmICF0aGlzLl9pbkljdSkge1xuICAgICAgaWYgKCF0aGlzLl9pbkkxOG5CbG9jaykge1xuICAgICAgICBpZiAoaXNPcGVuaW5nKSB7XG4gICAgICAgICAgLy8gZGVwcmVjYXRlZCBmcm9tIHY1IHlvdSBzaG91bGQgdXNlIDxuZy1jb250YWluZXIgaTE4bj4gaW5zdGVhZCBvZiBpMThuIGNvbW1lbnRzXG4gICAgICAgICAgaWYgKCFpMThuQ29tbWVudHNXYXJuZWQgJiYgPGFueT5jb25zb2xlICYmIDxhbnk+Y29uc29sZS53YXJuKSB7XG4gICAgICAgICAgICBpMThuQ29tbWVudHNXYXJuZWQgPSB0cnVlO1xuICAgICAgICAgICAgY29uc3QgZGV0YWlscyA9IGNvbW1lbnQuc291cmNlU3Bhbi5kZXRhaWxzID8gYCwgJHtjb21tZW50LnNvdXJjZVNwYW4uZGV0YWlsc31gIDogJyc7XG4gICAgICAgICAgICAvLyBUT0RPKG9jb21iZSk6IHVzZSBhIGxvZyBzZXJ2aWNlIG9uY2UgdGhlcmUgaXMgYSBwdWJsaWMgb25lIGF2YWlsYWJsZVxuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICBgSTE4biBjb21tZW50cyBhcmUgZGVwcmVjYXRlZCwgdXNlIGFuIDxuZy1jb250YWluZXI+IGVsZW1lbnQgaW5zdGVhZCAoJHtjb21tZW50LnNvdXJjZVNwYW4uc3RhcnR9JHtkZXRhaWxzfSlgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5faW5JMThuQmxvY2sgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuX2Jsb2NrU3RhcnREZXB0aCA9IHRoaXMuX2RlcHRoO1xuICAgICAgICAgIHRoaXMuX2Jsb2NrQ2hpbGRyZW4gPSBbXTtcbiAgICAgICAgICB0aGlzLl9ibG9ja01lYW5pbmdBbmREZXNjID0gY29tbWVudFxuICAgICAgICAgICAgLnZhbHVlIS5yZXBsYWNlKF9JMThOX0NPTU1FTlRfUFJFRklYX1JFR0VYUCwgJycpXG4gICAgICAgICAgICAudHJpbSgpO1xuICAgICAgICAgIHRoaXMuX29wZW5UcmFuc2xhdGFibGVTZWN0aW9uKGNvbW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaXNDbG9zaW5nKSB7XG4gICAgICAgICAgaWYgKHRoaXMuX2RlcHRoID09IHRoaXMuX2Jsb2NrU3RhcnREZXB0aCkge1xuICAgICAgICAgICAgdGhpcy5fY2xvc2VUcmFuc2xhdGFibGVTZWN0aW9uKGNvbW1lbnQsIHRoaXMuX2Jsb2NrQ2hpbGRyZW4pO1xuICAgICAgICAgICAgdGhpcy5faW5JMThuQmxvY2sgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLl9hZGRNZXNzYWdlKHRoaXMuX2Jsb2NrQ2hpbGRyZW4sIHRoaXMuX2Jsb2NrTWVhbmluZ0FuZERlc2MpITtcbiAgICAgICAgICAgIC8vIG1lcmdlIGF0dHJpYnV0ZXMgaW4gc2VjdGlvbnNcbiAgICAgICAgICAgIGNvbnN0IG5vZGVzID0gdGhpcy5fdHJhbnNsYXRlTWVzc2FnZShjb21tZW50LCBtZXNzYWdlKTtcbiAgICAgICAgICAgIHJldHVybiBodG1sLnZpc2l0QWxsKHRoaXMsIG5vZGVzKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcmVwb3J0RXJyb3IoY29tbWVudCwgJ0kxOE4gYmxvY2tzIHNob3VsZCBub3QgY3Jvc3MgZWxlbWVudCBib3VuZGFyaWVzJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmlzaXRUZXh0KHRleHQ6IGh0bWwuVGV4dCwgY29udGV4dDogYW55KTogaHRtbC5UZXh0IHtcbiAgICBpZiAodGhpcy5faXNJblRyYW5zbGF0YWJsZVNlY3Rpb24pIHtcbiAgICAgIHRoaXMuX21heUJlQWRkQmxvY2tDaGlsZHJlbih0ZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIHRleHQ7XG4gIH1cblxuICB2aXNpdEVsZW1lbnQoZWw6IGh0bWwuRWxlbWVudCwgY29udGV4dDogYW55KTogaHRtbC5FbGVtZW50IHwgbnVsbCB7XG4gICAgdGhpcy5fbWF5QmVBZGRCbG9ja0NoaWxkcmVuKGVsKTtcbiAgICB0aGlzLl9kZXB0aCsrO1xuICAgIGNvbnN0IHdhc0luSTE4bk5vZGUgPSB0aGlzLl9pbkkxOG5Ob2RlO1xuICAgIGNvbnN0IHdhc0luSW1wbGljaXROb2RlID0gdGhpcy5faW5JbXBsaWNpdE5vZGU7XG4gICAgbGV0IGNoaWxkTm9kZXM6IGh0bWwuTm9kZVtdID0gW107XG4gICAgbGV0IHRyYW5zbGF0ZWRDaGlsZE5vZGVzOiBodG1sLk5vZGVbXSA9IHVuZGVmaW5lZCE7XG5cbiAgICAvLyBFeHRyYWN0OlxuICAgIC8vIC0gdG9wIGxldmVsIG5vZGVzIHdpdGggdGhlIChpbXBsaWNpdCkgXCJpMThuXCIgYXR0cmlidXRlIGlmIG5vdCBhbHJlYWR5IGluIGEgc2VjdGlvblxuICAgIC8vIC0gSUNVIG1lc3NhZ2VzXG4gICAgY29uc3QgaTE4bkF0dHIgPSBfZ2V0STE4bkF0dHIoZWwpO1xuICAgIGNvbnN0IGkxOG5NZXRhID0gaTE4bkF0dHIgPyBpMThuQXR0ci52YWx1ZSA6ICcnO1xuICAgIGNvbnN0IGlzSW1wbGljaXQgPVxuICAgICAgdGhpcy5faW1wbGljaXRUYWdzLnNvbWUoKHRhZykgPT4gZWwubmFtZSA9PT0gdGFnKSAmJlxuICAgICAgIXRoaXMuX2luSWN1ICYmXG4gICAgICAhdGhpcy5faXNJblRyYW5zbGF0YWJsZVNlY3Rpb247XG4gICAgY29uc3QgaXNUb3BMZXZlbEltcGxpY2l0ID0gIXdhc0luSW1wbGljaXROb2RlICYmIGlzSW1wbGljaXQ7XG4gICAgdGhpcy5faW5JbXBsaWNpdE5vZGUgPSB3YXNJbkltcGxpY2l0Tm9kZSB8fCBpc0ltcGxpY2l0O1xuXG4gICAgaWYgKCF0aGlzLl9pc0luVHJhbnNsYXRhYmxlU2VjdGlvbiAmJiAhdGhpcy5faW5JY3UpIHtcbiAgICAgIGlmIChpMThuQXR0ciB8fCBpc1RvcExldmVsSW1wbGljaXQpIHtcbiAgICAgICAgdGhpcy5faW5JMThuTm9kZSA9IHRydWU7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLl9hZGRNZXNzYWdlKGVsLmNoaWxkcmVuLCBpMThuTWV0YSkhO1xuICAgICAgICB0cmFuc2xhdGVkQ2hpbGROb2RlcyA9IHRoaXMuX3RyYW5zbGF0ZU1lc3NhZ2UoZWwsIG1lc3NhZ2UpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fbW9kZSA9PSBfVmlzaXRvck1vZGUuRXh0cmFjdCkge1xuICAgICAgICBjb25zdCBpc1RyYW5zbGF0YWJsZSA9IGkxOG5BdHRyIHx8IGlzVG9wTGV2ZWxJbXBsaWNpdDtcbiAgICAgICAgaWYgKGlzVHJhbnNsYXRhYmxlKSB0aGlzLl9vcGVuVHJhbnNsYXRhYmxlU2VjdGlvbihlbCk7XG4gICAgICAgIGh0bWwudmlzaXRBbGwodGhpcywgZWwuY2hpbGRyZW4pO1xuICAgICAgICBpZiAoaXNUcmFuc2xhdGFibGUpIHRoaXMuX2Nsb3NlVHJhbnNsYXRhYmxlU2VjdGlvbihlbCwgZWwuY2hpbGRyZW4pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaTE4bkF0dHIgfHwgaXNUb3BMZXZlbEltcGxpY2l0KSB7XG4gICAgICAgIHRoaXMuX3JlcG9ydEVycm9yKFxuICAgICAgICAgIGVsLFxuICAgICAgICAgICdDb3VsZCBub3QgbWFyayBhbiBlbGVtZW50IGFzIHRyYW5zbGF0YWJsZSBpbnNpZGUgYSB0cmFuc2xhdGFibGUgc2VjdGlvbicsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9tb2RlID09IF9WaXNpdG9yTW9kZS5FeHRyYWN0KSB7XG4gICAgICAgIC8vIERlc2NlbmQgaW50byBjaGlsZCBub2RlcyBmb3IgZXh0cmFjdGlvblxuICAgICAgICBodG1sLnZpc2l0QWxsKHRoaXMsIGVsLmNoaWxkcmVuKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5fbW9kZSA9PT0gX1Zpc2l0b3JNb2RlLk1lcmdlKSB7XG4gICAgICBjb25zdCB2aXNpdE5vZGVzID0gdHJhbnNsYXRlZENoaWxkTm9kZXMgfHwgZWwuY2hpbGRyZW47XG4gICAgICB2aXNpdE5vZGVzLmZvckVhY2goKGNoaWxkKSA9PiB7XG4gICAgICAgIGNvbnN0IHZpc2l0ZWQgPSBjaGlsZC52aXNpdCh0aGlzLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKHZpc2l0ZWQgJiYgIXRoaXMuX2lzSW5UcmFuc2xhdGFibGVTZWN0aW9uKSB7XG4gICAgICAgICAgLy8gRG8gbm90IGFkZCB0aGUgY2hpbGRyZW4gZnJvbSB0cmFuc2xhdGFibGUgc2VjdGlvbnMgKD0gaTE4biBibG9ja3MgaGVyZSlcbiAgICAgICAgICAvLyBUaGV5IHdpbGwgYmUgYWRkZWQgbGF0ZXIgaW4gdGhpcyBsb29wIHdoZW4gdGhlIGJsb2NrIGNsb3NlcyAoaS5lLiBvbiBgPCEtLSAvaTE4biAtLT5gKVxuICAgICAgICAgIGNoaWxkTm9kZXMgPSBjaGlsZE5vZGVzLmNvbmNhdCh2aXNpdGVkKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5fdmlzaXRBdHRyaWJ1dGVzT2YoZWwpO1xuXG4gICAgdGhpcy5fZGVwdGgtLTtcbiAgICB0aGlzLl9pbkkxOG5Ob2RlID0gd2FzSW5JMThuTm9kZTtcbiAgICB0aGlzLl9pbkltcGxpY2l0Tm9kZSA9IHdhc0luSW1wbGljaXROb2RlO1xuXG4gICAgaWYgKHRoaXMuX21vZGUgPT09IF9WaXNpdG9yTW9kZS5NZXJnZSkge1xuICAgICAgY29uc3QgdHJhbnNsYXRlZEF0dHJzID0gdGhpcy5fdHJhbnNsYXRlQXR0cmlidXRlcyhlbCk7XG4gICAgICByZXR1cm4gbmV3IGh0bWwuRWxlbWVudChcbiAgICAgICAgZWwubmFtZSxcbiAgICAgICAgdHJhbnNsYXRlZEF0dHJzLFxuICAgICAgICBjaGlsZE5vZGVzLFxuICAgICAgICBlbC5zb3VyY2VTcGFuLFxuICAgICAgICBlbC5zdGFydFNvdXJjZVNwYW4sXG4gICAgICAgIGVsLmVuZFNvdXJjZVNwYW4sXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZpc2l0QXR0cmlidXRlKGF0dHJpYnV0ZTogaHRtbC5BdHRyaWJ1dGUsIGNvbnRleHQ6IGFueSk6IGFueSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bnJlYWNoYWJsZSBjb2RlJyk7XG4gIH1cblxuICB2aXNpdEJsb2NrKGJsb2NrOiBodG1sLkJsb2NrLCBjb250ZXh0OiBhbnkpIHtcbiAgICBodG1sLnZpc2l0QWxsKHRoaXMsIGJsb2NrLmNoaWxkcmVuLCBjb250ZXh0KTtcbiAgfVxuXG4gIHZpc2l0QmxvY2tQYXJhbWV0ZXIocGFyYW1ldGVyOiBodG1sLkJsb2NrUGFyYW1ldGVyLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRMZXREZWNsYXJhdGlvbihkZWNsOiBodG1sLkxldERlY2xhcmF0aW9uLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgcHJpdmF0ZSBfaW5pdChtb2RlOiBfVmlzaXRvck1vZGUsIGludGVycG9sYXRpb25Db25maWc6IEludGVycG9sYXRpb25Db25maWcpOiB2b2lkIHtcbiAgICB0aGlzLl9tb2RlID0gbW9kZTtcbiAgICB0aGlzLl9pbkkxOG5CbG9jayA9IGZhbHNlO1xuICAgIHRoaXMuX2luSTE4bk5vZGUgPSBmYWxzZTtcbiAgICB0aGlzLl9kZXB0aCA9IDA7XG4gICAgdGhpcy5faW5JY3UgPSBmYWxzZTtcbiAgICB0aGlzLl9tc2dDb3VudEF0U2VjdGlvblN0YXJ0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2Vycm9ycyA9IFtdO1xuICAgIHRoaXMuX21lc3NhZ2VzID0gW107XG4gICAgdGhpcy5faW5JbXBsaWNpdE5vZGUgPSBmYWxzZTtcbiAgICB0aGlzLl9jcmVhdGVJMThuTWVzc2FnZSA9IGNyZWF0ZUkxOG5NZXNzYWdlRmFjdG9yeShcbiAgICAgIGludGVycG9sYXRpb25Db25maWcsXG4gICAgICBERUZBVUxUX0NPTlRBSU5FUl9CTE9DS1MsXG4gICAgKTtcbiAgfVxuXG4gIC8vIGxvb2tzIGZvciB0cmFuc2xhdGFibGUgYXR0cmlidXRlc1xuICBwcml2YXRlIF92aXNpdEF0dHJpYnV0ZXNPZihlbDogaHRtbC5FbGVtZW50KTogdm9pZCB7XG4gICAgY29uc3QgZXhwbGljaXRBdHRyTmFtZVRvVmFsdWU6IHtbazogc3RyaW5nXTogc3RyaW5nfSA9IHt9O1xuICAgIGNvbnN0IGltcGxpY2l0QXR0ck5hbWVzOiBzdHJpbmdbXSA9IHRoaXMuX2ltcGxpY2l0QXR0cnNbZWwubmFtZV0gfHwgW107XG5cbiAgICBlbC5hdHRyc1xuICAgICAgLmZpbHRlcigoYXR0cikgPT4gYXR0ci5uYW1lLnN0YXJ0c1dpdGgoX0kxOE5fQVRUUl9QUkVGSVgpKVxuICAgICAgLmZvckVhY2goXG4gICAgICAgIChhdHRyKSA9PiAoZXhwbGljaXRBdHRyTmFtZVRvVmFsdWVbYXR0ci5uYW1lLnNsaWNlKF9JMThOX0FUVFJfUFJFRklYLmxlbmd0aCldID0gYXR0ci52YWx1ZSksXG4gICAgICApO1xuXG4gICAgZWwuYXR0cnMuZm9yRWFjaCgoYXR0cikgPT4ge1xuICAgICAgaWYgKGF0dHIubmFtZSBpbiBleHBsaWNpdEF0dHJOYW1lVG9WYWx1ZSkge1xuICAgICAgICB0aGlzLl9hZGRNZXNzYWdlKFthdHRyXSwgZXhwbGljaXRBdHRyTmFtZVRvVmFsdWVbYXR0ci5uYW1lXSk7XG4gICAgICB9IGVsc2UgaWYgKGltcGxpY2l0QXR0ck5hbWVzLnNvbWUoKG5hbWUpID0+IGF0dHIubmFtZSA9PT0gbmFtZSkpIHtcbiAgICAgICAgdGhpcy5fYWRkTWVzc2FnZShbYXR0cl0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gYWRkIGEgdHJhbnNsYXRhYmxlIG1lc3NhZ2VcbiAgcHJpdmF0ZSBfYWRkTWVzc2FnZShhc3Q6IGh0bWwuTm9kZVtdLCBtc2dNZXRhPzogc3RyaW5nKTogaTE4bi5NZXNzYWdlIHwgbnVsbCB7XG4gICAgaWYgKFxuICAgICAgYXN0Lmxlbmd0aCA9PSAwIHx8XG4gICAgICAoYXN0Lmxlbmd0aCA9PSAxICYmIGFzdFswXSBpbnN0YW5jZW9mIGh0bWwuQXR0cmlidXRlICYmICEoPGh0bWwuQXR0cmlidXRlPmFzdFswXSkudmFsdWUpXG4gICAgKSB7XG4gICAgICAvLyBEbyBub3QgY3JlYXRlIGVtcHR5IG1lc3NhZ2VzXG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCB7bWVhbmluZywgZGVzY3JpcHRpb24sIGlkfSA9IF9wYXJzZU1lc3NhZ2VNZXRhKG1zZ01ldGEpO1xuICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLl9jcmVhdGVJMThuTWVzc2FnZShhc3QsIG1lYW5pbmcsIGRlc2NyaXB0aW9uLCBpZCk7XG4gICAgdGhpcy5fbWVzc2FnZXMucHVzaChtZXNzYWdlKTtcbiAgICByZXR1cm4gbWVzc2FnZTtcbiAgfVxuXG4gIC8vIFRyYW5zbGF0ZXMgdGhlIGdpdmVuIG1lc3NhZ2UgZ2l2ZW4gdGhlIGBUcmFuc2xhdGlvbkJ1bmRsZWBcbiAgLy8gVGhpcyBpcyB1c2VkIGZvciB0cmFuc2xhdGluZyBlbGVtZW50cyAvIGJsb2NrcyAtIHNlZSBgX3RyYW5zbGF0ZUF0dHJpYnV0ZXNgIGZvciBhdHRyaWJ1dGVzXG4gIC8vIG5vLW9wIHdoZW4gY2FsbGVkIGluIGV4dHJhY3Rpb24gbW9kZSAocmV0dXJucyBbXSlcbiAgcHJpdmF0ZSBfdHJhbnNsYXRlTWVzc2FnZShlbDogaHRtbC5Ob2RlLCBtZXNzYWdlOiBpMThuLk1lc3NhZ2UpOiBodG1sLk5vZGVbXSB7XG4gICAgaWYgKG1lc3NhZ2UgJiYgdGhpcy5fbW9kZSA9PT0gX1Zpc2l0b3JNb2RlLk1lcmdlKSB7XG4gICAgICBjb25zdCBub2RlcyA9IHRoaXMuX3RyYW5zbGF0aW9ucy5nZXQobWVzc2FnZSk7XG5cbiAgICAgIGlmIChub2Rlcykge1xuICAgICAgICByZXR1cm4gbm9kZXM7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3JlcG9ydEVycm9yKFxuICAgICAgICBlbCxcbiAgICAgICAgYFRyYW5zbGF0aW9uIHVuYXZhaWxhYmxlIGZvciBtZXNzYWdlIGlkPVwiJHt0aGlzLl90cmFuc2xhdGlvbnMuZGlnZXN0KG1lc3NhZ2UpfVwiYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLy8gdHJhbnNsYXRlIHRoZSBhdHRyaWJ1dGVzIG9mIGFuIGVsZW1lbnQgYW5kIHJlbW92ZSBpMThuIHNwZWNpZmljIGF0dHJpYnV0ZXNcbiAgcHJpdmF0ZSBfdHJhbnNsYXRlQXR0cmlidXRlcyhlbDogaHRtbC5FbGVtZW50KTogaHRtbC5BdHRyaWJ1dGVbXSB7XG4gICAgY29uc3QgYXR0cmlidXRlcyA9IGVsLmF0dHJzO1xuICAgIGNvbnN0IGkxOG5QYXJzZWRNZXNzYWdlTWV0YToge1xuICAgICAgW25hbWU6IHN0cmluZ106IHttZWFuaW5nOiBzdHJpbmc7IGRlc2NyaXB0aW9uOiBzdHJpbmc7IGlkOiBzdHJpbmd9O1xuICAgIH0gPSB7fTtcblxuICAgIGF0dHJpYnV0ZXMuZm9yRWFjaCgoYXR0cikgPT4ge1xuICAgICAgaWYgKGF0dHIubmFtZS5zdGFydHNXaXRoKF9JMThOX0FUVFJfUFJFRklYKSkge1xuICAgICAgICBpMThuUGFyc2VkTWVzc2FnZU1ldGFbYXR0ci5uYW1lLnNsaWNlKF9JMThOX0FUVFJfUFJFRklYLmxlbmd0aCldID0gX3BhcnNlTWVzc2FnZU1ldGEoXG4gICAgICAgICAgYXR0ci52YWx1ZSxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnN0IHRyYW5zbGF0ZWRBdHRyaWJ1dGVzOiBodG1sLkF0dHJpYnV0ZVtdID0gW107XG5cbiAgICBhdHRyaWJ1dGVzLmZvckVhY2goKGF0dHIpID0+IHtcbiAgICAgIGlmIChhdHRyLm5hbWUgPT09IF9JMThOX0FUVFIgfHwgYXR0ci5uYW1lLnN0YXJ0c1dpdGgoX0kxOE5fQVRUUl9QUkVGSVgpKSB7XG4gICAgICAgIC8vIHN0cmlwIGkxOG4gc3BlY2lmaWMgYXR0cmlidXRlc1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChhdHRyLnZhbHVlICYmIGF0dHIudmFsdWUgIT0gJycgJiYgaTE4blBhcnNlZE1lc3NhZ2VNZXRhLmhhc093blByb3BlcnR5KGF0dHIubmFtZSkpIHtcbiAgICAgICAgY29uc3Qge21lYW5pbmcsIGRlc2NyaXB0aW9uLCBpZH0gPSBpMThuUGFyc2VkTWVzc2FnZU1ldGFbYXR0ci5uYW1lXTtcbiAgICAgICAgY29uc3QgbWVzc2FnZTogaTE4bi5NZXNzYWdlID0gdGhpcy5fY3JlYXRlSTE4bk1lc3NhZ2UoW2F0dHJdLCBtZWFuaW5nLCBkZXNjcmlwdGlvbiwgaWQpO1xuICAgICAgICBjb25zdCBub2RlcyA9IHRoaXMuX3RyYW5zbGF0aW9ucy5nZXQobWVzc2FnZSk7XG4gICAgICAgIGlmIChub2Rlcykge1xuICAgICAgICAgIGlmIChub2Rlcy5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgdHJhbnNsYXRlZEF0dHJpYnV0ZXMucHVzaChcbiAgICAgICAgICAgICAgbmV3IGh0bWwuQXR0cmlidXRlKFxuICAgICAgICAgICAgICAgIGF0dHIubmFtZSxcbiAgICAgICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICAgICBhdHRyLnNvdXJjZVNwYW4sXG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkIC8qIGtleVNwYW4gKi8sXG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkIC8qIHZhbHVlU3BhbiAqLyxcbiAgICAgICAgICAgICAgICB1bmRlZmluZWQgLyogdmFsdWVUb2tlbnMgKi8sXG4gICAgICAgICAgICAgICAgdW5kZWZpbmVkIC8qIGkxOG4gKi8sXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAobm9kZXNbMF0gaW5zdGFuY2VvZiBodG1sLlRleHQpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gKG5vZGVzWzBdIGFzIGh0bWwuVGV4dCkudmFsdWU7XG4gICAgICAgICAgICB0cmFuc2xhdGVkQXR0cmlidXRlcy5wdXNoKFxuICAgICAgICAgICAgICBuZXcgaHRtbC5BdHRyaWJ1dGUoXG4gICAgICAgICAgICAgICAgYXR0ci5uYW1lLFxuICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgICAgIGF0dHIuc291cmNlU3BhbixcbiAgICAgICAgICAgICAgICB1bmRlZmluZWQgLyoga2V5U3BhbiAqLyxcbiAgICAgICAgICAgICAgICB1bmRlZmluZWQgLyogdmFsdWVTcGFuICovLFxuICAgICAgICAgICAgICAgIHVuZGVmaW5lZCAvKiB2YWx1ZVRva2VucyAqLyxcbiAgICAgICAgICAgICAgICB1bmRlZmluZWQgLyogaTE4biAqLyxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3JlcG9ydEVycm9yKFxuICAgICAgICAgICAgICBlbCxcbiAgICAgICAgICAgICAgYFVuZXhwZWN0ZWQgdHJhbnNsYXRpb24gZm9yIGF0dHJpYnV0ZSBcIiR7YXR0ci5uYW1lfVwiIChpZD1cIiR7XG4gICAgICAgICAgICAgICAgaWQgfHwgdGhpcy5fdHJhbnNsYXRpb25zLmRpZ2VzdChtZXNzYWdlKVxuICAgICAgICAgICAgICB9XCIpYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuX3JlcG9ydEVycm9yKFxuICAgICAgICAgICAgZWwsXG4gICAgICAgICAgICBgVHJhbnNsYXRpb24gdW5hdmFpbGFibGUgZm9yIGF0dHJpYnV0ZSBcIiR7YXR0ci5uYW1lfVwiIChpZD1cIiR7XG4gICAgICAgICAgICAgIGlkIHx8IHRoaXMuX3RyYW5zbGF0aW9ucy5kaWdlc3QobWVzc2FnZSlcbiAgICAgICAgICAgIH1cIilgLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyYW5zbGF0ZWRBdHRyaWJ1dGVzLnB1c2goYXR0cik7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdHJhbnNsYXRlZEF0dHJpYnV0ZXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkIHRoZSBub2RlIGFzIGEgY2hpbGQgb2YgdGhlIGJsb2NrIHdoZW46XG4gICAqIC0gd2UgYXJlIGluIGEgYmxvY2ssXG4gICAqIC0gd2UgYXJlIG5vdCBpbnNpZGUgYSBJQ1UgbWVzc2FnZSAodGhvc2UgYXJlIGhhbmRsZWQgc2VwYXJhdGVseSksXG4gICAqIC0gdGhlIG5vZGUgaXMgYSBcImRpcmVjdCBjaGlsZFwiIG9mIHRoZSBibG9ja1xuICAgKi9cbiAgcHJpdmF0ZSBfbWF5QmVBZGRCbG9ja0NoaWxkcmVuKG5vZGU6IGh0bWwuTm9kZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9pbkkxOG5CbG9jayAmJiAhdGhpcy5faW5JY3UgJiYgdGhpcy5fZGVwdGggPT0gdGhpcy5fYmxvY2tTdGFydERlcHRoKSB7XG4gICAgICB0aGlzLl9ibG9ja0NoaWxkcmVuLnB1c2gobm9kZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1hcmtzIHRoZSBzdGFydCBvZiBhIHNlY3Rpb24sIHNlZSBgX2Nsb3NlVHJhbnNsYXRhYmxlU2VjdGlvbmBcbiAgICovXG4gIHByaXZhdGUgX29wZW5UcmFuc2xhdGFibGVTZWN0aW9uKG5vZGU6IGh0bWwuTm9kZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9pc0luVHJhbnNsYXRhYmxlU2VjdGlvbikge1xuICAgICAgdGhpcy5fcmVwb3J0RXJyb3Iobm9kZSwgJ1VuZXhwZWN0ZWQgc2VjdGlvbiBzdGFydCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9tc2dDb3VudEF0U2VjdGlvblN0YXJ0ID0gdGhpcy5fbWVzc2FnZXMubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBIHRyYW5zbGF0YWJsZSBzZWN0aW9uIGNvdWxkIGJlOlxuICAgKiAtIHRoZSBjb250ZW50IG9mIHRyYW5zbGF0YWJsZSBlbGVtZW50LFxuICAgKiAtIG5vZGVzIGJldHdlZW4gYDwhLS0gaTE4biAtLT5gIGFuZCBgPCEtLSAvaTE4biAtLT5gIGNvbW1lbnRzXG4gICAqL1xuICBwcml2YXRlIGdldCBfaXNJblRyYW5zbGF0YWJsZVNlY3Rpb24oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX21zZ0NvdW50QXRTZWN0aW9uU3RhcnQgIT09IHZvaWQgMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBUZXJtaW5hdGVzIGEgc2VjdGlvbi5cbiAgICpcbiAgICogSWYgYSBzZWN0aW9uIGhhcyBvbmx5IG9uZSBzaWduaWZpY2FudCBjaGlsZHJlbiAoY29tbWVudHMgbm90IHNpZ25pZmljYW50KSB0aGVuIHdlIHNob3VsZCBub3RcbiAgICoga2VlcCB0aGUgbWVzc2FnZSBmcm9tIHRoaXMgY2hpbGRyZW46XG4gICAqXG4gICAqIGA8cCBpMThuPVwibWVhbmluZ3xkZXNjcmlwdGlvblwiPntJQ1UgbWVzc2FnZX08L3A+YCB3b3VsZCBwcm9kdWNlIHR3byBtZXNzYWdlczpcbiAgICogLSBvbmUgZm9yIHRoZSA8cD4gY29udGVudCB3aXRoIG1lYW5pbmcgYW5kIGRlc2NyaXB0aW9uLFxuICAgKiAtIGFub3RoZXIgb25lIGZvciB0aGUgSUNVIG1lc3NhZ2UuXG4gICAqXG4gICAqIEluIHRoaXMgY2FzZSB0aGUgbGFzdCBtZXNzYWdlIGlzIGRpc2NhcmRlZCBhcyBpdCBjb250YWlucyBsZXNzIGluZm9ybWF0aW9uICh0aGUgQVNUIGlzXG4gICAqIG90aGVyd2lzZSBpZGVudGljYWwpLlxuICAgKlxuICAgKiBOb3RlIHRoYXQgd2Ugc2hvdWxkIHN0aWxsIGtlZXAgbWVzc2FnZXMgZXh0cmFjdGVkIGZyb20gYXR0cmlidXRlcyBpbnNpZGUgdGhlIHNlY3Rpb24gKGllIGluIHRoZVxuICAgKiBJQ1UgbWVzc2FnZSBoZXJlKVxuICAgKi9cbiAgcHJpdmF0ZSBfY2xvc2VUcmFuc2xhdGFibGVTZWN0aW9uKG5vZGU6IGh0bWwuTm9kZSwgZGlyZWN0Q2hpbGRyZW46IGh0bWwuTm9kZVtdKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLl9pc0luVHJhbnNsYXRhYmxlU2VjdGlvbikge1xuICAgICAgdGhpcy5fcmVwb3J0RXJyb3Iobm9kZSwgJ1VuZXhwZWN0ZWQgc2VjdGlvbiBlbmQnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzdGFydEluZGV4ID0gdGhpcy5fbXNnQ291bnRBdFNlY3Rpb25TdGFydDtcbiAgICBjb25zdCBzaWduaWZpY2FudENoaWxkcmVuOiBudW1iZXIgPSBkaXJlY3RDaGlsZHJlbi5yZWR1Y2UoXG4gICAgICAoY291bnQ6IG51bWJlciwgbm9kZTogaHRtbC5Ob2RlKTogbnVtYmVyID0+IGNvdW50ICsgKG5vZGUgaW5zdGFuY2VvZiBodG1sLkNvbW1lbnQgPyAwIDogMSksXG4gICAgICAwLFxuICAgICk7XG5cbiAgICBpZiAoc2lnbmlmaWNhbnRDaGlsZHJlbiA9PSAxKSB7XG4gICAgICBmb3IgKGxldCBpID0gdGhpcy5fbWVzc2FnZXMubGVuZ3RoIC0gMTsgaSA+PSBzdGFydEluZGV4ITsgaS0tKSB7XG4gICAgICAgIGNvbnN0IGFzdCA9IHRoaXMuX21lc3NhZ2VzW2ldLm5vZGVzO1xuICAgICAgICBpZiAoIShhc3QubGVuZ3RoID09IDEgJiYgYXN0WzBdIGluc3RhbmNlb2YgaTE4bi5UZXh0KSkge1xuICAgICAgICAgIHRoaXMuX21lc3NhZ2VzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX21zZ0NvdW50QXRTZWN0aW9uU3RhcnQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIF9yZXBvcnRFcnJvcihub2RlOiBodG1sLk5vZGUsIG1zZzogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5fZXJyb3JzLnB1c2gobmV3IEkxOG5FcnJvcihub2RlLnNvdXJjZVNwYW4sIG1zZykpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9pc09wZW5pbmdDb21tZW50KG46IGh0bWwuTm9kZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gISEobiBpbnN0YW5jZW9mIGh0bWwuQ29tbWVudCAmJiBuLnZhbHVlICYmIG4udmFsdWUuc3RhcnRzV2l0aCgnaTE4bicpKTtcbn1cblxuZnVuY3Rpb24gX2lzQ2xvc2luZ0NvbW1lbnQobjogaHRtbC5Ob2RlKTogYm9vbGVhbiB7XG4gIHJldHVybiAhIShuIGluc3RhbmNlb2YgaHRtbC5Db21tZW50ICYmIG4udmFsdWUgJiYgbi52YWx1ZSA9PT0gJy9pMThuJyk7XG59XG5cbmZ1bmN0aW9uIF9nZXRJMThuQXR0cihwOiBodG1sLkVsZW1lbnQpOiBodG1sLkF0dHJpYnV0ZSB8IG51bGwge1xuICByZXR1cm4gcC5hdHRycy5maW5kKChhdHRyKSA9PiBhdHRyLm5hbWUgPT09IF9JMThOX0FUVFIpIHx8IG51bGw7XG59XG5cbmZ1bmN0aW9uIF9wYXJzZU1lc3NhZ2VNZXRhKGkxOG4/OiBzdHJpbmcpOiB7bWVhbmluZzogc3RyaW5nOyBkZXNjcmlwdGlvbjogc3RyaW5nOyBpZDogc3RyaW5nfSB7XG4gIGlmICghaTE4bikgcmV0dXJuIHttZWFuaW5nOiAnJywgZGVzY3JpcHRpb246ICcnLCBpZDogJyd9O1xuXG4gIGNvbnN0IGlkSW5kZXggPSBpMThuLmluZGV4T2YoSURfU0VQQVJBVE9SKTtcbiAgY29uc3QgZGVzY0luZGV4ID0gaTE4bi5pbmRleE9mKE1FQU5JTkdfU0VQQVJBVE9SKTtcbiAgY29uc3QgW21lYW5pbmdBbmREZXNjLCBpZF0gPVxuICAgIGlkSW5kZXggPiAtMSA/IFtpMThuLnNsaWNlKDAsIGlkSW5kZXgpLCBpMThuLnNsaWNlKGlkSW5kZXggKyAyKV0gOiBbaTE4biwgJyddO1xuICBjb25zdCBbbWVhbmluZywgZGVzY3JpcHRpb25dID1cbiAgICBkZXNjSW5kZXggPiAtMVxuICAgICAgPyBbbWVhbmluZ0FuZERlc2Muc2xpY2UoMCwgZGVzY0luZGV4KSwgbWVhbmluZ0FuZERlc2Muc2xpY2UoZGVzY0luZGV4ICsgMSldXG4gICAgICA6IFsnJywgbWVhbmluZ0FuZERlc2NdO1xuXG4gIHJldHVybiB7bWVhbmluZywgZGVzY3JpcHRpb24sIGlkOiBpZC50cmltKCl9O1xufVxuIl19
|