@angular/core 10.0.6 → 10.0.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.
Files changed (58) hide show
  1. package/bundles/core-testing.umd.js +1 -1
  2. package/bundles/core-testing.umd.min.js +1 -1
  3. package/bundles/core-testing.umd.min.js.map +1 -1
  4. package/bundles/core.umd.js +1678 -1387
  5. package/bundles/core.umd.js.map +1 -1
  6. package/bundles/core.umd.min.js +152 -124
  7. package/bundles/core.umd.min.js.map +1 -1
  8. package/core.d.ts +258 -58
  9. package/core.metadata.json +1 -1
  10. package/esm2015/core.js +3 -3
  11. package/esm2015/src/application_module.js +2 -2
  12. package/esm2015/src/application_ref.js +2 -2
  13. package/esm2015/src/core_render3_private_export.js +2 -1
  14. package/esm2015/src/metadata/di.js +1 -1
  15. package/esm2015/src/r3_symbols.js +2 -1
  16. package/esm2015/src/reflection/reflection_capabilities.js +38 -8
  17. package/esm2015/src/render3/bindings.js +3 -3
  18. package/esm2015/src/render3/component.js +3 -3
  19. package/esm2015/src/render3/di.js +1 -1
  20. package/esm2015/src/render3/i18n/i18n_apply.js +445 -0
  21. package/esm2015/src/render3/i18n/i18n_debug.js +170 -0
  22. package/esm2015/src/render3/i18n/i18n_locale_id.js +37 -0
  23. package/esm2015/src/render3/i18n/i18n_parse.js +635 -0
  24. package/esm2015/src/render3/i18n/i18n_postprocess.js +121 -0
  25. package/esm2015/src/render3/index.js +3 -2
  26. package/esm2015/src/render3/instructions/advance.js +3 -3
  27. package/esm2015/src/render3/instructions/element.js +3 -3
  28. package/esm2015/src/render3/instructions/element_container.js +3 -3
  29. package/esm2015/src/render3/instructions/i18n.js +164 -0
  30. package/esm2015/src/render3/instructions/listener.js +3 -3
  31. package/esm2015/src/render3/instructions/lview_debug.js +54 -213
  32. package/esm2015/src/render3/instructions/shared.js +54 -38
  33. package/esm2015/src/render3/instructions/text.js +3 -3
  34. package/esm2015/src/render3/interfaces/i18n.js +12 -3
  35. package/esm2015/src/render3/interfaces/node.js +13 -1
  36. package/esm2015/src/render3/interfaces/view.js +1 -1
  37. package/esm2015/src/render3/jit/directive.js +33 -10
  38. package/esm2015/src/render3/ng_module_ref.js +2 -2
  39. package/esm2015/src/render3/node_manipulation.js +1 -11
  40. package/esm2015/src/render3/pure_function.js +3 -3
  41. package/esm2015/src/render3/query.js +14 -12
  42. package/esm2015/src/render3/styling/style_binding_list.js +3 -3
  43. package/esm2015/src/render3/styling/styling_parser.js +3 -2
  44. package/esm2015/src/render3/util/debug_utils.js +31 -2
  45. package/esm2015/src/render3/util/discovery_utils.js +1 -1
  46. package/esm2015/src/render3/util/view_utils.js +5 -5
  47. package/esm2015/src/render3/view_engine_compatibility.js +13 -4
  48. package/esm2015/src/util/assert.js +2 -2
  49. package/esm2015/src/util/char_code.js +1 -1
  50. package/esm2015/src/version.js +1 -1
  51. package/fesm2015/core.js +1652 -1364
  52. package/fesm2015/core.js.map +1 -1
  53. package/fesm2015/testing.js +1 -1
  54. package/package.json +1 -1
  55. package/src/r3_symbols.d.ts +13 -1
  56. package/testing/testing.d.ts +1 -1
  57. package/testing.d.ts +1 -1
  58. package/esm2015/src/render3/i18n.js +0 -1225
@@ -0,0 +1,445 @@
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 { getPluralCase } from '../../i18n/localization';
9
+ import { assertDefined, assertEqual, assertIndexInRange } from '../../util/assert';
10
+ import { attachPatchData } from '../context_discovery';
11
+ import { elementAttributeInternal, elementPropertyInternal, getOrCreateTNode, textBindingInternal } from '../instructions/shared';
12
+ import { NATIVE } from '../interfaces/container';
13
+ import { COMMENT_MARKER, ELEMENT_MARKER } from '../interfaces/i18n';
14
+ import { isLContainer } from '../interfaces/type_checks';
15
+ import { HEADER_OFFSET, RENDERER, T_HOST } from '../interfaces/view';
16
+ import { appendChild, applyProjection, createTextNode, nativeRemoveNode } from '../node_manipulation';
17
+ import { getBindingIndex, getPreviousOrParentTNode, setIsNotParent, setPreviousOrParentTNode } from '../state';
18
+ import { renderStringify } from '../util/misc_utils';
19
+ import { getNativeByIndex, getNativeByTNode, getTNode, load } from '../util/view_utils';
20
+ import { getLocaleId } from './i18n_locale_id';
21
+ const i18nIndexStack = [];
22
+ let i18nIndexStackPointer = -1;
23
+ function popI18nIndex() {
24
+ return i18nIndexStack[i18nIndexStackPointer--];
25
+ }
26
+ export function pushI18nIndex(index) {
27
+ i18nIndexStack[++i18nIndexStackPointer] = index;
28
+ }
29
+ let changeMask = 0b0;
30
+ let shiftsCounter = 0;
31
+ export function setMaskBit(bit) {
32
+ if (bit) {
33
+ changeMask = changeMask | (1 << shiftsCounter);
34
+ }
35
+ shiftsCounter++;
36
+ }
37
+ export function applyI18n(tView, lView, index) {
38
+ if (shiftsCounter > 0) {
39
+ ngDevMode && assertDefined(tView, `tView should be defined`);
40
+ const tI18n = tView.data[index + HEADER_OFFSET];
41
+ let updateOpCodes;
42
+ let tIcus = null;
43
+ if (Array.isArray(tI18n)) {
44
+ updateOpCodes = tI18n;
45
+ }
46
+ else {
47
+ updateOpCodes = tI18n.update;
48
+ tIcus = tI18n.icus;
49
+ }
50
+ const bindingsStartIndex = getBindingIndex() - shiftsCounter - 1;
51
+ applyUpdateOpCodes(tView, tIcus, lView, updateOpCodes, bindingsStartIndex, changeMask);
52
+ // Reset changeMask & maskBit to default for the next update cycle
53
+ changeMask = 0b0;
54
+ shiftsCounter = 0;
55
+ }
56
+ }
57
+ /**
58
+ * Apply `I18nMutateOpCodes` OpCodes.
59
+ *
60
+ * @param tView Current `TView`
61
+ * @param rootIndex Pointer to the root (parent) tNode for the i18n.
62
+ * @param createOpCodes OpCodes to process
63
+ * @param lView Current `LView`
64
+ */
65
+ export function applyCreateOpCodes(tView, rootindex, createOpCodes, lView) {
66
+ const renderer = lView[RENDERER];
67
+ let currentTNode = null;
68
+ let previousTNode = null;
69
+ const visitedNodes = [];
70
+ for (let i = 0; i < createOpCodes.length; i++) {
71
+ const opCode = createOpCodes[i];
72
+ if (typeof opCode == 'string') {
73
+ const textRNode = createTextNode(opCode, renderer);
74
+ const textNodeIndex = createOpCodes[++i];
75
+ ngDevMode && ngDevMode.rendererCreateTextNode++;
76
+ previousTNode = currentTNode;
77
+ currentTNode =
78
+ createDynamicNodeAtIndex(tView, lView, textNodeIndex, 3 /* Element */, textRNode, null);
79
+ visitedNodes.push(textNodeIndex);
80
+ setIsNotParent();
81
+ }
82
+ else if (typeof opCode == 'number') {
83
+ switch (opCode & 7 /* MASK_INSTRUCTION */) {
84
+ case 1 /* AppendChild */:
85
+ const destinationNodeIndex = opCode >>> 17 /* SHIFT_PARENT */;
86
+ let destinationTNode;
87
+ if (destinationNodeIndex === rootindex) {
88
+ // If the destination node is `i18nStart`, we don't have a
89
+ // top-level node and we should use the host node instead
90
+ destinationTNode = lView[T_HOST];
91
+ }
92
+ else {
93
+ destinationTNode = getTNode(tView, destinationNodeIndex);
94
+ }
95
+ ngDevMode &&
96
+ assertDefined(currentTNode, `You need to create or select a node before you can insert it into the DOM`);
97
+ previousTNode =
98
+ appendI18nNode(tView, currentTNode, destinationTNode, previousTNode, lView);
99
+ break;
100
+ case 0 /* Select */:
101
+ // Negative indices indicate that a given TNode is a sibling node, not a parent node
102
+ // (see `i18nStartFirstPass` for additional information).
103
+ const isParent = opCode >= 0;
104
+ // FIXME(misko): This SHIFT_REF looks suspect as it does not have mask.
105
+ const nodeIndex = (isParent ? opCode : ~opCode) >>> 3 /* SHIFT_REF */;
106
+ visitedNodes.push(nodeIndex);
107
+ previousTNode = currentTNode;
108
+ currentTNode = getTNode(tView, nodeIndex);
109
+ if (currentTNode) {
110
+ setPreviousOrParentTNode(currentTNode, isParent);
111
+ }
112
+ break;
113
+ case 5 /* ElementEnd */:
114
+ const elementIndex = opCode >>> 3 /* SHIFT_REF */;
115
+ previousTNode = currentTNode = getTNode(tView, elementIndex);
116
+ setPreviousOrParentTNode(currentTNode, false);
117
+ break;
118
+ case 4 /* Attr */:
119
+ const elementNodeIndex = opCode >>> 3 /* SHIFT_REF */;
120
+ const attrName = createOpCodes[++i];
121
+ const attrValue = createOpCodes[++i];
122
+ // This code is used for ICU expressions only, since we don't support
123
+ // directives/components in ICUs, we don't need to worry about inputs here
124
+ elementAttributeInternal(getTNode(tView, elementNodeIndex), lView, attrName, attrValue, null, null);
125
+ break;
126
+ default:
127
+ throw new Error(`Unable to determine the type of mutate operation for "${opCode}"`);
128
+ }
129
+ }
130
+ else {
131
+ switch (opCode) {
132
+ case COMMENT_MARKER:
133
+ const commentValue = createOpCodes[++i];
134
+ const commentNodeIndex = createOpCodes[++i];
135
+ ngDevMode &&
136
+ assertEqual(typeof commentValue, 'string', `Expected "${commentValue}" to be a comment node value`);
137
+ const commentRNode = renderer.createComment(commentValue);
138
+ ngDevMode && ngDevMode.rendererCreateComment++;
139
+ previousTNode = currentTNode;
140
+ currentTNode = createDynamicNodeAtIndex(tView, lView, commentNodeIndex, 5 /* IcuContainer */, commentRNode, null);
141
+ visitedNodes.push(commentNodeIndex);
142
+ attachPatchData(commentRNode, lView);
143
+ // We will add the case nodes later, during the update phase
144
+ setIsNotParent();
145
+ break;
146
+ case ELEMENT_MARKER:
147
+ const tagNameValue = createOpCodes[++i];
148
+ const elementNodeIndex = createOpCodes[++i];
149
+ ngDevMode &&
150
+ assertEqual(typeof tagNameValue, 'string', `Expected "${tagNameValue}" to be an element node tag name`);
151
+ const elementRNode = renderer.createElement(tagNameValue);
152
+ ngDevMode && ngDevMode.rendererCreateElement++;
153
+ previousTNode = currentTNode;
154
+ currentTNode = createDynamicNodeAtIndex(tView, lView, elementNodeIndex, 3 /* Element */, elementRNode, tagNameValue);
155
+ visitedNodes.push(elementNodeIndex);
156
+ break;
157
+ default:
158
+ throw new Error(`Unable to determine the type of mutate operation for "${opCode}"`);
159
+ }
160
+ }
161
+ }
162
+ setIsNotParent();
163
+ return visitedNodes;
164
+ }
165
+ /**
166
+ * Apply `I18nUpdateOpCodes` OpCodes
167
+ *
168
+ * @param tView Current `TView`
169
+ * @param tIcus If ICUs present than this contains them.
170
+ * @param lView Current `LView`
171
+ * @param updateOpCodes OpCodes to process
172
+ * @param bindingsStartIndex Location of the first `ɵɵi18nApply`
173
+ * @param changeMask Each bit corresponds to a `ɵɵi18nExp` (Counting backwards from
174
+ * `bindingsStartIndex`)
175
+ */
176
+ export function applyUpdateOpCodes(tView, tIcus, lView, updateOpCodes, bindingsStartIndex, changeMask) {
177
+ let caseCreated = false;
178
+ for (let i = 0; i < updateOpCodes.length; i++) {
179
+ // bit code to check if we should apply the next update
180
+ const checkBit = updateOpCodes[i];
181
+ // Number of opCodes to skip until next set of update codes
182
+ const skipCodes = updateOpCodes[++i];
183
+ if (checkBit & changeMask) {
184
+ // The value has been updated since last checked
185
+ let value = '';
186
+ for (let j = i + 1; j <= (i + skipCodes); j++) {
187
+ const opCode = updateOpCodes[j];
188
+ if (typeof opCode == 'string') {
189
+ value += opCode;
190
+ }
191
+ else if (typeof opCode == 'number') {
192
+ if (opCode < 0) {
193
+ // Negative opCode represent `i18nExp` values offset.
194
+ value += renderStringify(lView[bindingsStartIndex - opCode]);
195
+ }
196
+ else {
197
+ const nodeIndex = opCode >>> 2 /* SHIFT_REF */;
198
+ switch (opCode & 3 /* MASK_OPCODE */) {
199
+ case 1 /* Attr */:
200
+ const propName = updateOpCodes[++j];
201
+ const sanitizeFn = updateOpCodes[++j];
202
+ elementPropertyInternal(tView, getTNode(tView, nodeIndex), lView, propName, value, lView[RENDERER], sanitizeFn, false);
203
+ break;
204
+ case 0 /* Text */:
205
+ textBindingInternal(lView, nodeIndex, value);
206
+ break;
207
+ case 2 /* IcuSwitch */:
208
+ caseCreated =
209
+ applyIcuSwitchCase(tView, tIcus, updateOpCodes[++j], lView, value);
210
+ break;
211
+ case 3 /* IcuUpdate */:
212
+ applyIcuUpdateCase(tView, tIcus, updateOpCodes[++j], bindingsStartIndex, lView, caseCreated);
213
+ break;
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
219
+ i += skipCodes;
220
+ }
221
+ }
222
+ /**
223
+ * Apply OpCodes associated with updating an existing ICU.
224
+ *
225
+ * @param tView Current `TView`
226
+ * @param tIcus ICUs active at this location.
227
+ * @param tIcuIndex Index into `tIcus` to process.
228
+ * @param bindingsStartIndex Location of the first `ɵɵi18nApply`
229
+ * @param lView Current `LView`
230
+ * @param changeMask Each bit corresponds to a `ɵɵi18nExp` (Counting backwards from
231
+ * `bindingsStartIndex`)
232
+ */
233
+ function applyIcuUpdateCase(tView, tIcus, tIcuIndex, bindingsStartIndex, lView, caseCreated) {
234
+ ngDevMode && assertIndexInRange(tIcus, tIcuIndex);
235
+ const tIcu = tIcus[tIcuIndex];
236
+ ngDevMode && assertIndexInRange(lView, tIcu.currentCaseLViewIndex);
237
+ const activeCaseIndex = lView[tIcu.currentCaseLViewIndex];
238
+ if (activeCaseIndex !== null) {
239
+ const mask = caseCreated ?
240
+ -1 : // -1 is same as all bits on, which simulates creation since it marks all bits dirty
241
+ changeMask;
242
+ applyUpdateOpCodes(tView, tIcus, lView, tIcu.update[activeCaseIndex], bindingsStartIndex, mask);
243
+ }
244
+ }
245
+ /**
246
+ * Apply OpCodes associated with switching a case on ICU.
247
+ *
248
+ * This involves tearing down existing case and than building up a new case.
249
+ *
250
+ * @param tView Current `TView`
251
+ * @param tIcus ICUs active at this location.
252
+ * @param tICuIndex Index into `tIcus` to process.
253
+ * @param lView Current `LView`
254
+ * @param value Value of the case to update to.
255
+ * @returns true if a new case was created (needed so that the update executes regardless of the
256
+ * bitmask)
257
+ */
258
+ function applyIcuSwitchCase(tView, tIcus, tICuIndex, lView, value) {
259
+ applyIcuSwitchCaseRemove(tView, tIcus, tICuIndex, lView);
260
+ // Rebuild a new case for this ICU
261
+ let caseCreated = false;
262
+ const tIcu = tIcus[tICuIndex];
263
+ const caseIndex = getCaseIndex(tIcu, value);
264
+ lView[tIcu.currentCaseLViewIndex] = caseIndex !== -1 ? caseIndex : null;
265
+ if (caseIndex > -1) {
266
+ // Add the nodes for the new case
267
+ applyCreateOpCodes(tView, -1, // -1 means we don't have parent node
268
+ tIcu.create[caseIndex], lView);
269
+ caseCreated = true;
270
+ }
271
+ return caseCreated;
272
+ }
273
+ /**
274
+ * Apply OpCodes associated with tearing down of DOM.
275
+ *
276
+ * This involves tearing down existing case and than building up a new case.
277
+ *
278
+ * @param tView Current `TView`
279
+ * @param tIcus ICUs active at this location.
280
+ * @param tIcuIndex Index into `tIcus` to process.
281
+ * @param lView Current `LView`
282
+ * @returns true if a new case was created (needed so that the update executes regardless of the
283
+ * bitmask)
284
+ */
285
+ function applyIcuSwitchCaseRemove(tView, tIcus, tIcuIndex, lView) {
286
+ ngDevMode && assertIndexInRange(tIcus, tIcuIndex);
287
+ const tIcu = tIcus[tIcuIndex];
288
+ const activeCaseIndex = lView[tIcu.currentCaseLViewIndex];
289
+ if (activeCaseIndex !== null) {
290
+ const removeCodes = tIcu.remove[activeCaseIndex];
291
+ for (let k = 0; k < removeCodes.length; k++) {
292
+ const removeOpCode = removeCodes[k];
293
+ const nodeOrIcuIndex = removeOpCode >>> 3 /* SHIFT_REF */;
294
+ switch (removeOpCode & 7 /* MASK_INSTRUCTION */) {
295
+ case 3 /* Remove */:
296
+ // FIXME(misko): this comment is wrong!
297
+ // Remove DOM element, but do *not* mark TNode as detached, since we are
298
+ // just switching ICU cases (while keeping the same TNode), so a DOM element
299
+ // representing a new ICU case will be re-created.
300
+ removeNode(tView, lView, nodeOrIcuIndex, /* markAsDetached */ false);
301
+ break;
302
+ case 6 /* RemoveNestedIcu */:
303
+ applyIcuSwitchCaseRemove(tView, tIcus, nodeOrIcuIndex, lView);
304
+ break;
305
+ }
306
+ }
307
+ }
308
+ }
309
+ function appendI18nNode(tView, tNode, parentTNode, previousTNode, lView) {
310
+ ngDevMode && ngDevMode.rendererMoveNode++;
311
+ const nextNode = tNode.next;
312
+ if (!previousTNode) {
313
+ previousTNode = parentTNode;
314
+ }
315
+ // Re-organize node tree to put this node in the correct position.
316
+ if (previousTNode === parentTNode && tNode !== parentTNode.child) {
317
+ tNode.next = parentTNode.child;
318
+ parentTNode.child = tNode;
319
+ }
320
+ else if (previousTNode !== parentTNode && tNode !== previousTNode.next) {
321
+ tNode.next = previousTNode.next;
322
+ previousTNode.next = tNode;
323
+ }
324
+ else {
325
+ tNode.next = null;
326
+ }
327
+ if (parentTNode !== lView[T_HOST]) {
328
+ tNode.parent = parentTNode;
329
+ }
330
+ // If tNode was moved around, we might need to fix a broken link.
331
+ let cursor = tNode.next;
332
+ while (cursor) {
333
+ if (cursor.next === tNode) {
334
+ cursor.next = nextNode;
335
+ }
336
+ cursor = cursor.next;
337
+ }
338
+ // If the placeholder to append is a projection, we need to move the projected nodes instead
339
+ if (tNode.type === 1 /* Projection */) {
340
+ applyProjection(tView, lView, tNode);
341
+ return tNode;
342
+ }
343
+ appendChild(tView, lView, getNativeByTNode(tNode, lView), tNode);
344
+ const slotValue = lView[tNode.index];
345
+ if (tNode.type !== 0 /* Container */ && isLContainer(slotValue)) {
346
+ // Nodes that inject ViewContainerRef also have a comment node that should be moved
347
+ appendChild(tView, lView, slotValue[NATIVE], tNode);
348
+ }
349
+ return tNode;
350
+ }
351
+ /**
352
+ * See `i18nEnd` above.
353
+ */
354
+ export function i18nEndFirstPass(tView, lView) {
355
+ ngDevMode &&
356
+ assertEqual(getBindingIndex(), tView.bindingStartIndex, 'i18nEnd should be called before any binding');
357
+ const rootIndex = popI18nIndex();
358
+ const tI18n = tView.data[rootIndex + HEADER_OFFSET];
359
+ ngDevMode && assertDefined(tI18n, `You should call i18nStart before i18nEnd`);
360
+ // Find the last node that was added before `i18nEnd`
361
+ const lastCreatedNode = getPreviousOrParentTNode();
362
+ // Read the instructions to insert/move/remove DOM elements
363
+ const visitedNodes = applyCreateOpCodes(tView, rootIndex, tI18n.create, lView);
364
+ // Remove deleted nodes
365
+ let index = rootIndex + 1;
366
+ while (index <= lastCreatedNode.index - HEADER_OFFSET) {
367
+ if (visitedNodes.indexOf(index) === -1) {
368
+ removeNode(tView, lView, index, /* markAsDetached */ true);
369
+ }
370
+ // Check if an element has any local refs and skip them
371
+ const tNode = getTNode(tView, index);
372
+ if (tNode &&
373
+ (tNode.type === 0 /* Container */ || tNode.type === 3 /* Element */ ||
374
+ tNode.type === 4 /* ElementContainer */) &&
375
+ tNode.localNames !== null) {
376
+ // Divide by 2 to get the number of local refs,
377
+ // since they are stored as an array that also includes directive indexes,
378
+ // i.e. ["localRef", directiveIndex, ...]
379
+ index += tNode.localNames.length >> 1;
380
+ }
381
+ index++;
382
+ }
383
+ }
384
+ function removeNode(tView, lView, index, markAsDetached) {
385
+ const removedPhTNode = getTNode(tView, index);
386
+ const removedPhRNode = getNativeByIndex(index, lView);
387
+ if (removedPhRNode) {
388
+ nativeRemoveNode(lView[RENDERER], removedPhRNode);
389
+ }
390
+ const slotValue = load(lView, index);
391
+ if (isLContainer(slotValue)) {
392
+ const lContainer = slotValue;
393
+ if (removedPhTNode.type !== 0 /* Container */) {
394
+ nativeRemoveNode(lView[RENDERER], lContainer[NATIVE]);
395
+ }
396
+ }
397
+ if (markAsDetached) {
398
+ // Define this node as detached to avoid projecting it later
399
+ removedPhTNode.flags |= 64 /* isDetached */;
400
+ }
401
+ ngDevMode && ngDevMode.rendererRemoveNode++;
402
+ }
403
+ /**
404
+ * Creates and stores the dynamic TNode, and unhooks it from the tree for now.
405
+ */
406
+ function createDynamicNodeAtIndex(tView, lView, index, type, native, name) {
407
+ const previousOrParentTNode = getPreviousOrParentTNode();
408
+ ngDevMode && assertIndexInRange(lView, index + HEADER_OFFSET);
409
+ lView[index + HEADER_OFFSET] = native;
410
+ // FIXME(misko): Why does this create A TNode??? I would not expect this to be here.
411
+ const tNode = getOrCreateTNode(tView, lView[T_HOST], index, type, name, null);
412
+ // We are creating a dynamic node, the previous tNode might not be pointing at this node.
413
+ // We will link ourselves into the tree later with `appendI18nNode`.
414
+ if (previousOrParentTNode && previousOrParentTNode.next === tNode) {
415
+ previousOrParentTNode.next = null;
416
+ }
417
+ return tNode;
418
+ }
419
+ /**
420
+ * Returns the index of the current case of an ICU expression depending on the main binding value
421
+ *
422
+ * @param icuExpression
423
+ * @param bindingValue The value of the main binding used by this ICU expression
424
+ */
425
+ function getCaseIndex(icuExpression, bindingValue) {
426
+ let index = icuExpression.cases.indexOf(bindingValue);
427
+ if (index === -1) {
428
+ switch (icuExpression.type) {
429
+ case 1 /* plural */: {
430
+ const resolvedCase = getPluralCase(bindingValue, getLocaleId());
431
+ index = icuExpression.cases.indexOf(resolvedCase);
432
+ if (index === -1 && resolvedCase !== 'other') {
433
+ index = icuExpression.cases.indexOf('other');
434
+ }
435
+ break;
436
+ }
437
+ case 0 /* select */: {
438
+ index = icuExpression.cases.indexOf('other');
439
+ break;
440
+ }
441
+ }
442
+ }
443
+ return index;
444
+ }
445
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaTE4bl9hcHBseS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3JlbmRlcjMvaTE4bi9pMThuX2FwcGx5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUN0RCxPQUFPLEVBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSxrQkFBa0IsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2pGLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUNyRCxPQUFPLEVBQUMsd0JBQXdCLEVBQUUsdUJBQXVCLEVBQUUsZ0JBQWdCLEVBQUUsbUJBQW1CLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUNoSSxPQUFPLEVBQWEsTUFBTSxFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFDM0QsT0FBTyxFQUFDLGNBQWMsRUFBRSxjQUFjLEVBQWlHLE1BQU0sb0JBQW9CLENBQUM7QUFJbEssT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBQ3ZELE9BQU8sRUFBQyxhQUFhLEVBQVMsUUFBUSxFQUFFLE1BQU0sRUFBUSxNQUFNLG9CQUFvQixDQUFDO0FBQ2pGLE9BQU8sRUFBQyxXQUFXLEVBQUUsZUFBZSxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLHNCQUFzQixDQUFDO0FBQ3BHLE9BQU8sRUFBQyxlQUFlLEVBQVksd0JBQXdCLEVBQVksY0FBYyxFQUFFLHdCQUF3QixFQUFDLE1BQU0sVUFBVSxDQUFDO0FBQ2pJLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUNuRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQ3RGLE9BQU8sRUFBQyxXQUFXLEVB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S0FBSyxLQUFLLENBQUMsQ0FBQyxJQUFJLFlBQVksS0FBSyxPQUFPLEVBQUU7b0JBQzVDLEtBQUssR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztpQkFDOUM7Z0JBQ0QsTUFBTTthQUNQO1lBQ0QsbUJBQW1CLENBQUMsQ0FBQztnQkFDbkIsS0FBSyxHQUFHLGFBQWEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUM3QyxNQUFNO2FBQ1A7U0FDRjtLQUNGO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7Z2V0UGx1cmFsQ2FzZX0gZnJvbSAnLi4vLi4vaTE4bi9sb2NhbGl6YXRpb24nO1xuaW1wb3J0IHthc3NlcnREZWZpbmVkLCBhc3NlcnRFcXVhbCwgYXNzZXJ0SW5kZXhJblJhbmdlfSBmcm9tICcuLi8uLi91dGlsL2Fzc2VydCc7XG5pbXBvcnQge2F0dGFjaFBhdGNoRGF0YX0gZnJvbSAnLi4vY29udGV4dF9kaXNjb3ZlcnknO1xuaW1wb3J0IHtlbGVtZW50QXR0cmlidXRlSW50ZXJuYWwsIGVsZW1lbnRQcm9wZXJ0eUludGVybmFsLCBnZXRPckNyZWF0ZVROb2RlLCB0ZXh0QmluZGluZ0ludGVybmFsfSBmcm9tICcuLi9pbnN0cnVjdGlvbnMvc2hhcmVkJztcbmltcG9ydCB7TENvbnRhaW5lciwgTkFUSVZFfSBmcm9tICcuLi9pbnRlcmZhY2VzL2NvbnRhaW5lcic7XG5pbXBvcnQge0NPTU1FTlRfTUFSS0VSLCBFTEVNRU5UX01BUktFUiwgSTE4bk11dGF0ZU9wQ29kZSwgSTE4bk11dGF0ZU9wQ29kZXMsIEkxOG5VcGRhdGVPcENvZGUsIEkxOG5VcGRhdGVPcENvZGVzLCBJY3VUeXBlLCBUSTE4biwgVEljdX0gZnJvbSAnLi4vaW50ZXJmYWNlcy9pMThuJztcbmltcG9ydCB7VEVsZW1lbnROb2RlLCBUSWN1Q29udGFpbmVyTm9kZSwgVE5vZGUsIFROb2RlRmxhZ3MsIFROb2RlVHlwZSwgVFByb2plY3Rpb25Ob2RlfSBmcm9tICcuLi9pbnRlcmZhY2VzL25vZGUnO1xuaW1wb3J0IHtSQ29tbWVudCwgUkVsZW1lbnQsIFJUZXh0fSBmcm9tICcuLi9pbnRlcmZhY2VzL3JlbmRlcmVyJztcbmltcG9ydCB7U2FuaXRpemVyRm59IGZyb20gJy4uL2ludGVyZmFjZXMvc2FuaXRpemF0aW9uJztcbmltcG9ydCB7aXNMQ29udGFpbmVyfSBmcm9tICcuLi9pbnRlcmZhY2VzL3R5cGVfY2hlY2tzJztcbmltcG9ydCB7SEVBREVSX09GRlNFVCwgTFZpZXcsIFJFTkRFUkVSLCBUX0hPU1QsIFRWaWV3fSBmcm9tICcuLi9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHthcHBlbmRDaGlsZCwgYXBwbHlQcm9qZWN0aW9uLCBjcmVhdGVUZXh0Tm9kZSwgbmF0aXZlUmVtb3ZlTm9kZX0gZnJvbSAnLi4vbm9kZV9tYW5pcHVsYXRpb24nO1xuaW1wb3J0IHtnZXRCaW5kaW5nSW5kZXgsIGdldExWaWV3LCBnZXRQcmV2aW91c09yUGFyZW50VE5vZGUsIGdldFRWaWV3LCBzZXRJc05vdFBhcmVudCwgc2V0UHJldmlvdXNPclBhcmVudFROb2RlfSBmcm9tICcuLi9zdGF0ZSc7XG5pbXBvcnQge3JlbmRlclN0cmluZ2lmeX0gZnJvbSAnLi4vdXRpbC9taXNjX3V0aWxzJztcbmltcG9ydCB7Z2V0TmF0aXZlQnlJbmRleCwgZ2V0TmF0aXZlQnlUTm9kZSwgZ2V0VE5vZGUsIGxvYWR9IGZyb20gJy4uL3V0aWwvdmlld191dGlscyc7XG5pbXBvcnQge2dldExvY2FsZUlkfSBmcm9tICcuL2kxOG5fbG9jYWxlX2lkJztcblxuXG5jb25zdCBpMThuSW5kZXhTdGFjazogbnVtYmVyW10gPSBbXTtcbmxldCBpMThuSW5kZXhTdGFja1BvaW50ZXIgPSAtMTtcblxuZnVuY3Rpb24gcG9wSTE4bkluZGV4KCkge1xuICByZXR1cm4gaTE4bkluZGV4U3RhY2tbaTE4bkluZGV4U3RhY2tQb2ludGVyLS1dO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVzaEkxOG5JbmRleChpbmRleDogbnVtYmVyKSB7XG4gIGkxOG5JbmRleFN0YWNrWysraTE4bkluZGV4U3RhY2tQb2ludGVyXSA9IGluZGV4O1xufVxuXG5sZXQgY2hhbmdlTWFzayA9IDBiMDtcbmxldCBzaGlmdHNDb3VudGVyID0gMDtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldE1hc2tCaXQoYml0OiBib29sZWFuKSB7XG4gIGlmIChiaXQpIHtcbiAgICBjaGFuZ2VNYXNrID0gY2hhbmdlTWFzayB8ICgxIDw8IHNoaWZ0c0NvdW50ZXIpO1xuICB9XG4gIHNoaWZ0c0NvdW50ZXIrKztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5STE4bih0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldywgaW5kZXg6IG51bWJlcikge1xuICBpZiAoc2hpZnRzQ291bnRlciA+IDApIHtcbiAgICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RGVmaW5lZCh0VmlldywgYHRWaWV3IHNob3VsZCBiZSBkZWZpbmVkYCk7XG4gICAgY29uc3QgdEkxOG4gPSB0Vmlldy5kYXRhW2luZGV4ICsgSEVBREVSX09GRlNFVF0gYXMgVEkxOG4gfCBJMThuVXBkYXRlT3BDb2RlcztcbiAgICBsZXQgdXBkYXRlT3BDb2RlczogSTE4blVwZGF0ZU9wQ29kZXM7XG4gICAgbGV0IHRJY3VzOiBUSWN1W118bnVsbCA9IG51bGw7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodEkxOG4pKSB7XG4gICAgICB1cGRhdGVPcENvZGVzID0gdEkxOG4gYXMgSTE4blVwZGF0ZU9wQ29kZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHVwZGF0ZU9wQ29kZXMgPSAodEkxOG4gYXMgVEkxOG4pLnVwZGF0ZTtcbiAgICAgIHRJY3VzID0gKHRJMThuIGFzIFRJMThuKS5pY3VzO1xuICAgIH1cbiAgICBjb25zdCBiaW5kaW5nc1N0YXJ0SW5kZXggPSBnZXRCaW5kaW5nSW5kZXgoKSAtIHNoaWZ0c0NvdW50ZXIgLSAxO1xuICAgIGFwcGx5VXBkYXRlT3BDb2Rlcyh0VmlldywgdEljdXMsIGxWaWV3LCB1cGRhdGVPcENvZGVzLCBiaW5kaW5nc1N0YXJ0SW5kZXgsIGNoYW5nZU1hc2spO1xuXG4gICAgLy8gUmVzZXQgY2hhbmdlTWFzayAmIG1hc2tCaXQgdG8gZGVmYXVsdCBmb3IgdGhlIG5leHQgdXBkYXRlIGN5Y2xlXG4gICAgY2hhbmdlTWFzayA9IDBiMDtcbiAgICBzaGlmdHNDb3VudGVyID0gMDtcbiAgfVxufVxuXG4vKipcbiAqIEFwcGx5IGBJMThuTXV0YXRlT3BDb2Rlc2AgT3BDb2Rlcy5cbiAqXG4gKiBAcGFyYW0gdFZpZXcgQ3VycmVudCBgVFZpZXdgXG4gKiBAcGFyYW0gcm9vdEluZGV4IFBvaW50ZXIgdG8gdGhlIHJvb3QgKHBhcmVudCkgdE5vZGUgZm9yIHRoZSBpMThuLlxuICogQHBhcmFtIGNyZWF0ZU9wQ29kZXMgT3BDb2RlcyB0byBwcm9jZXNzXG4gKiBAcGFyYW0gbFZpZXcgQ3VycmVudCBgTFZpZXdgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseUNyZWF0ZU9wQ29kZXMoXG4gICAgdFZpZXc6IFRWaWV3LCByb290aW5kZXg6IG51bWJlciwgY3JlYXRlT3BDb2RlczogSTE4bk11dGF0ZU9wQ29kZXMsIGxWaWV3OiBMVmlldyk6IG51bWJlcltdIHtcbiAgY29uc3QgcmVuZGVyZXIgPSBsVmlld1tSRU5ERVJFUl07XG4gIGxldCBjdXJyZW50VE5vZGU6IFROb2RlfG51bGwgPSBudWxsO1xuICBsZXQgcHJldmlvdXNUTm9kZTogVE5vZGV8bnVsbCA9IG51bGw7XG4gIGNvbnN0IHZpc2l0ZWROb2RlczogbnVtYmVyW10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjcmVhdGVPcENvZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3Qgb3BDb2RlID0gY3JlYXRlT3BDb2Rlc1tpXTtcbiAgICBpZiAodHlwZW9mIG9wQ29kZSA9PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgdGV4dFJOb2RlID0gY3JlYXRlVGV4dE5vZGUob3BDb2RlLCByZW5kZXJlcik7XG4gICAgICBjb25zdCB0ZXh0Tm9kZUluZGV4ID0gY3JlYXRlT3BDb2Rlc1srK2ldIGFzIG51bWJlcjtcbiAgICAgIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUucmVuZGVyZXJDcmVhdGVUZXh0Tm9kZSsrO1xuICAgICAgcHJldmlvdXNUTm9kZSA9IGN1cnJlbnRUTm9kZTtcbiAgICAgIGN1cnJlbnRUTm9kZSA9XG4gICAgICAgICAgY3JlYXRlRHluYW1pY05vZGVBdEluZGV4KHRWaWV3LCBsVmlldywgdGV4dE5vZGVJbmRleCwgVE5vZGVUeXBlLkVsZW1lbnQsIHRleHRSTm9kZSwgbnVsbCk7XG4gICAgICB2aXNpdGVkTm9kZXMucHVzaCh0ZXh0Tm9kZUluZGV4KTtcbiAgICAgIHNldElzTm90UGFyZW50KCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygb3BDb2RlID09ICdudW1iZXInKSB7XG4gICAgICBzd2l0Y2ggKG9wQ29kZSAmIEkxOG5NdXRhdGVPcENvZGUuTUFTS19JTlNUUlVDVElPTikge1xuICAgICAgICBjYXNlIEkxOG5NdXRhdGVPcENvZGUuQXBwZW5kQ2hpbGQ6XG4gICAgICAgICAgY29uc3QgZGVzdGluYXRpb25Ob2RlSW5kZXggPSBvcENvZGUgPj4+IEkxOG5NdXRhdGVPcENvZGUuU0hJRlRfUEFSRU5UO1xuICAgICAgICAgIGxldCBkZXN0aW5hdGlvblROb2RlOiBUTm9kZTtcbiAgICAgICAgICBpZiAoZGVzdGluYXRpb25Ob2RlSW5kZXggPT09IHJvb3RpbmRleCkge1xuICAgICAgICAgICAgLy8gSWYgdGhlIGRlc3RpbmF0aW9uIG5vZGUgaXMgYGkxOG5TdGFydGAsIHdlIGRvbid0IGhhdmUgYVxuICAgICAgICAgICAgLy8gdG9wLWxldmVsIG5vZGUgYW5kIHdlIHNob3VsZCB1c2UgdGhlIGhvc3Qgbm9kZSBpbnN0ZWFkXG4gICAgICAgICAgICBkZXN0aW5hdGlvblROb2RlID0gbFZpZXdbVF9IT1NUXSE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uVE5vZGUgPSBnZXRUTm9kZSh0VmlldywgZGVzdGluYXRpb25Ob2RlSW5kZXgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBuZ0Rldk1vZGUgJiZcbiAgICAgICAgICAgICAgYXNzZXJ0RGVmaW5lZChcbiAgICAgICAgICAgICAgICAgIGN1cnJlbnRUTm9kZSEsXG4gICAgICAgICAgICAgICAgICBgWW91IG5lZWQgdG8gY3JlYXRlIG9yIHNlbGVjdCBhIG5vZGUgYmVmb3JlIHlvdSBjYW4gaW5zZXJ0IGl0IGludG8gdGhlIERPTWApO1xuICAgICAgICAgIHByZXZpb3VzVE5vZGUgPVxuICAgICAgICAgICAgICBhcHBlbmRJMThuTm9kZSh0VmlldywgY3VycmVudFROb2RlISwgZGVzdGluYXRpb25UTm9kZSwgcHJldmlvdXNUTm9kZSwgbFZpZXcpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIEkxOG5NdXRhdGVPcENvZGUuU2VsZWN0OlxuICAgICAgICAgIC8vIE5lZ2F0aXZlIGluZGljZXMgaW5kaWNhdGUgdGhhdCBhIGdpdmVuIFROb2RlIGlzIGEgc2libGluZyBub2RlLCBub3QgYSBwYXJlbnQgbm9kZVxuICAgICAgICAgIC8vIChzZWUgYGkxOG5TdGFydEZpcnN0UGFzc2AgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24pLlxuICAgICAgICAgIGNvbnN0IGlzUGFyZW50ID0gb3BDb2RlID49IDA7XG4gICAgICAgICAgLy8gRklYTUUobWlza28pOiBUaGlzIFNISUZUX1JFRiBsb29rcyBzdXNwZWN0IGFzIGl0IGRvZXMgbm90IGhhdmUgbWFzay5cbiAgICAgICAgICBjb25zdCBub2RlSW5kZXggPSAoaXNQYXJlbnQgPyBvcENvZGUgOiB+b3BDb2RlKSA+Pj4gSTE4bk11dGF0ZU9wQ29kZS5TSElGVF9SRUY7XG4gICAgICAgICAgdmlzaXRlZE5vZGVzLnB1c2gobm9kZUluZGV4KTtcbiAgICAgICAgICBwcmV2aW91c1ROb2RlID0gY3VycmVudFROb2RlO1xuICAgICAgICAgIGN1cnJlbnRUTm9kZSA9IGdldFROb2RlKHRWaWV3LCBub2RlSW5kZXgpO1xuICAgICAgICAgIGlmIChjdXJyZW50VE5vZGUpIHtcbiAgICAgICAgICAgIHNldFByZXZpb3VzT3JQYXJlbnRUTm9kZShjdXJyZW50VE5vZGUsIGlzUGFyZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgSTE4bk11dGF0ZU9wQ29kZS5FbGVtZW50RW5kOlxuICAgICAgICAgIGNvbnN0IGVsZW1lbnRJbmRleCA9IG9wQ29kZSA+Pj4gSTE4bk11dGF0ZU9wQ29kZS5TSElGVF9SRUY7XG4gICAgICAgICAgcHJldmlvdXNUTm9kZSA9IGN1cnJlbnRUTm9kZSA9IGdldFROb2RlKHRWaWV3LCBlbGVtZW50SW5kZXgpO1xuICAgICAgICAgIHNldFByZXZpb3VzT3JQYXJlbnRUTm9kZShjdXJyZW50VE5vZGUsIGZhbHNlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBJMThuTXV0YXRlT3BDb2RlLkF0dHI6XG4gICAgICAgICAgY29uc3QgZWxlbWVudE5vZGVJbmRleCA9IG9wQ29kZSA+Pj4gSTE4bk11dGF0ZU9wQ29kZS5TSElGVF9SRUY7XG4gICAgICAgICAgY29uc3QgYXR0ck5hbWUgPSBjcmVhdGVPcENvZGVzWysraV0gYXMgc3RyaW5nO1xuICAgICAgICAgIGNvbnN0IGF0dHJWYWx1ZSA9IGNyZWF0ZU9wQ29kZXNbKytpXSBhcyBzdHJpbmc7XG4gICAgICAgICAgLy8gVGhpcyBjb2RlIGlzIHVzZWQgZm9yIElDVSBleHByZXNzaW9ucyBvbmx5LCBzaW5jZSB3ZSBkb24ndCBzdXBwb3J0XG4gICAgICAgICAgLy8gZGlyZWN0aXZlcy9jb21wb25lbnRzIGluIElDVXMsIHdlIGRvbid0IG5lZWQgdG8gd29ycnkgYWJvdXQgaW5wdXRzIGhlcmVcbiAgICAgICAgICBlbGVtZW50QXR0cmlidXRlSW50ZXJuYWwoXG4gICAgICAgICAgICAgIGdldFROb2RlKHRWaWV3LCBlbGVtZW50Tm9kZUluZGV4KSwgbFZpZXcsIGF0dHJOYW1lLCBhdHRyVmFsdWUsIG51bGwsIG51bGwpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGRldGVybWluZSB0aGUgdHlwZSBvZiBtdXRhdGUgb3BlcmF0aW9uIGZvciBcIiR7b3BDb2RlfVwiYCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXRjaCAob3BDb2RlKSB7XG4gICAgICAgIGNhc2UgQ09NTUVOVF9NQVJLRVI6XG4gICAgICAgICAgY29uc3QgY29tbWVudFZhbHVlID0gY3JlYXRlT3BDb2Rlc1srK2ldIGFzIHN0cmluZztcbiAgICAgICAgICBjb25zdCBjb21tZW50Tm9kZUluZGV4ID0gY3JlYXRlT3BDb2Rlc1srK2ldIGFzIG51bWJlcjtcbiAgICAgICAgICBuZ0Rldk1vZGUgJiZcbiAgICAgICAgICAgICAgYXNzZXJ0RXF1YWwoXG4gICAgICAgICAgICAgICAgICB0eXBlb2YgY29tbWVudFZhbHVlLCAnc3RyaW5nJyxcbiAgICAgICAgICAgICAgICAgIGBFeHBlY3RlZCBcIiR7Y29tbWVudFZhbHVlfVwiIHRvIGJlIGEgY29tbWVudCBub2RlIHZhbHVlYCk7XG4gICAgICAgICAgY29uc3QgY29tbWVudFJOb2RlID0gcmVuZGVyZXIuY3JlYXRlQ29tbWVudChjb21tZW50VmFsdWUpO1xuICAgICAgICAgIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUucmVuZGVyZXJDcmVhdGVDb21tZW50Kys7XG4gICAgICAgICAgcHJldmlvdXNUTm9kZSA9IGN1cnJlbnRUTm9kZTtcbiAgICAgICAgICBjdXJyZW50VE5vZGUgPSBjcmVhdGVEeW5hbWljTm9kZUF0SW5kZXgoXG4gICAgICAgICAgICAgIHRWaWV3LCBsVmlldywgY29tbWVudE5vZGVJbmRleCwgVE5vZGVUeXBlLkljdUNvbnRhaW5lciwgY29tbWVudFJOb2RlLCBudWxsKTtcbiAgICAgICAgICB2aXNpdGVkTm9kZXMucHVzaChjb21tZW50Tm9kZUluZGV4KTtcbiAgICAgICAgICBhdHRhY2hQYXRjaERhdGEoY29tbWVudFJOb2RlLCBsVmlldyk7XG4gICAgICAgICAgLy8gV2Ugd2lsbCBhZGQgdGhlIGNhc2Ugbm9kZXMgbGF0ZXIsIGR1cmluZyB0aGUgdXBkYXRlIHBoYXNlXG4gICAgICAgICAgc2V0SXNOb3RQYXJlbnQoKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBFTEVNRU5UX01BUktFUjpcbiAgICAgICAgICBjb25zdCB0YWdOYW1lVmFsdWUgPSBjcmVhdGVPcENvZGVzWysraV0gYXMgc3RyaW5nO1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnROb2RlSW5kZXggPSBjcmVhdGVPcENvZGVzWysraV0gYXMgbnVtYmVyO1xuICAgICAgICAgIG5nRGV2TW9kZSAmJlxuICAgICAgICAgICAgICBhc3NlcnRFcXVhbChcbiAgICAgICAgICAgICAgICAgIHR5cGVvZiB0YWdOYW1lVmFsdWUsICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgICAgYEV4cGVjdGVkIFwiJHt0YWdOYW1lVmFsdWV9XCIgdG8gYmUgYW4gZWxlbWVudCBub2RlIHRhZyBuYW1lYCk7XG4gICAgICAgICAgY29uc3QgZWxlbWVudFJOb2RlID0gcmVuZGVyZXIuY3JlYXRlRWxlbWVudCh0YWdOYW1lVmFsdWUpO1xuICAgICAgICAgIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUucmVuZGVyZXJDcmVhdGVFbGVtZW50Kys7XG4gICAgICAgICAgcHJldmlvdXNUTm9kZSA9IGN1cnJlbnRUTm9kZTtcbiAgICAgICAgICBjdXJyZW50VE5vZGUgPSBjcmVhdGVEeW5hbWljTm9kZUF0SW5kZXgoXG4gICAgICAgICAgICAgIHRWaWV3LCBsVmlldywgZWxlbWVudE5vZGVJbmRleCwgVE5vZGVUeXBlLkVsZW1lbnQsIGVsZW1lbnRSTm9kZSwgdGFnTmFtZVZhbHVlKTtcbiAgICAgICAgICB2aXNpdGVkTm9kZXMucHVzaChlbGVtZW50Tm9kZUluZGV4KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgbXV0YXRlIG9wZXJhdGlvbiBmb3IgXCIke29wQ29kZX1cImApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNldElzTm90UGFyZW50KCk7XG5cbiAgcmV0dXJuIHZpc2l0ZWROb2Rlcztcbn1cblxuXG4vKipcbiAqIEFwcGx5IGBJMThuVXBkYXRlT3BDb2Rlc2AgT3BDb2Rlc1xuICpcbiAqIEBwYXJhbSB0VmlldyBDdXJyZW50IGBUVmlld2BcbiAqIEBwYXJhbSB0SWN1cyBJZiBJQ1VzIHByZXNlbnQgdGhhbiB0aGlzIGNvbnRhaW5zIHRoZW0uXG4gKiBAcGFyYW0gbFZpZXcgQ3VycmVudCBgTFZpZXdgXG4gKiBAcGFyYW0gdXBkYXRlT3BDb2RlcyBPcENvZGVzIHRvIHByb2Nlc3NcbiAqIEBwYXJhbSBiaW5kaW5nc1N0YXJ0SW5kZXggTG9jYXRpb24gb2YgdGhlIGZpcnN0IGDJtcm1aTE4bkFwcGx5YFxuICogQHBhcmFtIGNoYW5nZU1hc2sgRWFjaCBiaXQgY29ycmVzcG9uZHMgdG8gYSBgybXJtWkxOG5FeHBgIChDb3VudGluZyBiYWNrd2FyZHMgZnJvbVxuICogICAgIGBiaW5kaW5nc1N0YXJ0SW5kZXhgKVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlVcGRhdGVPcENvZGVzKFxuICAgIHRWaWV3OiBUVmlldywgdEljdXM6IFRJY3VbXXxudWxsLCBsVmlldzogTFZpZXcsIHVwZGF0ZU9wQ29kZXM6IEkxOG5VcGRhdGVPcENvZGVzLFxuICAgIGJpbmRpbmdzU3RhcnRJbmRleDogbnVtYmVyLCBjaGFuZ2VNYXNrOiBudW1iZXIpIHtcbiAgbGV0IGNhc2VDcmVhdGVkID0gZmFsc2U7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdXBkYXRlT3BDb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgIC8vIGJpdCBjb2RlIHRvIGNoZWNrIGlmIHdlIHNob3VsZCBhcHBseSB0aGUgbmV4dCB1cGRhdGVcbiAgICBjb25zdCBjaGVja0JpdCA9IHVwZGF0ZU9wQ29kZXNbaV0gYXMgbnVtYmVyO1xuICAgIC8vIE51bWJlciBvZiBvcENvZGVzIHRvIHNraXAgdW50aWwgbmV4dCBzZXQgb2YgdXBkYXRlIGNvZGVzXG4gICAgY29uc3Qgc2tpcENvZGVzID0gdXBkYXRlT3BDb2Rlc1srK2ldIGFzIG51bWJlcjtcbiAgICBpZiAoY2hlY2tCaXQgJiBjaGFuZ2VNYXNrKSB7XG4gICAgICAvLyBUaGUgdmFsdWUgaGFzIGJlZW4gdXBkYXRlZCBzaW5jZSBsYXN0IGNoZWNrZWRcbiAgICAgIGxldCB2YWx1ZSA9ICcnO1xuICAgICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDw9IChpICsgc2tpcENvZGVzKTsgaisrKSB7XG4gICAgICAgIGNvbnN0IG9wQ29kZSA9IHVwZGF0ZU9wQ29kZXNbal07XG4gICAgICAgIGlmICh0eXBlb2Ygb3BDb2RlID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdmFsdWUgKz0gb3BDb2RlO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvcENvZGUgPT0gJ251bWJlcicpIHtcbiAgICAgICAgICBpZiAob3BDb2RlIDwgMCkge1xuICAgICAgICAgICAgLy8gTmVnYXRpdmUgb3BDb2RlIHJlcHJlc2VudCBgaTE4bkV4cGAgdmFsdWVzIG9mZnNldC5cbiAgICAgICAgICAgIHZhbHVlICs9IHJlbmRlclN0cmluZ2lmeShsVmlld1tiaW5kaW5nc1N0YXJ0SW5kZXggLSBvcENvZGVdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgbm9kZUluZGV4ID0gb3BDb2RlID4+PiBJMThuVXBkYXRlT3BDb2RlLlNISUZUX1JFRjtcbiAgICAgICAgICAgIHN3aXRjaCAob3BDb2RlICYgSTE4blVwZGF0ZU9wQ29kZS5NQVNLX09QQ09ERSkge1xuICAgICAgICAgICAgICBjYXNlIEkxOG5VcGRhdGVPcENvZGUuQXR0cjpcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9wTmFtZSA9IHVwZGF0ZU9wQ29kZXNbKytqXSBhcyBzdHJpbmc7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2FuaXRpemVGbiA9IHVwZGF0ZU9wQ29kZXNbKytqXSBhcyBTYW5pdGl6ZXJGbiB8IG51bGw7XG4gICAgICAgICAgICAgICAgZWxlbWVudFByb3BlcnR5SW50ZXJuYWwoXG4gICAgICAgICAgICAgICAgICAgIHRWaWV3LCBnZXRUTm9kZSh0Vmlldywgbm9kZUluZGV4KSwgbFZpZXcsIHByb3BOYW1lLCB2YWx1ZSwgbFZpZXdbUkVOREVSRVJdLFxuICAgICAgICAgICAgICAgICAgICBzYW5pdGl6ZUZuLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgSTE4blVwZGF0ZU9wQ29kZS5UZXh0OlxuICAgICAgICAgICAgICAgIHRleHRCaW5kaW5nSW50ZXJuYWwobFZpZXcsIG5vZGVJbmRleCwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlIEkxOG5VcGRhdGVPcENvZGUuSWN1U3dpdGNoOlxuICAgICAgICAgICAgICAgIGNhc2VDcmVhdGVkID1cbiAgICAgICAgICAgICAgICAgICAgYXBwbHlJY3VTd2l0Y2hDYXNlKHRWaWV3LCB0SWN1cyEsIHVwZGF0ZU9wQ29kZXNbKytqXSBhcyBudW1iZXIsIGxWaWV3LCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgSTE4blVwZGF0ZU9wQ29kZS5JY3VVcGRhdGU6XG4gICAgICAgICAgICAgICAgYXBwbHlJY3VVcGRhdGVDYXNlKFxuICAgICAgICAgICAgICAgICAgICB0VmlldywgdEljdXMhLCB1cGRhdGVPcENvZGVzWysral0gYXMgbnVtYmVyLCBiaW5kaW5nc1N0YXJ0SW5kZXgsIGxWaWV3LFxuICAgICAgICAgICAgICAgICAgICBjYXNlQ3JlYXRlZCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGkgKz0gc2tpcENvZGVzO1xuICB9XG59XG5cbi8qKlxuICogQXBwbHkgT3BDb2RlcyBhc3NvY2lhdGVkIHdpdGggdXBkYXRpbmcgYW4gZXhpc3RpbmcgSUNVLlxuICpcbiAqIEBwYXJhbSB0VmlldyBDdXJyZW50IGBUVmlld2BcbiAqIEBwYXJhbSB0SWN1cyBJQ1VzIGFjdGl2ZSBhdCB0aGlzIGxvY2F0aW9uLlxuICogQHBhcmFtIHRJY3VJbmRleCBJbmRleCBpbnRvIGB0SWN1c2AgdG8gcHJvY2Vzcy5cbiAqIEBwYXJhbSBiaW5kaW5nc1N0YXJ0SW5kZXggTG9jYXRpb24gb2YgdGhlIGZpcnN0IGDJtcm1aTE4bkFwcGx5YFxuICogQHBhcmFtIGxWaWV3IEN1cnJlbnQgYExWaWV3YFxuICogQHBhcmFtIGNoYW5nZU1hc2sgRWFjaCBiaXQgY29ycmVzcG9uZHMgdG8gYSBgybXJtWkxOG5FeHBgIChDb3VudGluZyBiYWNrd2FyZHMgZnJvbVxuICogICAgIGBiaW5kaW5nc1N0YXJ0SW5kZXhgKVxuICovXG5mdW5jdGlvbiBhcHBseUljdVVwZGF0ZUNhc2UoXG4gICAgdFZpZXc6IFRWaWV3LCB0SWN1czogVEljdVtdLCB0SWN1SW5kZXg6IG51bWJlciwgYmluZGluZ3NTdGFydEluZGV4OiBudW1iZXIsIGxWaWV3OiBMVmlldyxcbiAgICBjYXNlQ3JlYXRlZDogYm9vbGVhbikge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0SW5kZXhJblJhbmdlKHRJY3VzLCB0SWN1SW5kZXgpO1xuICBjb25zdCB0SWN1ID0gdEljdXNbdEljdUluZGV4XTtcbiAgbmdEZXZNb2RlICYmIGFzc2VydEluZGV4SW5SYW5nZShsVmlldywgdEljdS5jdXJyZW50Q2FzZUxWaWV3SW5kZXgpO1xuICBjb25zdCBhY3RpdmVDYXNlSW5kZXggPSBsVmlld1t0SWN1LmN1cnJlbnRDYXNlTFZpZXdJbmRleF07XG4gIGlmIChhY3RpdmVDYXNlSW5kZXggIT09IG51bGwpIHtcbiAgICBjb25zdCBtYXNrID0gY2FzZUNyZWF0ZWQgP1xuICAgICAgICAtMSA6ICAvLyAtMSBpcyBzYW1lIGFzIGFsbCBiaXRzIG9uLCB3aGljaCBzaW11bGF0ZXMgY3JlYXRpb24gc2luY2UgaXQgbWFya3MgYWxsIGJpdHMgZGlydHlcbiAgICAgICAgY2hhbmdlTWFzaztcbiAgICBhcHBseVVwZGF0ZU9wQ29kZXModFZpZXcsIHRJY3VzLCBsVmlldywgdEljdS51cGRhdGVbYWN0aXZlQ2FzZUluZGV4XSwgYmluZGluZ3NTdGFydEluZGV4LCBtYXNrKTtcbiAgfVxufVxuXG4vKipcbiAqIEFwcGx5IE9wQ29kZXMgYXNzb2NpYXRlZCB3aXRoIHN3aXRjaGluZyBhIGNhc2Ugb24gSUNVLlxuICpcbiAqIFRoaXMgaW52b2x2ZXMgdGVhcmluZyBkb3duIGV4aXN0aW5nIGNhc2UgYW5kIHRoYW4gYnVpbGRpbmcgdXAgYSBuZXcgY2FzZS5cbiAqXG4gKiBAcGFyYW0gdFZpZXcgQ3VycmVudCBgVFZpZXdgXG4gKiBAcGFyYW0gdEljdXMgSUNVcyBhY3RpdmUgYXQgdGhpcyBsb2NhdGlvbi5cbiAqIEBwYXJhbSB0SUN1SW5kZXggSW5kZXggaW50byBgdEljdXNgIHRvIHByb2Nlc3MuXG4gKiBAcGFyYW0gbFZpZXcgQ3VycmVudCBgTFZpZXdgXG4gKiBAcGFyYW0gdmFsdWUgVmFsdWUgb2YgdGhlIGNhc2UgdG8gdXBkYXRlIHRvLlxuICogQHJldHVybnMgdHJ1ZSBpZiBhIG5ldyBjYXNlIHdhcyBjcmVhdGVkIChuZWVkZWQgc28gdGhhdCB0aGUgdXBkYXRlIGV4ZWN1dGVzIHJlZ2FyZGxlc3Mgb2YgdGhlXG4gKiAgICAgYml0bWFzaylcbiAqL1xuZnVuY3Rpb24gYXBwbHlJY3VTd2l0Y2hDYXNlKFxuICAgIHRWaWV3OiBUVmlldywgdEljdXM6IFRJY3VbXSwgdElDdUluZGV4OiBudW1iZXIsIGxWaWV3OiBMVmlldywgdmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBhcHBseUljdVN3aXRjaENhc2VSZW1vdmUodFZpZXcsIHRJY3VzLCB0SUN1SW5kZXgsIGxWaWV3KTtcblxuICAvLyBSZWJ1aWxkIGEgbmV3IGNhc2UgZm9yIHRoaXMgSUNVXG4gIGxldCBjYXNlQ3JlYXRlZCA9IGZhbHNlO1xuICBjb25zdCB0SWN1ID0gdEljdXNbdElDdUluZGV4XTtcbiAgY29uc3QgY2FzZUluZGV4ID0gZ2V0Q2FzZUluZGV4KHRJY3UsIHZhbHVlKTtcbiAgbFZpZXdbdEljdS5jdXJyZW50Q2FzZUxWaWV3SW5kZXhdID0gY2FzZUluZGV4ICE9PSAtMSA/IGNhc2VJbmRleCA6IG51bGw7XG4gIGlmIChjYXNlSW5kZXggPiAtMSkge1xuICAgIC8vIEFkZCB0aGUgbm9kZXMgZm9yIHRoZSBuZXcgY2FzZVxuICAgIGFwcGx5Q3JlYXRlT3BDb2RlcyhcbiAgICAgICAgdFZpZXcsIC0xLCAgLy8gLTEgbWVhbnMgd2UgZG9uJ3QgaGF2ZSBwYXJlbnQgbm9kZVxuICAgICAgICB0SWN1LmNyZWF0ZVtjYXNlSW5kZXhdLCBsVmlldyk7XG4gICAgY2FzZUNyZWF0ZWQgPSB0cnVlO1xuICB9XG4gIHJldHVybiBjYXNlQ3JlYXRlZDtcbn1cblxuLyoqXG4gKiBBcHBseSBPcENvZGVzIGFzc29jaWF0ZWQgd2l0aCB0ZWFyaW5nIGRvd24gb2YgRE9NLlxuICpcbiAqIFRoaXMgaW52b2x2ZXMgdGVhcmluZyBkb3duIGV4aXN0aW5nIGNhc2UgYW5kIHRoYW4gYnVpbGRpbmcgdXAgYSBuZXcgY2FzZS5cbiAqXG4gKiBAcGFyYW0gdFZpZXcgQ3VycmVudCBgVFZpZXdgXG4gKiBAcGFyYW0gdEljdXMgSUNVcyBhY3RpdmUgYXQgdGhpcyBsb2NhdGlvbi5cbiAqIEBwYXJhbSB0SWN1SW5kZXggSW5kZXggaW50byBgdEljdXNgIHRvIHByb2Nlc3MuXG4gKiBAcGFyYW0gbFZpZXcgQ3VycmVudCBgTFZpZXdgXG4gKiBAcmV0dXJucyB0cnVlIGlmIGEgbmV3IGNhc2Ugd2FzIGNyZWF0ZWQgKG5lZWRlZCBzbyB0aGF0IHRoZSB1cGRhdGUgZXhlY3V0ZXMgcmVnYXJkbGVzcyBvZiB0aGVcbiAqICAgICBiaXRtYXNrKVxuICovXG5mdW5jdGlvbiBhcHBseUljdVN3aXRjaENhc2VSZW1vdmUodFZpZXc6IFRWaWV3LCB0SWN1czogVEljdVtdLCB0SWN1SW5kZXg6IG51bWJlciwgbFZpZXc6IExWaWV3KSB7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRJbmRleEluUmFuZ2UodEljdXMsIHRJY3VJbmRleCk7XG4gIGNvbnN0IHRJY3UgPSB0SWN1c1t0SWN1SW5kZXhdO1xuICBjb25zdCBhY3RpdmVDYXNlSW5kZXggPSBsVmlld1t0SWN1LmN1cnJlbnRDYXNlTFZpZXdJbmRleF07XG4gIGlmIChhY3RpdmVDYXNlSW5kZXggIT09IG51bGwpIHtcbiAgICBjb25zdCByZW1vdmVDb2RlcyA9IHRJY3UucmVtb3ZlW2FjdGl2ZUNhc2VJbmRleF07XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCByZW1vdmVDb2Rlcy5sZW5ndGg7IGsrKykge1xuICAgICAgY29uc3QgcmVtb3ZlT3BDb2RlID0gcmVtb3ZlQ29kZXNba10gYXMgbnVtYmVyO1xuICAgICAgY29uc3Qgbm9kZU9ySWN1SW5kZXggPSByZW1vdmVPcENvZGUgPj4+IEkxOG5NdXRhdGVPcENvZGUuU0hJRlRfUkVGO1xuICAgICAgc3dpdGNoIChyZW1vdmVPcENvZGUgJiBJMThuTXV0YXRlT3BDb2RlLk1BU0tfSU5TVFJVQ1RJT04pIHtcbiAgICAgICAgY2FzZSBJMThuTXV0YXRlT3BDb2RlLlJlbW92ZTpcbiAgICAgICAgICAvLyBGSVhNRShtaXNrbyk6IHRoaXMgY29tbWVudCBpcyB3cm9uZyFcbiAgICAgICAgICAvLyBSZW1vdmUgRE9NIGVsZW1lbnQsIGJ1dCBkbyAqbm90KiBtYXJrIFROb2RlIGFzIGRldGFjaGVkLCBzaW5jZSB3ZSBhcmVcbiAgICAgICAgICAvLyBqdXN0IHN3aXRjaGluZyBJQ1UgY2FzZXMgKHdoaWxlIGtlZXBpbmcgdGhlIHNhbWUgVE5vZGUpLCBzbyBhIERPTSBlbGVtZW50XG4gICAgICAgICAgLy8gcmVwcmVzZW50aW5nIGEgbmV3IElDVSBjYXNlIHdpbGwgYmUgcmUtY3JlYXRlZC5cbiAgICAgICAgICByZW1vdmVOb2RlKHRWaWV3LCBsVmlldywgbm9kZU9ySWN1SW5kZXgsIC8qIG1hcmtBc0RldGFjaGVkICovIGZhbHNlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBJMThuTXV0YXRlT3BDb2RlLlJlbW92ZU5lc3RlZEljdTpcbiAgICAgICAgICBhcHBseUljdVN3aXRjaENhc2VSZW1vdmUodFZpZXcsIHRJY3VzLCBub2RlT3JJY3VJbmRleCwgbFZpZXcpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhcHBlbmRJMThuTm9kZShcbiAgICB0VmlldzogVFZpZXcsIHROb2RlOiBUTm9kZSwgcGFyZW50VE5vZGU6IFROb2RlLCBwcmV2aW91c1ROb2RlOiBUTm9kZXxudWxsLFxuICAgIGxWaWV3OiBMVmlldyk6IFROb2RlIHtcbiAgbmdEZXZNb2RlICYmIG5nRGV2TW9kZS5yZW5kZXJlck1vdmVOb2RlKys7XG4gIGNvbnN0IG5leHROb2RlID0gdE5vZGUubmV4dDtcbiAgaWYgKCFwcmV2aW91c1ROb2RlKSB7XG4gICAgcHJldmlvdXNUTm9kZSA9IHBhcmVudFROb2RlO1xuICB9XG5cbiAgLy8gUmUtb3JnYW5pemUgbm9kZSB0cmVlIHRvIHB1dCB0aGlzIG5vZGUgaW4gdGhlIGNvcnJlY3QgcG9zaXRpb24uXG4gIGlmIChwcmV2aW91c1ROb2RlID09PSBwYXJlbnRUTm9kZSAmJiB0Tm9kZSAhPT0gcGFyZW50VE5vZGUuY2hpbGQpIHtcbiAgICB0Tm9kZS5uZXh0ID0gcGFyZW50VE5vZGUuY2hpbGQ7XG4gICAgcGFyZW50VE5vZGUuY2hpbGQgPSB0Tm9kZTtcbiAgfSBlbHNlIGlmIChwcmV2aW91c1ROb2RlICE9PSBwYXJlbnRUTm9kZSAmJiB0Tm9kZSAhPT0gcHJldmlvdXNUTm9kZS5uZXh0KSB7XG4gICAgdE5vZGUubmV4dCA9IHByZXZpb3VzVE5vZGUubmV4dDtcbiAgICBwcmV2aW91c1ROb2RlLm5leHQgPSB0Tm9kZTtcbiAgfSBlbHNlIHtcbiAgICB0Tm9kZS5uZXh0ID0gbnVsbDtcbiAgfVxuXG4gIGlmIChwYXJlbnRUTm9kZSAhPT0gbFZpZXdbVF9IT1NUXSkge1xuICAgIHROb2RlLnBhcmVudCA9IHBhcmVudFROb2RlIGFzIFRFbGVtZW50Tm9kZTtcbiAgfVxuXG4gIC8vIElmIHROb2RlIHdhcyBtb3ZlZCBhcm91bmQsIHdlIG1pZ2h0IG5lZWQgdG8gZml4IGEgYnJva2VuIGxpbmsuXG4gIGxldCBjdXJzb3I6IFROb2RlfG51bGwgPSB0Tm9kZS5uZXh0O1xuICB3aGlsZSAoY3Vyc29yKSB7XG4gICAgaWYgKGN1cnNvci5uZXh0ID09PSB0Tm9kZSkge1xuICAgICAgY3Vyc29yLm5leHQgPSBuZXh0Tm9kZTtcbiAgICB9XG4gICAgY3Vyc29yID0gY3Vyc29yLm5leHQ7XG4gIH1cblxuICAvLyBJZiB0aGUgcGxhY2Vob2xkZXIgdG8gYXBwZW5kIGlzIGEgcHJvamVjdGlvbiwgd2UgbmVlZCB0byBtb3ZlIHRoZSBwcm9qZWN0ZWQgbm9kZXMgaW5zdGVhZFxuICBpZiAodE5vZGUudHlwZSA9PT0gVE5vZGVUeXBlLlByb2plY3Rpb24pIHtcbiAgICBhcHBseVByb2plY3Rpb24odFZpZXcsIGxWaWV3LCB0Tm9kZSBhcyBUUHJvamVjdGlvbk5vZGUpO1xuICAgIHJldHVybiB0Tm9kZTtcbiAgfVxuXG4gIGFwcGVuZENoaWxkKHRWaWV3LCBsVmlldywgZ2V0TmF0aXZlQnlUTm9kZSh0Tm9kZSwgbFZpZXcpLCB0Tm9kZSk7XG5cbiAgY29uc3Qgc2xvdFZhbHVlID0gbFZpZXdbdE5vZGUuaW5kZXhdO1xuICBpZiAodE5vZGUudHlwZSAhPT0gVE5vZGVUeXBlLkNvbnRhaW5lciAmJiBpc0xDb250YWluZXIoc2xvdFZhbHVlKSkge1xuICAgIC8vIE5vZGVzIHRoYXQgaW5qZWN0IFZpZXdDb250YWluZXJSZWYgYWxzbyBoYXZlIGEgY29tbWVudCBub2RlIHRoYXQgc2hvdWxkIGJlIG1vdmVkXG4gICAgYXBwZW5kQ2hpbGQodFZpZXcsIGxWaWV3LCBzbG90VmFsdWVbTkFUSVZFXSwgdE5vZGUpO1xuICB9XG4gIHJldHVybiB0Tm9kZTtcbn1cblxuLyoqXG4gKiBTZWUgYGkxOG5FbmRgIGFib3ZlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaTE4bkVuZEZpcnN0UGFzcyh0VmlldzogVFZpZXcsIGxWaWV3OiBMVmlldykge1xuICBuZ0Rldk1vZGUgJiZcbiAgICAgIGFzc2VydEVxdWFsKFxuICAgICAgICAgIGdldEJpbmRpbmdJbmRleCgpLCB0Vmlldy5iaW5kaW5nU3RhcnRJbmRleCxcbiAgICAgICAgICAnaTE4bkVuZCBzaG91bGQgYmUgY2FsbGVkIGJlZm9yZSBhbnkgYmluZGluZycpO1xuXG4gIGNvbnN0IHJvb3RJbmRleCA9IHBvcEkxOG5JbmRleCgpO1xuICBjb25zdCB0STE4biA9IHRWaWV3LmRhdGFbcm9vdEluZGV4ICsgSEVBREVSX09GRlNFVF0gYXMgVEkxOG47XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnREZWZpbmVkKHRJMThuLCBgWW91IHNob3VsZCBjYWxsIGkxOG5TdGFydCBiZWZvcmUgaTE4bkVuZGApO1xuXG4gIC8vIEZpbmQgdGhlIGxhc3Qgbm9kZSB0aGF0IHdhcyBhZGRlZCBiZWZvcmUgYGkxOG5FbmRgXG4gIGNvbnN0IGxhc3RDcmVhdGVkTm9kZSA9IGdldFByZXZpb3VzT3JQYXJlbnRUTm9kZSgpO1xuXG4gIC8vIFJlYWQgdGhlIGluc3RydWN0aW9ucyB0byBpbnNlcnQvbW92ZS9yZW1vdmUgRE9NIGVsZW1lbnRzXG4gIGNvbnN0IHZpc2l0ZWROb2RlcyA9IGFwcGx5Q3JlYXRlT3BDb2Rlcyh0Vmlldywgcm9vdEluZGV4LCB0STE4bi5jcmVhdGUsIGxWaWV3KTtcblxuICAvLyBSZW1vdmUgZGVsZXRlZCBub2Rlc1xuICBsZXQgaW5kZXggPSByb290SW5kZXggKyAxO1xuICB3aGlsZSAoaW5kZXggPD0gbGFzdENyZWF0ZWROb2RlLmluZGV4IC0gSEVBREVSX09GRlNFVCkge1xuICAgIGlmICh2aXNpdGVkTm9kZXMuaW5kZXhPZihpbmRleCkgPT09IC0xKSB7XG4gICAgICByZW1vdmVOb2RlKHRWaWV3LCBsVmlldywgaW5kZXgsIC8qIG1hcmtBc0RldGFjaGVkICovIHRydWUpO1xuICAgIH1cbiAgICAvLyBDaGVjayBpZiBhbiBlbGVtZW50IGhhcyBhbnkgbG9jYWwgcmVmcyBhbmQgc2tpcCB0aGVtXG4gICAgY29uc3QgdE5vZGUgPSBnZXRUTm9kZSh0VmlldywgaW5kZXgpO1xuICAgIGlmICh0Tm9kZSAmJlxuICAgICAgICAodE5vZGUudHlwZSA9PT0gVE5vZGVUeXBlLkNvbnRhaW5lciB8fCB0Tm9kZS50eXBlID09PSBUTm9kZVR5cGUuRWxlbWVudCB8fFxuICAgICAgICAgdE5vZGUudHlwZSA9PT0gVE5vZGVUeXBlLkVsZW1lbnRDb250YWluZXIpICYmXG4gICAgICAgIHROb2RlLmxvY2FsTmFtZXMgIT09IG51bGwpIHtcbiAgICAgIC8vIERpdmlkZSBieSAyIHRvIGdldCB0aGUgbnVtYmVyIG9mIGxvY2FsIHJlZnMsXG4gICAgICAvLyBzaW5jZSB0aGV5IGFyZSBzdG9yZWQgYXMgYW4gYXJyYXkgdGhhdCBhbHNvIGluY2x1ZGVzIGRpcmVjdGl2ZSBpbmRleGVzLFxuICAgICAgLy8gaS5lLiBbXCJsb2NhbFJlZlwiLCBkaXJlY3RpdmVJbmRleCwgLi4uXVxuICAgICAgaW5kZXggKz0gdE5vZGUubG9jYWxOYW1lcy5sZW5ndGggPj4gMTtcbiAgICB9XG4gICAgaW5kZXgrKztcbiAgfVxufVxuXG5mdW5jdGlvbiByZW1vdmVOb2RlKHRWaWV3OiBUVmlldywgbFZpZXc6IExWaWV3LCBpbmRleDogbnVtYmVyLCBtYXJrQXNEZXRhY2hlZDogYm9vbGVhbikge1xuICBjb25zdCByZW1vdmVkUGhUTm9kZSA9IGdldFROb2RlKHRWaWV3LCBpbmRleCk7XG4gIGNvbnN0IHJlbW92ZWRQaFJOb2RlID0gZ2V0TmF0aXZlQnlJbmRleChpbmRleCwgbFZpZXcpO1xuICBpZiAocmVtb3ZlZFBoUk5vZGUpIHtcbiAgICBuYXRpdmVSZW1vdmVOb2RlKGxWaWV3W1JFTkRFUkVSXSwgcmVtb3ZlZFBoUk5vZGUpO1xuICB9XG5cbiAgY29uc3Qgc2xvdFZhbHVlID0gbG9hZChsVmlldywgaW5kZXgpIGFzIFJFbGVtZW50IHwgUkNvbW1lbnQgfCBMQ29udGFpbmVyO1xuICBpZiAoaXNMQ29udGFpbmVyKHNsb3RWYWx1ZSkpIHtcbiAgICBjb25zdCBsQ29udGFpbmVyID0gc2xvdFZhbHVlIGFzIExDb250YWluZXI7XG4gICAgaWYgKHJlbW92ZWRQaFROb2RlLnR5cGUgIT09IFROb2RlVHlwZS5Db250YWluZXIpIHtcbiAgICAgIG5hdGl2ZVJlbW92ZU5vZGUobFZpZXdbUkVOREVSRVJdLCBsQ29udGFpbmVyW05BVElWRV0pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChtYXJrQXNEZXRhY2hlZCkge1xuICAgIC8vIERlZmluZSB0aGlzIG5vZGUgYXMgZGV0YWNoZWQgdG8gYXZvaWQgcHJvamVjdGluZyBpdCBsYXRlclxuICAgIHJlbW92ZWRQaFROb2RlLmZsYWdzIHw9IFROb2RlRmxhZ3MuaXNEZXRhY2hlZDtcbiAgfVxuICBuZ0Rldk1vZGUgJiYgbmdEZXZNb2RlLnJlbmRlcmVyUmVtb3ZlTm9kZSsrO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYW5kIHN0b3JlcyB0aGUgZHluYW1pYyBUTm9kZSwgYW5kIHVuaG9va3MgaXQgZnJvbSB0aGUgdHJlZSBmb3Igbm93LlxuICovXG5mdW5jdGlvbiBjcmVhdGVEeW5hbWljTm9kZUF0SW5kZXgoXG4gICAgdFZpZXc6IFRWaWV3LCBsVmlldzogTFZpZXcsIGluZGV4OiBudW1iZXIsIHR5cGU6IFROb2RlVHlwZSwgbmF0aXZlOiBSRWxlbWVudHxSVGV4dHxudWxsLFxuICAgIG5hbWU6IHN0cmluZ3xudWxsKTogVEVsZW1lbnROb2RlfFRJY3VDb250YWluZXJOb2RlIHtcbiAgY29uc3QgcHJldmlvdXNPclBhcmVudFROb2RlID0gZ2V0UHJldmlvdXNPclBhcmVudFROb2RlKCk7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRJbmRleEluUmFuZ2UobFZpZXcsIGluZGV4ICsgSEVBREVSX09GRlNFVCk7XG4gIGxWaWV3W2luZGV4ICsgSEVBREVSX09GRlNFVF0gPSBuYXRpdmU7XG4gIC8vIEZJWE1FKG1pc2tvKTogV2h5IGRvZXMgdGhpcyBjcmVhdGUgQSBUTm9kZT8/PyBJIHdvdWxkIG5vdCBleHBlY3QgdGhpcyB0byBiZSBoZXJlLlxuICBjb25zdCB0Tm9kZSA9IGdldE9yQ3JlYXRlVE5vZGUodFZpZXcsIGxWaWV3W1RfSE9TVF0sIGluZGV4LCB0eXBlIGFzIGFueSwgbmFtZSwgbnVsbCk7XG5cbiAgLy8gV2UgYXJlIGNyZWF0aW5nIGEgZHluYW1pYyBub2RlLCB0aGUgcHJldmlvdXMgdE5vZGUgbWlnaHQgbm90IGJlIHBvaW50aW5nIGF0IHRoaXMgbm9kZS5cbiAgLy8gV2Ugd2lsbCBsaW5rIG91cnNlbHZlcyBpbnRvIHRoZSB0cmVlIGxhdGVyIHdpdGggYGFwcGVuZEkxOG5Ob2RlYC5cbiAgaWYgKHByZXZpb3VzT3JQYXJlbnRUTm9kZSAmJiBwcmV2aW91c09yUGFyZW50VE5vZGUubmV4dCA9PT0gdE5vZGUpIHtcbiAgICBwcmV2aW91c09yUGFyZW50VE5vZGUubmV4dCA9IG51bGw7XG4gIH1cblxuICByZXR1cm4gdE5vZGU7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgY3VycmVudCBjYXNlIG9mIGFuIElDVSBleHByZXNzaW9uIGRlcGVuZGluZyBvbiB0aGUgbWFpbiBiaW5kaW5nIHZhbHVlXG4gKlxuICogQHBhcmFtIGljdUV4cHJlc3Npb25cbiAqIEBwYXJhbSBiaW5kaW5nVmFsdWUgVGhlIHZhbHVlIG9mIHRoZSBtYWluIGJpbmRpbmcgdXNlZCBieSB0aGlzIElDVSBleHByZXNzaW9uXG4gKi9cbmZ1bmN0aW9uIGdldENhc2VJbmRleChpY3VFeHByZXNzaW9uOiBUSWN1LCBiaW5kaW5nVmFsdWU6IHN0cmluZyk6IG51bWJlciB7XG4gIGxldCBpbmRleCA9IGljdUV4cHJlc3Npb24uY2FzZXMuaW5kZXhPZihiaW5kaW5nVmFsdWUpO1xuICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgc3dpdGNoIChpY3VFeHByZXNzaW9uLnR5cGUpIHtcbiAgICAgIGNhc2UgSWN1VHlwZS5wbHVyYWw6IHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZWRDYXNlID0gZ2V0UGx1cmFsQ2FzZShiaW5kaW5nVmFsdWUsIGdldExvY2FsZUlkKCkpO1xuICAgICAgICBpbmRleCA9IGljdUV4cHJlc3Npb24uY2FzZXMuaW5kZXhPZihyZXNvbHZlZENhc2UpO1xuICAgICAgICBpZiAoaW5kZXggPT09IC0xICYmIHJlc29sdmVkQ2FzZSAhPT0gJ290aGVyJykge1xuICAgICAgICAgIGluZGV4ID0gaWN1RXhwcmVzc2lvbi5jYXNlcy5pbmRleE9mKCdvdGhlcicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSBJY3VUeXBlLnNlbGVjdDoge1xuICAgICAgICBpbmRleCA9IGljdUV4cHJlc3Npb24uY2FzZXMuaW5kZXhPZignb3RoZXInKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBpbmRleDtcbn1cbiJdfQ==