@angular/compiler 17.0.5 → 17.0.7
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/esm2022/src/compiler.mjs +2 -1
- package/esm2022/src/render3/partial/class_metadata.mjs +1 -1
- package/esm2022/src/render3/partial/directive.mjs +1 -1
- package/esm2022/src/render3/partial/factory.mjs +1 -1
- package/esm2022/src/render3/partial/injectable.mjs +1 -1
- package/esm2022/src/render3/partial/injector.mjs +1 -1
- package/esm2022/src/render3/partial/ng_module.mjs +1 -1
- package/esm2022/src/render3/partial/pipe.mjs +1 -1
- package/esm2022/src/render3/view/api.mjs +1 -1
- package/esm2022/src/render3/view/compiler.mjs +21 -8
- package/esm2022/src/render3/view/t2_api.mjs +1 -1
- package/esm2022/src/render3/view/t2_binder.mjs +6 -7
- package/esm2022/src/render3/view/template.mjs +1 -20
- package/esm2022/src/render3/view/util.mjs +24 -2
- package/esm2022/src/template/pipeline/ir/src/enums.mjs +34 -17
- package/esm2022/src/template/pipeline/ir/src/expression.mjs +19 -20
- package/esm2022/src/template/pipeline/ir/src/ops/create.mjs +37 -11
- package/esm2022/src/template/pipeline/ir/src/ops/host.mjs +5 -2
- package/esm2022/src/template/pipeline/ir/src/ops/update.mjs +29 -14
- package/esm2022/src/template/pipeline/src/emit.mjs +13 -9
- package/esm2022/src/template/pipeline/src/ingest.mjs +293 -158
- package/esm2022/src/template/pipeline/src/instruction.mjs +18 -14
- package/esm2022/src/template/pipeline/src/phases/apply_i18n_expressions.mjs +20 -4
- package/esm2022/src/template/pipeline/src/phases/assign_i18n_slot_dependencies.mjs +44 -22
- package/esm2022/src/template/pipeline/src/phases/attribute_extraction.mjs +26 -5
- package/esm2022/src/template/pipeline/src/phases/binding_specialization.mjs +4 -4
- package/esm2022/src/template/pipeline/src/phases/const_collection.mjs +15 -6
- package/esm2022/src/template/pipeline/src/phases/convert_i18n_bindings.mjs +52 -0
- package/esm2022/src/template/pipeline/src/phases/create_i18n_contexts.mjs +23 -1
- package/esm2022/src/template/pipeline/src/phases/extract_i18n_messages.mjs +65 -88
- package/esm2022/src/template/pipeline/src/phases/generate_advance.mjs +2 -2
- package/esm2022/src/template/pipeline/src/phases/generate_variables.mjs +7 -1
- package/esm2022/src/template/pipeline/src/phases/i18n_const_collection.mjs +147 -35
- package/esm2022/src/template/pipeline/src/phases/i18n_text_extraction.mjs +5 -3
- package/esm2022/src/template/pipeline/src/phases/parse_extracted_styles.mjs +4 -3
- package/esm2022/src/template/pipeline/src/phases/phase_remove_content_selectors.mjs +15 -3
- package/esm2022/src/template/pipeline/src/phases/propagate_i18n_blocks.mjs +31 -12
- package/esm2022/src/template/pipeline/src/phases/reify.mjs +18 -15
- package/esm2022/src/template/pipeline/src/phases/remove_unused_i18n_attrs.mjs +33 -0
- package/esm2022/src/template/pipeline/src/phases/resolve_i18n_element_placeholders.mjs +175 -31
- package/esm2022/src/template/pipeline/src/phases/resolve_i18n_expression_placeholders.mjs +10 -5
- package/esm2022/src/template/pipeline/src/phases/resolve_sanitizers.mjs +78 -14
- package/esm2022/src/template/pipeline/src/phases/slot_allocation.mjs +3 -1
- package/esm2022/src/template/pipeline/src/phases/var_counting.mjs +3 -1
- package/esm2022/src/version.mjs +1 -1
- package/fesm2022/compiler.mjs +1266 -549
- package/fesm2022/compiler.mjs.map +1 -1
- package/index.d.ts +21 -1
- package/package.json +2 -2
|
@@ -27,10 +27,14 @@ export function resolveI18nElementPlaceholders(job) {
|
|
|
27
27
|
}
|
|
28
28
|
resolvePlaceholdersForView(job, job.root, i18nContexts, elements);
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Recursively resolves element and template tag placeholders in the given view.
|
|
32
|
+
*/
|
|
33
|
+
function resolvePlaceholdersForView(job, unit, i18nContexts, elements, pendingStructuralDirective) {
|
|
31
34
|
// Track the current i18n op and corresponding i18n context op as we step through the creation
|
|
32
35
|
// IR.
|
|
33
36
|
let currentOps = null;
|
|
37
|
+
let pendingStructuralDirectiveCloses = new Map();
|
|
34
38
|
for (const op of unit.create) {
|
|
35
39
|
switch (op.kind) {
|
|
36
40
|
case ir.OpKind.I18nStart:
|
|
@@ -49,14 +53,14 @@ function resolvePlaceholdersForView(job, unit, i18nContexts, elements) {
|
|
|
49
53
|
if (currentOps === null) {
|
|
50
54
|
throw Error('i18n tag placeholder should only occur inside an i18n block');
|
|
51
55
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
flags |= ir.I18nParamValueFlags.CloseTag;
|
|
56
|
+
recordElementStart(op, currentOps.i18nContext, currentOps.i18nBlock, pendingStructuralDirective);
|
|
57
|
+
// If there is a separate close tag placeholder for this element, save the pending
|
|
58
|
+
// structural directive so we can pass it to the closing tag as well.
|
|
59
|
+
if (pendingStructuralDirective && op.i18nPlaceholder.closeName) {
|
|
60
|
+
pendingStructuralDirectiveCloses.set(op.xref, pendingStructuralDirective);
|
|
58
61
|
}
|
|
59
|
-
|
|
62
|
+
// Clear out the pending structural directive now that its been accounted for.
|
|
63
|
+
pendingStructuralDirective = undefined;
|
|
60
64
|
}
|
|
61
65
|
break;
|
|
62
66
|
case ir.OpKind.ElementEnd:
|
|
@@ -65,58 +69,198 @@ function resolvePlaceholdersForView(job, unit, i18nContexts, elements) {
|
|
|
65
69
|
const startOp = elements.get(op.xref);
|
|
66
70
|
if (startOp && startOp.i18nPlaceholder !== undefined) {
|
|
67
71
|
if (currentOps === null) {
|
|
68
|
-
throw Error('i18n tag placeholder should only occur inside an i18n block');
|
|
72
|
+
throw Error('AssertionError: i18n tag placeholder should only occur inside an i18n block');
|
|
69
73
|
}
|
|
70
|
-
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
recordElementClose(startOp, currentOps.i18nContext, currentOps.i18nBlock, pendingStructuralDirectiveCloses.get(op.xref));
|
|
75
|
+
// Clear out the pending structural directive close that was accounted for.
|
|
76
|
+
pendingStructuralDirectiveCloses.delete(op.xref);
|
|
77
|
+
}
|
|
78
|
+
break;
|
|
79
|
+
case ir.OpKind.Projection:
|
|
80
|
+
// For content projections with i18n placeholders, record its slot value in the params map
|
|
81
|
+
// under the corresponding tag start and close placeholders.
|
|
82
|
+
if (op.i18nPlaceholder !== undefined) {
|
|
83
|
+
if (currentOps === null) {
|
|
84
|
+
throw Error('i18n tag placeholder should only occur inside an i18n block');
|
|
74
85
|
}
|
|
86
|
+
recordElementStart(op, currentOps.i18nContext, currentOps.i18nBlock, pendingStructuralDirective);
|
|
87
|
+
recordElementClose(op, currentOps.i18nContext, currentOps.i18nBlock, pendingStructuralDirective);
|
|
88
|
+
// Clear out the pending structural directive now that its been accounted for.
|
|
89
|
+
pendingStructuralDirective = undefined;
|
|
75
90
|
}
|
|
76
91
|
break;
|
|
77
92
|
case ir.OpKind.Template:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
93
|
+
const view = job.views.get(op.xref);
|
|
94
|
+
if (op.i18nPlaceholder === undefined) {
|
|
95
|
+
// If there is no i18n placeholder, just recurse into the view in case it contains i18n
|
|
96
|
+
// blocks.
|
|
97
|
+
resolvePlaceholdersForView(job, view, i18nContexts, elements);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
81
100
|
if (currentOps === null) {
|
|
82
101
|
throw Error('i18n tag placeholder should only occur inside an i18n block');
|
|
83
102
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
103
|
+
if (op.templateKind === ir.TemplateKind.Structural) {
|
|
104
|
+
// If this is a structural directive template, don't record anything yet. Instead pass
|
|
105
|
+
// the current template as a pending structural directive to be recorded when we find
|
|
106
|
+
// the element, content, or template it belongs to. This allows us to create combined
|
|
107
|
+
// values that represent, e.g. the start of a template and element at the same time.
|
|
108
|
+
resolvePlaceholdersForView(job, view, i18nContexts, elements, op);
|
|
90
109
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
110
|
+
else {
|
|
111
|
+
// If this is some other kind of template, we can record its start, recurse into its
|
|
112
|
+
// view, and then record its end.
|
|
113
|
+
recordTemplateStart(job, view, op.handle.slot, op.i18nPlaceholder, currentOps.i18nContext, currentOps.i18nBlock, pendingStructuralDirective);
|
|
114
|
+
resolvePlaceholdersForView(job, view, i18nContexts, elements);
|
|
115
|
+
recordTemplateClose(job, view, op.handle.slot, op.i18nPlaceholder, currentOps.i18nContext, currentOps.i18nBlock, pendingStructuralDirective);
|
|
116
|
+
pendingStructuralDirective = undefined;
|
|
95
117
|
}
|
|
96
118
|
}
|
|
119
|
+
break;
|
|
120
|
+
case ir.OpKind.RepeaterCreate:
|
|
121
|
+
if (pendingStructuralDirective !== undefined) {
|
|
122
|
+
throw Error('AssertionError: Unexpected structural directive associated with @for block');
|
|
123
|
+
}
|
|
124
|
+
// RepeaterCreate has 3 slots: the first is for the op itself, the second is for the @for
|
|
125
|
+
// template and the (optional) third is for the @empty template.
|
|
126
|
+
const forSlot = op.handle.slot + 1;
|
|
127
|
+
const forView = job.views.get(op.xref);
|
|
128
|
+
// First record all of the placeholders for the @for template.
|
|
129
|
+
if (op.i18nPlaceholder === undefined) {
|
|
130
|
+
// If there is no i18n placeholder, just recurse into the view in case it contains i18n
|
|
131
|
+
// blocks.
|
|
132
|
+
resolvePlaceholdersForView(job, forView, i18nContexts, elements);
|
|
133
|
+
}
|
|
97
134
|
else {
|
|
98
|
-
|
|
135
|
+
if (currentOps === null) {
|
|
136
|
+
throw Error('i18n tag placeholder should only occur inside an i18n block');
|
|
137
|
+
}
|
|
138
|
+
recordTemplateStart(job, forView, forSlot, op.i18nPlaceholder, currentOps.i18nContext, currentOps.i18nBlock, pendingStructuralDirective);
|
|
139
|
+
resolvePlaceholdersForView(job, forView, i18nContexts, elements);
|
|
140
|
+
recordTemplateClose(job, forView, forSlot, op.i18nPlaceholder, currentOps.i18nContext, currentOps.i18nBlock, pendingStructuralDirective);
|
|
141
|
+
pendingStructuralDirective = undefined;
|
|
142
|
+
}
|
|
143
|
+
// Then if there's an @empty template, add its placeholders as well.
|
|
144
|
+
if (op.emptyView !== null) {
|
|
145
|
+
// RepeaterCreate has 3 slots: the first is for the op itself, the second is for the @for
|
|
146
|
+
// template and the (optional) third is for the @empty template.
|
|
147
|
+
const emptySlot = op.handle.slot + 2;
|
|
148
|
+
const emptyView = job.views.get(op.emptyView);
|
|
149
|
+
if (op.emptyI18nPlaceholder === undefined) {
|
|
150
|
+
// If there is no i18n placeholder, just recurse into the view in case it contains i18n
|
|
151
|
+
// blocks.
|
|
152
|
+
resolvePlaceholdersForView(job, emptyView, i18nContexts, elements);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
if (currentOps === null) {
|
|
156
|
+
throw Error('i18n tag placeholder should only occur inside an i18n block');
|
|
157
|
+
}
|
|
158
|
+
recordTemplateStart(job, emptyView, emptySlot, op.emptyI18nPlaceholder, currentOps.i18nContext, currentOps.i18nBlock, pendingStructuralDirective);
|
|
159
|
+
resolvePlaceholdersForView(job, emptyView, i18nContexts, elements);
|
|
160
|
+
recordTemplateClose(job, emptyView, emptySlot, op.emptyI18nPlaceholder, currentOps.i18nContext, currentOps.i18nBlock, pendingStructuralDirective);
|
|
161
|
+
pendingStructuralDirective = undefined;
|
|
162
|
+
}
|
|
99
163
|
}
|
|
100
164
|
break;
|
|
101
165
|
}
|
|
102
166
|
}
|
|
103
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Records an i18n param value for the start of an element.
|
|
170
|
+
*/
|
|
171
|
+
function recordElementStart(op, i18nContext, i18nBlock, structuralDirective) {
|
|
172
|
+
const { startName, closeName } = op.i18nPlaceholder;
|
|
173
|
+
let flags = ir.I18nParamValueFlags.ElementTag | ir.I18nParamValueFlags.OpenTag;
|
|
174
|
+
let value = op.handle.slot;
|
|
175
|
+
// If the element is associated with a structural directive, start it as well.
|
|
176
|
+
if (structuralDirective !== undefined) {
|
|
177
|
+
flags |= ir.I18nParamValueFlags.TemplateTag;
|
|
178
|
+
value = { element: value, template: structuralDirective.handle.slot };
|
|
179
|
+
}
|
|
180
|
+
// For self-closing tags, there is no close tag placeholder. Instead, the start tag
|
|
181
|
+
// placeholder accounts for the start and close of the element.
|
|
182
|
+
if (!closeName) {
|
|
183
|
+
flags |= ir.I18nParamValueFlags.CloseTag;
|
|
184
|
+
}
|
|
185
|
+
addParam(i18nContext.params, startName, value, i18nBlock.subTemplateIndex, flags);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Records an i18n param value for the closing of an element.
|
|
189
|
+
*/
|
|
190
|
+
function recordElementClose(op, i18nContext, i18nBlock, structuralDirective) {
|
|
191
|
+
const { closeName } = op.i18nPlaceholder;
|
|
192
|
+
// Self-closing tags don't have a closing tag placeholder, instead the element closing is
|
|
193
|
+
// recorded via an additional flag on the element start value.
|
|
194
|
+
if (closeName) {
|
|
195
|
+
let flags = ir.I18nParamValueFlags.ElementTag | ir.I18nParamValueFlags.CloseTag;
|
|
196
|
+
let value = op.handle.slot;
|
|
197
|
+
// If the element is associated with a structural directive, close it as well.
|
|
198
|
+
if (structuralDirective !== undefined) {
|
|
199
|
+
flags |= ir.I18nParamValueFlags.TemplateTag;
|
|
200
|
+
value = { element: value, template: structuralDirective.handle.slot };
|
|
201
|
+
}
|
|
202
|
+
addParam(i18nContext.params, closeName, value, i18nBlock.subTemplateIndex, flags);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Records an i18n param value for the start of a template.
|
|
207
|
+
*/
|
|
208
|
+
function recordTemplateStart(job, view, slot, i18nPlaceholder, i18nContext, i18nBlock, structuralDirective) {
|
|
209
|
+
let { startName, closeName } = i18nPlaceholder;
|
|
210
|
+
let flags = ir.I18nParamValueFlags.TemplateTag | ir.I18nParamValueFlags.OpenTag;
|
|
211
|
+
// For self-closing tags, there is no close tag placeholder. Instead, the start tag
|
|
212
|
+
// placeholder accounts for the start and close of the element.
|
|
213
|
+
if (!closeName) {
|
|
214
|
+
flags |= ir.I18nParamValueFlags.CloseTag;
|
|
215
|
+
}
|
|
216
|
+
// If the template is associated with a structural directive, record the structural directive's
|
|
217
|
+
// start first. Since this template must be in the structural directive's view, we can just
|
|
218
|
+
// directly use the current i18n block's sub-template index.
|
|
219
|
+
if (structuralDirective !== undefined) {
|
|
220
|
+
addParam(i18nContext.params, startName, structuralDirective.handle.slot, i18nBlock.subTemplateIndex, flags);
|
|
221
|
+
}
|
|
222
|
+
// Record the start of the template. For the sub-template index, pass the index for the template's
|
|
223
|
+
// view, rather than the current i18n block's index.
|
|
224
|
+
addParam(i18nContext.params, startName, slot, getSubTemplateIndexForTemplateTag(job, i18nBlock, view), flags);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Records an i18n param value for the closing of a template.
|
|
228
|
+
*/
|
|
229
|
+
function recordTemplateClose(job, view, slot, i18nPlaceholder, i18nContext, i18nBlock, structuralDirective) {
|
|
230
|
+
const { startName, closeName } = i18nPlaceholder;
|
|
231
|
+
const flags = ir.I18nParamValueFlags.TemplateTag | ir.I18nParamValueFlags.CloseTag;
|
|
232
|
+
// Self-closing tags don't have a closing tag placeholder, instead the template's closing is
|
|
233
|
+
// recorded via an additional flag on the template start value.
|
|
234
|
+
if (closeName) {
|
|
235
|
+
// Record the closing of the template. For the sub-template index, pass the index for the
|
|
236
|
+
// template's view, rather than the current i18n block's index.
|
|
237
|
+
addParam(i18nContext.params, closeName, slot, getSubTemplateIndexForTemplateTag(job, i18nBlock, view), flags);
|
|
238
|
+
// If the template is associated with a structural directive, record the structural directive's
|
|
239
|
+
// closing after. Since this template must be in the structural directive's view, we can just
|
|
240
|
+
// directly use the current i18n block's sub-template index.
|
|
241
|
+
if (structuralDirective !== undefined) {
|
|
242
|
+
addParam(i18nContext.params, closeName, structuralDirective.handle.slot, i18nBlock.subTemplateIndex, flags);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
104
246
|
/**
|
|
105
247
|
* Get the subTemplateIndex for the given template op. For template ops, use the subTemplateIndex of
|
|
106
248
|
* the child i18n block inside the template.
|
|
107
249
|
*/
|
|
108
|
-
function getSubTemplateIndexForTemplateTag(job, i18nOp,
|
|
109
|
-
for (const childOp of
|
|
250
|
+
function getSubTemplateIndexForTemplateTag(job, i18nOp, view) {
|
|
251
|
+
for (const childOp of view.create) {
|
|
110
252
|
if (childOp.kind === ir.OpKind.I18nStart) {
|
|
111
253
|
return childOp.subTemplateIndex;
|
|
112
254
|
}
|
|
113
255
|
}
|
|
114
256
|
return i18nOp.subTemplateIndex;
|
|
115
257
|
}
|
|
116
|
-
/**
|
|
258
|
+
/**
|
|
259
|
+
* Add a param value to the given params map.
|
|
260
|
+
*/
|
|
117
261
|
function addParam(params, placeholder, value, subTemplateIndex, flags) {
|
|
118
262
|
const values = params.get(placeholder) ?? [];
|
|
119
263
|
values.push({ value, subTemplateIndex, flags });
|
|
120
264
|
params.set(placeholder, values);
|
|
121
265
|
}
|
|
122
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZV9pMThuX2VsZW1lbnRfcGxhY2Vob2xkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3RlbXBsYXRlL3BpcGVsaW5lL3NyYy9waGFzZXMvcmVzb2x2ZV9pMThuX2VsZW1lbnRfcGxhY2Vob2xkZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRy9COztHQUVHO0FBQ0gsTUFBTSxVQUFVLDhCQUE4QixDQUFDLEdBQTRCO0lBQ3pFLGdFQUFnRTtJQUNoRSxNQUFNLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBK0IsQ0FBQztJQUM1RCxNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBZ0MsQ0FBQztJQUN6RCxLQUFLLE1BQU0sSUFBSSxJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUU7UUFDNUIsS0FBSyxNQUFNLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQzVCLFFBQVEsRUFBRSxDQUFDLElBQUksRUFBRTtnQkFDZixLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUMsV0FBVztvQkFDeEIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUM5QixNQUFNO2dCQUNSLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxZQUFZO29CQUN6QixRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7b0JBQzFCLE1BQU07YUFDVDtTQUNGO0tBQ0Y7SUFFRCwwQkFBMEIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDcEUsQ0FBQztBQUVELFNBQVMsMEJBQTBCLENBQy9CLEdBQTRCLEVBQUUsSUFB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QUMsQ0FBQztpQkFDbEY7Z0JBQ0QsTUFBTTtTQUNUO0tBQ0Y7QUFDSCxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxpQ0FBaUMsQ0FDdEMsR0FBNEIsRUFBRSxNQUFzQixFQUFFLEVBQWlCO0lBQ3pFLEtBQUssTUFBTSxPQUFPLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBRSxDQUFDLE1BQU0sRUFBRTtRQUNwRCxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7WUFDeEMsT0FBTyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7U0FDakM7S0FDRjtJQUNELE9BQU8sTUFBTSxDQUFDLGdCQUFnQixDQUFDO0FBQ2pDLENBQUM7QUFFRCxpREFBaUQ7QUFDakQsU0FBUyxRQUFRLENBQ2IsTUFBd0MsRUFBRSxXQUFtQixFQUFFLEtBQW9CLEVBQ25GLGdCQUE2QixFQUFFLEtBQTZCO0lBQzlELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzdDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBQyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQztJQUM5QyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUNsQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCAqIGFzIGlyIGZyb20gJy4uLy4uL2lyJztcbmltcG9ydCB7Q29tcG9uZW50Q29tcGlsYXRpb25Kb2IsIFZpZXdDb21waWxhdGlvblVuaXR9IGZyb20gJy4uL2NvbXBpbGF0aW9uJztcblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBlbGVtZW50IHBsYWNlaG9sZGVycyBpbiBpMThuIG1lc3NhZ2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUkxOG5FbGVtZW50UGxhY2Vob2xkZXJzKGpvYjogQ29tcG9uZW50Q29tcGlsYXRpb25Kb2IpIHtcbiAgLy8gUmVjb3JkIGFsbCBvZiB0aGUgZWxlbWVudCBhbmQgaTE4biBjb250ZXh0IG9wcyBmb3IgdXNlIGxhdGVyLlxuICBjb25zdCBpMThuQ29udGV4dHMgPSBuZXcgTWFwPGlyLlhyZWZJZCwgaXIuSTE4bkNvbnRleHRPcD4oKTtcbiAgY29uc3QgZWxlbWVudHMgPSBuZXcgTWFwPGlyLlhyZWZJZCwgaXIuRWxlbWVudFN0YXJ0T3A+KCk7XG4gIGZvciAoY29uc3QgdW5pdCBvZiBqb2IudW5pdHMpIHtcbiAgICBmb3IgKGNvbnN0IG9wIG9mIHVuaXQuY3JlYXRlKSB7XG4gICAgICBzd2l0Y2ggKG9wLmtpbmQpIHtcbiAgICAgICAgY2FzZSBpci5PcEtpbmQuSTE4bkNvbnRleHQ6XG4gICAgICAgICAgaTE4bkNvbnRleHRzLnNldChvcC54cmVmLCBvcCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgaXIuT3BLaW5kLkVsZW1lbnRTdGFydDpcbiAgICAgICAgICBlbGVtZW50cy5zZXQob3AueHJlZiwgb3ApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJlc29sdmVQbGFjZWhvbGRlcnNGb3JWaWV3KGpvYiwgam9iLnJvb3QsIGkxOG5Db250ZXh0cywgZWxlbWVudHMpO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlUGxhY2Vob2xkZXJzRm9yVmlldyhcbiAgICBqb2I6IENvbXBvbmVudENvbXBpbGF0aW9uSm9iLCB1bml0OiBWaWV3Q29tcGlsYXRpb25Vbml0LFxuICAgIGkxOG5Db250ZXh0czogTWFwPGlyLlhyZWZJZCwgaXIuSTE4bkNvbnRleHRPcD4sIGVsZW1lbnRzOiBNYXA8aXIuWHJlZklkLCBpci5FbGVtZW50U3RhcnRPcD4pIHtcbiAgLy8gVHJhY2sgdGhlIGN1cnJlbnQgaTE4biBvcCBhbmQgY29ycmVzcG9uZGluZyBpMThuIGNvbnRleHQgb3AgYXMgd2Ugc3RlcCB0aHJvdWdoIHRoZSBjcmVhdGlvblxuICAvLyBJUi5cbiAgbGV0IGN1cnJlbnRPcHM6IHtpMThuQmxvY2s6IGlyLkkxOG5TdGFydE9wLCBpMThuQ29udGV4dDogaXIuSTE4bkNvbnRleHRPcH18bnVsbCA9IG51bGw7XG4gIGZvciAoY29uc3Qgb3Agb2YgdW5pdC5jcmVhdGUpIHtcbiAgICBzd2l0Y2ggKG9wLmtpbmQpIHtcbiAgICAgIGNhc2UgaXIuT3BLaW5kLkkxOG5TdGFydDpcbiAgICAgICAgaWYgKCFvcC5jb250ZXh0KSB7XG4gICAgICAgICAgdGhyb3cgRXJyb3IoJ0NvdWxkIG5vdCBmaW5kIGkxOG4gY29udGV4dCBmb3IgaTE4biBvcCcpO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnRPcHMgPSB7aTE4bkJsb2NrOiBvcCwgaTE4bkNvbnRleHQ6IGkxOG5Db250ZXh0cy5nZXQob3AuY29udGV4dCkhfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGlyLk9wS2luZC5JMThuRW5kOlxuICAgICAgICBjdXJyZW50T3BzID0gbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGlyLk9wS2luZC5FbGVtZW50U3RhcnQ6XG4gICAgICAgIC8vIEZvciBlbGVtZW50cyB3aXRoIGkxOG4gcGxhY2Vob2xkZXJzLCByZWNvcmQgaXRzIHNsb3QgdmFsdWUgaW4gdGhlIHBhcmFtcyBtYXAgdW5kZXIgdGhlXG4gICAgICAgIC8vIGNvcnJlc3BvbmRpbmcgdGFnIHN0YXJ0IHBsYWNlaG9sZGVyLlxuICAgICAgICBpZiAob3AuaTE4blBsYWNlaG9sZGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAoY3VycmVudE9wcyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2kxOG4gdGFnIHBsYWNlaG9sZGVyIHNob3VsZCBvbmx5IG9jY3VyIGluc2lkZSBhbiBpMThuIGJsb2NrJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHtzdGFydE5hbWUsIGNsb3NlTmFtZX0gPSBvcC5pMThuUGxhY2Vob2xkZXI7XG4gICAgICAgICAgbGV0IGZsYWdzID0gaXIuSTE4blBhcmFtVmFsdWVGbGFncy5FbGVtZW50VGFnIHwgaXIuSTE4blBhcmFtVmFsdWVGbGFncy5PcGVuVGFnO1xuICAgICAgICAgIC8vIEZvciBzZWxmLWNsb3NpbmcgdGFncywgdGhlcmUgaXMgbm8gY2xvc2UgdGFnIHBsYWNlaG9sZGVyLiBJbnN0ZWFkLCB0aGUgc3RhcnQgdGFnXG4gICAgICAgICAgLy8gcGxhY2Vob2xkZXIgYWNjb3VudHMgZm9yIHRoZSBzdGFydCBhbmQgY2xvc2Ugb2YgdGhlIGVsZW1lbnQuXG4gICAgICAgICAgaWYgKGNsb3NlTmFtZSA9PT0gJycpIHtcbiAgICAgICAgICAgIGZsYWdzIHw9IGlyLkkxOG5QYXJhbVZhbHVlRmxhZ3MuQ2xvc2VUYWc7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFkZFBhcmFtKFxuICAgICAgICAgICAgICBjdXJyZW50T3BzLmkxOG5Db250ZXh0LnBhcmFtcywgc3RhcnROYW1lLCBvcC5oYW5kbGUuc2xvdCEsXG4gICAgICAgICAgICAgIGN1cnJlbnRPcHMuaTE4bkJsb2NrLnN1YlRlbXBsYXRlSW5kZXgsIGZsYWdzKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgaXIuT3BLaW5kLkVsZW1lbnRFbmQ6XG4gICAgICAgIC8vIEZvciBlbGVtZW50cyB3aXRoIGkxOG4gcGxhY2Vob2xkZXJzLCByZWNvcmQgaXRzIHNsb3QgdmFsdWUgaW4gdGhlIHBhcmFtcyBtYXAgdW5kZXIgdGhlXG4gICAgICAgIC8vIGNvcnJlc3BvbmRpbmcgdGFnIGNsb3NlIHBsYWNlaG9sZGVyLlxuICAgICAgICBjb25zdCBzdGFydE9wID0gZWxlbWVudHMuZ2V0KG9wLnhyZWYpO1xuICAgICAgICBpZiAoc3RhcnRPcCAmJiBzdGFydE9wLmkxOG5QbGFjZWhvbGRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnRPcHMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdpMThuIHRhZyBwbGFjZWhvbGRlciBzaG91bGQgb25seSBvY2N1ciBpbnNpZGUgYW4gaTE4biBibG9jaycpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB7Y2xvc2VOYW1lfSA9IHN0YXJ0T3AuaTE4blBsYWNlaG9sZGVyO1xuICAgICAgICAgIC8vIFNlbGYtY2xvc2luZyB0YWdzIGRvbid0IGhhdmUgYSBjbG9zaW5nIHRhZyBwbGFjZWhvbGRlci5cbiAgICAgICAgICBpZiAoY2xvc2VOYW1lICE9PSAnJykge1xuICAgICAgICAgICAgYWRkUGFyYW0oXG4gICAgICAgICAgICAgICAgY3VycmVudE9wcy5pMThuQ29udGV4dC5wYXJhbXMsIGNsb3NlTmFtZSwgc3RhcnRPcC5oYW5kbGUuc2xvdCEsXG4gICAgICAgICAgICAgICAgY3VycmVudE9wcy5pMThuQmxvY2suc3ViVGVtcGxhdGVJbmRleCxcbiAgICAgICAgICAgICAgICBpci5JMThuUGFyYW1WYWx1ZUZsYWdzLkVsZW1lbnRUYWcgfCBpci5JMThuUGFyYW1WYWx1ZUZsYWdzLkNsb3NlVGFnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGlyLk9wS2luZC5UZW1wbGF0ZTpcbiAgICAgICAgLy8gRm9yIHRlbXBsYXRlcyB3aXRoIGkxOG4gcGxhY2Vob2xkZXJzLCByZWNvcmQgaXRzIHNsb3QgdmFsdWUgaW4gdGhlIHBhcmFtcyBtYXAgdW5kZXIgdGhlXG4gICAgICAgIC8vIGNvcnJlc3BvbmRpbmcgdGVtcGxhdGUgc3RhcnQgYW5kIGNsb3NlIHBsYWNlaG9sZGVycy5cbiAgICAgICAgaWYgKG9wLmkxOG5QbGFjZWhvbGRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnRPcHMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdpMThuIHRhZyBwbGFjZWhvbGRlciBzaG91bGQgb25seSBvY2N1ciBpbnNpZGUgYW4gaTE4biBibG9jaycpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsZXQgc3RhcnRGbGFncyA9IGlyLkkxOG5QYXJhbVZhbHVlRmxhZ3MuVGVtcGxhdGVUYWcgfCBpci5JMThuUGFyYW1WYWx1ZUZsYWdzLk9wZW5UYWc7XG4gICAgICAgICAgY29uc3Qgc3ViVGVtcGxhdGVJbmRleCA9IGdldFN1YlRlbXBsYXRlSW5kZXhGb3JUZW1wbGF0ZVRhZyhqb2IsIGN1cnJlbnRPcHMuaTE4bkJsb2NrLCBvcCk7XG4gICAgICAgICAgY29uc3Qge3N0YXJ0TmFtZSwgY2xvc2VOYW1lfSA9IG9wLmkxOG5QbGFjZWhvbGRlcjtcbiAgICAgICAgICBjb25zdCBpc1NlbGZDbG9zaW5nID0gY2xvc2VOYW1lID09PSAnJztcbiAgICAgICAgICBpZiAoaXNTZWxmQ2xvc2luZykge1xuICAgICAgICAgICAgc3RhcnRGbGFncyB8PSBpci5JMThuUGFyYW1WYWx1ZUZsYWdzLkNsb3NlVGFnO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGFkZFBhcmFtKFxuICAgICAgICAgICAgICBjdXJyZW50T3BzLmkxOG5Db250ZXh0LnBhcmFtcywgc3RhcnROYW1lLCBvcC5oYW5kbGUuc2xvdCEsIHN1YlRlbXBsYXRlSW5kZXgsXG4gICAgICAgICAgICAgIHN0YXJ0RmxhZ3MpO1xuICAgICAgICAgIHJlc29sdmVQbGFjZWhvbGRlcnNGb3JWaWV3KGpvYiwgam9iLnZpZXdzLmdldChvcC54cmVmKSEsIGkxOG5Db250ZXh0cywgZWxlbWVudHMpO1xuICAgICAgICAgIGlmICghaXNTZWxmQ2xvc2luZykge1xuICAgICAgICAgICAgYWRkUGFyYW0oXG4gICAgICAgICAgICAgICAgY3VycmVudE9wcy5pMThuQ29udGV4dC5wYXJhbXMsIGNsb3NlTmFtZSwgb3AuaGFuZGxlLnNsb3QhLCBzdWJUZW1wbGF0ZUluZGV4LFxuICAgICAgICAgICAgICAgIGlyLkkxOG5QYXJhbVZhbHVlRmxhZ3MuVGVtcGxhdGVUYWcgfCBpci5JMThuUGFyYW1WYWx1ZUZsYWdzLkNsb3NlVGFnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzb2x2ZVBsYWNlaG9sZGVyc0ZvclZpZXcoam9iLCBqb2Iudmlld3MuZ2V0KG9wLnhyZWYpISwgaTE4bkNvbnRleHRzLCBlbGVtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogR2V0IHRoZSBzdWJUZW1wbGF0ZUluZGV4IGZvciB0aGUgZ2l2ZW4gdGVtcGxhdGUgb3AuIEZvciB0ZW1wbGF0ZSBvcHMsIHVzZSB0aGUgc3ViVGVtcGxhdGVJbmRleCBvZlxuICogdGhlIGNoaWxkIGkxOG4gYmxvY2sgaW5zaWRlIHRoZSB0ZW1wbGF0ZS5cbiAqL1xuZnVuY3Rpb24gZ2V0U3ViVGVtcGxhdGVJbmRleEZvclRlbXBsYXRlVGFnKFxuICAgIGpvYjogQ29tcG9uZW50Q29tcGlsYXRpb25Kb2IsIGkxOG5PcDogaXIuSTE4blN0YXJ0T3AsIG9wOiBpci5UZW1wbGF0ZU9wKTogbnVtYmVyfG51bGwge1xuICBmb3IgKGNvbnN0IGNoaWxkT3Agb2Ygam9iLnZpZXdzLmdldChvcC54cmVmKSEuY3JlYXRlKSB7XG4gICAgaWYgKGNoaWxkT3Aua2luZCA9PT0gaXIuT3BLaW5kLkkxOG5TdGFydCkge1xuICAgICAgcmV0dXJuIGNoaWxkT3Auc3ViVGVtcGxhdGVJbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGkxOG5PcC5zdWJUZW1wbGF0ZUluZGV4O1xufVxuXG4vKiogQWRkIGEgcGFyYW0gdmFsdWUgdG8gdGhlIGdpdmVuIHBhcmFtcyBtYXAuICovXG5mdW5jdGlvbiBhZGRQYXJhbShcbiAgICBwYXJhbXM6IE1hcDxzdHJpbmcsIGlyLkkxOG5QYXJhbVZhbHVlW10+LCBwbGFjZWhvbGRlcjogc3RyaW5nLCB2YWx1ZTogc3RyaW5nfG51bWJlcixcbiAgICBzdWJUZW1wbGF0ZUluZGV4OiBudW1iZXJ8bnVsbCwgZmxhZ3M6IGlyLkkxOG5QYXJhbVZhbHVlRmxhZ3MpIHtcbiAgY29uc3QgdmFsdWVzID0gcGFyYW1zLmdldChwbGFjZWhvbGRlcikgPz8gW107XG4gIHZhbHVlcy5wdXNoKHt2YWx1ZSwgc3ViVGVtcGxhdGVJbmRleCwgZmxhZ3N9KTtcbiAgcGFyYW1zLnNldChwbGFjZWhvbGRlciwgdmFsdWVzKTtcbn1cbiJdfQ==
|
|
266
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZV9pMThuX2VsZW1lbnRfcGxhY2Vob2xkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3RlbXBsYXRlL3BpcGVsaW5lL3NyYy9waGFzZXMvcmVzb2x2ZV9pMThuX2VsZW1lbnRfcGxhY2Vob2xkZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUdILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRy9COztHQUVHO0FBQ0gsTUFBTSxVQUFVLDhCQUE4QixDQUFDLEdBQTRCO0lBQ3pFLGdFQUFnRTtJQUNoRSxNQUFNLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBK0IsQ0FBQztJQUM1RCxNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBZ0MsQ0FBQztJQUN6RCxLQUFLLE1BQU0sSUFBSSxJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUU7UUFDNUIsS0FBSyxNQUFNLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQzVCLFFBQVEsRUFBRSxDQUFDLElBQUksRUFBRTtnQkFDZixLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUMsV0FBVztvQkFDeEIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUM5QixNQUFNO2dCQUNSLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxZQUFZO29CQUN6QixRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7b0JBQzFCLE1BQU07YUFDVDtTQUNGO0tBQ0Y7SUFFRCwwQkFBMEIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDcEUsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUywwQkFBMEIsQ0FDL0IsR0FB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QUdHO0FBQ0gsU0FBUyxpQ0FBaUMsQ0FDdEMsR0FBNEIsRUFBRSxNQUFzQixFQUFFLElBQXlCO0lBQ2pGLEtBQUssTUFBTSxPQUFPLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtRQUNqQyxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7WUFDeEMsT0FBTyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7U0FDakM7S0FDRjtJQUNELE9BQU8sTUFBTSxDQUFDLGdCQUFnQixDQUFDO0FBQ2pDLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsUUFBUSxDQUNiLE1BQXdDLEVBQUUsV0FBbUIsRUFDN0QsS0FBd0QsRUFBRSxnQkFBNkIsRUFDdkYsS0FBNkI7SUFDL0IsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDN0MsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFDLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDO0lBQzlDLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ2xDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0ICogYXMgaTE4biBmcm9tICcuLi8uLi8uLi8uLi9pMThuL2kxOG5fYXN0JztcbmltcG9ydCAqIGFzIGlyIGZyb20gJy4uLy4uL2lyJztcbmltcG9ydCB7Q29tcG9uZW50Q29tcGlsYXRpb25Kb2IsIFZpZXdDb21waWxhdGlvblVuaXR9IGZyb20gJy4uL2NvbXBpbGF0aW9uJztcblxuLyoqXG4gKiBSZXNvbHZlIHRoZSBlbGVtZW50IHBsYWNlaG9sZGVycyBpbiBpMThuIG1lc3NhZ2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUkxOG5FbGVtZW50UGxhY2Vob2xkZXJzKGpvYjogQ29tcG9uZW50Q29tcGlsYXRpb25Kb2IpIHtcbiAgLy8gUmVjb3JkIGFsbCBvZiB0aGUgZWxlbWVudCBhbmQgaTE4biBjb250ZXh0IG9wcyBmb3IgdXNlIGxhdGVyLlxuICBjb25zdCBpMThuQ29udGV4dHMgPSBuZXcgTWFwPGlyLlhyZWZJZCwgaXIuSTE4bkNvbnRleHRPcD4oKTtcbiAgY29uc3QgZWxlbWVudHMgPSBuZXcgTWFwPGlyLlhyZWZJZCwgaXIuRWxlbWVudFN0YXJ0T3A+KCk7XG4gIGZvciAoY29uc3QgdW5pdCBvZiBqb2IudW5pdHMpIHtcbiAgICBmb3IgKGNvbnN0IG9wIG9mIHVuaXQuY3JlYXRlKSB7XG4gICAgICBzd2l0Y2ggKG9wLmtpbmQpIHtcbiAgICAgICAgY2FzZSBpci5PcEtpbmQuSTE4bkNvbnRleHQ6XG4gICAgICAgICAgaTE4bkNvbnRleHRzLnNldChvcC54cmVmLCBvcCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgaXIuT3BLaW5kLkVsZW1lbnRTdGFydDpcbiAgICAgICAgICBlbGVtZW50cy5zZXQob3AueHJlZiwgb3ApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJlc29sdmVQbGFjZWhvbGRlcnNGb3JWaWV3KGpvYiwgam9iLnJvb3QsIGkxOG5Db250ZXh0cywgZWxlbWVudHMpO1xufVxuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5IHJlc29sdmVzIGVsZW1lbnQgYW5kIHRlbXBsYXRlIHRhZyBwbGFjZWhvbGRlcnMgaW4gdGhlIGdpdmVuIHZpZXcuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVQbGFjZWhvbGRlcnNGb3JWaWV3KFxuICAgIGpvYjogQ29tcG9uZW50Q29tcGlsYXRpb25Kb2IsIHVuaXQ6IFZpZXdDb21waWxhdGlvblVuaXQsXG4gICAgaTE4bkNvbnRleHRzOiBNYXA8aXIuWHJlZklkLCBpci5JMThuQ29udGV4dE9wPiwgZWxlbWVudHM6IE1hcDxpci5YcmVmSWQsIGlyLkVsZW1lbnRTdGFydE9wPixcbiAgICBwZW5kaW5nU3RydWN0dXJhbERpcmVjdGl2ZT86IGlyLlRlbXBsYXRlT3ApIHtcbiAgLy8gVHJhY2sgdGhlIGN1cnJlbnQgaTE4biBvcCBhbmQgY29ycmVzcG9uZGluZyBpMThuIGNvbnRleHQgb3AgYXMgd2Ugc3RlcCB0aHJvdWdoIHRoZSBjcmVhdGlvblxuICAvLyBJUi5cbiAgbGV0IGN1cnJlbnRPcHM6IHtpMThuQmxvY2s6IGlyLkkxOG5TdGFydE9wLCBpMThuQ29udGV4dDogaXIuSTE4bkNvbnRleHRPcH18bnVsbCA9IG51bGw7XG4gIGxldCBwZW5kaW5nU3RydWN0dXJhbERpcmVjdGl2ZUNsb3NlcyA9IG5ldyBNYXA8aXIuWHJlZklkLCBpci5UZW1wbGF0ZU9wPigpO1xuICBmb3IgKGNvbnN0IG9wIG9mIHVuaXQuY3JlYXRlKSB7XG4gICAgc3dpdGNoIChvcC5raW5kKSB7XG4gICAgICBjYXNlIGlyLk9wS2luZC5JMThuU3RhcnQ6XG4gICAgICAgIGlmICghb3AuY29udGV4dCkge1xuICAgICAgICAgIHRocm93IEVycm9yKCdDb3VsZCBub3QgZmluZCBpMThuIGNvbnRleHQgZm9yIGkxOG4gb3AnKTtcbiAgICAgICAgfVxuICAgICAgICBjdXJyZW50T3BzID0ge2kxOG5CbG9jazogb3AsIGkxOG5Db250ZXh0OiBpMThuQ29udGV4dHMuZ2V0KG9wLmNvbnRleHQpIX07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBpci5PcEtpbmQuSTE4bkVuZDpcbiAgICAgICAgY3VycmVudE9wcyA9IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBpci5PcEtpbmQuRWxlbWVudFN0YXJ0OlxuICAgICAgICAvLyBGb3IgZWxlbWVudHMgd2l0aCBpMThuIHBsYWNlaG9sZGVycywgcmVjb3JkIGl0cyBzbG90IHZhbHVlIGluIHRoZSBwYXJhbXMgbWFwIHVuZGVyIHRoZVxuICAgICAgICAvLyBjb3JyZXNwb25kaW5nIHRhZyBzdGFydCBwbGFjZWhvbGRlci5cbiAgICAgICAgaWYgKG9wLmkxOG5QbGFjZWhvbGRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnRPcHMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdpMThuIHRhZyBwbGFjZWhvbGRlciBzaG91bGQgb25seSBvY2N1ciBpbnNpZGUgYW4gaTE4biBibG9jaycpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZWNvcmRFbGVtZW50U3RhcnQoXG4gICAgICAgICAgICAgIG9wLCBjdXJyZW50T3BzLmkxOG5Db250ZXh0LCBjdXJyZW50T3BzLmkxOG5CbG9jaywgcGVuZGluZ1N0cnVjdHVyYWxEaXJlY3RpdmUpO1xuICAgICAgICAgIC8vIElmIHRoZXJlIGlzIGEgc2VwYXJhdGUgY2xvc2UgdGFnIHBsYWNlaG9sZGVyIGZvciB0aGlzIGVsZW1lbnQsIHNhdmUgdGhlIHBlbmRpbmdcbiAgICAgICAgICAvLyBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZSBzbyB3ZSBjYW4gcGFzcyBpdCB0byB0aGUgY2xvc2luZyB0YWcgYXMgd2VsbC5cbiAgICAgICAgICBpZiAocGVuZGluZ1N0cnVjdHVyYWxEaXJlY3RpdmUgJiYgb3AuaTE4blBsYWNlaG9sZGVyLmNsb3NlTmFtZSkge1xuICAgICAgICAgICAgcGVuZGluZ1N0cnVjdHVyYWxEaXJlY3RpdmVDbG9zZXMuc2V0KG9wLnhyZWYsIHBlbmRpbmdTdHJ1Y3R1cmFsRGlyZWN0aXZlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gQ2xlYXIgb3V0IHRoZSBwZW5kaW5nIHN0cnVjdHVyYWwgZGlyZWN0aXZlIG5vdyB0aGF0IGl0cyBiZWVuIGFjY291bnRlZCBmb3IuXG4gICAgICAgICAgcGVuZGluZ1N0cnVjdHVyYWxEaXJlY3RpdmUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGlyLk9wS2luZC5FbGVtZW50RW5kOlxuICAgICAgICAvLyBGb3IgZWxlbWVudHMgd2l0aCBpMThuIHBsYWNlaG9sZGVycywgcmVjb3JkIGl0cyBzbG90IHZhbHVlIGluIHRoZSBwYXJhbXMgbWFwIHVuZGVyIHRoZVxuICAgICAgICAvLyBjb3JyZXNwb25kaW5nIHRhZyBjbG9zZSBwbGFjZWhvbGRlci5cbiAgICAgICAgY29uc3Qgc3RhcnRPcCA9IGVsZW1lbnRzLmdldChvcC54cmVmKTtcbiAgICAgICAgaWYgKHN0YXJ0T3AgJiYgc3RhcnRPcC5pMThuUGxhY2Vob2xkZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChjdXJyZW50T3BzID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgICAgICAgICAnQXNzZXJ0aW9uRXJyb3I6IGkxOG4gdGFnIHBsYWNlaG9sZGVyIHNob3VsZCBvbmx5IG9jY3VyIGluc2lkZSBhbiBpMThuIGJsb2NrJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlY29yZEVsZW1lbnRDbG9zZShcbiAgICAgICAgICAgICAgc3RhcnRPcCwgY3VycmVudE9wcy5pMThuQ29udGV4dCwgY3VycmVudE9wcy5pMThuQmxvY2ssXG4gICAgICAgICAgICAgIHBlbmRpbmdTdHJ1Y3R1cmFsRGlyZWN0aXZlQ2xvc2VzLmdldChvcC54cmVmKSk7XG4gICAgICAgICAgLy8gQ2xlYXIgb3V0IHRoZSBwZW5kaW5nIHN0cnVjdHVyYWwgZGlyZWN0aXZlIGNsb3NlIHRoYXQgd2FzIGFjY291bnRlZCBmb3IuXG4gICAgICAgICAgcGVuZGluZ1N0cnVjdHVyYWxEaXJlY3RpdmVDbG9zZXMuZGVsZXRlKG9wLnhyZWYpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBpci5PcEtpbmQuUHJvamVjdGlvbjpcbiAgICAgICAgLy8gRm9yIGNvbnRlbnQgcHJvamVjdGlvbnMgd2l0aCBpMThuIHBsYWNlaG9sZGVycywgcmVjb3JkIGl0cyBzbG90IHZhbHVlIGluIHRoZSBwYXJhbXMgbWFwXG4gICAgICAgIC8vIHVuZGVyIHRoZSBjb3JyZXNwb25kaW5nIHRhZyBzdGFydCBhbmQgY2xvc2UgcGxhY2Vob2xkZXJzLlxuICAgICAgICBpZiAob3AuaTE4blBsYWNlaG9sZGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAoY3VycmVudE9wcyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ2kxOG4gdGFnIHBsYWNlaG9sZGVyIHNob3VsZCBvbmx5IG9jY3VyIGluc2lkZSBhbiBpMThuIGJsb2NrJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlY29yZEVsZW1lbnRTdGFydChcbiAgICAgICAgICAgICAgb3AsIGN1cnJlbnRPcHMuaTE4bkNvbnRleHQsIGN1cnJlbnRPcHMuaTE4bkJsb2NrLCBwZW5kaW5nU3RydWN0dXJhbERpcmVjdGl2ZSk7XG4gICAgICAgICAgcmVjb3JkRWxlbWVudENsb3NlKFxuICAgICAgICAgICAgICBvcCwgY3VycmVudE9wcy5pMThuQ29udGV4dCwgY3VycmVudE9wcy5pMThuQmxvY2ssIHBlbmRpbmdTdHJ1Y3R1cmFsRGlyZWN0aXZlKTtcbiAgICAgICAgICAvLyBDbGVhciBvdXQgdGhlIHBlbmRpbmcgc3RydWN0dXJhbCBkaXJlY3RpdmUgbm93IHRoYXQgaXRzIGJlZW4gYWNjb3VudGVkIGZvci5cbiAgICAgICAgICBwZW5kaW5nU3RydWN0dXJhbERpcmVjdGl2ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgaXIuT3BLaW5kLlRlbXBsYXRlOlxuICAgICAgICBjb25zdCB2aWV3ID0gam9iLnZpZXdzLmdldChvcC54cmVmKSE7XG4gICAgICAgIGlmIChvcC5pMThuUGxhY2Vob2xkZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGkxOG4gcGxhY2Vob2xkZXIsIGp1c3QgcmVjdXJzZSBpbnRvIHRoZSB2aWV3IGluIGNhc2UgaXQgY29udGFpbnMgaTE4blxuICAgICAgICAgIC8vIGJsb2Nrcy5cbiAgICAgICAgICByZXNvbHZlUGxhY2Vob2xkZXJzRm9yVmlldyhqb2IsIHZpZXcsIGkxOG5Db250ZXh0cywgZWxlbWVudHMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChjdXJyZW50T3BzID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBFcnJvcignaTE4biB0YWcgcGxhY2Vob2xkZXIgc2hvdWxkIG9ubHkgb2NjdXIgaW5zaWRlIGFuIGkxOG4gYmxvY2snKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG9wLnRlbXBsYXRlS2luZCA9PT0gaXIuVGVtcGxhdGVLaW5kLlN0cnVjdHVyYWwpIHtcbiAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgYSBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZSB0ZW1wbGF0ZSwgZG9uJ3QgcmVjb3JkIGFueXRoaW5nIHlldC4gSW5zdGVhZCBwYXNzXG4gICAgICAgICAgICAvLyB0aGUgY3VycmVudCB0ZW1wbGF0ZSBhcyBhIHBlbmRpbmcgc3RydWN0dXJhbCBkaXJlY3RpdmUgdG8gYmUgcmVjb3JkZWQgd2hlbiB3ZSBmaW5kXG4gICAgICAgICAgICAvLyB0aGUgZWxlbWVudCwgY29udGVudCwgb3IgdGVtcGxhdGUgaXQgYmVsb25ncyB0by4gVGhpcyBhbGxvd3MgdXMgdG8gY3JlYXRlIGNvbWJpbmVkXG4gICAgICAgICAgICAvLyB2YWx1ZXMgdGhhdCByZXByZXNlbnQsIGUuZy4gdGhlIHN0YXJ0IG9mIGEgdGVtcGxhdGUgYW5kIGVsZW1lbnQgYXQgdGhlIHNhbWUgdGltZS5cbiAgICAgICAgICAgIHJlc29sdmVQbGFjZWhvbGRlcnNGb3JWaWV3KGpvYiwgdmlldywgaTE4bkNvbnRleHRzLCBlbGVtZW50cywgb3ApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBJZiB0aGlzIGlzIHNvbWUgb3RoZXIga2luZCBvZiB0ZW1wbGF0ZSwgd2UgY2FuIHJlY29yZCBpdHMgc3RhcnQsIHJlY3Vyc2UgaW50byBpdHNcbiAgICAgICAgICAgIC8vIHZpZXcsIGFuZCB0aGVuIHJlY29yZCBpdHMgZW5kLlxuICAgICAgICAgICAgcmVjb3JkVGVtcGxhdGVTdGFydChcbiAgICAgICAgICAgICAgICBqb2IsIHZpZXcsIG9wLmhhbmRsZS5zbG90ISwgb3AuaTE4blBsYWNlaG9sZGVyLCBjdXJyZW50T3BzLmkxOG5Db250ZXh0LFxuICAgICAgICAgICAgICAgIGN1cnJlbnRPcHMuaTE4bkJsb2NrLCBwZW5kaW5nU3RydWN0dXJhbERpcmVjdGl2ZSk7XG4gICAgICAgICAgICByZXNvbHZlUGxhY2Vob2xkZXJzRm9yVmlldyhqb2IsIHZpZXcsIGkxOG5Db250ZXh0cywgZWxlbWVudHMpO1xuICAgICAgICAgICAgcmVjb3JkVGVtcGxhdGVDbG9zZShcbiAgICAgICAgICAgICAgICBqb2IsIHZpZXcsIG9wLmhhbmRsZS5zbG90ISwgb3AuaTE4blBsYWNlaG9sZGVyLCBjdXJyZW50T3BzIS5pMThuQ29udGV4dCxcbiAgICAgICAgICAgICAgICBjdXJyZW50T3BzIS5pMThuQmxvY2ssIHBlbmRpbmdTdHJ1Y3R1cmFsRGlyZWN0aXZlKTtcbiAgICAgICAgICAgIHBlbmRpbmdTdHJ1Y3R1cmFsRGlyZWN0aXZlID0gdW5kZWZpbmVkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgaXIuT3BLaW5kLlJlcGVhdGVyQ3JlYXRlOlxuICAgICAgICBpZiAocGVuZGluZ1N0cnVjdHVyYWxEaXJlY3RpdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IEVycm9yKCdBc3NlcnRpb25FcnJvcjogVW5leHBlY3RlZCBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZSBhc3NvY2lhdGVkIHdpdGggQGZvciBibG9jaycpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlcGVhdGVyQ3JlYXRlIGhhcyAzIHNsb3RzOiB0aGUgZmlyc3QgaXMgZm9yIHRoZSBvcCBpdHNlbGYsIHRoZSBzZWNvbmQgaXMgZm9yIHRoZSBAZm9yXG4gICAgICAgIC8vIHRlbXBsYXRlIGFuZCB0aGUgKG9wdGlvbmFsKSB0aGlyZCBpcyBmb3IgdGhlIEBlbXB0eSB0ZW1wbGF0ZS5cbiAgICAgICAgY29uc3QgZm9yU2xvdCA9IG9wLmhhbmRsZS5zbG90ISArIDE7XG4gICAgICAgIGNvbnN0IGZvclZpZXcgPSBqb2Iudmlld3MuZ2V0KG9wLnhyZWYpITtcbiAgICAgICAgLy8gRmlyc3QgcmVjb3JkIGFsbCBvZiB0aGUgcGxhY2Vob2xkZXJzIGZvciB0aGUgQGZvciB0ZW1wbGF0ZS5cbiAgICAgICAgaWYgKG9wLmkxOG5QbGFjZWhvbGRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gaTE4biBwbGFjZWhvbGRlciwganVzdCByZWN1cnNlIGludG8gdGhlIHZpZXcgaW4gY2FzZSBpdCBjb250YWlucyBpMThuXG4gICAgICAgICAgLy8gYmxvY2tzLlxuICAgICAgICAgIHJlc29sdmVQbGFjZWhvbGRlcnNGb3JWaWV3KGpvYiwgZm9yVmlldywgaTE4bkNvbnRleHRzLCBlbGVtZW50cyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGN1cnJlbnRPcHMgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdpMThuIHRhZyBwbGFjZWhvbGRlciBzaG91bGQgb25seSBvY2N1ciBpbnNpZGUgYW4gaTE4biBibG9jaycpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZWNvcmRUZW1wbGF0ZVN0YXJ0KFxuICAgICAgICAgICAgICBqb2IsIGZvclZpZXcsIGZvclNsb3QsIG9wLmkxOG5QbGFjZWhvbGRlciwgY3VycmVudE9wcy5pMThuQ29udGV4dCxcbiAgICAgICAgICAgICAgY3VycmVudE9wcy5pMThuQmxvY2ssIHBlbmRpbmdTdHJ1Y3R1cmFsRGlyZWN0aXZlKTtcbiAgICAgICAgICByZXNvbHZlUGxhY2Vob2xkZXJzRm9yVmlldyhqb2IsIGZvclZpZXcsIGkxOG5Db250ZXh0cywgZWxlbWVudHMpO1xuICAgICAgICAgIHJlY29yZFRlbXBsYXRlQ2xvc2UoXG4gICAgICAgICAgICAgIGpvYiwgZm9yVmlldywgZm9yU2xvdCwgb3AuaTE4blBsYWNlaG9sZGVyLCBjdXJyZW50T3BzIS5pMThuQ29udGV4dCxcbiAgICAgICAgICAgICAgY3VycmVudE9wcyEuaTE4bkJsb2NrLCBwZW5kaW5nU3RydWN0dXJhbERpcmVjdGl2ZSk7XG4gICAgICAgICAgcGVuZGluZ1N0cnVjdHVyYWxEaXJlY3RpdmUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGhlbiBpZiB0aGVyZSdzIGFuIEBlbXB0eSB0ZW1wbGF0ZSwgYWRkIGl0cyBwbGFjZWhvbGRlcnMgYXMgd2VsbC5cbiAgICAgICAgaWYgKG9wLmVtcHR5VmlldyAhPT0gbnVsbCkge1xuICAgICAgICAgIC8vIFJlcGVhdGVyQ3JlYXRlIGhhcyAzIHNsb3RzOiB0aGUgZmlyc3QgaXMgZm9yIHRoZSBvcCBpdHNlbGYsIHRoZSBzZWNvbmQgaXMgZm9yIHRoZSBAZm9yXG4gICAgICAgICAgLy8gdGVtcGxhdGUgYW5kIHRoZSAob3B0aW9uYWwpIHRoaXJkIGlzIGZvciB0aGUgQGVtcHR5IHRlbXBsYXRlLlxuICAgICAgICAgIGNvbnN0IGVtcHR5U2xvdCA9IG9wLmhhbmRsZS5zbG90ISArIDI7XG4gICAgICAgICAgY29uc3QgZW1wdHlWaWV3ID0gam9iLnZpZXdzLmdldChvcC5lbXB0eVZpZXchKSE7XG4gICAgICAgICAgaWYgKG9wLmVtcHR5STE4blBsYWNlaG9sZGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGkxOG4gcGxhY2Vob2xkZXIsIGp1c3QgcmVjdXJzZSBpbnRvIHRoZSB2aWV3IGluIGNhc2UgaXQgY29udGFpbnMgaTE4blxuICAgICAgICAgICAgLy8gYmxvY2tzLlxuICAgICAgICAgICAgcmVzb2x2ZVBsYWNlaG9sZGVyc0ZvclZpZXcoam9iLCBlbXB0eVZpZXcsIGkxOG5Db250ZXh0cywgZWxlbWVudHMpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudE9wcyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICB0aHJvdyBFcnJvcignaTE4biB0YWcgcGxhY2Vob2xkZXIgc2hvdWxkIG9ubHkgb2NjdXIgaW5zaWRlIGFuIGkxOG4gYmxvY2snKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlY29yZFRlbXBsYXRlU3RhcnQoXG4gICAgICAgICAgICAgICAgam9iLCBlbXB0eVZpZXcsIGVtcHR5U2xvdCwgb3AuZW1wdHlJMThuUGxhY2Vob2xkZXIsIGN1cnJlbnRPcHMuaTE4bkNvbnRleHQsXG4gICAgICAgICAgICAgICAgY3VycmVudE9wcy5pMThuQmxvY2ssIHBlbmRpbmdTdHJ1Y3R1cmFsRGlyZWN0aXZlKTtcbiAgICAgICAgICAgIHJlc29sdmVQbGFjZWhvbGRlcnNGb3JWaWV3KGpvYiwgZW1wdHlWaWV3LCBpMThuQ29udGV4dHMsIGVsZW1lbnRzKTtcbiAgICAgICAgICAgIHJlY29yZFRlbXBsYXRlQ2xvc2UoXG4gICAgICAgICAgICAgICAgam9iLCBlbXB0eVZpZXcsIGVtcHR5U2xvdCwgb3AuZW1wdHlJMThuUGxhY2Vob2xkZXIsIGN1cnJlbnRPcHMhLmkxOG5Db250ZXh0LFxuICAgICAgICAgICAgICAgIGN1cnJlbnRPcHMhLmkxOG5CbG9jaywgcGVuZGluZ1N0cnVjdHVyYWxEaXJlY3RpdmUpO1xuICAgICAgICAgICAgcGVuZGluZ1N0cnVjdHVyYWxEaXJlY3RpdmUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlY29yZHMgYW4gaTE4biBwYXJhbSB2YWx1ZSBmb3IgdGhlIHN0YXJ0IG9mIGFuIGVsZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIHJlY29yZEVsZW1lbnRTdGFydChcbiAgICBvcDogaXIuRWxlbWVudFN0YXJ0T3B8aXIuUHJvamVjdGlvbk9wLCBpMThuQ29udGV4dDogaXIuSTE4bkNvbnRleHRPcCwgaTE4bkJsb2NrOiBpci5JMThuU3RhcnRPcCxcbiAgICBzdHJ1Y3R1cmFsRGlyZWN0aXZlPzogaXIuVGVtcGxhdGVPcCkge1xuICBjb25zdCB7c3RhcnROYW1lLCBjbG9zZU5hbWV9ID0gb3AuaTE4blBsYWNlaG9sZGVyITtcbiAgbGV0IGZsYWdzID0gaXIuSTE4blBhcmFtVmFsdWVGbGFncy5FbGVtZW50VGFnIHwgaXIuSTE4blBhcmFtVmFsdWVGbGFncy5PcGVuVGFnO1xuICBsZXQgdmFsdWU6IGlyLkkxOG5QYXJhbVZhbHVlWyd2YWx1ZSddID0gb3AuaGFuZGxlLnNsb3QhO1xuICAvLyBJZiB0aGUgZWxlbWVudCBpcyBhc3NvY2lhdGVkIHdpdGggYSBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZSwgc3RhcnQgaXQgYXMgd2VsbC5cbiAgaWYgKHN0cnVjdHVyYWxEaXJlY3RpdmUgIT09IHVuZGVmaW5lZCkge1xuICAgIGZsYWdzIHw9IGlyLkkxOG5QYXJhbVZhbHVlRmxhZ3MuVGVtcGxhdGVUYWc7XG4gICAgdmFsdWUgPSB7ZWxlbWVudDogdmFsdWUsIHRlbXBsYXRlOiBzdHJ1Y3R1cmFsRGlyZWN0aXZlLmhhbmRsZS5zbG90IX07XG4gIH1cbiAgLy8gRm9yIHNlbGYtY2xvc2luZyB0YWdzLCB0aGVyZSBpcyBubyBjbG9zZSB0YWcgcGxhY2Vob2xkZXIuIEluc3RlYWQsIHRoZSBzdGFydCB0YWdcbiAgLy8gcGxhY2Vob2xkZXIgYWNjb3VudHMgZm9yIHRoZSBzdGFydCBhbmQgY2xvc2Ugb2YgdGhlIGVsZW1lbnQuXG4gIGlmICghY2xvc2VOYW1lKSB7XG4gICAgZmxhZ3MgfD0gaXIuSTE4blBhcmFtVmFsdWVGbGFncy5DbG9zZVRhZztcbiAgfVxuICBhZGRQYXJhbShpMThuQ29udGV4dC5wYXJhbXMsIHN0YXJ0TmFtZSwgdmFsdWUsIGkxOG5CbG9jay5zdWJUZW1wbGF0ZUluZGV4LCBmbGFncyk7XG59XG5cbi8qKlxuICogUmVjb3JkcyBhbiBpMThuIHBhcmFtIHZhbHVlIGZvciB0aGUgY2xvc2luZyBvZiBhbiBlbGVtZW50LlxuICovXG5mdW5jdGlvbiByZWNvcmRFbGVtZW50Q2xvc2UoXG4gICAgb3A6IGlyLkVsZW1lbnRTdGFydE9wfGlyLlByb2plY3Rpb25PcCwgaTE4bkNvbnRleHQ6IGlyLkkxOG5Db250ZXh0T3AsIGkxOG5CbG9jazogaXIuSTE4blN0YXJ0T3AsXG4gICAgc3RydWN0dXJhbERpcmVjdGl2ZT86IGlyLlRlbXBsYXRlT3ApIHtcbiAgY29uc3Qge2Nsb3NlTmFtZX0gPSBvcC5pMThuUGxhY2Vob2xkZXIhO1xuICAvLyBTZWxmLWNsb3NpbmcgdGFncyBkb24ndCBoYXZlIGEgY2xvc2luZyB0YWcgcGxhY2Vob2xkZXIsIGluc3RlYWQgdGhlIGVsZW1lbnQgY2xvc2luZyBpc1xuICAvLyByZWNvcmRlZCB2aWEgYW4gYWRkaXRpb25hbCBmbGFnIG9uIHRoZSBlbGVtZW50IHN0YXJ0IHZhbHVlLlxuICBpZiAoY2xvc2VOYW1lKSB7XG4gICAgbGV0IGZsYWdzID0gaXIuSTE4blBhcmFtVmFsdWVGbGFncy5FbGVtZW50VGFnIHwgaXIuSTE4blBhcmFtVmFsdWVGbGFncy5DbG9zZVRhZztcbiAgICBsZXQgdmFsdWU6IGlyLkkxOG5QYXJhbVZhbHVlWyd2YWx1ZSddID0gb3AuaGFuZGxlLnNsb3QhO1xuICAgIC8vIElmIHRoZSBlbGVtZW50IGlzIGFzc29jaWF0ZWQgd2l0aCBhIHN0cnVjdHVyYWwgZGlyZWN0aXZlLCBjbG9zZSBpdCBhcyB3ZWxsLlxuICAgIGlmIChzdHJ1Y3R1cmFsRGlyZWN0aXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGZsYWdzIHw9IGlyLkkxOG5QYXJhbVZhbHVlRmxhZ3MuVGVtcGxhdGVUYWc7XG4gICAgICB2YWx1ZSA9IHtlbGVtZW50OiB2YWx1ZSwgdGVtcGxhdGU6IHN0cnVjdHVyYWxEaXJlY3RpdmUuaGFuZGxlLnNsb3QhfTtcbiAgICB9XG4gICAgYWRkUGFyYW0oaTE4bkNvbnRleHQucGFyYW1zLCBjbG9zZU5hbWUsIHZhbHVlLCBpMThuQmxvY2suc3ViVGVtcGxhdGVJbmRleCwgZmxhZ3MpO1xuICB9XG59XG5cbi8qKlxuICogUmVjb3JkcyBhbiBpMThuIHBhcmFtIHZhbHVlIGZvciB0aGUgc3RhcnQgb2YgYSB0ZW1wbGF0ZS5cbiAqL1xuZnVuY3Rpb24gcmVjb3JkVGVtcGxhdGVTdGFydChcbiAgICBqb2I6IENvbXBvbmVudENvbXBpbGF0aW9uSm9iLCB2aWV3OiBWaWV3Q29tcGlsYXRpb25Vbml0LCBzbG90OiBudW1iZXIsXG4gICAgaTE4blBsYWNlaG9sZGVyOiBpMThuLlRhZ1BsYWNlaG9sZGVyfGkxOG4uQmxvY2tQbGFjZWhvbGRlciwgaTE4bkNvbnRleHQ6IGlyLkkxOG5Db250ZXh0T3AsXG4gICAgaTE4bkJsb2NrOiBpci5JMThuU3RhcnRPcCwgc3RydWN0dXJhbERpcmVjdGl2ZT86IGlyLlRlbXBsYXRlT3ApIHtcbiAgbGV0IHtzdGFydE5hbWUsIGNsb3NlTmFtZX0gPSBpMThuUGxhY2Vob2xkZXI7XG4gIGxldCBmbGFncyA9IGlyLkkxOG5QYXJhbVZhbHVlRmxhZ3MuVGVtcGxhdGVUYWcgfCBpci5JMThuUGFyYW1WYWx1ZUZsYWdzLk9wZW5UYWc7XG4gIC8vIEZvciBzZWxmLWNsb3NpbmcgdGFncywgdGhlcmUgaXMgbm8gY2xvc2UgdGFnIHBsYWNlaG9sZGVyLiBJbnN0ZWFkLCB0aGUgc3RhcnQgdGFnXG4gIC8vIHBsYWNlaG9sZGVyIGFjY291bnRzIGZvciB0aGUgc3RhcnQgYW5kIGNsb3NlIG9mIHRoZSBlbGVtZW50LlxuICBpZiAoIWNsb3NlTmFtZSkge1xuICAgIGZsYWdzIHw9IGlyLkkxOG5QYXJhbVZhbHVlRmxhZ3MuQ2xvc2VUYWc7XG4gIH1cbiAgLy8gSWYgdGhlIHRlbXBsYXRlIGlzIGFzc29jaWF0ZWQgd2l0aCBhIHN0cnVjdHVyYWwgZGlyZWN0aXZlLCByZWNvcmQgdGhlIHN0cnVjdHVyYWwgZGlyZWN0aXZlJ3NcbiAgLy8gc3RhcnQgZmlyc3QuIFNpbmNlIHRoaXMgdGVtcGxhdGUgbXVzdCBiZSBpbiB0aGUgc3RydWN0dXJhbCBkaXJlY3RpdmUncyB2aWV3LCB3ZSBjYW4ganVzdFxuICAvLyBkaXJlY3RseSB1c2UgdGhlIGN1cnJlbnQgaTE4biBibG9jaydzIHN1Yi10ZW1wbGF0ZSBpbmRleC5cbiAgaWYgKHN0cnVjdHVyYWxEaXJlY3RpdmUgIT09IHVuZGVmaW5lZCkge1xuICAgIGFkZFBhcmFtKFxuICAgICAgICBpMThuQ29udGV4dC5wYXJhbXMsIHN0YXJ0TmFtZSwgc3RydWN0dXJhbERpcmVjdGl2ZS5oYW5kbGUuc2xvdCEsIGkxOG5CbG9jay5zdWJUZW1wbGF0ZUluZGV4LFxuICAgICAgICBmbGFncyk7XG4gIH1cbiAgLy8gUmVjb3JkIHRoZSBzdGFydCBvZiB0aGUgdGVtcGxhdGUuIEZvciB0aGUgc3ViLXRlbXBsYXRlIGluZGV4LCBwYXNzIHRoZSBpbmRleCBmb3IgdGhlIHRlbXBsYXRlJ3NcbiAgLy8gdmlldywgcmF0aGVyIHRoYW4gdGhlIGN1cnJlbnQgaTE4biBibG9jaydzIGluZGV4LlxuICBhZGRQYXJhbShcbiAgICAgIGkxOG5Db250ZXh0LnBhcmFtcywgc3RhcnROYW1lLCBzbG90LCBnZXRTdWJUZW1wbGF0ZUluZGV4Rm9yVGVtcGxhdGVUYWcoam9iLCBpMThuQmxvY2ssIHZpZXcpLFxuICAgICAgZmxhZ3MpO1xufVxuXG4vKipcbiAqIFJlY29yZHMgYW4gaTE4biBwYXJhbSB2YWx1ZSBmb3IgdGhlIGNsb3Npbmcgb2YgYSB0ZW1wbGF0ZS5cbiAqL1xuZnVuY3Rpb24gcmVjb3JkVGVtcGxhdGVDbG9zZShcbiAgICBqb2I6IENvbXBvbmVudENvbXBpbGF0aW9uSm9iLCB2aWV3OiBWaWV3Q29tcGlsYXRpb25Vbml0LCBzbG90OiBudW1iZXIsXG4gICAgaTE4blBsYWNlaG9sZGVyOiBpMThuLlRhZ1BsYWNlaG9sZGVyfGkxOG4uQmxvY2tQbGFjZWhvbGRlciwgaTE4bkNvbnRleHQ6IGlyLkkxOG5Db250ZXh0T3AsXG4gICAgaTE4bkJsb2NrOiBpci5JMThuU3RhcnRPcCwgc3RydWN0dXJhbERpcmVjdGl2ZT86IGlyLlRlbXBsYXRlT3ApIHtcbiAgY29uc3Qge3N0YXJ0TmFtZSwgY2xvc2VOYW1lfSA9IGkxOG5QbGFjZWhvbGRlcjtcbiAgY29uc3QgZmxhZ3MgPSBpci5JMThuUGFyYW1WYWx1ZUZsYWdzLlRlbXBsYXRlVGFnIHwgaXIuSTE4blBhcmFtVmFsdWVGbGFncy5DbG9zZVRhZztcbiAgLy8gU2VsZi1jbG9zaW5nIHRhZ3MgZG9uJ3QgaGF2ZSBhIGNsb3NpbmcgdGFnIHBsYWNlaG9sZGVyLCBpbnN0ZWFkIHRoZSB0ZW1wbGF0ZSdzIGNsb3NpbmcgaXNcbiAgLy8gcmVjb3JkZWQgdmlhIGFuIGFkZGl0aW9uYWwgZmxhZyBvbiB0aGUgdGVtcGxhdGUgc3RhcnQgdmFsdWUuXG4gIGlmIChjbG9zZU5hbWUpIHtcbiAgICAvLyBSZWNvcmQgdGhlIGNsb3Npbmcgb2YgdGhlIHRlbXBsYXRlLiBGb3IgdGhlIHN1Yi10ZW1wbGF0ZSBpbmRleCwgcGFzcyB0aGUgaW5kZXggZm9yIHRoZVxuICAgIC8vIHRlbXBsYXRlJ3MgdmlldywgcmF0aGVyIHRoYW4gdGhlIGN1cnJlbnQgaTE4biBibG9jaydzIGluZGV4LlxuICAgIGFkZFBhcmFtKFxuICAgICAgICBpMThuQ29udGV4dC5wYXJhbXMsIGNsb3NlTmFtZSwgc2xvdCxcbiAgICAgICAgZ2V0U3ViVGVtcGxhdGVJbmRleEZvclRlbXBsYXRlVGFnKGpvYiwgaTE4bkJsb2NrLCB2aWV3KSwgZmxhZ3MpO1xuICAgIC8vIElmIHRoZSB0ZW1wbGF0ZSBpcyBhc3NvY2lhdGVkIHdpdGggYSBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZSwgcmVjb3JkIHRoZSBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZSdzXG4gICAgLy8gY2xvc2luZyBhZnRlci4gU2luY2UgdGhpcyB0ZW1wbGF0ZSBtdXN0IGJlIGluIHRoZSBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZSdzIHZpZXcsIHdlIGNhbiBqdXN0XG4gICAgLy8gZGlyZWN0bHkgdXNlIHRoZSBjdXJyZW50IGkxOG4gYmxvY2sncyBzdWItdGVtcGxhdGUgaW5kZXguXG4gICAgaWYgKHN0cnVjdHVyYWxEaXJlY3RpdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYWRkUGFyYW0oXG4gICAgICAgICAgaTE4bkNvbnRleHQucGFyYW1zLCBjbG9zZU5hbWUsIHN0cnVjdHVyYWxEaXJlY3RpdmUuaGFuZGxlLnNsb3QhLFxuICAgICAgICAgIGkxOG5CbG9jay5zdWJUZW1wbGF0ZUluZGV4LCBmbGFncyk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogR2V0IHRoZSBzdWJUZW1wbGF0ZUluZGV4IGZvciB0aGUgZ2l2ZW4gdGVtcGxhdGUgb3AuIEZvciB0ZW1wbGF0ZSBvcHMsIHVzZSB0aGUgc3ViVGVtcGxhdGVJbmRleCBvZlxuICogdGhlIGNoaWxkIGkxOG4gYmxvY2sgaW5zaWRlIHRoZSB0ZW1wbGF0ZS5cbiAqL1xuZnVuY3Rpb24gZ2V0U3ViVGVtcGxhdGVJbmRleEZvclRlbXBsYXRlVGFnKFxuICAgIGpvYjogQ29tcG9uZW50Q29tcGlsYXRpb25Kb2IsIGkxOG5PcDogaXIuSTE4blN0YXJ0T3AsIHZpZXc6IFZpZXdDb21waWxhdGlvblVuaXQpOiBudW1iZXJ8bnVsbCB7XG4gIGZvciAoY29uc3QgY2hpbGRPcCBvZiB2aWV3LmNyZWF0ZSkge1xuICAgIGlmIChjaGlsZE9wLmtpbmQgPT09IGlyLk9wS2luZC5JMThuU3RhcnQpIHtcbiAgICAgIHJldHVybiBjaGlsZE9wLnN1YlRlbXBsYXRlSW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiBpMThuT3Auc3ViVGVtcGxhdGVJbmRleDtcbn1cblxuLyoqXG4gKiBBZGQgYSBwYXJhbSB2YWx1ZSB0byB0aGUgZ2l2ZW4gcGFyYW1zIG1hcC5cbiAqL1xuZnVuY3Rpb24gYWRkUGFyYW0oXG4gICAgcGFyYW1zOiBNYXA8c3RyaW5nLCBpci5JMThuUGFyYW1WYWx1ZVtdPiwgcGxhY2Vob2xkZXI6IHN0cmluZyxcbiAgICB2YWx1ZTogc3RyaW5nfG51bWJlcnx7ZWxlbWVudDogbnVtYmVyLCB0ZW1wbGF0ZTogbnVtYmVyfSwgc3ViVGVtcGxhdGVJbmRleDogbnVtYmVyfG51bGwsXG4gICAgZmxhZ3M6IGlyLkkxOG5QYXJhbVZhbHVlRmxhZ3MpIHtcbiAgY29uc3QgdmFsdWVzID0gcGFyYW1zLmdldChwbGFjZWhvbGRlcikgPz8gW107XG4gIHZhbHVlcy5wdXNoKHt2YWx1ZSwgc3ViVGVtcGxhdGVJbmRleCwgZmxhZ3N9KTtcbiAgcGFyYW1zLnNldChwbGFjZWhvbGRlciwgdmFsdWVzKTtcbn1cbiJdfQ==
|
|
@@ -25,14 +25,19 @@ export function resolveI18nExpressionPlaceholders(job) {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
// Keep track of the next available expression index
|
|
28
|
+
// Keep track of the next available expression index for each i18n message.
|
|
29
29
|
const expressionIndices = new Map();
|
|
30
|
+
// Keep track of a reference index for each expression.
|
|
31
|
+
// We use different references for normal i18n expressio and attribute i18n expressions. This is
|
|
32
|
+
// because child i18n blocks in templates don't get their own context, since they're rolled into
|
|
33
|
+
// the translated message of the parent, but they may target a different slot.
|
|
34
|
+
const referenceIndex = (op) => op.usage === ir.I18nExpressionFor.I18nText ? op.i18nOwner : op.context;
|
|
30
35
|
for (const unit of job.units) {
|
|
31
36
|
for (const op of unit.update) {
|
|
32
37
|
if (op.kind === ir.OpKind.I18nExpression) {
|
|
33
38
|
const i18nContext = i18nContexts.get(op.context);
|
|
34
|
-
const index = expressionIndices.get(op
|
|
35
|
-
const subTemplateIndex = subTemplateIndicies.get(op.
|
|
39
|
+
const index = expressionIndices.get(referenceIndex(op)) || 0;
|
|
40
|
+
const subTemplateIndex = subTemplateIndicies.get(op.i18nOwner) ?? null;
|
|
36
41
|
// Add the expression index in the appropriate params map.
|
|
37
42
|
const params = op.resolutionTime === ir.I18nParamResolutionTime.Creation ?
|
|
38
43
|
i18nContext.params :
|
|
@@ -44,9 +49,9 @@ export function resolveI18nExpressionPlaceholders(job) {
|
|
|
44
49
|
flags: ir.I18nParamValueFlags.ExpressionIndex
|
|
45
50
|
});
|
|
46
51
|
params.set(op.i18nPlaceholder, values);
|
|
47
|
-
expressionIndices.set(op
|
|
52
|
+
expressionIndices.set(referenceIndex(op), index + 1);
|
|
48
53
|
}
|
|
49
54
|
}
|
|
50
55
|
}
|
|
51
56
|
}
|
|
52
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZV9pMThuX2V4cHJlc3Npb25fcGxhY2Vob2xkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3RlbXBsYXRlL3BpcGVsaW5lL3NyYy9waGFzZXMvcmVzb2x2ZV9pMThuX2V4cHJlc3Npb25fcGxhY2Vob2xkZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRy9COztHQUVHO0FBQ0gsTUFBTSxVQUFVLGlDQUFpQyxDQUFDLEdBQTRCO0lBQzVFLG1GQUFtRjtJQUNuRixNQUFNLG1CQUFtQixHQUFHLElBQUksR0FBRyxFQUEwQixDQUFDO0lBQzlELE1BQU0sWUFBWSxHQUFHLElBQUksR0FBRyxFQUErQixDQUFDO0lBQzVELEtBQUssTUFBTSxJQUFJLElBQUksR0FBRyxDQUFDLEtBQUssRUFBRTtRQUM1QixLQUFLLE1BQU0sRUFBRSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDNUIsUUFBUSxFQUFFLENBQUMsSUFBSSxFQUFFO2dCQUNmLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTO29CQUN0QixtQkFBbUIsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztvQkFDdEQsTUFBTTtnQkFDUixLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUMsV0FBVztvQkFDeEIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO29CQUM5QixNQUFNO2FBQ1Q7U0FDRjtLQUNGO0lBRUQsMkVBQTJFO0lBQzNFLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLEVBQXFCLENBQUM7SUFFdkQsdURBQXVEO0lBQ3ZELGdHQUFnRztJQUNoRyxnR0FBZ0c7SUFDaEcsOEVBQThFO0lBQzlFLE1BQU0sY0FBYyxHQUFHLENBQUMsRUFBdUIsRUFBYSxFQUFFLENBQzFELEVBQUUsQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQztJQUUzRSxLQUFLLE1BQU0sSUFBSSxJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUU7UUFDNUIsS0FBSyxNQUFNLEVBQUUsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQzVCLElBQUksRUFBRSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRTtnQkFDeEMsTUFBTSxXQUFXLEdBQUcsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFFLENBQUM7Z0JBQ2xELE1BQU0sS0FBSyxHQUFHLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzdELE1BQU0sZ0JBQWdCLEdBQUcsbUJBQW1CLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxJQUFJLENBQUM7Z0JBQ3ZFLDBEQUEwRDtnQkFDMUQsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLGNBQWMsS0FBSyxFQUFFLENBQUMsdUJBQXVCLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ3RFLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDcEIsV0FBVyxDQUFDLG9CQUFvQixDQUFDO2dCQUNyQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3BELE1BQU0sQ0FBQyxJQUFJLENBQUM7b0JBQ1YsS0FBSyxFQUFFLEtBQUs7b0JBQ1osZ0JBQWdCLEVBQUUsZ0JBQWdCO29CQUNsQyxLQUFLLEVBQUUsRUFBRSxDQUFDLG1CQUFtQixDQUFDLGVBQWU7aUJBQzlDLENBQUMsQ0FBQztnQkFDSCxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxlQUFlLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBRXZDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLEVBQUUsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO2FBQ3REO1NBQ0Y7S0FDRjtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0ICogYXMgaXIgZnJvbSAnLi4vLi4vaXInO1xuaW1wb3J0IHtDb21wb25lbnRDb21waWxhdGlvbkpvYn0gZnJvbSAnLi4vY29tcGlsYXRpb24nO1xuXG4vKipcbiAqIFJlc29sdmUgdGhlIGkxOG4gZXhwcmVzc2lvbiBwbGFjZWhvbGRlcnMgaW4gaTE4biBtZXNzYWdlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVJMThuRXhwcmVzc2lvblBsYWNlaG9sZGVycyhqb2I6IENvbXBvbmVudENvbXBpbGF0aW9uSm9iKSB7XG4gIC8vIFJlY29yZCBhbGwgb2YgdGhlIGkxOG4gY29udGV4dCBvcHMsIGFuZCB0aGUgc3ViLXRlbXBsYXRlIGluZGV4IGZvciBlYWNoIGkxOG4gb3AuXG4gIGNvbnN0IHN1YlRlbXBsYXRlSW5kaWNpZXMgPSBuZXcgTWFwPGlyLlhyZWZJZCwgbnVtYmVyfG51bGw+KCk7XG4gIGNvbnN0IGkxOG5Db250ZXh0cyA9IG5ldyBNYXA8aXIuWHJlZklkLCBpci5JMThuQ29udGV4dE9wPigpO1xuICBmb3IgKGNvbnN0IHVuaXQgb2Ygam9iLnVuaXRzKSB7XG4gICAgZm9yIChjb25zdCBvcCBvZiB1bml0LmNyZWF0ZSkge1xuICAgICAgc3dpdGNoIChvcC5raW5kKSB7XG4gICAgICAgIGNhc2UgaXIuT3BLaW5kLkkxOG5TdGFydDpcbiAgICAgICAgICBzdWJUZW1wbGF0ZUluZGljaWVzLnNldChvcC54cmVmLCBvcC5zdWJUZW1wbGF0ZUluZGV4KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBpci5PcEtpbmQuSTE4bkNvbnRleHQ6XG4gICAgICAgICAgaTE4bkNvbnRleHRzLnNldChvcC54cmVmLCBvcCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gS2VlcCB0cmFjayBvZiB0aGUgbmV4dCBhdmFpbGFibGUgZXhwcmVzc2lvbiBpbmRleCBmb3IgZWFjaCBpMThuIG1lc3NhZ2UuXG4gIGNvbnN0IGV4cHJlc3Npb25JbmRpY2VzID0gbmV3IE1hcDxpci5YcmVmSWQsIG51bWJlcj4oKTtcblxuICAvLyBLZWVwIHRyYWNrIG9mIGEgcmVmZXJlbmNlIGluZGV4IGZvciBlYWNoIGV4cHJlc3Npb24uXG4gIC8vIFdlIHVzZSBkaWZmZXJlbnQgcmVmZXJlbmNlcyBmb3Igbm9ybWFsIGkxOG4gZXhwcmVzc2lvIGFuZCBhdHRyaWJ1dGUgaTE4biBleHByZXNzaW9ucy4gVGhpcyBpc1xuICAvLyBiZWNhdXNlIGNoaWxkIGkxOG4gYmxvY2tzIGluIHRlbXBsYXRlcyBkb24ndCBnZXQgdGhlaXIgb3duIGNvbnRleHQsIHNpbmNlIHRoZXkncmUgcm9sbGVkIGludG9cbiAgLy8gdGhlIHRyYW5zbGF0ZWQgbWVzc2FnZSBvZiB0aGUgcGFyZW50LCBidXQgdGhleSBtYXkgdGFyZ2V0IGEgZGlmZmVyZW50IHNsb3QuXG4gIGNvbnN0IHJlZmVyZW5jZUluZGV4ID0gKG9wOiBpci5JMThuRXhwcmVzc2lvbk9wKTogaXIuWHJlZklkID0+XG4gICAgICBvcC51c2FnZSA9PT0gaXIuSTE4bkV4cHJlc3Npb25Gb3IuSTE4blRleHQgPyBvcC5pMThuT3duZXIgOiBvcC5jb250ZXh0O1xuXG4gIGZvciAoY29uc3QgdW5pdCBvZiBqb2IudW5pdHMpIHtcbiAgICBmb3IgKGNvbnN0IG9wIG9mIHVuaXQudXBkYXRlKSB7XG4gICAgICBpZiAob3Aua2luZCA9PT0gaXIuT3BLaW5kLkkxOG5FeHByZXNzaW9uKSB7XG4gICAgICAgIGNvbnN0IGkxOG5Db250ZXh0ID0gaTE4bkNvbnRleHRzLmdldChvcC5jb250ZXh0KSE7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gZXhwcmVzc2lvbkluZGljZXMuZ2V0KHJlZmVyZW5jZUluZGV4KG9wKSkgfHwgMDtcbiAgICAgICAgY29uc3Qgc3ViVGVtcGxhdGVJbmRleCA9IHN1YlRlbXBsYXRlSW5kaWNpZXMuZ2V0KG9wLmkxOG5Pd25lcikgPz8gbnVsbDtcbiAgICAgICAgLy8gQWRkIHRoZSBleHByZXNzaW9uIGluZGV4IGluIHRoZSBhcHByb3ByaWF0ZSBwYXJhbXMgbWFwLlxuICAgICAgICBjb25zdCBwYXJhbXMgPSBvcC5yZXNvbHV0aW9uVGltZSA9PT0gaXIuSTE4blBhcmFtUmVzb2x1dGlvblRpbWUuQ3JlYXRpb24gP1xuICAgICAgICAgICAgaTE4bkNvbnRleHQucGFyYW1zIDpcbiAgICAgICAgICAgIGkxOG5Db250ZXh0LnBvc3Rwcm9jZXNzaW5nUGFyYW1zO1xuICAgICAgICBjb25zdCB2YWx1ZXMgPSBwYXJhbXMuZ2V0KG9wLmkxOG5QbGFjZWhvbGRlcikgfHwgW107XG4gICAgICAgIHZhbHVlcy5wdXNoKHtcbiAgICAgICAgICB2YWx1ZTogaW5kZXgsXG4gICAgICAgICAgc3ViVGVtcGxhdGVJbmRleDogc3ViVGVtcGxhdGVJbmRleCxcbiAgICAgICAgICBmbGFnczogaXIuSTE4blBhcmFtVmFsdWVGbGFncy5FeHByZXNzaW9uSW5kZXhcbiAgICAgICAgfSk7XG4gICAgICAgIHBhcmFtcy5zZXQob3AuaTE4blBsYWNlaG9sZGVyLCB2YWx1ZXMpO1xuXG4gICAgICAgIGV4cHJlc3Npb25JbmRpY2VzLnNldChyZWZlcmVuY2VJbmRleChvcCksIGluZGV4ICsgMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
@@ -6,16 +6,27 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
import { SecurityContext } from '../../../../core';
|
|
9
|
+
import * as o from '../../../../output/output_ast';
|
|
10
|
+
import { Identifiers } from '../../../../render3/r3_identifiers';
|
|
9
11
|
import { isIframeSecuritySensitiveAttr } from '../../../../schema/dom_security_schema';
|
|
10
12
|
import * as ir from '../../ir';
|
|
13
|
+
import { CompilationJobKind } from '../compilation';
|
|
11
14
|
import { createOpXrefMap } from '../util/elements';
|
|
12
15
|
/**
|
|
13
|
-
*
|
|
16
|
+
* Map of security contexts to their sanitizer function.
|
|
14
17
|
*/
|
|
15
|
-
const
|
|
16
|
-
[SecurityContext.HTML,
|
|
17
|
-
[SecurityContext.
|
|
18
|
-
[SecurityContext.
|
|
18
|
+
const sanitizerFns = new Map([
|
|
19
|
+
[SecurityContext.HTML, Identifiers.sanitizeHtml],
|
|
20
|
+
[SecurityContext.RESOURCE_URL, Identifiers.sanitizeResourceUrl],
|
|
21
|
+
[SecurityContext.SCRIPT, Identifiers.sanitizeScript],
|
|
22
|
+
[SecurityContext.STYLE, Identifiers.sanitizeStyle], [SecurityContext.URL, Identifiers.sanitizeUrl]
|
|
23
|
+
]);
|
|
24
|
+
/**
|
|
25
|
+
* Map of security contexts to their trusted value function.
|
|
26
|
+
*/
|
|
27
|
+
const trustedValueFns = new Map([
|
|
28
|
+
[SecurityContext.HTML, Identifiers.trustConstantHtml],
|
|
29
|
+
[SecurityContext.RESOURCE_URL, Identifiers.trustConstantResourceUrl],
|
|
19
30
|
]);
|
|
20
31
|
/**
|
|
21
32
|
* Resolves sanitization functions for ops that need them.
|
|
@@ -23,24 +34,61 @@ const sanitizers = new Map([
|
|
|
23
34
|
export function resolveSanitizers(job) {
|
|
24
35
|
for (const unit of job.units) {
|
|
25
36
|
const elements = createOpXrefMap(unit);
|
|
26
|
-
|
|
37
|
+
// For normal element bindings we create trusted values for security sensitive constant
|
|
38
|
+
// attributes. However, for host bindings we skip this step (this matches what
|
|
39
|
+
// TemplateDefinitionBuilder does).
|
|
40
|
+
// TODO: Is the TDB behavior correct here?
|
|
41
|
+
if (job.kind !== CompilationJobKind.Host) {
|
|
42
|
+
for (const op of unit.create) {
|
|
43
|
+
if (op.kind === ir.OpKind.ExtractedAttribute) {
|
|
44
|
+
const trustedValueFn = trustedValueFns.get(getOnlySecurityContext(op.securityContext)) ?? null;
|
|
45
|
+
op.trustedValueFn = trustedValueFn !== null ? o.importExpr(trustedValueFn) : null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
27
49
|
for (const op of unit.update) {
|
|
28
50
|
switch (op.kind) {
|
|
29
51
|
case ir.OpKind.Property:
|
|
30
52
|
case ir.OpKind.Attribute:
|
|
31
|
-
|
|
32
|
-
|
|
53
|
+
case ir.OpKind.HostProperty:
|
|
54
|
+
let sanitizerFn = null;
|
|
55
|
+
if (Array.isArray(op.securityContext) && op.securityContext.length === 2 &&
|
|
56
|
+
op.securityContext.indexOf(SecurityContext.URL) > -1 &&
|
|
57
|
+
op.securityContext.indexOf(SecurityContext.RESOURCE_URL) > -1) {
|
|
58
|
+
// When the host element isn't known, some URL attributes (such as "src" and "href") may
|
|
59
|
+
// be part of multiple different security contexts. In this case we use special
|
|
60
|
+
// sanitization function and select the actual sanitizer at runtime based on a tag name
|
|
61
|
+
// that is provided while invoking sanitization function.
|
|
62
|
+
sanitizerFn = Identifiers.sanitizeUrlOrResourceUrl;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
sanitizerFn = sanitizerFns.get(getOnlySecurityContext(op.securityContext)) ?? null;
|
|
66
|
+
}
|
|
67
|
+
op.sanitizer = sanitizerFn !== null ? o.importExpr(sanitizerFn) : null;
|
|
33
68
|
// If there was no sanitization function found based on the security context of an
|
|
34
69
|
// attribute/property, check whether this attribute/property is one of the
|
|
35
70
|
// security-sensitive <iframe> attributes (and that the current element is actually an
|
|
36
71
|
// <iframe>).
|
|
37
72
|
if (op.sanitizer === null) {
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
|
|
73
|
+
let isIframe = false;
|
|
74
|
+
if (job.kind === CompilationJobKind.Host || op.kind === ir.OpKind.HostProperty) {
|
|
75
|
+
// Note: for host bindings defined on a directive, we do not try to find all
|
|
76
|
+
// possible places where it can be matched, so we can not determine whether
|
|
77
|
+
// the host element is an <iframe>. In this case, we just assume it is and append a
|
|
78
|
+
// validation function, which is invoked at runtime and would have access to the
|
|
79
|
+
// underlying DOM element to check if it's an <iframe> and if so - run extra checks.
|
|
80
|
+
isIframe = true;
|
|
41
81
|
}
|
|
42
|
-
|
|
43
|
-
|
|
82
|
+
else {
|
|
83
|
+
// For a normal binding we can just check if the element its on is an iframe.
|
|
84
|
+
const ownerOp = elements.get(op.target);
|
|
85
|
+
if (ownerOp === undefined || !ir.isElementOrContainerOp(ownerOp)) {
|
|
86
|
+
throw Error('Property should have an element-like owner');
|
|
87
|
+
}
|
|
88
|
+
isIframe = isIframeElement(ownerOp);
|
|
89
|
+
}
|
|
90
|
+
if (isIframe && isIframeSecuritySensitiveAttr(op.name)) {
|
|
91
|
+
op.sanitizer = o.importExpr(Identifiers.validateIframeAttribute);
|
|
44
92
|
}
|
|
45
93
|
}
|
|
46
94
|
break;
|
|
@@ -54,4 +102,20 @@ export function resolveSanitizers(job) {
|
|
|
54
102
|
function isIframeElement(op) {
|
|
55
103
|
return op.kind === ir.OpKind.ElementStart && op.tag?.toLowerCase() === 'iframe';
|
|
56
104
|
}
|
|
57
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Asserts that there is only a single security context and returns it.
|
|
107
|
+
*/
|
|
108
|
+
function getOnlySecurityContext(securityContext) {
|
|
109
|
+
if (Array.isArray(securityContext)) {
|
|
110
|
+
if (securityContext.length > 1) {
|
|
111
|
+
// TODO: What should we do here? TDB just took the first one, but this feels like something we
|
|
112
|
+
// would want to know about and create a special case for like we did for Url/ResourceUrl. My
|
|
113
|
+
// guess is that, outside of the Url/ResourceUrl case, this never actually happens. If there
|
|
114
|
+
// do turn out to be other cases, throwing an error until we can address it feels safer.
|
|
115
|
+
throw Error(`AssertionError: Ambiguous security context`);
|
|
116
|
+
}
|
|
117
|
+
return securityContext[0] || SecurityContext.NONE;
|
|
118
|
+
}
|
|
119
|
+
return securityContext;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZV9zYW5pdGl6ZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3RlbXBsYXRlL3BpcGVsaW5lL3NyYy9waGFzZXMvcmVzb2x2ZV9zYW5pdGl6ZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEtBQUssQ0FBQyxNQUFNLCtCQUErQixDQUFDO0FBQ25ELE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQztBQUMvRCxPQUFPLEVBQUMsNkJBQTZCLEVBQUMsTUFBTSx3Q0FBd0MsQ0FBQztBQUNyRixPQUFPLEtBQUssRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMvQixPQUFPLEVBQWlCLGtCQUFrQixFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEUsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBRWpEOztHQUVHO0FBQ0gsTUFBTSxZQUFZLEdBQUcsSUFBSSxHQUFHLENBQXVDO0lBQ2pFLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsWUFBWSxDQUFDO0lBQ2hELENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxXQUFXLENBQUMsbUJBQW1CLENBQUM7SUFDL0QsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxjQUFjLENBQUM7SUFDcEQsQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsV0FBVyxDQUFDLFdBQVcsQ0FBQztDQUNuRyxDQUFDLENBQUM7QUFFSDs7R0FFRztBQUNILE1BQU0sZUFBZSxHQUFHLElBQUksR0FBRyxDQUF1QztJQUNwRSxDQUFDLGVBQWUsQ0FBQyxJQUFJ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Y2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtTZWN1cml0eUNvbnRleHR9IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUnO1xuaW1wb3J0ICogYXMgbyBmcm9tICcuLi8uLi8uLi8uLi9vdXRwdXQvb3V0cHV0X2FzdCc7XG5pbXBvcnQge0lkZW50aWZpZXJzfSBmcm9tICcuLi8uLi8uLi8uLi9yZW5kZXIzL3IzX2lkZW50aWZpZXJzJztcbmltcG9ydCB7aXNJZnJhbWVTZWN1cml0eVNlbnNpdGl2ZUF0dHJ9IGZyb20gJy4uLy4uLy4uLy4uL3NjaGVtYS9kb21fc2VjdXJpdHlfc2NoZW1hJztcbmltcG9ydCAqIGFzIGlyIGZyb20gJy4uLy4uL2lyJztcbmltcG9ydCB7Q29tcGlsYXRpb25Kb2IsIENvbXBpbGF0aW9uSm9iS2luZH0gZnJvbSAnLi4vY29tcGlsYXRpb24nO1xuaW1wb3J0IHtjcmVhdGVPcFhyZWZNYXB9IGZyb20gJy4uL3V0aWwvZWxlbWVudHMnO1xuXG4vKipcbiAqIE1hcCBvZiBzZWN1cml0eSBjb250ZXh0cyB0byB0aGVpciBzYW5pdGl6ZXIgZnVuY3Rpb24uXG4gKi9cbmNvbnN0IHNhbml0aXplckZucyA9IG5ldyBNYXA8U2VjdXJpdHlDb250ZXh0LCBvLkV4dGVybmFsUmVmZXJlbmNlPihbXG4gIFtTZWN1cml0eUNvbnRleHQuSFRNTCwgSWRlbnRpZmllcnMuc2FuaXRpemVIdG1sXSxcbiAgW1NlY3VyaXR5Q29udGV4dC5SRVNPVVJDRV9VUkwsIElkZW50aWZpZXJzLnNhbml0aXplUmVzb3VyY2VVcmxdLFxuICBbU2VjdXJpdHlDb250ZXh0LlNDUklQVCwgSWRlbnRpZmllcnMuc2FuaXRpemVTY3JpcHRdLFxuICBbU2VjdXJpdHlDb250ZXh0LlNUWUxFLCBJZGVudGlmaWVycy5zYW5pdGl6ZVN0eWxlXSwgW1NlY3VyaXR5Q29udGV4dC5VUkwsIElkZW50aWZpZXJzLnNhbml0aXplVXJsXVxuXSk7XG5cbi8qKlxuICogTWFwIG9mIHNlY3VyaXR5IGNvbnRleHRzIHRvIHRoZWlyIHRydXN0ZWQgdmFsdWUgZnVuY3Rpb24uXG4gKi9cbmNvbnN0IHRydXN0ZWRWYWx1ZUZucyA9IG5ldyBNYXA8U2VjdXJpdHlDb250ZXh0LCBvLkV4dGVybmFsUmVmZXJlbmNlPihbXG4gIFtTZWN1cml0eUNvbnRleHQuSFRNTCwgSWRlbnRpZmllcnMudHJ1c3RDb25zdGFudEh0bWxdLFxuICBbU2VjdXJpdHlDb250ZXh0LlJFU09VUkNFX1VSTCwgSWRlbnRpZmllcnMudHJ1c3RDb25zdGFudFJlc291cmNlVXJsXSxcbl0pO1xuXG4vKipcbiAqIFJlc29sdmVzIHNhbml0aXphdGlvbiBmdW5jdGlvbnMgZm9yIG9wcyB0aGF0IG5lZWQgdGhlbS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVTYW5pdGl6ZXJzKGpvYjogQ29tcGlsYXRpb25Kb2IpOiB2b2lkIHtcbiAgZm9yIChjb25zdCB1bml0IG9mIGpvYi51bml0cykge1xuICAgIGNvbnN0IGVsZW1lbnRzID0gY3JlYXRlT3BYcmVmTWFwKHVuaXQpO1xuXG4gICAgLy8gRm9yIG5vcm1hbCBlbGVtZW50IGJpbmRpbmdzIHdlIGNyZWF0ZSB0cnVzdGVkIHZhbHVlcyBmb3Igc2VjdXJpdHkgc2Vuc2l0aXZlIGNvbnN0YW50XG4gICAgLy8gYXR0cmlidXRlcy4gSG93ZXZlciwgZm9yIGhvc3QgYmluZGluZ3Mgd2Ugc2tpcCB0aGlzIHN0ZXAgKHRoaXMgbWF0Y2hlcyB3aGF0XG4gICAgLy8gVGVtcGxhdGVEZWZpbml0aW9uQnVpbGRlciBkb2VzKS5cbiAgICAvLyBUT0RPOiBJcyB0aGUgVERCIGJlaGF2aW9yIGNvcnJlY3QgaGVyZT9cbiAgICBpZiAoam9iLmtpbmQgIT09IENvbXBpbGF0aW9uSm9iS2luZC5Ib3N0KSB7XG4gICAgICBmb3IgKGNvbnN0IG9wIG9mIHVuaXQuY3JlYXRlKSB7XG4gICAgICAgIGlmIChvcC5raW5kID09PSBpci5PcEtpbmQuRXh0cmFjdGVkQXR0cmlidXRlKSB7XG4gICAgICAgICAgY29uc3QgdHJ1c3RlZFZhbHVlRm4gPVxuICAgICAgICAgICAgICB0cnVzdGVkVmFsdWVGbnMuZ2V0KGdldE9ubHlTZWN1cml0eUNvbnRleHQob3Auc2VjdXJpdHlDb250ZXh0KSkgPz8gbnVsbDtcbiAgICAgICAgICBvcC50cnVzdGVkVmFsdWVGbiA9IHRydXN0ZWRWYWx1ZUZuICE9PSBudWxsID8gby5pbXBvcnRFeHByKHRydXN0ZWRWYWx1ZUZuKSA6IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG9wIG9mIHVuaXQudXBkYXRlKSB7XG4gICAgICBzd2l0Y2ggKG9wLmtpbmQpIHtcbiAgICAgICAgY2FzZSBpci5PcEtpbmQuUHJvcGVydHk6XG4gICAgICAgIGNhc2UgaXIuT3BLaW5kLkF0dHJpYnV0ZTpcbiAgICAgICAgY2FzZSBpci5PcEtpbmQuSG9zdFByb3BlcnR5OlxuICAgICAgICAgIGxldCBzYW5pdGl6ZXJGbjogby5FeHRlcm5hbFJlZmVyZW5jZXxudWxsID0gbnVsbDtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvcC5zZWN1cml0eUNvbnRleHQpICYmIG9wLnNlY3VyaXR5Q29udGV4dC5sZW5ndGggPT09IDIgJiZcbiAgICAgICAgICAgICAgb3Auc2VjdXJpdHlDb250ZXh0LmluZGV4T2YoU2VjdXJpdHlDb250ZXh0LlVSTCkgPiAtMSAmJlxuICAgICAgICAgICAgICBvcC5zZWN1cml0eUNvbnRleHQuaW5kZXhPZihTZWN1cml0eUNvbnRleHQuUkVTT1VSQ0VfVVJMKSA+IC0xKSB7XG4gICAgICAgICAgICAvLyBXaGVuIHRoZSBob3N0IGVsZW1lbnQgaXNuJ3Qga25vd24sIHNvbWUgVVJMIGF0dHJpYnV0ZXMgKHN1Y2ggYXMgXCJzcmNcIiBhbmQgXCJocmVmXCIpIG1heVxuICAgICAgICAgICAgLy8gYmUgcGFydCBvZiBtdWx0aXBsZSBkaWZmZXJlbnQgc2VjdXJpdHkgY29udGV4dHMuIEluIHRoaXMgY2FzZSB3ZSB1c2Ugc3BlY2lhbFxuICAgICAgICAgICAgLy8gc2FuaXRpemF0aW9uIGZ1bmN0aW9uIGFuZCBzZWxlY3QgdGhlIGFjdHVhbCBzYW5pdGl6ZXIgYXQgcnVudGltZSBiYXNlZCBvbiBhIHRhZyBuYW1lXG4gICAgICAgICAgICAvLyB0aGF0IGlzIHByb3ZpZGVkIHdoaWxlIGludm9raW5nIHNhbml0aXphdGlvbiBmdW5jdGlvbi5cbiAgICAgICAgICAgIHNhbml0aXplckZuID0gSWRlbnRpZmllcnMuc2FuaXRpemVVcmxPclJlc291cmNlVXJsO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzYW5pdGl6ZXJGbiA9IHNhbml0aXplckZucy5nZXQoZ2V0T25seVNlY3VyaXR5Q29udGV4dChvcC5zZWN1cml0eUNvbnRleHQpKSA/PyBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvcC5zYW5pdGl6ZXIgPSBzYW5pdGl6ZXJGbiAhPT0gbnVsbCA/IG8uaW1wb3J0RXhwcihzYW5pdGl6ZXJGbikgOiBudWxsO1xuXG4gICAgICAgICAgLy8gSWYgdGhlcmUgd2FzIG5vIHNhbml0aXphdGlvbiBmdW5jdGlvbiBmb3VuZCBiYXNlZCBvbiB0aGUgc2VjdXJpdHkgY29udGV4dCBvZiBhblxuICAgICAgICAgIC8vIGF0dHJpYnV0ZS9wcm9wZXJ0eSwgY2hlY2sgd2hldGhlciB0aGlzIGF0dHJpYnV0ZS9wcm9wZXJ0eSBpcyBvbmUgb2YgdGhlXG4gICAgICAgICAgLy8gc2VjdXJpdHktc2Vuc2l0aXZlIDxpZnJhbWU+IGF0dHJpYnV0ZXMgKGFuZCB0aGF0IHRoZSBjdXJyZW50IGVsZW1lbnQgaXMgYWN0dWFsbHkgYW5cbiAgICAgICAgICAvLyA8aWZyYW1lPikuXG4gICAgICAgICAgaWYgKG9wLnNhbml0aXplciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IGlzSWZyYW1lID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoam9iLmtpbmQgPT09IENvbXBpbGF0aW9uSm9iS2luZC5Ib3N0IHx8IG9wLmtpbmQgPT09IGlyLk9wS2luZC5Ib3N0UHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgLy8gTm90ZTogZm9yIGhvc3QgYmluZGluZ3MgZGVmaW5lZCBvbiBhIGRpcmVjdGl2ZSwgd2UgZG8gbm90IHRyeSB0byBmaW5kIGFsbFxuICAgICAgICAgICAgICAvLyBwb3NzaWJsZSBwbGFjZXMgd2hlcmUgaXQgY2FuIGJlIG1hdGNoZWQsIHNvIHdlIGNhbiBub3QgZGV0ZXJtaW5lIHdoZXRoZXJcbiAgICAgICAgICAgICAgLy8gdGhlIGhvc3QgZWxlbWVudCBpcyBhbiA8aWZyYW1lPi4gSW4gdGhpcyBjYXNlLCB3ZSBqdXN0IGFzc3VtZSBpdCBpcyBhbmQgYXBwZW5kIGFcbiAgICAgICAgICAgICAgLy8gdmFsaWRhdGlvbiBmdW5jdGlvbiwgd2hpY2ggaXMgaW52b2tlZCBhdCBydW50aW1lIGFuZCB3b3VsZCBoYXZlIGFjY2VzcyB0byB0aGVcbiAgICAgICAgICAgICAgLy8gdW5kZXJseWluZyBET00gZWxlbWVudCB0byBjaGVjayBpZiBpdCdzIGFuIDxpZnJhbWU+IGFuZCBpZiBzbyAtIHJ1biBleHRyYSBjaGVja3MuXG4gICAgICAgICAgICAgIGlzSWZyYW1lID0gdHJ1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIEZvciBhIG5vcm1hbCBiaW5kaW5nIHdlIGNhbiBqdXN0IGNoZWNrIGlmIHRoZSBlbGVtZW50IGl0cyBvbiBpcyBhbiBpZnJhbWUuXG4gICAgICAgICAgICAgIGNvbnN0IG93bmVyT3AgPSBlbGVtZW50cy5nZXQob3AudGFyZ2V0KTtcbiAgICAgICAgICAgICAgaWYgKG93bmVyT3AgPT09IHVuZGVmaW5lZCB8fCAhaXIuaXNFbGVtZW50T3JDb250YWluZXJPcChvd25lck9wKSkge1xuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKCdQcm9wZXJ0eSBzaG91bGQgaGF2ZSBhbiBlbGVtZW50LWxpa2Ugb3duZXInKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpc0lmcmFtZSA9IGlzSWZyYW1lRWxlbWVudChvd25lck9wKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc0lmcmFtZSAmJiBpc0lmcmFtZVNlY3VyaXR5U2Vuc2l0aXZlQXR0cihvcC5uYW1lKSkge1xuICAgICAgICAgICAgICBvcC5zYW5pdGl6ZXIgPSBvLmltcG9ydEV4cHIoSWRlbnRpZmllcnMudmFsaWRhdGVJZnJhbWVBdHRyaWJ1dGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gb3AgcmVwcmVzZW50cyBhbiBpZnJhbWUgZWxlbWVudC5cbiAqL1xuZnVuY3Rpb24gaXNJZnJhbWVFbGVtZW50KG9wOiBpci5FbGVtZW50T3JDb250YWluZXJPcHMpOiBib29sZWFuIHtcbiAgcmV0dXJuIG9wLmtpbmQgPT09IGlyLk9wS2luZC5FbGVtZW50U3RhcnQgJiYgb3AudGFnPy50b0xvd2VyQ2FzZSgpID09PSAnaWZyYW1lJztcbn1cblxuLyoqXG4gKiBBc3NlcnRzIHRoYXQgdGhlcmUgaXMgb25seSBhIHNpbmdsZSBzZWN1cml0eSBjb250ZXh0IGFuZCByZXR1cm5zIGl0LlxuICovXG5mdW5jdGlvbiBnZXRPbmx5U2VjdXJpdHlDb250ZXh0KHNlY3VyaXR5Q29udGV4dDogU2VjdXJpdHlDb250ZXh0fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWN1cml0eUNvbnRleHRbXSk6IFNlY3VyaXR5Q29udGV4dCB7XG4gIGlmIChBcnJheS5pc0FycmF5KHNlY3VyaXR5Q29udGV4dCkpIHtcbiAgICBpZiAoc2VjdXJpdHlDb250ZXh0Lmxlbmd0aCA+IDEpIHtcbiAgICAgIC8vIFRPRE86IFdoYXQgc2hvdWxkIHdlIGRvIGhlcmU/IFREQiBqdXN0IHRvb2sgdGhlIGZpcnN0IG9uZSwgYnV0IHRoaXMgZmVlbHMgbGlrZSBzb21ldGhpbmcgd2VcbiAgICAgIC8vIHdvdWxkIHdhbnQgdG8ga25vdyBhYm91dCBhbmQgY3JlYXRlIGEgc3BlY2lhbCBjYXNlIGZvciBsaWtlIHdlIGRpZCBmb3IgVXJsL1Jlc291cmNlVXJsLiBNeVxuICAgICAgLy8gZ3Vlc3MgaXMgdGhhdCwgb3V0c2lkZSBvZiB0aGUgVXJsL1Jlc291cmNlVXJsIGNhc2UsIHRoaXMgbmV2ZXIgYWN0dWFsbHkgaGFwcGVucy4gSWYgdGhlcmVcbiAgICAgIC8vIGRvIHR1cm4gb3V0IHRvIGJlIG90aGVyIGNhc2VzLCB0aHJvd2luZyBhbiBlcnJvciB1bnRpbCB3ZSBjYW4gYWRkcmVzcyBpdCBmZWVscyBzYWZlci5cbiAgICAgIHRocm93IEVycm9yKGBBc3NlcnRpb25FcnJvcjogQW1iaWd1b3VzIHNlY3VyaXR5IGNvbnRleHRgKTtcbiAgICB9XG4gICAgcmV0dXJuIHNlY3VyaXR5Q29udGV4dFswXSB8fCBTZWN1cml0eUNvbnRleHQuTk9ORTtcbiAgfVxuICByZXR1cm4gc2VjdXJpdHlDb250ZXh0O1xufVxuIl19
|