@rivet-health/design-system 39.7.0 → 39.7.2

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.
@@ -2,39 +2,27 @@ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewCh
2
2
  import * as i0 from "@angular/core";
3
3
  import * as i1 from "@angular/common";
4
4
  import * as i2 from "../../overlay/callout/callout.component";
5
+ const ZWS = '​';
6
+ const ZWS_REGEX = /​/g;
5
7
  /**
6
- * A rich text input component that allows users to type text and mention other users by typing `@` followed by a name.
7
- * Uses a `contenteditable` div instead of a traditional input/textarea.
8
+ * A rich text input that supports `@`-mentions inside a `contenteditable` div.
8
9
  *
9
10
  * ## Data Model
10
- * Works with a structured content model rather than plain strings:
11
- * - **Input/Output**: `ContentItem[]` - an array of content pieces
12
- * - **ContentItem types**:
13
- * - `UserMention`: `{ type: 'mention', id: number, name: string }`
14
- * - `Text`: `{ type: 'text', text: string }`
11
+ * - **Input/Output**: `ContentItem[]` (mentions, text, newlines)
15
12
  *
16
- * ## Rendering Flow
17
- * 1. **Content → DOM**: `renderContent()` converts the content input array to HTML. Mentions become `<span>` elements with `data-id` and `data-type` attributes. Text is escaped and rendered as plain text.
18
- * 2. **DOM Content**: `domToContentItems()` parses the DOM back into `ContentItem[]`, walking through child nodes extracting mentions and text. Emitted via `contentChange` event on input.
13
+ * ## DOM Invariant
14
+ * Every mention `<span data-type="mention" contenteditable="false">` is wrapped
15
+ * by exactly one zero-width-space (ZWS) text node before and after it. ZWS gives
16
+ * the cursor a valid landing spot adjacent to a non-editable element. The
17
+ * invariant is established at render time and re-established by
18
+ * `normalizeMentionPadding()` after any DOM-mutating operation.
19
19
  *
20
- * ## User Interaction
21
- * - **Typing `@` triggers mentions**: Monitors input for `@` character, extracts text after `@` (up to first space) as search text, positions a callout dropdown at the cursor location
22
- * - **Keyboard navigation**: Arrow keys navigate filtered users list, Enter selects highlighted user, Escape closes mentions dropdown
23
- * - **Selecting a mention**: Deletes the `@` and search text from DOM, creates a non-editable `<span>` element for the mention, inserts at cursor position, repositions cursor after the mention
24
- *
25
- * ## Technical Details
26
- * - **Cursor management**: Uses Selection API and Range objects to track/manipulate cursor position
27
- * - **Text extraction**: `getTextBeforeCursor()` gets plain text before cursor, treating mention spans as `@name`
28
- * - **Character position mapping**: `findDomPositionAtCharIndex()` converts character indices to DOM node positions using TreeWalker
29
- * - **Change detection**: Uses OnPush with manual `markForCheck()` calls
30
- * - **Readonly mode**: Swaps between contenteditable and non-editable divs, styles mentions differently
31
- *
32
- * ## State
33
- * - `mentionsVisible`: controls dropdown visibility
34
- * - `mentionSearchText`: current filter text after @
35
- * - `mentionAnchor`: DOMRect for positioning dropdown
36
- * - `selectedUserIndex`: keyboard navigation state
37
- * - `savedRange`: preserves cursor position for click-based selection
20
+ * ## Copy/Paste
21
+ * - **Copy**: `range.cloneContents()` preserves `data-*` attributes (only the
22
+ * browser's default copy path strips them). We override copy, serialize the
23
+ * clone ourselves, and strip ZWS from the output.
24
+ * - **Paste**: HTML paths look for `data-type="mention"` spans and rebuild
25
+ * them; otherwise plaintext fallback.
38
26
  */
39
27
  export class MentionsInputComponent {
40
28
  constructor(cdr) {
@@ -66,7 +54,10 @@ export class MentionsInputComponent {
66
54
  return;
67
55
  }
68
56
  const html = this.content
69
- .map(item => MentionsInputComponent.contentItemToHtml(item, this.readonly))
57
+ .map(item => {
58
+ const itemHtml = MentionsInputComponent.contentItemToHtml(item, this.readonly);
59
+ return item.type === 'mention' ? `${ZWS}${itemHtml}${ZWS}` : itemHtml;
60
+ })
70
61
  .join('');
71
62
  this.inputElement.nativeElement.innerHTML = html;
72
63
  }
@@ -86,39 +77,51 @@ export class MentionsInputComponent {
86
77
  div.textContent = text;
87
78
  return div.innerHTML;
88
79
  }
80
+ // ─── Event handlers ───────────────────────────────────────────────────
89
81
  onInput() {
82
+ this.normalizeMentionPadding();
90
83
  this.checkForMentionTrigger();
91
84
  this.emitContentChange();
92
85
  }
93
86
  onKeyDown(event) {
94
87
  if (this.mentionsVisible) {
95
- const filteredUsers = this.getFilteredUsers();
96
- if (filteredUsers.length === 0) {
97
- this.closeMentions();
88
+ this.handleMentionsDropdownNav(event);
89
+ return;
90
+ }
91
+ // Word/line jump: native behavior.
92
+ if (event.metaKey || event.ctrlKey) {
93
+ return;
94
+ }
95
+ if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
96
+ const direction = event.key === 'ArrowLeft' ? 'before' : 'after';
97
+ const mention = this.findMentionAdjacentToCursor(direction);
98
+ if (mention) {
99
+ event.preventDefault();
100
+ if (event.shiftKey) {
101
+ this.extendSelectionAcrossMention(mention, direction);
102
+ }
103
+ else {
104
+ this.placeCursorAdjacentToMention(mention, direction);
105
+ }
106
+ }
107
+ return;
108
+ }
109
+ if (event.key === 'Backspace' || event.key === 'Delete') {
110
+ const direction = event.key === 'Backspace' ? 'before' : 'after';
111
+ const mention = this.findMentionAdjacentToCursor(direction);
112
+ if (mention) {
113
+ event.preventDefault();
114
+ this.removeMention(mention);
115
+ this.emitContentChange();
98
116
  return;
99
117
  }
100
- switch (event.key) {
101
- case 'ArrowDown':
102
- event.preventDefault();
103
- this.selectedUserIndex = Math.min(this.selectedUserIndex + 1, filteredUsers.length - 1);
104
- this.cdr.markForCheck();
105
- break;
106
- case 'ArrowUp':
107
- event.preventDefault();
108
- this.selectedUserIndex = Math.max(this.selectedUserIndex - 1, 0);
109
- this.cdr.markForCheck();
110
- break;
111
- case 'Enter':
112
- case 'Tab':
113
- event.preventDefault();
114
- if (filteredUsers[this.selectedUserIndex]) {
115
- this.selectUser(filteredUsers[this.selectedUserIndex]);
116
- }
117
- break;
118
- case 'Escape':
118
+ if (event.key === 'Backspace') {
119
+ const br = this.findBrAdjacentToCursor();
120
+ if (br) {
119
121
  event.preventDefault();
120
- this.closeMentions();
121
- break;
122
+ br.remove();
123
+ this.emitContentChange();
124
+ }
122
125
  }
123
126
  return;
124
127
  }
@@ -137,16 +140,234 @@ export class MentionsInputComponent {
137
140
  //Look for HTML first
138
141
  const html = event.clipboardData.getData('text/html');
139
142
  const plainText = event.clipboardData.getData('text/plain');
140
- if (html && html.includes('data-type="mention"')) {
141
- const sanitizedNodes = this.parsePastedHtml(html);
142
- this.insertNodesAtCursor(sanitizedNodes);
143
+ const nodes = html && html.includes('data-type="mention"')
144
+ ? this.parsePastedHtml(html)
145
+ : this.plainTextToNodes(plainText);
146
+ this.insertNodesAtCursor(nodes);
147
+ this.normalizeMentionPadding();
148
+ this.emitContentChange();
149
+ }
150
+ // The browser strips data-* attributes during default copy serialization, but
151
+ // range.cloneContents() preserves them. We serialize the clone ourselves and
152
+ // strip ZWS so it doesn't leak into the clipboard.
153
+ onCopy(event) {
154
+ const selection = window.getSelection();
155
+ if (!selection?.rangeCount) {
156
+ return;
143
157
  }
144
- else if (plainText) {
145
- const nodes = this.plainTextToNodes(plainText);
146
- this.insertNodesAtCursor(nodes);
158
+ event.preventDefault();
159
+ const div = document.createElement('div');
160
+ div.appendChild(selection.getRangeAt(0).cloneContents());
161
+ const html = div.innerHTML.replace(ZWS_REGEX, '');
162
+ const text = (div.textContent || '').replace(ZWS_REGEX, '');
163
+ event.clipboardData?.setData('text/html', html);
164
+ event.clipboardData?.setData('text/plain', text);
165
+ }
166
+ onCut(event) {
167
+ this.onCopy(event);
168
+ const selection = window.getSelection();
169
+ if (!selection?.rangeCount) {
170
+ return;
147
171
  }
172
+ selection.getRangeAt(0).deleteContents();
173
+ this.normalizeMentionPadding();
148
174
  this.emitContentChange();
149
175
  }
176
+ // ─── Mention helpers ───────────────────────────────────────────────────
177
+ static isMention(node) {
178
+ return (!!node &&
179
+ node.nodeType === Node.ELEMENT_NODE &&
180
+ node.getAttribute('data-type') === 'mention');
181
+ }
182
+ static isZws(node) {
183
+ return (!!node &&
184
+ node.nodeType === Node.TEXT_NODE &&
185
+ (node.textContent || '').replace(ZWS_REGEX, '') === '');
186
+ }
187
+ // Resolve the node logically adjacent to (container, offset) in the given
188
+ // direction, transparently skipping any ZWS-only text nodes in between.
189
+ resolveAdjacentNode(container, offset, direction) {
190
+ let candidate = null;
191
+ if (container.nodeType === Node.TEXT_NODE) {
192
+ const length = (container.textContent || '').length;
193
+ const atBoundary = MentionsInputComponent.isZws(container) ||
194
+ (direction === 'before' ? offset === 0 : offset === length);
195
+ if (!atBoundary) {
196
+ return null;
197
+ }
198
+ candidate =
199
+ direction === 'before'
200
+ ? container.previousSibling
201
+ : container.nextSibling;
202
+ }
203
+ else if (container.nodeType === Node.ELEMENT_NODE) {
204
+ const children = container.childNodes;
205
+ candidate =
206
+ direction === 'before' ? children[offset - 1] : children[offset];
207
+ }
208
+ while (candidate && MentionsInputComponent.isZws(candidate)) {
209
+ candidate =
210
+ direction === 'before'
211
+ ? candidate.previousSibling
212
+ : candidate.nextSibling;
213
+ }
214
+ return candidate;
215
+ }
216
+ findMentionAdjacentToCursor(direction) {
217
+ const selection = window.getSelection();
218
+ if (!selection?.isCollapsed || !selection.rangeCount) {
219
+ return null;
220
+ }
221
+ const range = selection.getRangeAt(0);
222
+ const node = this.resolveAdjacentNode(range.startContainer, range.startOffset, direction);
223
+ return MentionsInputComponent.isMention(node) ? node : null;
224
+ }
225
+ findBrAdjacentToCursor() {
226
+ const selection = window.getSelection();
227
+ if (!selection?.isCollapsed || !selection.rangeCount) {
228
+ return null;
229
+ }
230
+ const range = selection.getRangeAt(0);
231
+ const node = this.resolveAdjacentNode(range.startContainer, range.startOffset, 'before');
232
+ return node?.nodeName === 'BR' ? node : null;
233
+ }
234
+ extendSelectionAcrossMention(mention, direction) {
235
+ const selection = window.getSelection();
236
+ const parent = mention.parentNode;
237
+ if (!selection || !parent) {
238
+ return;
239
+ }
240
+ const index = Array.from(parent.childNodes).indexOf(mention);
241
+ selection.extend(parent, direction === 'before' ? index : index + 1);
242
+ }
243
+ placeCursorAdjacentToMention(mention, side) {
244
+ const parent = mention.parentNode;
245
+ if (!parent) {
246
+ return;
247
+ }
248
+ const sibling = side === 'before' ? mention.previousSibling : mention.nextSibling;
249
+ let zws;
250
+ if (sibling && MentionsInputComponent.isZws(sibling)) {
251
+ zws = sibling;
252
+ }
253
+ else {
254
+ zws = document.createTextNode(ZWS);
255
+ parent.insertBefore(zws, side === 'before' ? mention : mention.nextSibling);
256
+ }
257
+ const range = document.createRange();
258
+ range.setStart(zws, side === 'before' ? (zws.textContent || '').length : 0);
259
+ range.collapse(true);
260
+ const selection = window.getSelection();
261
+ selection?.removeAllRanges();
262
+ selection?.addRange(range);
263
+ }
264
+ removeMention(mention) {
265
+ const parent = mention.parentNode;
266
+ if (!parent) {
267
+ return;
268
+ }
269
+ // Empty text-node anchor preserves cursor position through the removal.
270
+ const anchor = document.createTextNode('');
271
+ parent.insertBefore(anchor, mention);
272
+ const prev = mention.previousSibling;
273
+ const next = mention.nextSibling;
274
+ if (prev && MentionsInputComponent.isZws(prev)) {
275
+ prev.remove();
276
+ }
277
+ if (next && MentionsInputComponent.isZws(next)) {
278
+ next.remove();
279
+ }
280
+ mention.remove();
281
+ const range = document.createRange();
282
+ range.setStart(anchor, 0);
283
+ range.collapse(true);
284
+ const selection = window.getSelection();
285
+ selection?.removeAllRanges();
286
+ selection?.addRange(range);
287
+ }
288
+ // Re-establishes the invariant: every mention has exactly one ZWS text
289
+ // node immediately before and after it, and there are no orphan ZWS-only
290
+ // text nodes anywhere else. Run after any operation that may disturb the
291
+ // tree (typing, paste, cut, delete) so cruft doesn't accumulate across
292
+ // repeated copy/paste cycles.
293
+ normalizeMentionPadding() {
294
+ const root = this.inputElement?.nativeElement;
295
+ if (!root) {
296
+ return;
297
+ }
298
+ // 1. Ensure each mention has a ZWS pad on both sides.
299
+ const mentions = Array.from(root.querySelectorAll('span[data-type="mention"]'));
300
+ for (const m of mentions) {
301
+ const parent = m.parentNode;
302
+ if (!parent) {
303
+ continue;
304
+ }
305
+ if (!m.previousSibling ||
306
+ !MentionsInputComponent.isZws(m.previousSibling)) {
307
+ parent.insertBefore(document.createTextNode(ZWS), m);
308
+ }
309
+ if (!m.nextSibling || !MentionsInputComponent.isZws(m.nextSibling)) {
310
+ parent.insertBefore(document.createTextNode(ZWS), m.nextSibling);
311
+ }
312
+ }
313
+ // 2. Remove any ZWS-only text node that isn't directly adjacent to a
314
+ // mention (orphans from line-break pads, leftover splits from previous
315
+ // paste insertions, duplicate pads from accumulated copy/paste cycles).
316
+ // Skip a node if the cursor currently lives in it — preserves caret
317
+ // position without needing manual restoration.
318
+ const selection = window.getSelection();
319
+ const cursorNode = selection?.rangeCount &&
320
+ root.contains(selection.getRangeAt(0).startContainer)
321
+ ? selection.getRangeAt(0).startContainer
322
+ : null;
323
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null);
324
+ const orphans = [];
325
+ while (walker.nextNode()) {
326
+ const node = walker.currentNode;
327
+ if (!MentionsInputComponent.isZws(node) || node === cursorNode) {
328
+ continue;
329
+ }
330
+ const adjacentToMention = MentionsInputComponent.isMention(node.previousSibling) ||
331
+ MentionsInputComponent.isMention(node.nextSibling);
332
+ if (!adjacentToMention) {
333
+ orphans.push(node);
334
+ }
335
+ }
336
+ for (const node of orphans) {
337
+ node.remove();
338
+ }
339
+ }
340
+ handleMentionsDropdownNav(event) {
341
+ const filteredUsers = this.getFilteredUsers();
342
+ if (filteredUsers.length === 0) {
343
+ this.closeMentions();
344
+ return;
345
+ }
346
+ switch (event.key) {
347
+ case 'ArrowDown':
348
+ event.preventDefault();
349
+ this.selectedUserIndex = Math.min(this.selectedUserIndex + 1, filteredUsers.length - 1);
350
+ this.cdr.markForCheck();
351
+ break;
352
+ case 'ArrowUp':
353
+ event.preventDefault();
354
+ this.selectedUserIndex = Math.max(this.selectedUserIndex - 1, 0);
355
+ this.cdr.markForCheck();
356
+ break;
357
+ case 'Enter':
358
+ case 'Tab':
359
+ event.preventDefault();
360
+ if (filteredUsers[this.selectedUserIndex]) {
361
+ this.selectUser(filteredUsers[this.selectedUserIndex]);
362
+ }
363
+ break;
364
+ case 'Escape':
365
+ event.preventDefault();
366
+ this.closeMentions();
367
+ break;
368
+ }
369
+ }
370
+ // ─── Insertion ─────────────────────────────────────────────────────────
150
371
  plainTextToNodes(text) {
151
372
  const nodes = [];
152
373
  const lines = text.split('\n');
@@ -160,49 +381,49 @@ export class MentionsInputComponent {
160
381
  });
161
382
  return nodes;
162
383
  }
384
+ // Create a temporary container to parse the HTML
163
385
  parsePastedHtml(html) {
164
386
  // Create a temporary container to parse the HTML
165
387
  const tempContainer = document.createElement('div');
166
388
  tempContainer.innerHTML = html;
167
389
  const nodes = [];
168
- const walkNodes = (node) => {
390
+ const walk = (node) => {
169
391
  if (node.nodeType === Node.ELEMENT_NODE) {
170
- const element = node;
392
+ const el = node;
171
393
  // DAHNE NOTE - we only want mention spans, br elements, and text
172
- if (element.tagName === 'SPAN' &&
173
- element.getAttribute('data-type') === 'mention' &&
174
- element.hasAttribute('data-id')) {
394
+ if (el.tagName === 'SPAN' &&
395
+ el.getAttribute('data-type') === 'mention' &&
396
+ el.hasAttribute('data-id')) {
175
397
  //Create mention to ultimately insert into the DOM
176
- const mentionSpan = document.createElement('span');
177
- mentionSpan.className = this.readonly
178
- ? 'readonly-mention'
179
- : 'mention';
180
- mentionSpan.setAttribute('data-id', element.getAttribute('data-id'));
181
- mentionSpan.setAttribute('data-type', 'mention');
182
- mentionSpan.setAttribute('contenteditable', 'false');
183
- mentionSpan.textContent = element.textContent;
184
- nodes.push(mentionSpan);
398
+ const span = document.createElement('span');
399
+ span.className = this.readonly ? 'readonly-mention' : 'mention';
400
+ span.setAttribute('data-id', el.getAttribute('data-id') || '');
401
+ span.setAttribute('data-type', 'mention');
402
+ span.setAttribute('contenteditable', 'false');
403
+ const raw = el.textContent || '';
404
+ span.textContent = raw.startsWith('@') ? raw : `@${raw}`;
405
+ nodes.push(span);
185
406
  }
186
- else if (element.tagName === 'BR') {
407
+ else if (el.tagName === 'BR') {
187
408
  // Preserve line breaks
188
409
  nodes.push(document.createElement('br'));
189
410
  }
190
411
  else {
191
412
  //Recursively look for nested children
192
- for (const child of Array.from(element.childNodes)) {
193
- walkNodes(child);
413
+ for (const child of Array.from(el.childNodes)) {
414
+ walk(child);
194
415
  }
195
416
  }
196
417
  }
197
418
  else if (node.nodeType === Node.TEXT_NODE) {
198
- const text = node.textContent || '';
419
+ const text = (node.textContent || '').replace(ZWS_REGEX, '');
199
420
  if (text) {
200
421
  nodes.push(document.createTextNode(text));
201
422
  }
202
423
  }
203
424
  };
204
425
  for (const child of Array.from(tempContainer.childNodes)) {
205
- walkNodes(child);
426
+ walk(child);
206
427
  }
207
428
  //DAHNE NOTE - the result here should be an array of text/span-mention/br nodes
208
429
  return nodes;
@@ -214,36 +435,43 @@ export class MentionsInputComponent {
214
435
  //Insert the parsed nodes from above, move range ends to after node
215
436
  //Then remove the range and reset it to move the cursor position to the end
216
437
  const selection = window.getSelection();
217
- if (!selection || !selection.rangeCount) {
438
+ if (!selection?.rangeCount) {
218
439
  return;
219
440
  }
220
441
  const range = selection.getRangeAt(0);
221
442
  range.deleteContents();
443
+ let cursorTarget = null;
222
444
  for (const node of nodes) {
223
- range.insertNode(node);
224
- range.setStartAfter(node);
225
- range.setEndAfter(node);
445
+ if (MentionsInputComponent.isMention(node)) {
446
+ const before = document.createTextNode(ZWS);
447
+ const after = document.createTextNode(ZWS);
448
+ range.insertNode(before);
449
+ range.setStartAfter(before);
450
+ range.insertNode(node);
451
+ range.setStartAfter(node);
452
+ range.insertNode(after);
453
+ range.setStartAfter(after);
454
+ cursorTarget = after;
455
+ }
456
+ else {
457
+ range.insertNode(node);
458
+ range.setStartAfter(node);
459
+ cursorTarget = node;
460
+ }
461
+ range.collapse(true);
226
462
  }
227
- selection.removeAllRanges();
228
- selection.addRange(range);
229
- }
230
- insertTextAtCursor(text) {
231
- const selection = window.getSelection();
232
- if (!selection || !selection.rangeCount) {
233
- return;
463
+ // After a mention, leave the cursor inside the trailing ZWS so ArrowLeft
464
+ // can step back to before-the-mention naturally.
465
+ if (cursorTarget && MentionsInputComponent.isZws(cursorTarget)) {
466
+ range.setStart(cursorTarget, 0);
467
+ range.collapse(true);
234
468
  }
235
- const range = selection.getRangeAt(0);
236
- range.deleteContents();
237
- const textNode = document.createTextNode(text);
238
- range.insertNode(textNode);
239
- range.setStartAfter(textNode);
240
- range.setEndAfter(textNode);
241
469
  selection.removeAllRanges();
242
470
  selection.addRange(range);
243
471
  }
244
472
  insertLineBreak() {
245
473
  const selection = window.getSelection();
246
- if (!selection || !selection.rangeCount) {
474
+ if (!selection?.rangeCount || !this.inputElement?.nativeElement) {
247
475
  return;
248
476
  }
249
477
  const range = selection.getRangeAt(0);
@@ -251,10 +479,19 @@ export class MentionsInputComponent {
251
479
  const br = document.createElement('br');
252
480
  range.insertNode(br);
253
481
  range.setStartAfter(br);
254
- range.setEndAfter(br);
482
+ range.collapse(true);
483
+ // A trailing <br> alone doesn't render an empty line in contenteditable —
484
+ // a ZWS gives the caret a place to land.
485
+ if (!br.nextSibling) {
486
+ const zws = document.createTextNode(ZWS);
487
+ range.insertNode(zws);
488
+ range.setStart(zws, 0);
489
+ range.collapse(true);
490
+ }
255
491
  selection.removeAllRanges();
256
492
  selection.addRange(range);
257
493
  }
494
+ // ─── Mention trigger / dropdown ────────────────────────────────────────
258
495
  checkForMentionTrigger() {
259
496
  const selection = window.getSelection();
260
497
  if (!selection || !selection.rangeCount || !this.inputElement) {
@@ -362,23 +599,8 @@ export class MentionsInputComponent {
362
599
  mentionSpan.setAttribute('data-type', 'mention');
363
600
  mentionSpan.setAttribute('contenteditable', 'false');
364
601
  mentionSpan.textContent = `@${user.name}`;
365
- //Find current cursor position
366
- const newRange = window.getSelection()?.getRangeAt(0);
367
- if (newRange) {
368
- newRange.insertNode(mentionSpan);
369
- //collapse range to position cursor after mention
370
- newRange.setStartAfter(mentionSpan);
371
- newRange.collapse(true);
372
- //Add a space after the mention
373
- const spaceNode = document.createTextNode('\u00A0');
374
- newRange.insertNode(spaceNode);
375
- //Position cursor after the space
376
- newRange.setStartAfter(spaceNode);
377
- newRange.collapse(true);
378
- selection.removeAllRanges();
379
- //Apply this range to the DOM
380
- selection.addRange(newRange);
381
- }
602
+ this.insertNodesAtCursor([mentionSpan, document.createTextNode(' ')]);
603
+ this.normalizeMentionPadding();
382
604
  this.closeMentions();
383
605
  this.emitContentChange();
384
606
  }
@@ -396,7 +618,6 @@ export class MentionsInputComponent {
396
618
  if (lastAtIndex === -1) {
397
619
  return;
398
620
  }
399
- //Knowing the position of the last '@' character we can now find the actual DOM node + offset where "@" lives
400
621
  const atPosition = this.findDomPositionAtCharIndex(lastAtIndex);
401
622
  if (!atPosition) {
402
623
  return;
@@ -410,8 +631,7 @@ export class MentionsInputComponent {
410
631
  isInsideMentionSpan(node) {
411
632
  let currentNode = node;
412
633
  while (currentNode && currentNode !== this.inputElement?.nativeElement) {
413
- if (currentNode.nodeType === Node.ELEMENT_NODE &&
414
- currentNode.getAttribute('data-type') === 'mention') {
634
+ if (MentionsInputComponent.isMention(currentNode)) {
415
635
  return true;
416
636
  }
417
637
  currentNode = currentNode.parentNode;
@@ -432,9 +652,7 @@ export class MentionsInputComponent {
432
652
  const text = node.textContent || '';
433
653
  // Check if our target character is in this text node
434
654
  if (charCount + text.length > charIndex) {
435
- // The character at charIndex is in this node
436
- const offsetInNode = charIndex - charCount;
437
- return { node, offset: offsetInNode };
655
+ return { node, offset: charIndex - charCount };
438
656
  }
439
657
  charCount += text.length;
440
658
  }
@@ -452,8 +670,7 @@ export class MentionsInputComponent {
452
670
  if (!this.inputElement) {
453
671
  return;
454
672
  }
455
- const contentItems = this.domToContentItems();
456
- this.contentChange.emit(contentItems);
673
+ this.contentChange.emit(this.domToContentItems());
457
674
  }
458
675
  domToContentItems() {
459
676
  if (!this.inputElement?.nativeElement) {
@@ -475,7 +692,8 @@ export class MentionsInputComponent {
475
692
  }
476
693
  }
477
694
  else if (node.nodeType === Node.TEXT_NODE) {
478
- const text = node.textContent || '';
695
+ // ZWS pads are a DOM affordance — they shouldn't leak into the data model.
696
+ const text = (node.textContent || '').replace(ZWS_REGEX, '');
479
697
  if (text) {
480
698
  items.push({ type: 'text', text });
481
699
  }
@@ -488,10 +706,10 @@ export class MentionsInputComponent {
488
706
  }
489
707
  }
490
708
  MentionsInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MentionsInputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
491
- MentionsInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MentionsInputComponent, selector: "riv-mentions-input", inputs: { content: "content", users: "users", readonly: "readonly", placeholder: "placeholder" }, outputs: { contentChange: "contentChange" }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["input"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"mentions-container\" #container>\n <div\n *ngIf=\"!readonly\"\n #input\n class=\"text-content editable\"\n contenteditable=\"true\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (paste)=\"onPaste($event)\"\n ></div>\n\n <div *ngIf=\"readonly\" #input class=\"text-content\"></div>\n\n <riv-callout\n *ngIf=\"!readonly && mentionsVisible && mentionAnchor\"\n [anchor]=\"mentionAnchor\"\n [isModal]=\"true\"\n [showCaret]=\"false\"\n [allowedPositions]=\"['bottom-right', 'top-right']\"\n [theme]=\"'light'\"\n (close)=\"onCalloutClose()\"\n >\n <div class=\"mentions-content\">\n <div class=\"mentions-header\">Mention someone</div>\n <div class=\"mentions-list\">\n <button\n *ngFor=\"let user of getFilteredUsers(); let i = index\"\n [class.selected]=\"i === selectedUserIndex\"\n (mouseenter)=\"onUserHover(i)\"\n (click)=\"selectUser(user)\"\n >\n {{ user.name }}\n </button>\n </div>\n </div>\n </riv-callout>\n</div>\n", styles: [".mentions-container{position:relative;width:100%}.mentions-input{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);color:var(--type-light-high-contrast);overflow-y:auto;white-space:pre-wrap;word-wrap:break-word}.mentions-input:empty:before{content:attr(data-placeholder);color:var(--type-light-disabled);pointer-events:none}.mentions-input:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.mentions-input[contenteditable=false]{color:var(--type-light-disabled);background-color:var(--surface-light-1);cursor:not-allowed}span.mention{color:var(--type-light-link);font-weight:var(--font-weight-heavy)}span.readonly-mention{font-weight:var(--font-weight-heavy)}.mentions-input.warning{border-color:var(--surface-dark-caution)}.mentions-input.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.mentions-input.large{font:var(--input-large);padding:var(--size-medium)}.mentions-list{margin:0;padding:0;max-height:calc(var(--base-grid-size) * 50);overflow-y:auto;display:flex;flex-direction:column;gap:var(--size-xxsmall)}.mentions-list button{padding:var(--size-small) var(--size-small);border-radius:var(--border-radius-medium);cursor:pointer;transition:background-color .2s;font:var(--input-medium);text-align:left}.mentions-list button:hover,.mentions-list button.selected{background-color:var(--surface-light-2)}.mentions-content{max-height:50vh;min-width:calc(var(--base-grid-size) * 62);max-width:50vw;padding:var(--size-large);display:flex;flex-direction:column}.mentions-header{padding:var(--size-small) var(--size-small);font:var(--input-medium);color:var(--type-light-low-contrast)}.text-content{width:100%;min-height:9em;border-radius:var(--border-radius-small);font:var(--input-medium);color:var(--type-light-high-contrast);padding:var(--size-large);resize:vertical}.editable{border:var(--border-width) solid var(--border-light);background-color:var(--surface-light-0)}.text-content::placeholder{color:var(--type-light-disabled)}.text-content.editable[data-placeholder]:empty:before{content:attr(data-placeholder);color:var(--type-light-disabled)}.text-content:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.text-content:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.text-content.warning{border-color:var(--surface-dark-caution)}.text-content.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.text-content.large{font:var(--input-large);padding:var(--size-medium)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
709
+ MentionsInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: MentionsInputComponent, selector: "riv-mentions-input", inputs: { content: "content", users: "users", readonly: "readonly", placeholder: "placeholder" }, outputs: { contentChange: "contentChange" }, viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["input"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"mentions-container\" #container>\n <div\n *ngIf=\"!readonly\"\n #input\n class=\"text-content editable\"\n contenteditable=\"true\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (paste)=\"onPaste($event)\"\n (copy)=\"onCopy($event)\"\n (cut)=\"onCut($event)\"\n ></div>\n\n <div *ngIf=\"readonly\" #input class=\"text-content\"></div>\n\n <riv-callout\n *ngIf=\"!readonly && mentionsVisible && mentionAnchor\"\n [anchor]=\"mentionAnchor\"\n [isModal]=\"true\"\n [showCaret]=\"false\"\n [allowedPositions]=\"['bottom-right', 'top-right']\"\n [theme]=\"'light'\"\n (close)=\"onCalloutClose()\"\n >\n <div class=\"mentions-content\">\n <div class=\"mentions-header\">Mention someone</div>\n <div class=\"mentions-list\">\n <button\n *ngFor=\"let user of getFilteredUsers(); let i = index\"\n [class.selected]=\"i === selectedUserIndex\"\n (mouseenter)=\"onUserHover(i)\"\n (click)=\"selectUser(user)\"\n >\n {{ user.name }}\n </button>\n </div>\n </div>\n </riv-callout>\n</div>\n", styles: [".mentions-container{position:relative;width:100%}.mentions-input{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);color:var(--type-light-high-contrast);overflow-y:auto;white-space:pre-wrap;word-wrap:break-word}.mentions-input:empty:before{content:attr(data-placeholder);color:var(--type-light-disabled);pointer-events:none}.mentions-input:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.mentions-input[contenteditable=false]{color:var(--type-light-disabled);background-color:var(--surface-light-1);cursor:not-allowed}span.mention{color:var(--type-light-link);font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}span.readonly-mention{font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}.mentions-input.warning{border-color:var(--surface-dark-caution)}.mentions-input.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.mentions-input.large{font:var(--input-large);padding:var(--size-medium)}.mentions-list{margin:0;padding:0;max-height:calc(var(--base-grid-size) * 50);overflow-y:auto;display:flex;flex-direction:column;gap:var(--size-xxsmall)}.mentions-list button{padding:var(--size-small) var(--size-small);border-radius:var(--border-radius-medium);cursor:pointer;transition:background-color .2s;font:var(--input-medium);text-align:left}.mentions-list button:hover,.mentions-list button.selected{background-color:var(--surface-light-2)}.mentions-content{max-height:50vh;min-width:calc(var(--base-grid-size) * 62);max-width:50vw;padding:var(--size-large);display:flex;flex-direction:column}.mentions-header{padding:var(--size-small) var(--size-small);font:var(--input-medium);color:var(--type-light-low-contrast)}.text-content{width:100%;min-height:9em;border-radius:var(--border-radius-small);font:var(--input-medium);color:var(--type-light-high-contrast);padding:var(--size-large);resize:vertical}.editable{border:var(--border-width) solid var(--border-light);background-color:var(--surface-light-0)}.text-content::placeholder{color:var(--type-light-disabled)}.text-content.editable[data-placeholder]:empty:before{content:attr(data-placeholder);color:var(--type-light-disabled)}.text-content:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.text-content:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.text-content.warning{border-color:var(--surface-dark-caution)}.text-content.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.text-content.large{font:var(--input-large);padding:var(--size-medium)}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.CalloutComponent, selector: "riv-callout", inputs: ["anchor", "isModal", "preferredPosition", "allowedPositions", "fallbackDirection", "showCaret", "theme"], outputs: ["close"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
492
710
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: MentionsInputComponent, decorators: [{
493
711
  type: Component,
494
- args: [{ selector: 'riv-mentions-input', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"mentions-container\" #container>\n <div\n *ngIf=\"!readonly\"\n #input\n class=\"text-content editable\"\n contenteditable=\"true\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (paste)=\"onPaste($event)\"\n ></div>\n\n <div *ngIf=\"readonly\" #input class=\"text-content\"></div>\n\n <riv-callout\n *ngIf=\"!readonly && mentionsVisible && mentionAnchor\"\n [anchor]=\"mentionAnchor\"\n [isModal]=\"true\"\n [showCaret]=\"false\"\n [allowedPositions]=\"['bottom-right', 'top-right']\"\n [theme]=\"'light'\"\n (close)=\"onCalloutClose()\"\n >\n <div class=\"mentions-content\">\n <div class=\"mentions-header\">Mention someone</div>\n <div class=\"mentions-list\">\n <button\n *ngFor=\"let user of getFilteredUsers(); let i = index\"\n [class.selected]=\"i === selectedUserIndex\"\n (mouseenter)=\"onUserHover(i)\"\n (click)=\"selectUser(user)\"\n >\n {{ user.name }}\n </button>\n </div>\n </div>\n </riv-callout>\n</div>\n", styles: [".mentions-container{position:relative;width:100%}.mentions-input{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);color:var(--type-light-high-contrast);overflow-y:auto;white-space:pre-wrap;word-wrap:break-word}.mentions-input:empty:before{content:attr(data-placeholder);color:var(--type-light-disabled);pointer-events:none}.mentions-input:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.mentions-input[contenteditable=false]{color:var(--type-light-disabled);background-color:var(--surface-light-1);cursor:not-allowed}span.mention{color:var(--type-light-link);font-weight:var(--font-weight-heavy)}span.readonly-mention{font-weight:var(--font-weight-heavy)}.mentions-input.warning{border-color:var(--surface-dark-caution)}.mentions-input.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.mentions-input.large{font:var(--input-large);padding:var(--size-medium)}.mentions-list{margin:0;padding:0;max-height:calc(var(--base-grid-size) * 50);overflow-y:auto;display:flex;flex-direction:column;gap:var(--size-xxsmall)}.mentions-list button{padding:var(--size-small) var(--size-small);border-radius:var(--border-radius-medium);cursor:pointer;transition:background-color .2s;font:var(--input-medium);text-align:left}.mentions-list button:hover,.mentions-list button.selected{background-color:var(--surface-light-2)}.mentions-content{max-height:50vh;min-width:calc(var(--base-grid-size) * 62);max-width:50vw;padding:var(--size-large);display:flex;flex-direction:column}.mentions-header{padding:var(--size-small) var(--size-small);font:var(--input-medium);color:var(--type-light-low-contrast)}.text-content{width:100%;min-height:9em;border-radius:var(--border-radius-small);font:var(--input-medium);color:var(--type-light-high-contrast);padding:var(--size-large);resize:vertical}.editable{border:var(--border-width) solid var(--border-light);background-color:var(--surface-light-0)}.text-content::placeholder{color:var(--type-light-disabled)}.text-content.editable[data-placeholder]:empty:before{content:attr(data-placeholder);color:var(--type-light-disabled)}.text-content:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.text-content:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.text-content.warning{border-color:var(--surface-dark-caution)}.text-content.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.text-content.large{font:var(--input-large);padding:var(--size-medium)}\n"] }]
712
+ args: [{ selector: 'riv-mentions-input', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"mentions-container\" #container>\n <div\n *ngIf=\"!readonly\"\n #input\n class=\"text-content editable\"\n contenteditable=\"true\"\n [attr.data-placeholder]=\"placeholder\"\n (input)=\"onInput()\"\n (keydown)=\"onKeyDown($event)\"\n (paste)=\"onPaste($event)\"\n (copy)=\"onCopy($event)\"\n (cut)=\"onCut($event)\"\n ></div>\n\n <div *ngIf=\"readonly\" #input class=\"text-content\"></div>\n\n <riv-callout\n *ngIf=\"!readonly && mentionsVisible && mentionAnchor\"\n [anchor]=\"mentionAnchor\"\n [isModal]=\"true\"\n [showCaret]=\"false\"\n [allowedPositions]=\"['bottom-right', 'top-right']\"\n [theme]=\"'light'\"\n (close)=\"onCalloutClose()\"\n >\n <div class=\"mentions-content\">\n <div class=\"mentions-header\">Mention someone</div>\n <div class=\"mentions-list\">\n <button\n *ngFor=\"let user of getFilteredUsers(); let i = index\"\n [class.selected]=\"i === selectedUserIndex\"\n (mouseenter)=\"onUserHover(i)\"\n (click)=\"selectUser(user)\"\n >\n {{ user.name }}\n </button>\n </div>\n </div>\n </riv-callout>\n</div>\n", styles: [".mentions-container{position:relative;width:100%}.mentions-input{width:100%;border:var(--border-width) solid var(--border-light);border-radius:var(--border-radius-small);color:var(--type-light-high-contrast);overflow-y:auto;white-space:pre-wrap;word-wrap:break-word}.mentions-input:empty:before{content:attr(data-placeholder);color:var(--type-light-disabled);pointer-events:none}.mentions-input:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.mentions-input[contenteditable=false]{color:var(--type-light-disabled);background-color:var(--surface-light-1);cursor:not-allowed}span.mention{color:var(--type-light-link);font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}span.readonly-mention{font-weight:var(--font-weight-heavy);white-space:nowrap;display:inline}.mentions-input.warning{border-color:var(--surface-dark-caution)}.mentions-input.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.mentions-input.large{font:var(--input-large);padding:var(--size-medium)}.mentions-list{margin:0;padding:0;max-height:calc(var(--base-grid-size) * 50);overflow-y:auto;display:flex;flex-direction:column;gap:var(--size-xxsmall)}.mentions-list button{padding:var(--size-small) var(--size-small);border-radius:var(--border-radius-medium);cursor:pointer;transition:background-color .2s;font:var(--input-medium);text-align:left}.mentions-list button:hover,.mentions-list button.selected{background-color:var(--surface-light-2)}.mentions-content{max-height:50vh;min-width:calc(var(--base-grid-size) * 62);max-width:50vw;padding:var(--size-large);display:flex;flex-direction:column}.mentions-header{padding:var(--size-small) var(--size-small);font:var(--input-medium);color:var(--type-light-low-contrast)}.text-content{width:100%;min-height:9em;border-radius:var(--border-radius-small);font:var(--input-medium);color:var(--type-light-high-contrast);padding:var(--size-large);resize:vertical}.editable{border:var(--border-width) solid var(--border-light);background-color:var(--surface-light-0)}.text-content::placeholder{color:var(--type-light-disabled)}.text-content.editable[data-placeholder]:empty:before{content:attr(data-placeholder);color:var(--type-light-disabled)}.text-content:disabled{color:var(--type-light-disabled);background-color:var(--surface-light-1)}.text-content:focus{outline:none;border:var(--border-width) solid var(--purp-60)}.text-content.warning{border-color:var(--surface-dark-caution)}.text-content.error{border-color:var(--surface-dark-danger);box-shadow:inset 0 0 0 var(--border-width-large) var(--surface-dark-danger)}.text-content.large{font:var(--input-large);padding:var(--size-medium)}\n"] }]
495
713
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { content: [{
496
714
  type: Input
497
715
  }], users: [{
@@ -524,4 +742,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
524
742
  }
525
743
  MentionsInputComponent.contentToPlainText = contentToPlainText;
526
744
  })(MentionsInputComponent || (MentionsInputComponent = {}));
527
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudGlvbnMtaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcml2L3NyYy9saWIvaW5wdXQvbWVudGlvbnMtaW5wdXQvbWVudGlvbnMtaW5wdXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcml2L3NyYy9saWIvaW5wdXQvbWVudGlvbnMtaW5wdXQvbWVudGlvbnMtaW5wdXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBRU4sU0FBUyxFQUNULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQzs7OztBQUV2Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUNHO0FBUUgsTUFBTSxPQUFPLHNCQUFzQjtJQUNqQyxZQUE2QixHQUFzQjtRQUF0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUUxQyxZQUFPLEdBQXlDLEVBQUUsQ0FBQztRQUNuRCxVQUFLLEdBQWtDLEVBQUUsQ0FBQztRQUMxQyxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGdCQUFXLEdBQVcsZUFBZSxDQUFDO1FBRTVCLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBRWhELENBQUM7UUFLSixvQkFBZSxHQUFHLEtBQUssQ0FBQztRQUN4QixzQkFBaUIsR0FBRyxFQUFFLENBQUM7UUFDdkIsa0JBQWEsR0FBbUIsSUFBSSxDQUFDO1FBQ3JDLHNCQUFpQixHQUFHLENBQUMsQ0FBQztRQUNkLGVBQVUsR0FBaUIsSUFBSSxDQUFDO0lBbEJjLENBQUM7SUFvQnZELGVBQWU7UUFDYixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVELDZJQUE2STtJQUM3SSx3SUFBd0k7SUFDeEksV0FBVyxDQUFDLE9BQXNCO1FBQ2hD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b250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICogQSByaWNoIHRleHQgaW5wdXQgY29tcG9uZW50IHRoYXQgYWxsb3dzIHVzZXJzIHRvIHR5cGUgdGV4dCBhbmQgbWVudGlvbiBvdGhlciB1c2VycyBieSB0eXBpbmcgYEBgIGZvbGxvd2VkIGJ5IGEgbmFtZS5cbiAqIFVzZXMgYSBgY29udGVudGVkaXRhYmxlYCBkaXYgaW5zdGVhZCBvZiBhIHRyYWRpdGlvbmFsIGlucHV0L3RleHRhcmVhLlxuICpcbiAqICMjIERhdGEgTW9kZWxcbiAqIFdvcmtzIHdpdGggYSBzdHJ1Y3R1cmVkIGNvbnRlbnQgbW9kZWwgcmF0aGVyIHRoYW4gcGxhaW4gc3RyaW5nczpcbiAqIC0gKipJbnB1dC9PdXRwdXQqKjogYENvbnRlbnRJdGVtW11gIC0gYW4gYXJyYXkgb2YgY29udGVudCBwaWVjZXNcbiAqIC0gKipDb250ZW50SXRlbSB0eXBlcyoqOlxuICogICAtIGBVc2VyTWVudGlvbmA6IGB7IHR5cGU6ICdtZW50aW9uJywgaWQ6IG51bWJlciwgbmFtZTogc3RyaW5nIH1gXG4gKiAgIC0gYFRleHRgOiBgeyB0eXBlOiAndGV4dCcsIHRleHQ6IHN0cmluZyB9YFxuICpcbiAqICMjIFJlbmRlcmluZyBGbG93XG4gKiAxLiAqKkNvbnRlbnQg4oaSIERPTSoqOiBgcmVuZGVyQ29udGVudCgpYCBjb252ZXJ0cyB0aGUgY29udGVudCBpbnB1dCBhcnJheSB0byBIVE1MLiBNZW50aW9ucyBiZWNvbWUgYDxzcGFuPmAgZWxlbWVudHMgd2l0aCBgZGF0YS1pZGAgYW5kIGBkYXRhLXR5cGVgIGF0dHJpYnV0ZXMuIFRleHQgaXMgZXNjYXBlZCBhbmQgcmVuZGVyZWQgYXMgcGxhaW4gdGV4dC5cbiAqIDIuICoqRE9NIOKGkiBDb250ZW50Kio6IGBkb21Ub0NvbnRlbnRJdGVtcygpYCBwYXJzZXMgdGhlIERPTSBiYWNrIGludG8gYENvbnRlbnRJdGVtW11gLCB3YWxraW5nIHRocm91Z2ggY2hpbGQgbm9kZXMgZXh0cmFjdGluZyBtZW50aW9ucyBhbmQgdGV4dC4gRW1pdHRlZCB2aWEgYGNvbnRlbnRDaGFuZ2VgIGV2ZW50IG9uIGlucHV0LlxuICpcbiAqICMjIFVzZXIgSW50ZXJhY3Rpb25cbiAqIC0gKipUeXBpbmcgYEBgIHRyaWdnZXJzIG1lbnRpb25zKio6IE1vbml0b3JzIGlucHV0IGZvciBgQGAgY2hhcmFjdGVyLCBleHRyYWN0cyB0ZXh0IGFmdGVyIGBAYCAodXAgdG8gZmlyc3Qgc3BhY2UpIGFzIHNlYXJjaCB0ZXh0LCBwb3NpdGlvbnMgYSBjYWxsb3V0IGRyb3Bkb3duIGF0IHRoZSBjdXJzb3IgbG9jYXRpb25cbiAqIC0gKipLZXlib2FyZCBuYXZpZ2F0aW9uKio6IEFycm93IGtleXMgbmF2aWdhdGUgZmlsdGVyZWQgdXNlcnMgbGlzdCwgRW50ZXIgc2VsZWN0cyBoaWdobGlnaHRlZCB1c2VyLCBFc2NhcGUgY2xvc2VzIG1lbnRpb25zIGRyb3Bkb3duXG4gKiAtICoqU2VsZWN0aW5nIGEgbWVudGlvbioqOiBEZWxldGVzIHRoZSBgQGAgYW5kIHNlYXJjaCB0ZXh0IGZyb20gRE9NLCBjcmVhdGVzIGEgbm9uLWVkaXRhYmxlIGA8c3Bhbj5gIGVsZW1lbnQgZm9yIHRoZSBtZW50aW9uLCBpbnNlcnRzIGF0IGN1cnNvciBwb3NpdGlvbiwgcmVwb3NpdGlvbnMgY3Vyc29yIGFmdGVyIHRoZSBtZW50aW9uXG4gKlxuICogIyMgVGVjaG5pY2FsIERldGFpbHNcbiAqIC0gKipDdXJzb3IgbWFuYWdlbWVudCoqOiBVc2VzIFNlbGVjdGlvbiBBUEkgYW5kIFJhbmdlIG9iamVjdHMgdG8gdHJhY2svbWFuaXB1bGF0ZSBjdXJzb3IgcG9zaXRpb25cbiAqIC0gKipUZXh0IGV4dHJhY3Rpb24qKjogYGdldFRleHRCZWZvcmVDdXJzb3IoKWAgZ2V0cyBwbGFpbiB0ZXh0IGJlZm9yZSBjdXJzb3IsIHRyZWF0aW5nIG1lbnRpb24gc3BhbnMgYXMgYEBuYW1lYFxuICogLSAqKkNoYXJhY3RlciBwb3NpdGlvbiBtYXBwaW5nKio6IGBmaW5kRG9tUG9zaXRpb25BdENoYXJJbmRleCgpYCBjb252ZXJ0cyBjaGFyYWN0ZXIgaW5kaWNlcyB0byBET00gbm9kZSBwb3NpdGlvbnMgdXNpbmcgVHJlZVdhbGtlclxuICogLSAqKkNoYW5nZSBkZXRlY3Rpb24qKjogVXNlcyBPblB1c2ggd2l0aCBtYW51YWwgYG1hcmtGb3JDaGVjaygpYCBjYWxsc1xuICogLSAqKlJlYWRvbmx5IG1vZGUqKjogU3dhcHMgYmV0d2VlbiBjb250ZW50ZWRpdGFibGUgYW5kIG5vbi1lZGl0YWJsZSBkaXZzLCBzdHlsZXMgbWVudGlvbnMgZGlmZmVyZW50bHlcbiAqXG4gKiAjIyBTdGF0ZVxuICogLSBgbWVudGlvbnNWaXNpYmxlYDogY29udHJvbHMgZHJvcGRvd24gdmlzaWJpbGl0eVxuICogLSBgbWVudGlvblNlYXJjaFRleHRgOiBjdXJyZW50IGZpbHRlciB0ZXh0IGFmdGVyIEBcbiAqIC0gYG1lbnRpb25BbmNob3JgOiBET01SZWN0IGZvciBwb3NpdGlvbmluZyBkcm9wZG93blxuICogLSBgc2VsZWN0ZWRVc2VySW5kZXhgOiBrZXlib2FyZCBuYXZpZ2F0aW9uIHN0YXRlXG4gKiAtIGBzYXZlZFJhbmdlYDogcHJlc2VydmVzIGN1cnNvciBwb3NpdGlvbiBmb3IgY2xpY2stYmFzZWQgc2VsZWN0aW9uXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3Jpdi1tZW50aW9ucy1pbnB1dCcsXG4gIHRlbXBsYXRlVXJsOiBgLi9tZW50aW9ucy1pbnB1dC5jb21wb25lbnQuaHRtbGAsXG4gIHN0eWxlVXJsczogWycuL21lbnRpb25zLWlucHV0LmNvbXBvbmVudC5jc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIE1lbnRpb25zSW5wdXRDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XG5cbiAgQElucHV0KCkgY29udGVudDogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Db250ZW50SXRlbVtdID0gW107XG4gIEBJbnB1dCgpIHVzZXJzOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LlVzZXJbXSA9IFtdO1xuICBASW5wdXQoKSByZWFkb25seSA9IGZhbHNlO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nID0gJ0FkZCBhIGNvbW1lbnQnO1xuXG4gIEBPdXRwdXQoKSByZWFkb25seSBjb250ZW50Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxcbiAgICBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRJdGVtW11cbiAgPigpO1xuXG4gIEBWaWV3Q2hpbGQoJ2lucHV0JywgeyBzdGF0aWM6IGZhbHNlIH0pXG4gIHByaXZhdGUgcmVhZG9ubHkgaW5wdXRFbGVtZW50PzogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgbWVudGlvbnNWaXNpYmxlID0gZmFsc2U7XG4gIG1lbnRpb25TZWFyY2hUZXh0ID0gJyc7XG4gIG1lbnRpb25BbmNob3I6IERPTVJlY3QgfCBudWxsID0gbnVsbDtcbiAgc2VsZWN0ZWRVc2VySW5kZXggPSAwO1xuICBwcml2YXRlIHNhdmVkUmFuZ2U6IFJhbmdlIHwgbnVsbCA9IG51bGw7XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyQ29udGVudCgpO1xuICB9XG5cbiAgLy9EQUhORSBOT1RFIC0gbmdPbkNoYW5nZXMgaXMgY2FsbGVkIHdoZW5ldmVyIGFueSBASW5wdXQoKSBwcm9wZXJ0eSBjaGFuZ2VzLCB3aGVyZSB0aGUgY2hhbmdlZCBpbnB1dCBjb250YWlucyBpbmZvcm1hdGlvbiBhYm91dCB0aG9zZSBjaGFuZ2VzXG4gIC8vU28gaWYgQElucHV0KCkgY29udGVudCBjaGFuZ2VzIGFuZCBpdCdzIG5vdCB0aGUgZmlyc3QgY2hhbmdlICh0aGUgZmlyc3QgcmVuZGVyIGlzIGhhbmRsZWQgYnkgbmdBZnRlclZpZXdJbml0KCkpLCB3ZSByZW5kZXIgdGhlIGNvbnRlbnRcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydjb250ZW50J10gJiYgIWNoYW5nZXNbJ2NvbnRlbnQnXS5maXJzdENoYW5nZSkge1xuICAgICAgdGhpcy5yZW5kZXJDb250ZW50KCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJDb250ZW50KCk6IHZvaWQge1xuICAgIC8vVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSB0aGUgQFZpZXdDaGlsZCByZWZlcmVuY2UgaXNuJ3QgYXZhaWxhYmxlIHVudGlsIGFmdGVyIHRoZSB2aWV3IGluaXRpYWxpemVzXG4gICAgaWYgKCF0aGlzLmlucHV0RWxlbWVudD8ubmF0aXZlRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGh0bWwgPSB0aGlzLmNvbnRlbnRcbiAgICAgIC5tYXAoaXRlbSA9PlxuICAgICAgICBNZW50aW9uc0lucHV0Q29tcG9uZW50LmNvbnRlbnRJdGVtVG9IdG1sKGl0ZW0sIHRoaXMucmVhZG9ubHkpLFxuICAgICAgKVxuICAgICAgLmpvaW4oJycpO1xuICAgIHRoaXMuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbDtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGNvbnRlbnRJdGVtVG9IdG1sKFxuICAgIGl0ZW06IE1lbnRpb25zSW5wdXRDb21wb25lbnQuQ29udGVudEl0ZW0sXG4gICAgcmVhZG9ubHk6IGJvb2xlYW4sXG4gICk6IHN0cmluZyB7XG4gICAgc3dpdGNoIChpdGVtLnR5cGUpIHtcbiAgICAgIC8vREFITkUgVE9ETyAtIG1heWJlIHdlIGVzY2FwZSBIVE1MIGhlcmUgdG9vPyBBbHRob3VnaCBJIGRvbid0IHRoaW5rIGl0IHdpbGwgYmUgcG9zc2libGUgZm9yIHVzZXJzIHRvIGlucHV0IGFuIFhTUyBhdHRhY2sgaW4gaXRlbS5uYW1lXG4gICAgICBjYXNlICdtZW50aW9uJzpcbiAgICAgICAgcmV0dXJuIGA8c3BhbiBjbGFzcz1cIiR7XG4gICAgICAgICAgcmVhZG9ubHkgPyAncmVhZG9ubHktbWVudGlvbicgOiAnbWVudGlvbidcbiAgICAgICAgfVwiIGRhdGEtaWQ9XCIke1xuICAgICAgICAgIGl0ZW0uaWRcbiAgICAgICAgfVwiIGRhdGEtdHlwZT1cIm1lbnRpb25cIiBjb250ZW50ZWRpdGFibGU9XCJmYWxzZVwiPkAke01lbnRpb25zSW5wdXRDb21wb25lbnQuZXNjYXBlSHRtbChcbiAgICAgICAgICBpdGVtLm5hbWUsXG4gICAgICAgICl9PC9zcGFuPmA7XG4gICAgICBjYXNlICd0ZXh0JzpcbiAgICAgICAgcmV0dXJuIE1lbnRpb25zSW5wdXRDb21wb25lbnQuZXNjYXBlSHRtbChpdGVtLnRleHQpO1xuICAgICAgY2FzZSAnbmV3bGluZSc6XG4gICAgICAgIHJldHVybiAnPGJyPic7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZXNjYXBlSHRtbCh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi50ZXh0Q29udGVudCA9IHRleHQ7XG4gICAgcmV0dXJuIGRpdi5pbm5lckhUTUw7XG4gIH1cblxuICBvbklucHV0KCk6IHZvaWQge1xuICAgIHRoaXMuY2hlY2tGb3JNZW50aW9uVHJpZ2dlcigpO1xuICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgfVxuXG4gIG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1lbnRpb25zVmlzaWJsZSkge1xuICAgICAgY29uc3QgZmlsdGVyZWRVc2VycyA9IHRoaXMuZ2V0RmlsdGVyZWRVc2VycygpO1xuICAgICAgaWYgKGZpbHRlcmVkVXNlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMuY2xvc2VNZW50aW9ucygpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHN3aXRjaCAoZXZlbnQua2V5KSB7XG4gICAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkVXNlckluZGV4ID0gTWF0aC5taW4oXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkVXNlckluZGV4ICsgMSxcbiAgICAgICAgICAgIGZpbHRlcmVkVXNlcnMubGVuZ3RoIC0gMSxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdBcnJvd1VwJzpcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSBNYXRoLm1heCh0aGlzLnNlbGVjdGVkVXNlckluZGV4IC0gMSwgMCk7XG4gICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0VudGVyJzpcbiAgICAgICAgY2FzZSAnVGFiJzpcbiAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIGlmIChmaWx0ZXJlZFVzZXJzW3RoaXMuc2VsZWN0ZWRVc2VySW5kZXhdKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdFVzZXIoZmlsdGVyZWRVc2Vyc1t0aGlzLnNlbGVjdGVkVXNlckluZGV4XSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdFc2NhcGUnOlxuICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy9IYW5kbGUgbmV3bGluZXMgd2hlbiBtZW50aW9ucyBhcmVuJ3QgdmlzaWJsZVxuICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLmluc2VydExpbmVCcmVhaygpO1xuICAgICAgdGhpcy5lbWl0Q29udGVudENoYW5nZSgpO1xuICAgIH1cbiAgfVxuXG4gIG9uUGFzdGUoZXZlbnQ6IENsaXBib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIGlmICghZXZlbnQuY2xpcGJvYXJkRGF0YSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vTG9vayBmb3IgSFRNTCBmaXJzdFxuICAgIGNvbnN0IGh0bWwgPSBldmVudC5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQvaHRtbCcpO1xuICAgIGNvbnN0IHBsYWluVGV4dCA9IGV2ZW50LmNsaXBib2FyZERhdGEuZ2V0RGF0YSgndGV4dC9wbGFpbicpO1xuXG4gICAgaWYgKGh0bWwgJiYgaHRtbC5pbmNsdWRlcygnZGF0YS10eXBlPVwibWVudGlvblwiJykpIHtcbiAgICAgIGNvbnN0IHNhbml0aXplZE5vZGVzID0gdGhpcy5wYXJzZVBhc3RlZEh0bWwoaHRtbCk7XG5cbiAgICAgIHRoaXMuaW5zZXJ0Tm9kZXNBdEN1cnNvcihzYW5pdGl6ZWROb2Rlcyk7XG4gICAgfSBlbHNlIGlmIChwbGFpblRleHQpIHtcbiAgICAgIGNvbnN0IG5vZGVzID0gdGhpcy5wbGFpblRleHRUb05vZGVzKHBsYWluVGV4dCk7XG4gICAgICB0aGlzLmluc2VydE5vZGVzQXRDdXJzb3Iobm9kZXMpO1xuICAgIH1cblxuICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgcGxhaW5UZXh0VG9Ob2Rlcyh0ZXh0OiBzdHJpbmcpOiBOb2RlW10ge1xuICAgIGNvbnN0IG5vZGVzOiBOb2RlW10gPSBbXTtcbiAgICBjb25zdCBsaW5lcyA9IHRleHQuc3BsaXQoJ1xcbicpO1xuXG4gICAgbGluZXMuZm9yRWFjaCgobGluZSwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChsaW5lKSB7XG4gICAgICAgIG5vZGVzLnB1c2goZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobGluZSkpO1xuICAgICAgfVxuICAgICAgaWYgKGluZGV4IDwgbGluZXMubGVuZ3RoIC0gMSkge1xuICAgICAgICBub2Rlcy5wdXNoKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2JyJykpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG5vZGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVBhc3RlZEh0bWwoaHRtbDogc3RyaW5nKTogTm9kZVtdIHtcbiAgICAvLyBDcmVhdGUgYSB0ZW1wb3JhcnkgY29udGFpbmVyIHRvIHBhcnNlIHRoZSBIVE1MXG4gICAgY29uc3QgdGVtcENvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIHRlbXBDb250YWluZXIuaW5uZXJIVE1MID0gaHRtbDtcblxuICAgIGNvbnN0IG5vZGVzOiBOb2RlW10gPSBbXTtcblxuICAgIGNvbnN0IHdhbGtOb2RlcyA9IChub2RlOiBOb2RlKTogdm9pZCA9PiB7XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IG5vZGUgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIC8vIERBSE5FIE5PVEUgLSB3ZSBvbmx5IHdhbnQgbWVudGlvbiBzcGFucywgYnIgZWxlbWVudHMsIGFuZCB0ZXh0XG4gICAgICAgIGlmIChcbiAgICAgICAgICBlbGVtZW50LnRhZ05hbWUgPT09ICdTUEFOJyAmJlxuICAgICAgICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXR5cGUnKSA9PT0gJ21lbnRpb24nICYmXG4gICAgICAgICAgZWxlbWVudC5oYXNBdHRyaWJ1dGUoJ2RhdGEtaWQnKVxuICAgICAgICApIHtcbiAgICAgICAgICAvL0NyZWF0ZSBtZW50aW9uIHRvIHVsdGltYXRlbHkgaW5zZXJ0IGludG8gdGhlIERPTVxuICAgICAgICAgIGNvbnN0IG1lbnRpb25TcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgICAgICAgIG1lbnRpb25TcGFuLmNsYXNzTmFtZSA9IHRoaXMucmVhZG9ubHlcbiAgICAgICAgICAgID8gJ3JlYWRvbmx5LW1lbnRpb24nXG4gICAgICAgICAgICA6ICdtZW50aW9uJztcbiAgICAgICAgICBtZW50aW9uU3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnLCBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1pZCcpISk7XG4gICAgICAgICAgbWVudGlvblNwYW4uc2V0QXR0cmlidXRlKCdkYXRhLXR5cGUnLCAnbWVudGlvbicpO1xuICAgICAgICAgIG1lbnRpb25TcGFuLnNldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJywgJ2ZhbHNlJyk7XG4gICAgICAgICAgbWVudGlvblNwYW4udGV4dENvbnRlbnQgPSBlbGVtZW50LnRleHRDb250ZW50O1xuICAgICAgICAgIG5vZGVzLnB1c2gobWVudGlvblNwYW4pO1xuICAgICAgICB9IGVsc2UgaWYgKGVsZW1lbnQudGFnTmFtZSA9PT0gJ0JSJykge1xuICAgICAgICAgIC8vIFByZXNlcnZlIGxpbmUgYnJlYWtzXG4gICAgICAgICAgbm9kZXMucHVzaChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdicicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvL1JlY3Vyc2l2ZWx5IGxvb2sgZm9yIG5lc3RlZCBjaGlsZHJlblxuICAgICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgQXJyYXkuZnJvbShlbGVtZW50LmNoaWxkTm9kZXMpKSB7XG4gICAgICAgICAgICB3YWxrTm9kZXMoY2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgICBjb25zdCB0ZXh0ID0gbm9kZS50ZXh0Q29udGVudCB8fCAnJztcbiAgICAgICAgaWYgKHRleHQpIHtcbiAgICAgICAgICBub2Rlcy5wdXNoKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIEFycmF5LmZyb20odGVtcENvbnRhaW5lci5jaGlsZE5vZGVzKSkge1xuICAgICAgd2Fsa05vZGVzKGNoaWxkKTtcbiAgICB9XG5cbiAgICAvL0RBSE5FIE5PVEUgLSB0aGUgcmVzdWx0IGhlcmUgc2hvdWxkIGJlIGFuIGFycmF5IG9mIHRleHQvc3Bhbi1tZW50aW9uL2JyIG5vZGVzXG4gICAgcmV0dXJuIG5vZGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnROb2Rlc0F0Q3Vyc29yKG5vZGVzOiBOb2RlW10pOiB2b2lkIHtcbiAgICAvL0dldCBzZWxlY3Rpb24gb2JqZWN0LCByZXByZXNlbnRpbmcgdXNlciBjdXJzb3IgcG9zaXRpb24vc2VsZWN0aW9uXG4gICAgLy9HZXQgUmFuZ2Ugb2JqZWN0IGF0IHN0YXJ0IG9mIHNlbGVjdGlvbiwgd2hpY2ggc2hvdWxkIHJlcHJlc2VudCBjdXJzb3IgcG9zaXRpb25cbiAgICAvL0lmIHRoZXJlIGlzIGEgc2VsZWN0aW9uLCBkZWxldGUgaXRcbiAgICAvL0luc2VydCB0aGUgcGFyc2VkIG5vZGVzIGZyb20gYWJvdmUsIG1vdmUgcmFuZ2UgZW5kcyB0byBhZnRlciBub2RlXG4gICAgLy9UaGVuIHJlbW92ZSB0aGUgcmFuZ2UgYW5kIHJlc2V0IGl0IHRvIG1vdmUgdGhlIGN1cnNvciBwb3NpdGlvbiB0byB0aGUgZW5kXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsZWN0aW9uIHx8ICFzZWxlY3Rpb24ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG4gICAgcmFuZ2UuZGVsZXRlQ29udGVudHMoKTtcblxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBub2Rlcykge1xuICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShub2RlKTtcbiAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobm9kZSk7XG4gICAgICByYW5nZS5zZXRFbmRBZnRlcihub2RlKTtcbiAgICB9XG5cbiAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgc2VsZWN0aW9uLmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5zZXJ0VGV4dEF0Q3Vyc29yKHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbiB8fCAhc2VsZWN0aW9uLnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIHJhbmdlLmRlbGV0ZUNvbnRlbnRzKCk7XG5cbiAgICBjb25zdCB0ZXh0Tm9kZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpO1xuICAgIHJhbmdlLmluc2VydE5vZGUodGV4dE5vZGUpO1xuICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIodGV4dE5vZGUpO1xuICAgIHJhbmdlLnNldEVuZEFmdGVyKHRleHROb2RlKTtcblxuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnRMaW5lQnJlYWsoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsZWN0aW9uIHx8ICFzZWxlY3Rpb24ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG4gICAgcmFuZ2UuZGVsZXRlQ29udGVudHMoKTtcblxuICAgIGNvbnN0IGJyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYnInKTtcbiAgICByYW5nZS5pbnNlcnROb2RlKGJyKTtcbiAgICByYW5nZS5zZXRTdGFydEFmdGVyKGJyKTtcbiAgICByYW5nZS5zZXRFbmRBZnRlcihicik7XG5cbiAgICBzZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgc2VsZWN0aW9uLmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIHByaXZhdGUgY2hlY2tGb3JNZW50aW9uVHJpZ2dlcigpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXNlbGVjdGlvbi5yYW5nZUNvdW50IHx8ICF0aGlzLmlucHV0RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG4gICAgY29uc3QgdGV4dEJlZm9yZUN1cnNvciA9IHRoaXMuZ2V0VGV4dEJlZm9yZUN1cnNvcihyYW5nZSk7XG5cbiAgICBjb25zdCBsYXN0QXRJbmRleCA9IHRleHRCZWZvcmVDdXJzb3IubGFzdEluZGV4T2YoJ0AnKTtcblxuICAgIGlmIChsYXN0QXRJbmRleCA9PT0gLTEpIHtcbiAgICAgIHRoaXMuY2xvc2VNZW50aW9ucygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vSWYgd2UgYWxsb3cgZm9yIGEgc2luZ2xlIHNwYWNlLCB3ZSBuZWVkIHRvIGNoZWNrIHRvIG1ha2Ugc3VyZSB0aGF0IHRoaXMgbG9naWMgd29uJ3QgcGljayB1cCBwcmV2aW91c1xuICAgIC8vJ0AnIG1lbnRpb25zIGFuZCBrZWVwIHRoZSBtZW50aW9uIGRyb3Bkb3duIG9wZW5cbiAgICBjb25zdCBhdFBvc2l0aW9uID0gdGhpcy5maW5kRG9tUG9zaXRpb25BdENoYXJJbmRleChsYXN0QXRJbmRleCk7XG4gICAgaWYgKGF0UG9zaXRpb24gJiYgdGhpcy5pc0luc2lkZU1lbnRpb25TcGFuKGF0UG9zaXRpb24ubm9kZSkpIHtcbiAgICAgIHRoaXMuY2xvc2VNZW50aW9ucygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHRleHRBZnRlckF0ID0gdGV4dEJlZm9yZUN1cnNvci5zdWJzdHJpbmcobGFzdEF0SW5kZXggKyAxKTtcbiAgICBjb25zdCBjaGFyMSA9IHRleHRBZnRlckF0LmNoYXJDb2RlQXQoMCk7XG4gICAgY29uc3QgY2hhck4gPSB0ZXh0QWZ0ZXJBdC5jaGFyQ29kZUF0KHRleHRBZnRlckF0Lmxlbmd0aCAtIDEpO1xuICAgIGNvbnN0IGNoYXJOXzEgPSB0ZXh0QWZ0ZXJBdC5jaGFyQ29kZUF0KHRleHRBZnRlckF0Lmxlbmd0aCAtIDIpO1xuICAgIC8vVGhlc2UgYXJlIHRoZSBVbmljb2RlIHJlcHJlc2VudGF0aW9ucyBvZiBub3JtYWwgc3BhY2UgYW5kIG5vbi1icmVha2luZyBzcGFjZVxuICAgIGNvbnN0IHVuaWNvZGVTcGFjZUNoYXJzID0gWzMyLCAxNjBdO1xuXG4gICAgLy8gQ2xvc2UgbWVudGlvbnMgaWY6XG4gICAgLy8gLSBUaGVyZSdzIGEgZG91YmxlIHNwYWNlIChhbGxvd3Mgc2luZ2xlIHNwYWNlcyBpbiB0aGUgbWlkZGxlIG9mIHNlYXJjaClcbiAgICAvLyAtIFRoZSB0ZXh0IHN0YXJ0cyB3aXRoIGEgc3BhY2UgKHR5cGluZyBcIkAgXCIgc2hvdWxkIG5vdCB0cmlnZ2VyIG1lbnRpb25zKVxuICAgIGlmIChcbiAgICAgIHRleHRBZnRlckF0LmluY2x1ZGVzKCcgICcpIHx8XG4gICAgICB0ZXh0QWZ0ZXJBdC5zdGFydHNXaXRoKCcgJykgfHxcbiAgICAgIGNoYXIxID09IDE2MCB8fFxuICAgICAgKHVuaWNvZGVTcGFjZUNoYXJzLmluY2x1ZGVzKGNoYXJOKSAmJiB1bmljb2RlU3BhY2VDaGFycy5pbmNsdWRlcyhjaGFyTl8xKSlcbiAgICApIHtcbiAgICAgIHRoaXMuY2xvc2VNZW50aW9ucygpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFRyaW0gdHJhaWxpbmcvbGVhZGluZyBzcGFjZXMgZnJvbSBzZWFyY2ggdGV4dCB3aGlsZSBwcmVzZXJ2aW5nIHNwYWNlcyBpbiB0aGUgbWlkZGxlXG4gICAgdGhpcy5tZW50aW9uU2VhcmNoVGV4dCA9IHRleHRBZnRlckF0LnRyaW0oKTtcblxuICAgIC8vIE9ubHkgc2hvdyBtZW50aW9ucyBpZiB0aGVyZSBhcmUgZmlsdGVyZWQgdXNlcnNcbiAgICBjb25zdCBmaWx0ZXJlZFVzZXJzID0gdGhpcy5nZXRGaWx0ZXJlZFVzZXJzKCk7XG4gICAgaWYgKGZpbHRlcmVkVXNlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLm1lbnRpb25zVmlzaWJsZSA9IHRydWU7XG4gICAgdGhpcy5zZWxlY3RlZFVzZXJJbmRleCA9IDA7XG5cbiAgICAvL1NhdmUgdGhlIGN1cnJlbnQgcmFuZ2UgZm9yIGxhdGVyIHJlc3RvcmF0aW9uIChuZWVkZWQgZm9yIGNsaWNrIHNlbGVjdGlvbilcbiAgICAvL0RBSE5FIE5PVEUgLSB0aGlzIGlzIGFubm95aW5nbHkgbmVjZWVzc2FyeSBiZWNhdXNlIGNsaWNrcyBhbmQgZW50ZXIga2V5cyBoYXZlIGRpZmZlcmVudCBlZmZlY3RzIG9uIHRoZVxuICAgIC8vZm9jdXMgb2YgdGhlIGNvbnRlbnRlZGl0YWJsZSBkaXZcbiAgICB0aGlzLnNhdmVkUmFuZ2UgPSByYW5nZS5jbG9uZVJhbmdlKCk7XG5cbiAgICBpZiAoYXRQb3NpdGlvbikge1xuICAgICAgY29uc3QgYXRSYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgICBhdFJhbmdlLnNldFN0YXJ0KGF0UG9zaXRpb24ubm9kZSwgYXRQb3NpdGlvbi5vZmZzZXQpO1xuICAgICAgYXRSYW5nZS5zZXRFbmQoYXRQb3NpdGlvbi5ub2RlLCBhdFBvc2l0aW9uLm9mZnNldCArIDEpO1xuICAgICAgdGhpcy5tZW50aW9uQW5jaG9yID0gYXRSYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB9XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGdldFRleHRCZWZvcmVDdXJzb3IocmFuZ2U6IFJhbmdlKTogc3RyaW5nIHtcbiAgICBjb25zdCBjbG9uZWRSYW5nZSA9IHJhbmdlLmNsb25lUmFuZ2UoKTtcbiAgICAvL1dlIHNlbGVjdCBhbGwgb2YgdGhlIGlucHV0IGNvbnRlbnRzLCBhbmQgdGhlbiBtb3ZlIHRoZSBlbmQgcG9pbnQgdG8gdGhlIGN1cnJlbnQgY3Vyc29yIHBvc2l0aW9uXG4gICAgY2xvbmVkUmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKHRoaXMuaW5wdXRFbGVtZW50IS5uYXRpdmVFbGVtZW50KTtcbiAgICBjbG9uZWRSYW5nZS5zZXRFbmQocmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQpO1xuXG4gICAgLy9DcmVhdGUgYSB0ZW1wb3JhcnkgZGl2IHNvIHRoYXQgd2UgY2FuIGV4dHJhY3QgdGV4dCBjb250ZW50IGZyb20gaXRcbiAgICBjb25zdCBmcmFnbWVudCA9IGNsb25lZFJhbmdlLmNsb25lQ29udGVudHMoKTtcbiAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkaXYuYXBwZW5kQ2hpbGQoZnJhZ21lbnQpO1xuXG4gICAgLy9HZXQgdGV4dCBjb250ZW50LCByZXBsYWNpbmcgbWVudGlvbiBzcGFucyB3aXRoIEBuYW1lXG4gICAgcmV0dXJuIGRpdi50ZXh0Q29udGVudCB8fCAnJztcbiAgfVxuXG4gIGdldEZpbHRlcmVkVXNlcnMoKTogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Vc2VyW10ge1xuICAgIGNvbnN0IHVzZXJzID0gIXRoaXMubWVudGlvblNlYXJjaFRleHRcbiAgICAgID8gdGhpcy51c2Vyc1xuICAgICAgOiB0aGlzLnVzZXJzLmZpbHRlcih1c2VyID0+XG4gICAgICAgICAgdXNlci5uYW1lXG4gICAgICAgICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgLmluY2x1ZGVzKHRoaXMubWVudGlvblNlYXJjaFRleHQudG9Mb3dlckNhc2UoKSksXG4gICAgICAgICk7XG5cbiAgICByZXR1cm4gdXNlcnMuc2xpY2UoKS5zb3J0KChhLCBiKSA9PiBhLm5hbWUubG9jYWxlQ29tcGFyZShiLm5hbWUpKTtcbiAgfVxuXG4gIG9uVXNlckhvdmVyKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkVXNlckluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBzZWxlY3RVc2VyKHVzZXI6IE1lbnRpb25zSW5wdXRDb21wb25lbnQuVXNlcik6IHZvaWQge1xuICAgIGlmICghdGhpcy5pbnB1dEVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvL1RoaXMgZ2V0cyBET00gaW5mbyBmcm9tIHVzZXIgKGUuZy4gaGlnaGxpZ2h0ZWQgc2VsZWN0aW9ucywgYW5kIGN1cnNvciBwb3NpdGlvbilcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBSZXN0b3JlIHRoZSBzYXZlZCByYW5nZSBpZiBhdmFpbGFibGUgKG5lZWRlZCB3aGVuIHNlbGVjdGluZyB2aWEgY2xpY2spXG4gICAgaWYgKHRoaXMuc2F2ZWRSYW5nZSkge1xuICAgICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgc2VsZWN0aW9uLmFkZFJhbmdlKHRoaXMuc2F2ZWRSYW5nZSk7XG4gICAgfVxuXG4gICAgaWYgKCFzZWxlY3Rpb24ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIERlbGV0ZSB0aGUgXCJAXCIgYW5kIHNlYXJjaCB0ZXh0XG4gICAgdGhpcy5kZWxldGVBdE1lbnRpb25TZWFyY2goKTtcblxuICAgIC8vREFITkUgTk9URSAtIHRoaXMgd291bGQgaWRlYWxseSBiZSB0aGUgc2FtZSBhcyBjb250ZW50SXRlbVRvSFRNTCwgYnV0IHdlIG5lZWQgYW4gYWN0dWFsIGVsZW1lbnQgcmVmZXJlbmNlIGhlcmUgaW4gb3JkZXIgdG8gYXBwZW5kIGl0IHRvIHRoZSBET01cbiAgICBjb25zdCBtZW50aW9uU3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICBtZW50aW9uU3Bhbi5jbGFzc05hbWUgPSB0aGlzLnJlYWRvbmx5ID8gJ3JlYWRvbmx5LW1lbnRpb24nIDogJ21lbnRpb24nO1xuICAgIG1lbnRpb25TcGFuLnNldEF0dHJpYnV0ZSgnZGF0YS1pZCcsIFN0cmluZyh1c2VyLmlkKSk7XG4gICAgbWVudGlvblNwYW4uc2V0QXR0cmlidXRlKCdkYXRhLXR5cGUnLCAnbWVudGlvbicpO1xuICAgIG1lbnRpb25TcGFuLnNldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJywgJ2ZhbHNlJyk7XG4gICAgbWVudGlvblNwYW4udGV4dENvbnRlbnQgPSBgQCR7dXNlci5uYW1lfWA7XG5cbiAgICAvL0ZpbmQgY3VycmVudCBjdXJzb3IgcG9zaXRpb25cbiAgICBjb25zdCBuZXdSYW5nZSA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKT8uZ2V0UmFuZ2VBdCgwKTtcbiAgICBpZiAobmV3UmFuZ2UpIHtcbiAgICAgIG5ld1JhbmdlLmluc2VydE5vZGUobWVudGlvblNwYW4pO1xuICAgICAgLy9jb2xsYXBzZSByYW5nZSB0byBwb3NpdGlvbiBjdXJzb3IgYWZ0ZXIgbWVudGlvblxuICAgICAgbmV3UmFuZ2Uuc2V0U3RhcnRBZnRlcihtZW50aW9uU3Bhbik7XG4gICAgICBuZXdSYW5nZS5jb2xsYXBzZSh0cnVlKTtcblxuICAgICAgLy9BZGQgYSBzcGFjZSBhZnRlciB0aGUgbWVudGlvblxuICAgICAgY29uc3Qgc3BhY2VOb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJ1xcdTAwQTAnKTtcbiAgICAgIG5ld1JhbmdlLmluc2VydE5vZGUoc3BhY2VOb2RlKTtcbiAgICAgIC8vUG9zaXRpb24gY3Vyc29yIGFmdGVyIHRoZSBzcGFjZVxuICAgICAgbmV3UmFuZ2Uuc2V0U3RhcnRBZnRlcihzcGFjZU5vZGUpO1xuICAgICAgbmV3UmFuZ2UuY29sbGFwc2UodHJ1ZSk7XG5cbiAgICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgIC8vQXBwbHkgdGhpcyByYW5nZSB0byB0aGUgRE9NXG4gICAgICBzZWxlY3Rpb24uYWRkUmFuZ2UobmV3UmFuZ2UpO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2VNZW50aW9ucygpO1xuICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgZGVsZXRlQXRNZW50aW9uU2VhcmNoKCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbiB8fCAhc2VsZWN0aW9uLnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvL1RoaXMgcmVwcmVzZW50cyB0aGUgY3VycmVudCBwb3NpdGlvbiBvZiB0aGUgY3Vyc29yXG4gICAgY29uc3QgY3Vyc29yUmFuZ2UgPSBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTtcblxuICAgIC8vVGhpcyB3aWxsIHJldHVybiBhbGwgb2YgdGhlIHJhdyB0ZXh0IChIVE1MLXN0cmlwcGVkKSBiZWZvcmUgdGhlIGN1cnNvclxuICAgIGNvbnN0IHRleHRCZWZvcmVDdXJzb3IgPSB0aGlzLmdldFRleHRCZWZvcmVDdXJzb3IoY3Vyc29yUmFuZ2UpO1xuICAgIC8vV2UgZG8gdGhhdF4gc28gdGhhdCB3ZSBjYW4gZmluZCB0aGUgY29ycmVjdCBpbmRleCBvZiB0aGUgbW9zdCByZWNlbnQgJ0AnXG4gICAgY29uc3QgbGFzdEF0SW5kZXggPSB0ZXh0QmVmb3JlQ3Vyc29yLmxhc3RJbmRleE9mKCdAJyk7XG5cbiAgICBpZiAobGFzdEF0SW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy9Lbm93aW5nIHRoZSBwb3NpdGlvbiBvZiB0aGUgbGFzdCAnQCcgY2hhcmFjdGVyIHdlIGNhbiBub3cgZmluZCB0aGUgYWN0dWFsIERPTSBub2RlICsgb2Zmc2V0IHdoZXJlIFwiQFwiIGxpdmVzXG4gICAgY29uc3QgYXRQb3NpdGlvbiA9IHRoaXMuZmluZERvbVBvc2l0aW9uQXRDaGFySW5kZXgobGFzdEF0SW5kZXgpO1xuXG4gICAgaWYgKCFhdFBvc2l0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIHJhbmdlIGZyb20gXCJAXCIgdG8gY3Vyc29yIGFuZCBkZWxldGUgaXRcbiAgICBjb25zdCBkZWxldGVSYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgZGVsZXRlUmFuZ2Uuc2V0U3RhcnQoYXRQb3NpdGlvbi5ub2RlLCBhdFBvc2l0aW9uLm9mZnNldCk7XG4gICAgZGVsZXRlUmFuZ2Uuc2V0RW5kKGN1cnNvclJhbmdlLmVuZENvbnRhaW5lciwgY3Vyc29yUmFuZ2UuZW5kT2Zmc2V0KTtcbiAgICBkZWxldGVSYW5nZS5kZWxldGVDb250ZW50cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0luc2lkZU1lbnRpb25TcGFuKG5vZGU6IE5vZGUpOiBib29sZWFuIHtcbiAgICBsZXQgY3VycmVudE5vZGU6IE5vZGUgfCBudWxsID0gbm9kZTtcbiAgICB3aGlsZSAoY3VycmVudE5vZGUgJiYgY3VycmVudE5vZGUgIT09IHRoaXMuaW5wdXRFbGVtZW50Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICBpZiAoXG4gICAgICAgIGN1cnJlbnROb2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSAmJlxuICAgICAgICAoY3VycmVudE5vZGUgYXMgSFRNTEVsZW1lbnQpLmdldEF0dHJpYnV0ZSgnZGF0YS10eXBlJykgPT09ICdtZW50aW9uJ1xuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvL1RoaXMgd2lsbCBnbyB0ZXh0IG5vZGUgYnkgbm9kZSBsb29raW5nIGZvciB0aGVcbiAgLy9AIG1lbnRpb24gYW5kIGdpdmUgaXRzIHBvc2l0aW9uIGluIHRoZSBjb250ZXh0IG9mIHRoYXQgbm9kZVxuICBwcml2YXRlIGZpbmREb21Qb3NpdGlvbkF0Q2hhckluZGV4KFxuICAgIGNoYXJJbmRleDogbnVtYmVyLFxuICApOiB7IG5vZGU6IE5vZGU7IG9mZnNldDogbnVtYmVyIH0gfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaW5wdXRFbGVtZW50KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBXYWxrIHRocm91Z2ggYWxsIHRleHQgbm9kZXMgaW4gdGhlIGlucHV0LCBjb3VudGluZyBjaGFyYWN0ZXJzXG4gICAgY29uc3QgdHJlZVdhbGtlciA9IGRvY3VtZW50LmNyZWF0ZVRyZWVXYWxrZXIoXG4gICAgICB0aGlzLmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LFxuICAgICAgTm9kZUZpbHRlci5TSE9XX1RFWFQsXG4gICAgICBudWxsLFxuICAgICk7XG5cbiAgICBsZXQgY2hhckNvdW50ID0gMDtcblxuICAgIHdoaWxlICh0cmVlV2Fsa2VyLm5leHROb2RlKCkpIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB0cmVlV2Fsa2VyLmN1cnJlbnROb2RlO1xuICAgICAgY29uc3QgdGV4dCA9IG5vZGUudGV4dENvbnRlbnQgfHwgJyc7XG5cbiAgICAgIC8vIENoZWNrIGlmIG91ciB0YXJnZXQgY2hhcmFjdGVyIGlzIGluIHRoaXMgdGV4dCBub2RlXG4gICAgICBpZiAoY2hhckNvdW50ICsgdGV4dC5sZW5ndGggPiBjaGFySW5kZXgpIHtcbiAgICAgICAgLy8gVGhlIGNoYXJhY3RlciBhdCBjaGFySW5kZXggaXMgaW4gdGhpcyBub2RlXG4gICAgICAgIGNvbnN0IG9mZnNldEluTm9kZSA9IGNoYXJJbmRleCAtIGNoYXJDb3VudDtcbiAgICAgICAgcmV0dXJuIHsgbm9kZSwgb2Zmc2V0OiBvZmZzZXRJbk5vZGUgfTtcbiAgICAgIH1cblxuICAgICAgY2hhckNvdW50ICs9IHRleHQubGVuZ3RoO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBjbG9zZU1lbnRpb25zKCk6IHZvaWQge1xuICAgIHRoaXMubWVudGlvbnNWaXNpYmxlID0gZmFsc2U7XG4gICAgdGhpcy5tZW50aW9uU2VhcmNoVGV4dCA9ICcnO1xuICAgIHRoaXMubWVudGlvbkFuY2hvciA9IG51bGw7XG4gICAgdGhpcy5zZWxlY3RlZFVzZXJJbmRleCA9IDA7XG4gICAgdGhpcy5zYXZlZFJhbmdlID0gbnVsbDtcbiAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgZW1pdENvbnRlbnRDaGFuZ2UoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlucHV0RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRlbnRJdGVtcyA9IHRoaXMuZG9tVG9Db250ZW50SXRlbXMoKTtcbiAgICB0aGlzLmNvbnRlbnRDaGFuZ2UuZW1pdChjb250ZW50SXRlbXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBkb21Ub0NvbnRlbnRJdGVtcygpOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRJdGVtW10ge1xuICAgIGlmICghdGhpcy5pbnB1dEVsZW1lbnQ/Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBpdGVtczogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Db250ZW50SXRlbVtdID0gW107XG4gICAgY29uc3QgY2hpbGROb2RlcyA9IHRoaXMuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuY2hpbGROb2RlcztcblxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBBcnJheS5mcm9tKGNoaWxkTm9kZXMpKSB7XG4gICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IG5vZGUgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBlbGVtZW50LnRhZ05hbWUgPT09ICdTUEFOJyAmJlxuICAgICAgICAgIGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLXR5cGUnKSA9PT0gJ21lbnRpb24nXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IGlkID0gTnVtYmVyKGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWlkJykpO1xuICAgICAgICAgIGNvbnN0IG5hbWUgPSBlbGVtZW50LnRleHRDb250ZW50Py5yZXBsYWNlKCdAJywgJycpIHx8ICcnO1xuICAgICAgICAgIGl0ZW1zLnB1c2goeyB0eXBlOiAnbWVudGlvbicsIGlkLCBuYW1lIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGVsZW1lbnQudGFnTmFtZSA9PT0gJ0JSJykge1xuICAgICAgICAgIGl0ZW1zLnB1c2goeyB0eXBlOiAnbmV3bGluZScgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5URVhUX05PREUpIHtcbiAgICAgICAgY29uc3QgdGV4dCA9IG5vZGUudGV4dENvbnRlbnQgfHwgJyc7XG4gICAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICd0ZXh0JywgdGV4dCB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICBvbkNhbGxvdXRDbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgfVxufVxuXG5leHBvcnQgbmFtZXNwYWNlIE1lbnRpb25zSW5wdXRDb21wb25lbnQge1xuICBleHBvcnQgY29uc3QgQ29udGVudFR5cGVzID0gWydtZW50aW9uJywgJ3RleHQnLCAnbmV3bGluZSddIGFzIGNvbnN0O1xuICBleHBvcnQgdHlwZSBDb250ZW50VHlwZSA9XG4gICAgKHR5cGVvZiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRUeXBlcylbbnVtYmVyXTtcbiAgZXhwb3J0IGludGVyZmFjZSBVc2VyIHtcbiAgICBpZDogbnVtYmVyO1xuICAgIG5hbWU6IHN0cmluZztcbiAgfVxuICBleHBvcnQgdHlwZSBDb250ZW50PFQgZXh0ZW5kcyBDb250ZW50VHlwZT4gPSB7IHR5cGU6IFQgfTtcblxuICBleHBvcnQgdHlwZSBVc2VyTWVudGlvbiA9IENvbnRlbnQ8J21lbnRpb24nPiAmIFVzZXI7XG4gIGV4cG9ydCB0eXBlIFRleHQgPSBDb250ZW50PCd0ZXh0Jz4gJiB7IHRleHQ6IHN0cmluZyB9O1xuICBleHBvcnQgdHlwZSBOZXdsaW5lID0gQ29udGVudDwnbmV3bGluZSc+O1xuXG4gIGV4cG9ydCB0eXBlIENvbnRlbnRJdGVtID0gVXNlck1lbnRpb24gfCBUZXh0IHwgTmV3bGluZTtcblxuICBleHBvcnQgZnVuY3Rpb24gY29udGVudFRvUGxhaW5UZXh0KGNvbnRlbnQ6IENvbnRlbnRJdGVtW10pOiBzdHJpbmcge1xuICAgIHJldHVybiBjb250ZW50XG4gICAgICAubWFwKGl0ZW0gPT4ge1xuICAgICAgICBzd2l0Y2ggKGl0ZW0udHlwZSkge1xuICAgICAgICAgIGNhc2UgJ21lbnRpb24nOlxuICAgICAgICAgICAgcmV0dXJuIGBAJHtpdGVtLm5hbWV9YDtcbiAgICAgICAgICBjYXNlICd0ZXh0JzpcbiAgICAgICAgICAgIHJldHVybiBpdGVtLnRleHQ7XG4gICAgICAgICAgY2FzZSAnbmV3bGluZSc6XG4gICAgICAgICAgICByZXR1cm4gJ1xcbic7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJtZW50aW9ucy1jb250YWluZXJcIiAjY29udGFpbmVyPlxuICA8ZGl2XG4gICAgKm5nSWY9XCIhcmVhZG9ubHlcIlxuICAgICNpbnB1dFxuICAgIGNsYXNzPVwidGV4dC1jb250ZW50IGVkaXRhYmxlXCJcbiAgICBjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJcbiAgICBbYXR0ci5kYXRhLXBsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAoaW5wdXQpPVwib25JbnB1dCgpXCJcbiAgICAoa2V5ZG93bik9XCJvbktleURvd24oJGV2ZW50KVwiXG4gICAgKHBhc3RlKT1cIm9uUGFzdGUoJGV2ZW50KVwiXG4gID48L2Rpdj5cblxuICA8ZGl2ICpuZ0lmPVwicmVhZG9ubHlcIiAjaW5wdXQgY2xhc3M9XCJ0ZXh0LWNvbnRlbnRcIj48L2Rpdj5cblxuICA8cml2LWNhbGxvdXRcbiAgICAqbmdJZj1cIiFyZWFkb25seSAmJiBtZW50aW9uc1Zpc2libGUgJiYgbWVudGlvbkFuY2hvclwiXG4gICAgW2FuY2hvcl09XCJtZW50aW9uQW5jaG9yXCJcbiAgICBbaXNNb2RhbF09XCJ0cnVlXCJcbiAgICBbc2hvd0NhcmV0XT1cImZhbHNlXCJcbiAgICBbYWxsb3dlZFBvc2l0aW9uc109XCJbJ2JvdHRvbS1yaWdodCcsICd0b3AtcmlnaHQnXVwiXG4gICAgW3RoZW1lXT1cIidsaWdodCdcIlxuICAgIChjbG9zZSk9XCJvbkNhbGxvdXRDbG9zZSgpXCJcbiAgPlxuICAgIDxkaXYgY2xhc3M9XCJtZW50aW9ucy1jb250ZW50XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwibWVudGlvbnMtaGVhZGVyXCI+TWVudGlvbiBzb21lb25lPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibWVudGlvbnMtbGlzdFwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nRm9yPVwibGV0IHVzZXIgb2YgZ2V0RmlsdGVyZWRVc2VycygpOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgICBbY2xhc3Muc2VsZWN0ZWRdPVwiaSA9PT0gc2VsZWN0ZWRVc2VySW5kZXhcIlxuICAgICAgICAgIChtb3VzZWVudGVyKT1cIm9uVXNlckhvdmVyKGkpXCJcbiAgICAgICAgICAoY2xpY2spPVwic2VsZWN0VXNlcih1c2VyKVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyB1c2VyLm5hbWUgfX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9yaXYtY2FsbG91dD5cbjwvZGl2PlxuIl19
745
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudGlvbnMtaW5wdXQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcml2L3NyYy9saWIvaW5wdXQvbWVudGlvbnMtaW5wdXQvbWVudGlvbnMtaW5wdXQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcml2L3NyYy9saWIvaW5wdXQvbWVudGlvbnMtaW5wdXQvbWVudGlvbnMtaW5wdXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLHVCQUF1QixFQUV2QixTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBRU4sU0FBUyxFQUNULGlCQUFpQixHQUNsQixNQUFNLGVBQWUsQ0FBQzs7OztBQUV2QixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDaEIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDO0FBRXZCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBUUgsTUFBTSxPQUFPLHNCQUFzQjtJQUNqQyxZQUE2QixHQUFzQjtRQUF0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUUxQyxZQUFPLEdBQXlDLEVBQUUsQ0FBQztRQUNuRCxVQUFLLEdBQWtDLEVBQUUsQ0FBQztRQUMxQyxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGdCQUFXLEdBQVcsZUFBZSxDQUFDO1FBRTVCLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBRWhELENBQUM7UUFLSixvQkFBZSxHQUFHLEtBQUssQ0FBQztRQUN4QixzQkFBaUIsR0FBRyxFQUFFLENBQUM7UUFDdkIsa0JBQWEsR0FBbUIsSUFBSSxDQUFDO1FBQ3JDLHNCQUFpQixHQUFHLENBQUMsQ0FBQztRQUNkLGVBQVUsR0FBaUIsSUFBSSxDQUFDO0lBbEJjLENBQUM7SUFvQnZELGVBQWU7UUFDYixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVE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QUNuQixLQUFLLFNBQVM7b0JBQ1osT0FBTyxJQUFJLENBQUM7YUFDZjtRQUNILENBQUMsQ0FBQzthQUNELElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNkLENBQUM7SUFiZSx5Q0FBa0IscUJBYWpDLENBQUE7QUFDSCxDQUFDLEVBOUJnQixzQkFBc0IsS0FBdEIsc0JBQXNCLFFBOEJ0QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmNvbnN0IFpXUyA9ICfigIsnO1xuY29uc3QgWldTX1JFR0VYID0gL+KAiy9nO1xuXG4vKipcbiAqIEEgcmljaCB0ZXh0IGlucHV0IHRoYXQgc3VwcG9ydHMgYEBgLW1lbnRpb25zIGluc2lkZSBhIGBjb250ZW50ZWRpdGFibGVgIGRpdi5cbiAqXG4gKiAjIyBEYXRhIE1vZGVsXG4gKiAtICoqSW5wdXQvT3V0cHV0Kio6IGBDb250ZW50SXRlbVtdYCAobWVudGlvbnMsIHRleHQsIG5ld2xpbmVzKVxuICpcbiAqICMjIERPTSBJbnZhcmlhbnRcbiAqIEV2ZXJ5IG1lbnRpb24gYDxzcGFuIGRhdGEtdHlwZT1cIm1lbnRpb25cIiBjb250ZW50ZWRpdGFibGU9XCJmYWxzZVwiPmAgaXMgd3JhcHBlZFxuICogYnkgZXhhY3RseSBvbmUgemVyby13aWR0aC1zcGFjZSAoWldTKSB0ZXh0IG5vZGUgYmVmb3JlIGFuZCBhZnRlciBpdC4gWldTIGdpdmVzXG4gKiB0aGUgY3Vyc29yIGEgdmFsaWQgbGFuZGluZyBzcG90IGFkamFjZW50IHRvIGEgbm9uLWVkaXRhYmxlIGVsZW1lbnQuIFRoZVxuICogaW52YXJpYW50IGlzIGVzdGFibGlzaGVkIGF0IHJlbmRlciB0aW1lIGFuZCByZS1lc3RhYmxpc2hlZCBieVxuICogYG5vcm1hbGl6ZU1lbnRpb25QYWRkaW5nKClgIGFmdGVyIGFueSBET00tbXV0YXRpbmcgb3BlcmF0aW9uLlxuICpcbiAqICMjIENvcHkvUGFzdGVcbiAqIC0gKipDb3B5Kio6IGByYW5nZS5jbG9uZUNvbnRlbnRzKClgIHByZXNlcnZlcyBgZGF0YS0qYCBhdHRyaWJ1dGVzIChvbmx5IHRoZVxuICogICBicm93c2VyJ3MgZGVmYXVsdCBjb3B5IHBhdGggc3RyaXBzIHRoZW0pLiBXZSBvdmVycmlkZSBjb3B5LCBzZXJpYWxpemUgdGhlXG4gKiAgIGNsb25lIG91cnNlbHZlcywgYW5kIHN0cmlwIFpXUyBmcm9tIHRoZSBvdXRwdXQuXG4gKiAtICoqUGFzdGUqKjogSFRNTCBwYXRocyBsb29rIGZvciBgZGF0YS10eXBlPVwibWVudGlvblwiYCBzcGFucyBhbmQgcmVidWlsZFxuICogICB0aGVtOyBvdGhlcndpc2UgcGxhaW50ZXh0IGZhbGxiYWNrLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdyaXYtbWVudGlvbnMtaW5wdXQnLFxuICB0ZW1wbGF0ZVVybDogYC4vbWVudGlvbnMtaW5wdXQuY29tcG9uZW50Lmh0bWxgLFxuICBzdHlsZVVybHM6IFsnLi9tZW50aW9ucy1pbnB1dC5jb21wb25lbnQuY3NzJ10sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBNZW50aW9uc0lucHV0Q29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBjZHI6IENoYW5nZURldGVjdG9yUmVmKSB7fVxuXG4gIEBJbnB1dCgpIGNvbnRlbnQ6IE1lbnRpb25zSW5wdXRDb21wb25lbnQuQ29udGVudEl0ZW1bXSA9IFtdO1xuICBASW5wdXQoKSB1c2VyczogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Vc2VyW10gPSBbXTtcbiAgQElucHV0KCkgcmVhZG9ubHkgPSBmYWxzZTtcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICdBZGQgYSBjb21tZW50JztcblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgY29udGVudENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8XG4gICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5Db250ZW50SXRlbVtdXG4gID4oKTtcblxuICBAVmlld0NoaWxkKCdpbnB1dCcsIHsgc3RhdGljOiBmYWxzZSB9KVxuICBwcml2YXRlIHJlYWRvbmx5IGlucHV0RWxlbWVudD86IEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+O1xuXG4gIG1lbnRpb25zVmlzaWJsZSA9IGZhbHNlO1xuICBtZW50aW9uU2VhcmNoVGV4dCA9ICcnO1xuICBtZW50aW9uQW5jaG9yOiBET01SZWN0IHwgbnVsbCA9IG51bGw7XG4gIHNlbGVjdGVkVXNlckluZGV4ID0gMDtcbiAgcHJpdmF0ZSBzYXZlZFJhbmdlOiBSYW5nZSB8IG51bGwgPSBudWxsO1xuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlbmRlckNvbnRlbnQoKTtcbiAgfVxuXG4gIC8vREFITkUgTk9URSAtIG5nT25DaGFuZ2VzIGlzIGNhbGxlZCB3aGVuZXZlciBhbnkgQElucHV0KCkgcHJvcGVydHkgY2hhbmdlcywgd2hlcmUgdGhlIGNoYW5nZWQgaW5wdXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgdGhvc2UgY2hhbmdlc1xuICAvL1NvIGlmIEBJbnB1dCgpIGNvbnRlbnQgY2hhbmdlcyBhbmQgaXQncyBub3QgdGhlIGZpcnN0IGNoYW5nZSAodGhlIGZpcnN0IHJlbmRlciBpcyBoYW5kbGVkIGJ5IG5nQWZ0ZXJWaWV3SW5pdCgpKSwgd2UgcmVuZGVyIHRoZSBjb250ZW50XG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snY29udGVudCddICYmICFjaGFuZ2VzWydjb250ZW50J10uZmlyc3RDaGFuZ2UpIHtcbiAgICAgIHRoaXMucmVuZGVyQ29udGVudCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyQ29udGVudCgpOiB2b2lkIHtcbiAgICAvL1RoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdGhlIEBWaWV3Q2hpbGQgcmVmZXJlbmNlIGlzbid0IGF2YWlsYWJsZSB1bnRpbCBhZnRlciB0aGUgdmlldyBpbml0aWFsaXplc1xuICAgIGlmICghdGhpcy5pbnB1dEVsZW1lbnQ/Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaHRtbCA9IHRoaXMuY29udGVudFxuICAgICAgLm1hcChpdGVtID0+IHtcbiAgICAgICAgY29uc3QgaXRlbUh0bWwgPSBNZW50aW9uc0lucHV0Q29tcG9uZW50LmNvbnRlbnRJdGVtVG9IdG1sKFxuICAgICAgICAgIGl0ZW0sXG4gICAgICAgICAgdGhpcy5yZWFkb25seSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGl0ZW0udHlwZSA9PT0gJ21lbnRpb24nID8gYCR7WldTfSR7aXRlbUh0bWx9JHtaV1N9YCA6IGl0ZW1IdG1sO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcnKTtcbiAgICB0aGlzLmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LmlubmVySFRNTCA9IGh0bWw7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjb250ZW50SXRlbVRvSHRtbChcbiAgICBpdGVtOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRJdGVtLFxuICAgIHJlYWRvbmx5OiBib29sZWFuLFxuICApOiBzdHJpbmcge1xuICAgIHN3aXRjaCAoaXRlbS50eXBlKSB7XG4gICAgICAvL0RBSE5FIFRPRE8gLSBtYXliZSB3ZSBlc2NhcGUgSFRNTCBoZXJlIHRvbz8gQWx0aG91Z2ggSSBkb24ndCB0aGluayBpdCB3aWxsIGJlIHBvc3NpYmxlIGZvciB1c2VycyB0byBpbnB1dCBhbiBYU1MgYXR0YWNrIGluIGl0ZW0ubmFtZVxuICAgICAgY2FzZSAnbWVudGlvbic6XG4gICAgICAgIHJldHVybiBgPHNwYW4gY2xhc3M9XCIke1xuICAgICAgICAgIHJlYWRvbmx5ID8gJ3JlYWRvbmx5LW1lbnRpb24nIDogJ21lbnRpb24nXG4gICAgICAgIH1cIiBkYXRhLWlkPVwiJHtcbiAgICAgICAgICBpdGVtLmlkXG4gICAgICAgIH1cIiBkYXRhLXR5cGU9XCJtZW50aW9uXCIgY29udGVudGVkaXRhYmxlPVwiZmFsc2VcIj5AJHtNZW50aW9uc0lucHV0Q29tcG9uZW50LmVzY2FwZUh0bWwoXG4gICAgICAgICAgaXRlbS5uYW1lLFxuICAgICAgICApfTwvc3Bhbj5gO1xuICAgICAgY2FzZSAndGV4dCc6XG4gICAgICAgIHJldHVybiBNZW50aW9uc0lucHV0Q29tcG9uZW50LmVzY2FwZUh0bWwoaXRlbS50ZXh0KTtcbiAgICAgIGNhc2UgJ25ld2xpbmUnOlxuICAgICAgICByZXR1cm4gJzxicj4nO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGVzY2FwZUh0bWwodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBkaXYudGV4dENvbnRlbnQgPSB0ZXh0O1xuICAgIHJldHVybiBkaXYuaW5uZXJIVE1MO1xuICB9XG5cbiAgLy8g4pSA4pSA4pSAIEV2ZW50IGhhbmRsZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIG9uSW5wdXQoKTogdm9pZCB7XG4gICAgdGhpcy5ub3JtYWxpemVNZW50aW9uUGFkZGluZygpO1xuICAgIHRoaXMuY2hlY2tGb3JNZW50aW9uVHJpZ2dlcigpO1xuICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgfVxuXG4gIG9uS2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1lbnRpb25zVmlzaWJsZSkge1xuICAgICAgdGhpcy5oYW5kbGVNZW50aW9uc0Ryb3Bkb3duTmF2KGV2ZW50KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBXb3JkL2xpbmUganVtcDogbmF0aXZlIGJlaGF2aW9yLlxuICAgIGlmIChldmVudC5tZXRhS2V5IHx8IGV2ZW50LmN0cmxLZXkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dMZWZ0JyB8fCBldmVudC5rZXkgPT09ICdBcnJvd1JpZ2h0Jykge1xuICAgICAgY29uc3QgZGlyZWN0aW9uID0gZXZlbnQua2V5ID09PSAnQXJyb3dMZWZ0JyA/ICdiZWZvcmUnIDogJ2FmdGVyJztcbiAgICAgIGNvbnN0IG1lbnRpb24gPSB0aGlzLmZpbmRNZW50aW9uQWRqYWNlbnRUb0N1cnNvcihkaXJlY3Rpb24pO1xuICAgICAgaWYgKG1lbnRpb24pIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgdGhpcy5leHRlbmRTZWxlY3Rpb25BY3Jvc3NNZW50aW9uKG1lbnRpb24sIGRpcmVjdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5wbGFjZUN1cnNvckFkamFjZW50VG9NZW50aW9uKG1lbnRpb24sIGRpcmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQmFja3NwYWNlJyB8fCBldmVudC5rZXkgPT09ICdEZWxldGUnKSB7XG4gICAgICBjb25zdCBkaXJlY3Rpb24gPSBldmVudC5rZXkgPT09ICdCYWNrc3BhY2UnID8gJ2JlZm9yZScgOiAnYWZ0ZXInO1xuICAgICAgY29uc3QgbWVudGlvbiA9IHRoaXMuZmluZE1lbnRpb25BZGphY2VudFRvQ3Vyc29yKGRpcmVjdGlvbik7XG4gICAgICBpZiAobWVudGlvbikge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnJlbW92ZU1lbnRpb24obWVudGlvbik7XG4gICAgICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleSA9PT0gJ0JhY2tzcGFjZScpIHtcbiAgICAgICAgY29uc3QgYnIgPSB0aGlzLmZpbmRCckFkamFjZW50VG9DdXJzb3IoKTtcbiAgICAgICAgaWYgKGJyKSB7XG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICBici5yZW1vdmUoKTtcbiAgICAgICAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9IYW5kbGUgbmV3bGluZXMgd2hlbiBtZW50aW9ucyBhcmVuJ3QgdmlzaWJsZVxuICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLmluc2VydExpbmVCcmVhaygpO1xuICAgICAgdGhpcy5lbWl0Q29udGVudENoYW5nZSgpO1xuICAgIH1cbiAgfVxuXG4gIG9uUGFzdGUoZXZlbnQ6IENsaXBib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBpZiAoIWV2ZW50LmNsaXBib2FyZERhdGEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9Mb29rIGZvciBIVE1MIGZpcnN0XG4gICAgY29uc3QgaHRtbCA9IGV2ZW50LmNsaXBib2FyZERhdGEuZ2V0RGF0YSgndGV4dC9odG1sJyk7XG4gICAgY29uc3QgcGxhaW5UZXh0ID0gZXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd0ZXh0L3BsYWluJyk7XG5cbiAgICBjb25zdCBub2RlcyA9XG4gICAgICBodG1sICYmIGh0bWwuaW5jbHVkZXMoJ2RhdGEtdHlwZT1cIm1lbnRpb25cIicpXG4gICAgICAgID8gdGhpcy5wYXJzZVBhc3RlZEh0bWwoaHRtbClcbiAgICAgICAgOiB0aGlzLnBsYWluVGV4dFRvTm9kZXMocGxhaW5UZXh0KTtcblxuICAgIHRoaXMuaW5zZXJ0Tm9kZXNBdEN1cnNvcihub2Rlcyk7XG4gICAgdGhpcy5ub3JtYWxpemVNZW50aW9uUGFkZGluZygpO1xuICAgIHRoaXMuZW1pdENvbnRlbnRDaGFuZ2UoKTtcbiAgfVxuXG4gIC8vIFRoZSBicm93c2VyIHN0cmlwcyBkYXRhLSogYXR0cmlidXRlcyBkdXJpbmcgZGVmYXVsdCBjb3B5IHNlcmlhbGl6YXRpb24sIGJ1dFxuICAvLyByYW5nZS5jbG9uZUNvbnRlbnRzKCkgcHJlc2VydmVzIHRoZW0uIFdlIHNlcmlhbGl6ZSB0aGUgY2xvbmUgb3Vyc2VsdmVzIGFuZFxuICAvLyBzdHJpcCBaV1Mgc28gaXQgZG9lc24ndCBsZWFrIGludG8gdGhlIGNsaXBib2FyZC5cbiAgb25Db3B5KGV2ZW50OiBDbGlwYm9hcmRFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbj8ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZGl2LmFwcGVuZENoaWxkKHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApLmNsb25lQ29udGVudHMoKSk7XG5cbiAgICBjb25zdCBodG1sID0gZGl2LmlubmVySFRNTC5yZXBsYWNlKFpXU19SRUdFWCwgJycpO1xuICAgIGNvbnN0IHRleHQgPSAoZGl2LnRleHRDb250ZW50IHx8ICcnKS5yZXBsYWNlKFpXU19SRUdFWCwgJycpO1xuXG4gICAgZXZlbnQuY2xpcGJvYXJkRGF0YT8uc2V0RGF0YSgndGV4dC9odG1sJywgaHRtbCk7XG4gICAgZXZlbnQuY2xpcGJvYXJkRGF0YT8uc2V0RGF0YSgndGV4dC9wbGFpbicsIHRleHQpO1xuICB9XG5cbiAgb25DdXQoZXZlbnQ6IENsaXBib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5vbkNvcHkoZXZlbnQpO1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbj8ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5kZWxldGVDb250ZW50cygpO1xuICAgIHRoaXMubm9ybWFsaXplTWVudGlvblBhZGRpbmcoKTtcbiAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gIH1cblxuICAvLyDilIDilIDilIAgTWVudGlvbiBoZWxwZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgc3RhdGljIGlzTWVudGlvbihub2RlOiBOb2RlIHwgbnVsbCB8IHVuZGVmaW5lZCk6IG5vZGUgaXMgSFRNTEVsZW1lbnQge1xuICAgIHJldHVybiAoXG4gICAgICAhIW5vZGUgJiZcbiAgICAgIG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFICYmXG4gICAgICAobm9kZSBhcyBIVE1MRWxlbWVudCkuZ2V0QXR0cmlidXRlKCdkYXRhLXR5cGUnKSA9PT0gJ21lbnRpb24nXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGlzWndzKG5vZGU6IE5vZGUgfCBudWxsIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgICEhbm9kZSAmJlxuICAgICAgbm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5URVhUX05PREUgJiZcbiAgICAgIChub2RlLnRleHRDb250ZW50IHx8ICcnKS5yZXBsYWNlKFpXU19SRUdFWCwgJycpID09PSAnJ1xuICAgICk7XG4gIH1cblxuICAvLyBSZXNvbHZlIHRoZSBub2RlIGxvZ2ljYWxseSBhZGphY2VudCB0byAoY29udGFpbmVyLCBvZmZzZXQpIGluIHRoZSBnaXZlblxuICAvLyBkaXJlY3Rpb24sIHRyYW5zcGFyZW50bHkgc2tpcHBpbmcgYW55IFpXUy1vbmx5IHRleHQgbm9kZXMgaW4gYmV0d2Vlbi5cbiAgcHJpdmF0ZSByZXNvbHZlQWRqYWNlbnROb2RlKFxuICAgIGNvbnRhaW5lcjogTm9kZSxcbiAgICBvZmZzZXQ6IG51bWJlcixcbiAgICBkaXJlY3Rpb246ICdiZWZvcmUnIHwgJ2FmdGVyJyxcbiAgKTogTm9kZSB8IG51bGwge1xuICAgIGxldCBjYW5kaWRhdGU6IE5vZGUgfCBudWxsID0gbnVsbDtcblxuICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICBjb25zdCBsZW5ndGggPSAoY29udGFpbmVyLnRleHRDb250ZW50IHx8ICcnKS5sZW5ndGg7XG4gICAgICBjb25zdCBhdEJvdW5kYXJ5ID1cbiAgICAgICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc1p3cyhjb250YWluZXIpIHx8XG4gICAgICAgIChkaXJlY3Rpb24gPT09ICdiZWZvcmUnID8gb2Zmc2V0ID09PSAwIDogb2Zmc2V0ID09PSBsZW5ndGgpO1xuICAgICAgaWYgKCFhdEJvdW5kYXJ5KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJ1xuICAgICAgICAgID8gY29udGFpbmVyLnByZXZpb3VzU2libGluZ1xuICAgICAgICAgIDogY29udGFpbmVyLm5leHRTaWJsaW5nO1xuICAgIH0gZWxzZSBpZiAoY29udGFpbmVyLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgY29uc3QgY2hpbGRyZW4gPSAoY29udGFpbmVyIGFzIEhUTUxFbGVtZW50KS5jaGlsZE5vZGVzO1xuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJyA/IGNoaWxkcmVuW29mZnNldCAtIDFdIDogY2hpbGRyZW5bb2Zmc2V0XTtcbiAgICB9XG5cbiAgICB3aGlsZSAoY2FuZGlkYXRlICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MoY2FuZGlkYXRlKSkge1xuICAgICAgY2FuZGlkYXRlID1cbiAgICAgICAgZGlyZWN0aW9uID09PSAnYmVmb3JlJ1xuICAgICAgICAgID8gY2FuZGlkYXRlLnByZXZpb3VzU2libGluZ1xuICAgICAgICAgIDogY2FuZGlkYXRlLm5leHRTaWJsaW5nO1xuICAgIH1cbiAgICByZXR1cm4gY2FuZGlkYXRlO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kTWVudGlvbkFkamFjZW50VG9DdXJzb3IoXG4gICAgZGlyZWN0aW9uOiAnYmVmb3JlJyB8ICdhZnRlcicsXG4gICk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsZWN0aW9uPy5pc0NvbGxhcHNlZCB8fCAhc2VsZWN0aW9uLnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIGNvbnN0IG5vZGUgPSB0aGlzLnJlc29sdmVBZGphY2VudE5vZGUoXG4gICAgICByYW5nZS5zdGFydENvbnRhaW5lcixcbiAgICAgIHJhbmdlLnN0YXJ0T2Zmc2V0LFxuICAgICAgZGlyZWN0aW9uLFxuICAgICk7XG4gICAgcmV0dXJuIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNNZW50aW9uKG5vZGUpID8gbm9kZSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGZpbmRCckFkamFjZW50VG9DdXJzb3IoKTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24/LmlzQ29sbGFwc2VkIHx8ICFzZWxlY3Rpb24ucmFuZ2VDb3VudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMucmVzb2x2ZUFkamFjZW50Tm9kZShcbiAgICAgIHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgcmFuZ2Uuc3RhcnRPZmZzZXQsXG4gICAgICAnYmVmb3JlJyxcbiAgICApO1xuICAgIHJldHVybiBub2RlPy5ub2RlTmFtZSA9PT0gJ0JSJyA/IChub2RlIGFzIEhUTUxFbGVtZW50KSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGV4dGVuZFNlbGVjdGlvbkFjcm9zc01lbnRpb24oXG4gICAgbWVudGlvbjogSFRNTEVsZW1lbnQsXG4gICAgZGlyZWN0aW9uOiAnYmVmb3JlJyB8ICdhZnRlcicsXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBjb25zdCBwYXJlbnQgPSBtZW50aW9uLnBhcmVudE5vZGU7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpbmRleCA9IEFycmF5LmZyb20ocGFyZW50LmNoaWxkTm9kZXMpLmluZGV4T2YobWVudGlvbiBhcyBDaGlsZE5vZGUpO1xuICAgIHNlbGVjdGlvbi5leHRlbmQocGFyZW50LCBkaXJlY3Rpb24gPT09ICdiZWZvcmUnID8gaW5kZXggOiBpbmRleCArIDEpO1xuICB9XG5cbiAgcHJpdmF0ZSBwbGFjZUN1cnNvckFkamFjZW50VG9NZW50aW9uKFxuICAgIG1lbnRpb246IEhUTUxFbGVtZW50LFxuICAgIHNpZGU6ICdiZWZvcmUnIHwgJ2FmdGVyJyxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgcGFyZW50ID0gbWVudGlvbi5wYXJlbnROb2RlO1xuICAgIGlmICghcGFyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHNpYmxpbmcgPVxuICAgICAgc2lkZSA9PT0gJ2JlZm9yZScgPyBtZW50aW9uLnByZXZpb3VzU2libGluZyA6IG1lbnRpb24ubmV4dFNpYmxpbmc7XG4gICAgbGV0IHp3czogTm9kZTtcbiAgICBpZiAoc2libGluZyAmJiBNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzWndzKHNpYmxpbmcpKSB7XG4gICAgICB6d3MgPSBzaWJsaW5nO1xuICAgIH0gZWxzZSB7XG4gICAgICB6d3MgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpO1xuICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShcbiAgICAgICAgendzLFxuICAgICAgICBzaWRlID09PSAnYmVmb3JlJyA/IG1lbnRpb24gOiBtZW50aW9uLm5leHRTaWJsaW5nLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIHJhbmdlLnNldFN0YXJ0KHp3cywgc2lkZSA9PT0gJ2JlZm9yZScgPyAoendzLnRleHRDb250ZW50IHx8ICcnKS5sZW5ndGggOiAwKTtcbiAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsZWN0aW9uPy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24/LmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlTWVudGlvbihtZW50aW9uOiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmVudCA9IG1lbnRpb24ucGFyZW50Tm9kZTtcbiAgICBpZiAoIXBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBFbXB0eSB0ZXh0LW5vZGUgYW5jaG9yIHByZXNlcnZlcyBjdXJzb3IgcG9zaXRpb24gdGhyb3VnaCB0aGUgcmVtb3ZhbC5cbiAgICBjb25zdCBhbmNob3IgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJyk7XG4gICAgcGFyZW50Lmluc2VydEJlZm9yZShhbmNob3IsIG1lbnRpb24pO1xuXG4gICAgY29uc3QgcHJldiA9IG1lbnRpb24ucHJldmlvdXNTaWJsaW5nO1xuICAgIGNvbnN0IG5leHQgPSBtZW50aW9uLm5leHRTaWJsaW5nO1xuICAgIGlmIChwcmV2ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MocHJldikpIHtcbiAgICAgIHByZXYucmVtb3ZlKCk7XG4gICAgfVxuICAgIGlmIChuZXh0ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MobmV4dCkpIHtcbiAgICAgIG5leHQucmVtb3ZlKCk7XG4gICAgfVxuICAgIG1lbnRpb24ucmVtb3ZlKCk7XG5cbiAgICBjb25zdCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgcmFuZ2Uuc2V0U3RhcnQoYW5jaG9yLCAwKTtcbiAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgc2VsZWN0aW9uPy5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24/LmFkZFJhbmdlKHJhbmdlKTtcbiAgfVxuXG4gIC8vIFJlLWVzdGFibGlzaGVzIHRoZSBpbnZhcmlhbnQ6IGV2ZXJ5IG1lbnRpb24gaGFzIGV4YWN0bHkgb25lIFpXUyB0ZXh0XG4gIC8vIG5vZGUgaW1tZWRpYXRlbHkgYmVmb3JlIGFuZCBhZnRlciBpdCwgYW5kIHRoZXJlIGFyZSBubyBvcnBoYW4gWldTLW9ubHlcbiAgLy8gdGV4dCBub2RlcyBhbnl3aGVyZSBlbHNlLiBSdW4gYWZ0ZXIgYW55IG9wZXJhdGlvbiB0aGF0IG1heSBkaXN0dXJiIHRoZVxuICAvLyB0cmVlICh0eXBpbmcsIHBhc3RlLCBjdXQsIGRlbGV0ZSkgc28gY3J1ZnQgZG9lc24ndCBhY2N1bXVsYXRlIGFjcm9zc1xuICAvLyByZXBlYXRlZCBjb3B5L3Bhc3RlIGN5Y2xlcy5cbiAgcHJpdmF0ZSBub3JtYWxpemVNZW50aW9uUGFkZGluZygpOiB2b2lkIHtcbiAgICBjb25zdCByb290ID0gdGhpcy5pbnB1dEVsZW1lbnQ/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFyb290KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gMS4gRW5zdXJlIGVhY2ggbWVudGlvbiBoYXMgYSBaV1MgcGFkIG9uIGJvdGggc2lkZXMuXG4gICAgY29uc3QgbWVudGlvbnMgPSBBcnJheS5mcm9tKFxuICAgICAgcm9vdC5xdWVyeVNlbGVjdG9yQWxsKCdzcGFuW2RhdGEtdHlwZT1cIm1lbnRpb25cIl0nKSxcbiAgICApIGFzIEhUTUxFbGVtZW50W107XG4gICAgZm9yIChjb25zdCBtIG9mIG1lbnRpb25zKSB7XG4gICAgICBjb25zdCBwYXJlbnQgPSBtLnBhcmVudE5vZGU7XG4gICAgICBpZiAoIXBhcmVudCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIW0ucHJldmlvdXNTaWJsaW5nIHx8XG4gICAgICAgICFNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzWndzKG0ucHJldmlvdXNTaWJsaW5nKVxuICAgICAgKSB7XG4gICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoWldTKSwgbSk7XG4gICAgICB9XG4gICAgICBpZiAoIW0ubmV4dFNpYmxpbmcgfHwgIU1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MobS5uZXh0U2libGluZykpIHtcbiAgICAgICAgcGFyZW50Lmluc2VydEJlZm9yZShkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpLCBtLm5leHRTaWJsaW5nKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAyLiBSZW1vdmUgYW55IFpXUy1vbmx5IHRleHQgbm9kZSB0aGF0IGlzbid0IGRpcmVjdGx5IGFkamFjZW50IHRvIGFcbiAgICAvLyAgICBtZW50aW9uIChvcnBoYW5zIGZyb20gbGluZS1icmVhayBwYWRzLCBsZWZ0b3ZlciBzcGxpdHMgZnJvbSBwcmV2aW91c1xuICAgIC8vICAgIHBhc3RlIGluc2VydGlvbnMsIGR1cGxpY2F0ZSBwYWRzIGZyb20gYWNjdW11bGF0ZWQgY29weS9wYXN0ZSBjeWNsZXMpLlxuICAgIC8vICAgIFNraXAgYSBub2RlIGlmIHRoZSBjdXJzb3IgY3VycmVudGx5IGxpdmVzIGluIGl0IOKAlCBwcmVzZXJ2ZXMgY2FyZXRcbiAgICAvLyAgICBwb3NpdGlvbiB3aXRob3V0IG5lZWRpbmcgbWFudWFsIHJlc3RvcmF0aW9uLlxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBjb25zdCBjdXJzb3JOb2RlID1cbiAgICAgIHNlbGVjdGlvbj8ucmFuZ2VDb3VudCAmJlxuICAgICAgcm9vdC5jb250YWlucyhzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5zdGFydENvbnRhaW5lcilcbiAgICAgICAgPyBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5zdGFydENvbnRhaW5lclxuICAgICAgICA6IG51bGw7XG5cbiAgICBjb25zdCB3YWxrZXIgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKHJvb3QsIE5vZGVGaWx0ZXIuU0hPV19URVhULCBudWxsKTtcbiAgICBjb25zdCBvcnBoYW5zOiBUZXh0W10gPSBbXTtcbiAgICB3aGlsZSAod2Fsa2VyLm5leHROb2RlKCkpIHtcbiAgICAgIGNvbnN0IG5vZGUgPSB3YWxrZXIuY3VycmVudE5vZGUgYXMgVGV4dDtcbiAgICAgIGlmICghTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc1p3cyhub2RlKSB8fCBub2RlID09PSBjdXJzb3JOb2RlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgYWRqYWNlbnRUb01lbnRpb24gPVxuICAgICAgICBNZW50aW9uc0lucHV0Q29tcG9uZW50LmlzTWVudGlvbihub2RlLnByZXZpb3VzU2libGluZykgfHxcbiAgICAgICAgTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc01lbnRpb24obm9kZS5uZXh0U2libGluZyk7XG4gICAgICBpZiAoIWFkamFjZW50VG9NZW50aW9uKSB7XG4gICAgICAgIG9ycGhhbnMucHVzaChub2RlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yIChjb25zdCBub2RlIG9mIG9ycGhhbnMpIHtcbiAgICAgIG5vZGUucmVtb3ZlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVNZW50aW9uc0Ryb3Bkb3duTmF2KGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgZmlsdGVyZWRVc2VycyA9IHRoaXMuZ2V0RmlsdGVyZWRVc2VycygpO1xuICAgIGlmIChmaWx0ZXJlZFVzZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSBNYXRoLm1pbihcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkVXNlckluZGV4ICsgMSxcbiAgICAgICAgICBmaWx0ZXJlZFVzZXJzLmxlbmd0aCAtIDEsXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLnNlbGVjdGVkVXNlckluZGV4ID0gTWF0aC5tYXgodGhpcy5zZWxlY3RlZFVzZXJJbmRleCAtIDEsIDApO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdFbnRlcic6XG4gICAgICBjYXNlICdUYWInOlxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoZmlsdGVyZWRVc2Vyc1t0aGlzLnNlbGVjdGVkVXNlckluZGV4XSkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0VXNlcihmaWx0ZXJlZFVzZXJzW3RoaXMuc2VsZWN0ZWRVc2VySW5kZXhdKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0VzY2FwZSc6XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMuY2xvc2VNZW50aW9ucygpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIDilIAgSW5zZXJ0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgcGxhaW5UZXh0VG9Ob2Rlcyh0ZXh0OiBzdHJpbmcpOiBOb2RlW10ge1xuICAgIGNvbnN0IG5vZGVzOiBOb2RlW10gPSBbXTtcbiAgICBjb25zdCBsaW5lcyA9IHRleHQuc3BsaXQoJ1xcbicpO1xuICAgIGxpbmVzLmZvckVhY2goKGxpbmUsIGluZGV4KSA9PiB7XG4gICAgICBpZiAobGluZSkge1xuICAgICAgICBub2Rlcy5wdXNoKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGxpbmUpKTtcbiAgICAgIH1cbiAgICAgIGlmIChpbmRleCA8IGxpbmVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgbm9kZXMucHVzaChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdicicpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gbm9kZXM7XG4gIH1cbiAgLy8gQ3JlYXRlIGEgdGVtcG9yYXJ5IGNvbnRhaW5lciB0byBwYXJzZSB0aGUgSFRNTFxuICBwcml2YXRlIHBhcnNlUGFzdGVkSHRtbChodG1sOiBzdHJpbmcpOiBOb2RlW10ge1xuICAgIC8vIENyZWF0ZSBhIHRlbXBvcmFyeSBjb250YWluZXIgdG8gcGFyc2UgdGhlIEhUTUxcbiAgICBjb25zdCB0ZW1wQ29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGVtcENvbnRhaW5lci5pbm5lckhUTUwgPSBodG1sO1xuXG4gICAgY29uc3Qgbm9kZXM6IE5vZGVbXSA9IFtdO1xuICAgIGNvbnN0IHdhbGsgPSAobm9kZTogTm9kZSk6IHZvaWQgPT4ge1xuICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIGNvbnN0IGVsID0gbm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgLy8gREFITkUgTk9URSAtIHdlIG9ubHkgd2FudCBtZW50aW9uIHNwYW5zLCBiciBlbGVtZW50cywgYW5kIHRleHRcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGVsLnRhZ05hbWUgPT09ICdTUEFOJyAmJlxuICAgICAgICAgIGVsLmdldEF0dHJpYnV0ZSgnZGF0YS10eXBlJykgPT09ICdtZW50aW9uJyAmJlxuICAgICAgICAgIGVsLmhhc0F0dHJpYnV0ZSgnZGF0YS1pZCcpXG4gICAgICAgICkge1xuICAgICAgICAgIC8vQ3JlYXRlIG1lbnRpb24gdG8gdWx0aW1hdGVseSBpbnNlcnQgaW50byB0aGUgRE9NXG4gICAgICAgICAgY29uc3Qgc3BhbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICAgICAgICBzcGFuLmNsYXNzTmFtZSA9IHRoaXMucmVhZG9ubHkgPyAncmVhZG9ubHktbWVudGlvbicgOiAnbWVudGlvbic7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnLCBlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSB8fCAnJyk7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScsICdtZW50aW9uJyk7XG4gICAgICAgICAgc3Bhbi5zZXRBdHRyaWJ1dGUoJ2NvbnRlbnRlZGl0YWJsZScsICdmYWxzZScpO1xuICAgICAgICAgIGNvbnN0IHJhdyA9IGVsLnRleHRDb250ZW50IHx8ICcnO1xuICAgICAgICAgIHNwYW4udGV4dENvbnRlbnQgPSByYXcuc3RhcnRzV2l0aCgnQCcpID8gcmF3IDogYEAke3Jhd31gO1xuICAgICAgICAgIG5vZGVzLnB1c2goc3Bhbik7XG4gICAgICAgIH0gZWxzZSBpZiAoZWwudGFnTmFtZSA9PT0gJ0JSJykge1xuICAgICAgICAgIC8vIFByZXNlcnZlIGxpbmUgYnJlYWtzXG4gICAgICAgICAgbm9kZXMucHVzaChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdicicpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvL1JlY3Vyc2l2ZWx5IGxvb2sgZm9yIG5lc3RlZCBjaGlsZHJlblxuICAgICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgQXJyYXkuZnJvbShlbC5jaGlsZE5vZGVzKSkge1xuICAgICAgICAgICAgd2FsayhjaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG5vZGUubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICAgIGNvbnN0IHRleHQgPSAobm9kZS50ZXh0Q29udGVudCB8fCAnJykucmVwbGFjZShaV1NfUkVHRVgsICcnKTtcbiAgICAgICAgaWYgKHRleHQpIHtcbiAgICAgICAgICBub2Rlcy5wdXNoKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIEFycmF5LmZyb20odGVtcENvbnRhaW5lci5jaGlsZE5vZGVzKSkge1xuICAgICAgd2FsayhjaGlsZCk7XG4gICAgfVxuICAgIC8vREFITkUgTk9URSAtIHRoZSByZXN1bHQgaGVyZSBzaG91bGQgYmUgYW4gYXJyYXkgb2YgdGV4dC9zcGFuLW1lbnRpb24vYnIgbm9kZXNcbiAgICByZXR1cm4gbm9kZXM7XG4gIH1cblxuICBwcml2YXRlIGluc2VydE5vZGVzQXRDdXJzb3Iobm9kZXM6IE5vZGVbXSk6IHZvaWQge1xuICAgIC8vR2V0IHNlbGVjdGlvbiBvYmplY3QsIHJlcHJlc2VudGluZyB1c2VyIGN1cnNvciBwb3NpdGlvbi9zZWxlY3Rpb25cbiAgICAvL0dldCBSYW5nZSBvYmplY3QgYXQgc3RhcnQgb2Ygc2VsZWN0aW9uLCB3aGljaCBzaG91bGQgcmVwcmVzZW50IGN1cnNvciBwb3NpdGlvblxuICAgIC8vSWYgdGhlcmUgaXMgYSBzZWxlY3Rpb24sIGRlbGV0ZSBpdFxuICAgIC8vSW5zZXJ0IHRoZSBwYXJzZWQgbm9kZXMgZnJvbSBhYm92ZSwgbW92ZSByYW5nZSBlbmRzIHRvIGFmdGVyIG5vZGVcbiAgICAvL1RoZW4gcmVtb3ZlIHRoZSByYW5nZSBhbmQgcmVzZXQgaXQgdG8gbW92ZSB0aGUgY3Vyc29yIHBvc2l0aW9uIHRvIHRoZSBlbmRcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24/LnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmFuZ2UgPSBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTtcbiAgICByYW5nZS5kZWxldGVDb250ZW50cygpO1xuXG4gICAgbGV0IGN1cnNvclRhcmdldDogTm9kZSB8IG51bGwgPSBudWxsO1xuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBub2Rlcykge1xuICAgICAgaWYgKE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNNZW50aW9uKG5vZGUpKSB7XG4gICAgICAgIGNvbnN0IGJlZm9yZSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFpXUyk7XG4gICAgICAgIGNvbnN0IGFmdGVyID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoWldTKTtcbiAgICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZShiZWZvcmUpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKGJlZm9yZSk7XG4gICAgICAgIHJhbmdlLmluc2VydE5vZGUobm9kZSk7XG4gICAgICAgIHJhbmdlLnNldFN0YXJ0QWZ0ZXIobm9kZSk7XG4gICAgICAgIHJhbmdlLmluc2VydE5vZGUoYWZ0ZXIpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKGFmdGVyKTtcbiAgICAgICAgY3Vyc29yVGFyZ2V0ID0gYWZ0ZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByYW5nZS5pbnNlcnROb2RlKG5vZGUpO1xuICAgICAgICByYW5nZS5zZXRTdGFydEFmdGVyKG5vZGUpO1xuICAgICAgICBjdXJzb3JUYXJnZXQgPSBub2RlO1xuICAgICAgfVxuICAgICAgcmFuZ2UuY29sbGFwc2UodHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gQWZ0ZXIgYSBtZW50aW9uLCBsZWF2ZSB0aGUgY3Vyc29yIGluc2lkZSB0aGUgdHJhaWxpbmcgWldTIHNvIEFycm93TGVmdFxuICAgIC8vIGNhbiBzdGVwIGJhY2sgdG8gYmVmb3JlLXRoZS1tZW50aW9uIG5hdHVyYWxseS5cbiAgICBpZiAoY3Vyc29yVGFyZ2V0ICYmIE1lbnRpb25zSW5wdXRDb21wb25lbnQuaXNad3MoY3Vyc29yVGFyZ2V0KSkge1xuICAgICAgcmFuZ2Uuc2V0U3RhcnQoY3Vyc29yVGFyZ2V0LCAwKTtcbiAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgIH1cblxuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnNlcnRMaW5lQnJlYWsoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsZWN0aW9uPy5yYW5nZUNvdW50IHx8ICF0aGlzLmlucHV0RWxlbWVudD8ubmF0aXZlRWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIHJhbmdlLmRlbGV0ZUNvbnRlbnRzKCk7XG5cbiAgICBjb25zdCBiciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2JyJyk7XG4gICAgcmFuZ2UuaW5zZXJ0Tm9kZShicik7XG4gICAgcmFuZ2Uuc2V0U3RhcnRBZnRlcihicik7XG4gICAgcmFuZ2UuY29sbGFwc2UodHJ1ZSk7XG5cbiAgICAvLyBBIHRyYWlsaW5nIDxicj4gYWxvbmUgZG9lc24ndCByZW5kZXIgYW4gZW1wdHkgbGluZSBpbiBjb250ZW50ZWRpdGFibGUg4oCUXG4gICAgLy8gYSBaV1MgZ2l2ZXMgdGhlIGNhcmV0IGEgcGxhY2UgdG8gbGFuZC5cbiAgICBpZiAoIWJyLm5leHRTaWJsaW5nKSB7XG4gICAgICBjb25zdCB6d3MgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShaV1MpO1xuICAgICAgcmFuZ2UuaW5zZXJ0Tm9kZSh6d3MpO1xuICAgICAgcmFuZ2Uuc2V0U3RhcnQoendzLCAwKTtcbiAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgIH1cblxuICAgIHNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xuICB9XG5cbiAgLy8g4pSA4pSA4pSAIE1lbnRpb24gdHJpZ2dlciAvIGRyb3Bkb3duIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgY2hlY2tGb3JNZW50aW9uVHJpZ2dlcigpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXNlbGVjdGlvbi5yYW5nZUNvdW50IHx8ICF0aGlzLmlucHV0RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG4gICAgY29uc3QgdGV4dEJlZm9yZUN1cnNvciA9IHRoaXMuZ2V0VGV4dEJlZm9yZUN1cnNvcihyYW5nZSk7XG4gICAgY29uc3QgbGFzdEF0SW5kZXggPSB0ZXh0QmVmb3JlQ3Vyc29yLmxhc3RJbmRleE9mKCdAJyk7XG5cbiAgICBpZiAobGFzdEF0SW5kZXggPT09IC0xKSB7XG4gICAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy9JZiB3ZSBhbGxvdyBmb3IgYSBzaW5nbGUgc3BhY2UsIHdlIG5lZWQgdG8gY2hlY2sgdG8gbWFrZSBzdXJlIHRoYXQgdGhpcyBsb2dpYyB3b24ndCBwaWNrIHVwIHByZXZpb3VzXG4gICAgLy8nQCcgbWVudGlvbnMgYW5kIGtlZXAgdGhlIG1lbnRpb24gZHJvcGRvd24gb3BlblxuICAgIGNvbnN0IGF0UG9zaXRpb24gPSB0aGlzLmZpbmREb21Qb3NpdGlvbkF0Q2hhckluZGV4KGxhc3RBdEluZGV4KTtcbiAgICBpZiAoYXRQb3NpdGlvbiAmJiB0aGlzLmlzSW5zaWRlTWVudGlvblNwYW4oYXRQb3NpdGlvbi5ub2RlKSkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGV4dEFmdGVyQXQgPSB0ZXh0QmVmb3JlQ3Vyc29yLnN1YnN0cmluZyhsYXN0QXRJbmRleCArIDEpO1xuICAgIGNvbnN0IGNoYXIxID0gdGV4dEFmdGVyQXQuY2hhckNvZGVBdCgwKTtcbiAgICBjb25zdCBjaGFyTiA9IHRleHRBZnRlckF0LmNoYXJDb2RlQXQodGV4dEFmdGVyQXQubGVuZ3RoIC0gMSk7XG4gICAgY29uc3QgY2hhck5fMSA9IHRleHRBZnRlckF0LmNoYXJDb2RlQXQodGV4dEFmdGVyQXQubGVuZ3RoIC0gMik7XG4gICAgLy9UaGVzZSBhcmUgdGhlIFVuaWNvZGUgcmVwcmVzZW50YXRpb25zIG9mIG5vcm1hbCBzcGFjZSBhbmQgbm9uLWJyZWFraW5nIHNwYWNlXG4gICAgY29uc3QgdW5pY29kZVNwYWNlQ2hhcnMgPSBbMzIsIDE2MF07XG5cbiAgICAvLyBDbG9zZSBtZW50aW9ucyBpZjpcbiAgICAvLyAtIFRoZXJlJ3MgYSBkb3VibGUgc3BhY2UgKGFsbG93cyBzaW5nbGUgc3BhY2VzIGluIHRoZSBtaWRkbGUgb2Ygc2VhcmNoKVxuICAgIC8vIC0gVGhlIHRleHQgc3RhcnRzIHdpdGggYSBzcGFjZSAodHlwaW5nIFwiQCBcIiBzaG91bGQgbm90IHRyaWdnZXIgbWVudGlvbnMpXG4gICAgaWYgKFxuICAgICAgdGV4dEFmdGVyQXQuaW5jbHVkZXMoJyAgJykgfHxcbiAgICAgIHRleHRBZnRlckF0LnN0YXJ0c1dpdGgoJyAnKSB8fFxuICAgICAgY2hhcjEgPT0gMTYwIHx8XG4gICAgICAodW5pY29kZVNwYWNlQ2hhcnMuaW5jbHVkZXMoY2hhck4pICYmIHVuaWNvZGVTcGFjZUNoYXJzLmluY2x1ZGVzKGNoYXJOXzEpKVxuICAgICkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFRyaW0gdHJhaWxpbmcvbGVhZGluZyBzcGFjZXMgZnJvbSBzZWFyY2ggdGV4dCB3aGlsZSBwcmVzZXJ2aW5nIHNwYWNlcyBpbiB0aGUgbWlkZGxlXG4gICAgdGhpcy5tZW50aW9uU2VhcmNoVGV4dCA9IHRleHRBZnRlckF0LnRyaW0oKTtcbiAgICAvLyBPbmx5IHNob3cgbWVudGlvbnMgaWYgdGhlcmUgYXJlIGZpbHRlcmVkIHVzZXJzXG4gICAgY29uc3QgZmlsdGVyZWRVc2VycyA9IHRoaXMuZ2V0RmlsdGVyZWRVc2VycygpO1xuICAgIGlmIChmaWx0ZXJlZFVzZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5jbG9zZU1lbnRpb25zKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5tZW50aW9uc1Zpc2libGUgPSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSAwO1xuXG4gICAgLy9TYXZlIHRoZSBjdXJyZW50IHJhbmdlIGZvciBsYXRlciByZXN0b3JhdGlvbiAobmVlZGVkIGZvciBjbGljayBzZWxlY3Rpb24pXG4gICAgLy9EQUhORSBOT1RFIC0gdGhpcyBpcyBhbm5veWluZ2x5IG5lY2Vlc3NhcnkgYmVjYXVzZSBjbGlja3MgYW5kIGVudGVyIGtleXMgaGF2ZSBkaWZmZXJlbnQgZWZmZWN0cyBvbiB0aGVcbiAgICAvL2ZvY3VzIG9mIHRoZSBjb250ZW50ZWRpdGFibGUgZGl2XG4gICAgdGhpcy5zYXZlZFJhbmdlID0gcmFuZ2UuY2xvbmVSYW5nZSgpO1xuXG4gICAgaWYgKGF0UG9zaXRpb24pIHtcbiAgICAgIGNvbnN0IGF0UmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgICAgYXRSYW5nZS5zZXRTdGFydChhdFBvc2l0aW9uLm5vZGUsIGF0UG9zaXRpb24ub2Zmc2V0KTtcbiAgICAgIGF0UmFuZ2Uuc2V0RW5kKGF0UG9zaXRpb24ubm9kZSwgYXRQb3NpdGlvbi5vZmZzZXQgKyAxKTtcbiAgICAgIHRoaXMubWVudGlvbkFuY2hvciA9IGF0UmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRUZXh0QmVmb3JlQ3Vyc29yKHJhbmdlOiBSYW5nZSk6IHN0cmluZyB7XG4gICAgY29uc3QgY2xvbmVkUmFuZ2UgPSByYW5nZS5jbG9uZVJhbmdlKCk7XG4gICAgLy9XZSBzZWxlY3QgYWxsIG9mIHRoZSBpbnB1dCBjb250ZW50cywgYW5kIHRoZW4gbW92ZSB0aGUgZW5kIHBvaW50IHRvIHRoZSBjdXJyZW50IGN1cnNvciBwb3NpdGlvblxuICAgIGNsb25lZFJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyh0aGlzLmlucHV0RWxlbWVudCEubmF0aXZlRWxlbWVudCk7XG4gICAgY2xvbmVkUmFuZ2Uuc2V0RW5kKHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0KTtcbiAgICAvL0NyZWF0ZSBhIHRlbXBvcmFyeSBkaXYgc28gdGhhdCB3ZSBjYW4gZXh0cmFjdCB0ZXh0IGNvbnRlbnQgZnJvbSBpdFxuICAgIGNvbnN0IGZyYWdtZW50ID0gY2xvbmVkUmFuZ2UuY2xvbmVDb250ZW50cygpO1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5hcHBlbmRDaGlsZChmcmFnbWVudCk7XG4gICAgLy9HZXQgdGV4dCBjb250ZW50LCByZXBsYWNpbmcgbWVudGlvbiBzcGFucyB3aXRoIEBuYW1lXG4gICAgcmV0dXJuIGRpdi50ZXh0Q29udGVudCB8fCAnJztcbiAgfVxuXG4gIGdldEZpbHRlcmVkVXNlcnMoKTogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Vc2VyW10ge1xuICAgIGNvbnN0IHVzZXJzID0gIXRoaXMubWVudGlvblNlYXJjaFRleHRcbiAgICAgID8gdGhpcy51c2Vyc1xuICAgICAgOiB0aGlzLnVzZXJzLmZpbHRlcih1c2VyID0+XG4gICAgICAgICAgdXNlci5uYW1lXG4gICAgICAgICAgICAudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgLmluY2x1ZGVzKHRoaXMubWVudGlvblNlYXJjaFRleHQudG9Mb3dlckNhc2UoKSksXG4gICAgICAgICk7XG4gICAgcmV0dXJuIHVzZXJzLnNsaWNlKCkuc29ydCgoYSwgYikgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG4gIH1cblxuICBvblVzZXJIb3ZlcihpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZFVzZXJJbmRleCA9IGluZGV4O1xuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgc2VsZWN0VXNlcih1c2VyOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LlVzZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaW5wdXRFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vVGhpcyBnZXRzIERPTSBpbmZvIGZyb20gdXNlciAoZS5nLiBoaWdobGlnaHRlZCBzZWxlY3Rpb25zLCBhbmQgY3Vyc29yIHBvc2l0aW9uKVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbGVjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBSZXN0b3JlIHRoZSBzYXZlZCByYW5nZSBpZiBhdmFpbGFibGUgKG5lZWRlZCB3aGVuIHNlbGVjdGluZyB2aWEgY2xpY2spXG4gICAgaWYgKHRoaXMuc2F2ZWRSYW5nZSkge1xuICAgICAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgc2VsZWN0aW9uLmFkZFJhbmdlKHRoaXMuc2F2ZWRSYW5nZSk7XG4gICAgfVxuICAgIGlmICghc2VsZWN0aW9uLnJhbmdlQ291bnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gRGVsZXRlIHRoZSBcIkBcIiBhbmQgc2VhcmNoIHRleHRcbiAgICB0aGlzLmRlbGV0ZUF0TWVudGlvblNlYXJjaCgpO1xuXG4gICAgLy9EQUhORSBOT1RFIC0gdGhpcyB3b3VsZCBpZGVhbGx5IGJlIHRoZSBzYW1lIGFzIGNvbnRlbnRJdGVtVG9IVE1MLCBidXQgd2UgbmVlZCBhbiBhY3R1YWwgZWxlbWVudCByZWZlcmVuY2UgaGVyZSBpbiBvcmRlciB0byBhcHBlbmQgaXQgdG8gdGhlIERPTVxuICAgIGNvbnN0IG1lbnRpb25TcGFuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIG1lbnRpb25TcGFuLmNsYXNzTmFtZSA9IHRoaXMucmVhZG9ubHkgPyAncmVhZG9ubHktbWVudGlvbicgOiAnbWVudGlvbic7XG4gICAgbWVudGlvblNwYW4uc2V0QXR0cmlidXRlKCdkYXRhLWlkJywgU3RyaW5nKHVzZXIuaWQpKTtcbiAgICBtZW50aW9uU3Bhbi5zZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScsICdtZW50aW9uJyk7XG4gICAgbWVudGlvblNwYW4uc2V0QXR0cmlidXRlKCdjb250ZW50ZWRpdGFibGUnLCAnZmFsc2UnKTtcbiAgICBtZW50aW9uU3Bhbi50ZXh0Q29udGVudCA9IGBAJHt1c2VyLm5hbWV9YDtcblxuICAgIHRoaXMuaW5zZXJ0Tm9kZXNBdEN1cnNvcihbbWVudGlvblNwYW4sIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCcgJyldKTtcbiAgICB0aGlzLm5vcm1hbGl6ZU1lbnRpb25QYWRkaW5nKCk7XG5cbiAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgICB0aGlzLmVtaXRDb250ZW50Q2hhbmdlKCk7XG4gIH1cblxuICBwcml2YXRlIGRlbGV0ZUF0TWVudGlvblNlYXJjaCgpOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWxlY3Rpb24gfHwgIXNlbGVjdGlvbi5yYW5nZUNvdW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vVGhpcyByZXByZXNlbnRzIHRoZSBjdXJyZW50IHBvc2l0aW9uIG9mIHRoZSBjdXJzb3JcbiAgICBjb25zdCBjdXJzb3JSYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgIC8vVGhpcyB3aWxsIHJldHVybiBhbGwgb2YgdGhlIHJhdyB0ZXh0IChIVE1MLXN0cmlwcGVkKSBiZWZvcmUgdGhlIGN1cnNvclxuICAgIGNvbnN0IHRleHRCZWZvcmVDdXJzb3IgPSB0aGlzLmdldFRleHRCZWZvcmVDdXJzb3IoY3Vyc29yUmFuZ2UpO1xuICAgIC8vV2UgZG8gdGhhdF4gc28gdGhhdCB3ZSBjYW4gZmluZCB0aGUgY29ycmVjdCBpbmRleCBvZiB0aGUgbW9zdCByZWNlbnQgJ0AnXG4gICAgY29uc3QgbGFzdEF0SW5kZXggPSB0ZXh0QmVmb3JlQ3Vyc29yLmxhc3RJbmRleE9mKCdAJyk7XG5cbiAgICBpZiAobGFzdEF0SW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGF0UG9zaXRpb24gPSB0aGlzLmZpbmREb21Qb3NpdGlvbkF0Q2hhckluZGV4KGxhc3RBdEluZGV4KTtcbiAgICBpZiAoIWF0UG9zaXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gQ3JlYXRlIHJhbmdlIGZyb20gXCJAXCIgdG8gY3Vyc29yIGFuZCBkZWxldGUgaXRcbiAgICBjb25zdCBkZWxldGVSYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgZGVsZXRlUmFuZ2Uuc2V0U3RhcnQoYXRQb3NpdGlvbi5ub2RlLCBhdFBvc2l0aW9uLm9mZnNldCk7XG4gICAgZGVsZXRlUmFuZ2Uuc2V0RW5kKGN1cnNvclJhbmdlLmVuZENvbnRhaW5lciwgY3Vyc29yUmFuZ2UuZW5kT2Zmc2V0KTtcbiAgICBkZWxldGVSYW5nZS5kZWxldGVDb250ZW50cygpO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0luc2lkZU1lbnRpb25TcGFuKG5vZGU6IE5vZGUpOiBib29sZWFuIHtcbiAgICBsZXQgY3VycmVudE5vZGU6IE5vZGUgfCBudWxsID0gbm9kZTtcbiAgICB3aGlsZSAoY3VycmVudE5vZGUgJiYgY3VycmVudE5vZGUgIT09IHRoaXMuaW5wdXRFbGVtZW50Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICBpZiAoTWVudGlvbnNJbnB1dENvbXBvbmVudC5pc01lbnRpb24oY3VycmVudE5vZGUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9UaGlzIHdpbGwgZ28gdGV4dCBub2RlIGJ5IG5vZGUgbG9va2luZyBmb3IgdGhlXG4gIC8vQCBtZW50aW9uIGFuZCBnaXZlIGl0cyBwb3NpdGlvbiBpbiB0aGUgY29udGV4dCBvZiB0aGF0IG5vZGVcbiAgcHJpdmF0ZSBmaW5kRG9tUG9zaXRpb25BdENoYXJJbmRleChcbiAgICBjaGFySW5kZXg6IG51bWJlcixcbiAgKTogeyBub2RlOiBOb2RlOyBvZmZzZXQ6IG51bWJlciB9IHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmlucHV0RWxlbWVudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8vIFdhbGsgdGhyb3VnaCBhbGwgdGV4dCBub2RlcyBpbiB0aGUgaW5wdXQsIGNvdW50aW5nIGNoYXJhY3RlcnNcbiAgICBjb25zdCB0cmVlV2Fsa2VyID0gZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlcihcbiAgICAgIHRoaXMuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQsXG4gICAgICBOb2RlRmlsdGVyLlNIT1dfVEVYVCxcbiAgICAgIG51bGwsXG4gICAgKTtcbiAgICBsZXQgY2hhckNvdW50ID0gMDtcbiAgICB3aGlsZSAodHJlZVdhbGtlci5uZXh0Tm9kZSgpKSB7XG4gICAgICBjb25zdCBub2RlID0gdHJlZVdhbGtlci5jdXJyZW50Tm9kZTtcbiAgICAgIGNvbnN0IHRleHQgPSBub2RlLnRleHRDb250ZW50IHx8ICcnO1xuICAgICAgLy8gQ2hlY2sgaWYgb3VyIHRhcmdldCBjaGFyYWN0ZXIgaXMgaW4gdGhpcyB0ZXh0IG5vZGVcbiAgICAgIGlmIChjaGFyQ291bnQgKyB0ZXh0Lmxlbmd0aCA+IGNoYXJJbmRleCkge1xuICAgICAgICByZXR1cm4geyBub2RlLCBvZmZzZXQ6IGNoYXJJbmRleCAtIGNoYXJDb3VudCB9O1xuICAgICAgfVxuICAgICAgY2hhckNvdW50ICs9IHRleHQubGVuZ3RoO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgY2xvc2VNZW50aW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLm1lbnRpb25zVmlzaWJsZSA9IGZhbHNlO1xuICAgIHRoaXMubWVudGlvblNlYXJjaFRleHQgPSAnJztcbiAgICB0aGlzLm1lbnRpb25BbmNob3IgPSBudWxsO1xuICAgIHRoaXMuc2VsZWN0ZWRVc2VySW5kZXggPSAwO1xuICAgIHRoaXMuc2F2ZWRSYW5nZSA9IG51bGw7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRDb250ZW50Q2hhbmdlKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pbnB1dEVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jb250ZW50Q2hhbmdlLmVtaXQodGhpcy5kb21Ub0NvbnRlbnRJdGVtcygpKTtcbiAgfVxuXG4gIHByaXZhdGUgZG9tVG9Db250ZW50SXRlbXMoKTogTWVudGlvbnNJbnB1dENvbXBvbmVudC5Db250ZW50SXRlbVtdIHtcbiAgICBpZiAoIXRoaXMuaW5wdXRFbGVtZW50Py5uYXRpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IGl0ZW1zOiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRJdGVtW10gPSBbXTtcbiAgICBjb25zdCBjaGlsZE5vZGVzID0gdGhpcy5pbnB1dEVsZW1lbnQubmF0aXZlRWxlbWVudC5jaGlsZE5vZGVzO1xuXG4gICAgZm9yIChjb25zdCBub2RlIG9mIEFycmF5LmZyb20oY2hpbGROb2RlcykpIHtcbiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSkge1xuICAgICAgICBjb25zdCBlbGVtZW50ID0gbm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGVsZW1lbnQudGFnTmFtZSA9PT0gJ1NQQU4nICYmXG4gICAgICAgICAgZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdHlwZScpID09PSAnbWVudGlvbidcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgaWQgPSBOdW1iZXIoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtaWQnKSk7XG4gICAgICAgICAgY29uc3QgbmFtZSA9IGVsZW1lbnQudGV4dENvbnRlbnQ/LnJlcGxhY2UoJ0AnLCAnJykgfHwgJyc7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICdtZW50aW9uJywgaWQsIG5hbWUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZWxlbWVudC50YWdOYW1lID09PSAnQlInKSB7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICduZXdsaW5lJyB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgICAvLyBaV1MgcGFkcyBhcmUgYSBET00gYWZmb3JkYW5jZSDigJQgdGhleSBzaG91bGRuJ3QgbGVhayBpbnRvIHRoZSBkYXRhIG1vZGVsLlxuICAgICAgICBjb25zdCB0ZXh0ID0gKG5vZGUudGV4dENvbnRlbnQgfHwgJycpLnJlcGxhY2UoWldTX1JFR0VYLCAnJyk7XG4gICAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgICAgaXRlbXMucHVzaCh7IHR5cGU6ICd0ZXh0JywgdGV4dCB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXRlbXM7XG4gIH1cblxuICBvbkNhbGxvdXRDbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNsb3NlTWVudGlvbnMoKTtcbiAgfVxufVxuXG5leHBvcnQgbmFtZXNwYWNlIE1lbnRpb25zSW5wdXRDb21wb25lbnQge1xuICBleHBvcnQgY29uc3QgQ29udGVudFR5cGVzID0gWydtZW50aW9uJywgJ3RleHQnLCAnbmV3bGluZSddIGFzIGNvbnN0O1xuICBleHBvcnQgdHlwZSBDb250ZW50VHlwZSA9XG4gICAgKHR5cGVvZiBNZW50aW9uc0lucHV0Q29tcG9uZW50LkNvbnRlbnRUeXBlcylbbnVtYmVyXTtcbiAgZXhwb3J0IGludGVyZmFjZSBVc2VyIHtcbiAgICBpZDogbnVtYmVyO1xuICAgIG5hbWU6IHN0cmluZztcbiAgfVxuICBleHBvcnQgdHlwZSBDb250ZW50PFQgZXh0ZW5kcyBDb250ZW50VHlwZT4gPSB7IHR5cGU6IFQgfTtcblxuICBleHBvcnQgdHlwZSBVc2VyTWVudGlvbiA9IENvbnRlbnQ8J21lbnRpb24nPiAmIFVzZXI7XG4gIGV4cG9ydCB0eXBlIFRleHQgPSBDb250ZW50PCd0ZXh0Jz4gJiB7IHRleHQ6IHN0cmluZyB9O1xuICBleHBvcnQgdHlwZSBOZXdsaW5lID0gQ29udGVudDwnbmV3bGluZSc+O1xuXG4gIGV4cG9ydCB0eXBlIENvbnRlbnRJdGVtID0gVXNlck1lbnRpb24gfCBUZXh0IHwgTmV3bGluZTtcblxuICBleHBvcnQgZnVuY3Rpb24gY29udGVudFRvUGxhaW5UZXh0KGNvbnRlbnQ6IENvbnRlbnRJdGVtW10pOiBzdHJpbmcge1xuICAgIHJldHVybiBjb250ZW50XG4gICAgICAubWFwKGl0ZW0gPT4ge1xuICAgICAgICBzd2l0Y2ggKGl0ZW0udHlwZSkge1xuICAgICAgICAgIGNhc2UgJ21lbnRpb24nOlxuICAgICAgICAgICAgcmV0dXJuIGBAJHtpdGVtLm5hbWV9YDtcbiAgICAgICAgICBjYXNlICd0ZXh0JzpcbiAgICAgICAgICAgIHJldHVybiBpdGVtLnRleHQ7XG4gICAgICAgICAgY2FzZSAnbmV3bGluZSc6XG4gICAgICAgICAgICByZXR1cm4gJ1xcbic7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuam9pbignJyk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJtZW50aW9ucy1jb250YWluZXJcIiAjY29udGFpbmVyPlxuICA8ZGl2XG4gICAgKm5nSWY9XCIhcmVhZG9ubHlcIlxuICAgICNpbnB1dFxuICAgIGNsYXNzPVwidGV4dC1jb250ZW50IGVkaXRhYmxlXCJcbiAgICBjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJcbiAgICBbYXR0ci5kYXRhLXBsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAoaW5wdXQpPVwib25JbnB1dCgpXCJcbiAgICAoa2V5ZG93bik9XCJvbktleURvd24oJGV2ZW50KVwiXG4gICAgKHBhc3RlKT1cIm9uUGFzdGUoJGV2ZW50KVwiXG4gICAgKGNvcHkpPVwib25Db3B5KCRldmVudClcIlxuICAgIChjdXQpPVwib25DdXQoJGV2ZW50KVwiXG4gID48L2Rpdj5cblxuICA8ZGl2ICpuZ0lmPVwicmVhZG9ubHlcIiAjaW5wdXQgY2xhc3M9XCJ0ZXh0LWNvbnRlbnRcIj48L2Rpdj5cblxuICA8cml2LWNhbGxvdXRcbiAgICAqbmdJZj1cIiFyZWFkb25seSAmJiBtZW50aW9uc1Zpc2libGUgJiYgbWVudGlvbkFuY2hvclwiXG4gICAgW2FuY2hvcl09XCJtZW50aW9uQW5jaG9yXCJcbiAgICBbaXNNb2RhbF09XCJ0cnVlXCJcbiAgICBbc2hvd0NhcmV0XT1cImZhbHNlXCJcbiAgICBbYWxsb3dlZFBvc2l0aW9uc109XCJbJ2JvdHRvbS1yaWdodCcsICd0b3AtcmlnaHQnXVwiXG4gICAgW3RoZW1lXT1cIidsaWdodCdcIlxuICAgIChjbG9zZSk9XCJvbkNhbGxvdXRDbG9zZSgpXCJcbiAgPlxuICAgIDxkaXYgY2xhc3M9XCJtZW50aW9ucy1jb250ZW50XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwibWVudGlvbnMtaGVhZGVyXCI+TWVudGlvbiBzb21lb25lPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibWVudGlvbnMtbGlzdFwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nRm9yPVwibGV0IHVzZXIgb2YgZ2V0RmlsdGVyZWRVc2VycygpOyBsZXQgaSA9IGluZGV4XCJcbiAgICAgICAgICBbY2xhc3Muc2VsZWN0ZWRdPVwiaSA9PT0gc2VsZWN0ZWRVc2VySW5kZXhcIlxuICAgICAgICAgIChtb3VzZWVudGVyKT1cIm9uVXNlckhvdmVyKGkpXCJcbiAgICAgICAgICAoY2xpY2spPVwic2VsZWN0VXNlcih1c2VyKVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyB1c2VyLm5hbWUgfX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9yaXYtY2FsbG91dD5cbjwvZGl2PlxuIl19