slate-angular 1.9.3 → 13.0.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.
Files changed (63) hide show
  1. package/components/descendant/descendant.component.d.ts +2 -3
  2. package/{esm2015/components/block-card/block-card.component.js → esm2020/components/block-card/block-card.component.mjs} +5 -8
  3. package/{esm2015/components/children/children.component.js → esm2020/components/children/children.component.mjs} +3 -3
  4. package/esm2020/components/descendant/descendant.component.mjs +183 -0
  5. package/esm2020/components/editable/editable.component.mjs +1057 -0
  6. package/{esm2015/components/element/default-element.component.js → esm2020/components/element/default-element.component.mjs} +3 -3
  7. package/{esm2015/components/element/default-element.component.token.js → esm2020/components/element/default-element.component.token.mjs} +0 -0
  8. package/{esm2015/components/element/element.component.js → esm2020/components/element/element.component.mjs} +3 -3
  9. package/{esm2015/components/leaf/default-leaf.component.js → esm2020/components/leaf/default-leaf.component.mjs} +3 -3
  10. package/{esm2015/components/leaf/leaf.component.js → esm2020/components/leaf/leaf.component.mjs} +3 -3
  11. package/{esm2015/components/leaves/leaves.component.js → esm2020/components/leaves/leaves.component.mjs} +3 -3
  12. package/esm2020/components/string/string.component.mjs +73 -0
  13. package/esm2020/components/string/template.component.mjs +26 -0
  14. package/{esm2015/components/text/default-text.component.js → esm2020/components/text/default-text.component.mjs} +3 -3
  15. package/{esm2015/components/text/void-text.component.js → esm2020/components/text/void-text.component.mjs} +3 -3
  16. package/{esm2015/custom-event/BeforeInputEventPlugin.js → esm2020/custom-event/BeforeInputEventPlugin.mjs} +0 -0
  17. package/{esm2015/custom-event/DOMTopLevelEventTypes.js → esm2020/custom-event/DOMTopLevelEventTypes.mjs} +0 -0
  18. package/{esm2015/custom-event/FallbackCompositionState.js → esm2020/custom-event/FallbackCompositionState.mjs} +0 -0
  19. package/{esm2015/custom-event/before-input-polyfill.js → esm2020/custom-event/before-input-polyfill.mjs} +0 -0
  20. package/{esm2015/module.js → esm2020/module.mjs} +5 -6
  21. package/esm2020/plugins/angular-editor.mjs +565 -0
  22. package/{esm2015/plugins/with-angular.js → esm2020/plugins/with-angular.mjs} +0 -0
  23. package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  24. package/{esm2015/slate-angular.js → esm2020/slate-angular.mjs} +0 -0
  25. package/{esm2015/types/error.js → esm2020/types/error.mjs} +0 -0
  26. package/{esm2015/types/feature.js → esm2020/types/feature.mjs} +0 -0
  27. package/{esm2015/types/index.js → esm2020/types/index.mjs} +1 -1
  28. package/{esm2015/types/view.js → esm2020/types/view.mjs} +0 -0
  29. package/esm2020/utils/block-card.mjs +25 -0
  30. package/{esm2015/utils/dom.js → esm2020/utils/dom.mjs} +0 -0
  31. package/{esm2015/utils/environment.js → esm2020/utils/environment.mjs} +0 -0
  32. package/{esm2015/utils/global-normalize.js → esm2020/utils/global-normalize.mjs} +0 -0
  33. package/{esm2015/utils/hotkeys.js → esm2020/utils/hotkeys.mjs} +0 -0
  34. package/{esm2015/utils/index.js → esm2020/utils/index.mjs} +0 -0
  35. package/{esm2015/utils/key.js → esm2020/utils/key.mjs} +0 -0
  36. package/{esm2015/utils/lines.js → esm2020/utils/lines.mjs} +0 -0
  37. package/esm2020/utils/range-list.mjs +29 -0
  38. package/{esm2015/utils/view.js → esm2020/utils/view.mjs} +0 -0
  39. package/{esm2015/utils/weak-maps.js → esm2020/utils/weak-maps.mjs} +0 -0
  40. package/{esm2015/view/base.js → esm2020/view/base.mjs} +12 -12
  41. package/{esm2015/view/before-context-change.js → esm2020/view/before-context-change.mjs} +0 -0
  42. package/esm2020/view/container-item.mjs +102 -0
  43. package/{esm2015/view/container.js → esm2020/view/container.mjs} +3 -3
  44. package/{esm2015/view/context.js → esm2020/view/context.mjs} +0 -0
  45. package/fesm2015/{slate-angular.js → slate-angular.mjs} +83 -100
  46. package/fesm2015/slate-angular.mjs.map +1 -0
  47. package/fesm2020/slate-angular.mjs +3643 -0
  48. package/fesm2020/slate-angular.mjs.map +1 -0
  49. package/package.json +30 -6
  50. package/styles/index.scss +1 -1
  51. package/types/index.d.ts +1 -0
  52. package/view/container-item.d.ts +2 -3
  53. package/bundles/slate-angular.umd.js +0 -4298
  54. package/bundles/slate-angular.umd.js.map +0 -1
  55. package/esm2015/components/descendant/descendant.component.js +0 -179
  56. package/esm2015/components/editable/editable.component.js +0 -1063
  57. package/esm2015/components/string/string.component.js +0 -73
  58. package/esm2015/components/string/template.component.js +0 -30
  59. package/esm2015/plugins/angular-editor.js +0 -565
  60. package/esm2015/utils/block-card.js +0 -25
  61. package/esm2015/utils/range-list.js +0 -30
  62. package/esm2015/view/container-item.js +0 -105
  63. package/fesm2015/slate-angular.js.map +0 -1
@@ -0,0 +1,1057 @@
1
+ import { Component, Input, ViewChild, HostBinding, ElementRef, ChangeDetectionStrategy, forwardRef } from '@angular/core';
2
+ import { NODE_TO_ELEMENT, IS_FOCUSED, EDITOR_TO_ELEMENT, ELEMENT_TO_NODE, IS_READONLY, EDITOR_TO_ON_CHANGE, EDITOR_TO_WINDOW } from '../../utils/weak-maps';
3
+ import { Element, Transforms, Editor, Range, Path, Node } from 'slate';
4
+ import getDirection from 'direction';
5
+ import { AngularEditor } from '../../plugins/angular-editor';
6
+ import { isDOMNode, isDOMElement, isPlainTextOnlyPaste, getDefaultView } from '../../utils/dom';
7
+ import { Subject } from 'rxjs';
8
+ import { IS_FIREFOX, IS_SAFARI, IS_CHROME, HAS_BEFORE_INPUT_SUPPORT } from '../../utils/environment';
9
+ import Hotkeys from '../../utils/hotkeys';
10
+ import { extractBeforeInputEvent } from '../../custom-event/BeforeInputEventPlugin';
11
+ import { BEFORE_INPUT_EVENTS } from '../../custom-event/before-input-polyfill';
12
+ import { SlateErrorCode } from '../../types/error';
13
+ import Debug from 'debug';
14
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
15
+ import { HistoryEditor } from 'slate-history';
16
+ import { isDecoratorRangeListEqual } from '../../utils';
17
+ import { check, normalize } from '../../utils/global-normalize';
18
+ import * as i0 from "@angular/core";
19
+ import * as i1 from "../children/children.component";
20
+ import * as i2 from "../string/template.component";
21
+ const timeDebug = Debug('slate-angular-time');
22
+ // not correctly clipboardData on beforeinput
23
+ const forceOnDOMPaste = IS_SAFARI;
24
+ export class SlateEditableComponent {
25
+ constructor(elementRef, renderer2, cdr, ngZone, injector) {
26
+ this.elementRef = elementRef;
27
+ this.renderer2 = renderer2;
28
+ this.cdr = cdr;
29
+ this.ngZone = ngZone;
30
+ this.injector = injector;
31
+ this.destroy$ = new Subject();
32
+ this.isComposing = false;
33
+ this.isDraggingInternally = false;
34
+ this.isUpdatingSelection = false;
35
+ this.latestElement = null;
36
+ this.manualListeners = [];
37
+ this.onTouchedCallback = () => { };
38
+ this.onChangeCallback = () => { };
39
+ this.decorate = () => [];
40
+ this.isStrictDecorate = true;
41
+ this.trackBy = () => null;
42
+ this.readonly = false;
43
+ //#endregion
44
+ //#region DOM attr
45
+ this.spellCheck = false;
46
+ this.autoCorrect = false;
47
+ this.autoCapitalize = false;
48
+ this.dataSlateEditor = true;
49
+ this.dataSlateNode = 'value';
50
+ this.dataGramm = false;
51
+ }
52
+ get hasBeforeInputSupport() {
53
+ return HAS_BEFORE_INPUT_SUPPORT;
54
+ }
55
+ ngOnInit() {
56
+ this.editor.injector = this.injector;
57
+ this.editor.children = [];
58
+ let window = getDefaultView(this.elementRef.nativeElement);
59
+ EDITOR_TO_WINDOW.set(this.editor, window);
60
+ EDITOR_TO_ELEMENT.set(this.editor, this.elementRef.nativeElement);
61
+ NODE_TO_ELEMENT.set(this.editor, this.elementRef.nativeElement);
62
+ ELEMENT_TO_NODE.set(this.elementRef.nativeElement, this.editor);
63
+ IS_READONLY.set(this.editor, this.readonly);
64
+ EDITOR_TO_ON_CHANGE.set(this.editor, () => {
65
+ this.ngZone.run(() => {
66
+ this.onChange();
67
+ });
68
+ });
69
+ this.ngZone.runOutsideAngular(() => {
70
+ this.initialize();
71
+ });
72
+ this.initializeViewContext();
73
+ this.initializeContext();
74
+ // remove unused DOM, just keep templateComponent instance
75
+ this.templateElementRef.nativeElement.remove();
76
+ // add browser class
77
+ let browserClass = IS_FIREFOX ? 'firefox' : (IS_SAFARI ? 'safari' : '');
78
+ browserClass && this.elementRef.nativeElement.classList.add(browserClass);
79
+ }
80
+ ngOnChanges(simpleChanges) {
81
+ if (!this.initialized) {
82
+ return;
83
+ }
84
+ const decorateChange = simpleChanges['decorate'];
85
+ if (decorateChange) {
86
+ this.forceFlush();
87
+ }
88
+ const readonlyChange = simpleChanges['readonly'];
89
+ if (readonlyChange) {
90
+ IS_READONLY.set(this.editor, this.readonly);
91
+ this.detectContext();
92
+ this.toSlateSelection();
93
+ }
94
+ }
95
+ registerOnChange(fn) {
96
+ this.onChangeCallback = fn;
97
+ }
98
+ registerOnTouched(fn) {
99
+ this.onTouchedCallback = fn;
100
+ }
101
+ writeValue(value) {
102
+ if (value && value.length) {
103
+ if (check(value)) {
104
+ this.editor.children = value;
105
+ }
106
+ else {
107
+ this.editor.onError({
108
+ code: SlateErrorCode.InvalidValueError,
109
+ name: 'initialize invalid data',
110
+ data: value
111
+ });
112
+ this.editor.children = normalize(value);
113
+ }
114
+ this.initializeContext();
115
+ this.cdr.markForCheck();
116
+ }
117
+ }
118
+ initialize() {
119
+ this.initialized = true;
120
+ const window = AngularEditor.getWindow(this.editor);
121
+ this.addEventListener('selectionchange', event => {
122
+ this.toSlateSelection();
123
+ }, window.document);
124
+ if (HAS_BEFORE_INPUT_SUPPORT) {
125
+ this.addEventListener('beforeinput', this.onDOMBeforeInput.bind(this));
126
+ }
127
+ this.addEventListener('blur', this.onDOMBlur.bind(this));
128
+ this.addEventListener('click', this.onDOMClick.bind(this));
129
+ this.addEventListener('compositionend', this.onDOMCompositionEnd.bind(this));
130
+ this.addEventListener('compositionstart', this.onDOMCompositionStart.bind(this));
131
+ this.addEventListener('copy', this.onDOMCopy.bind(this));
132
+ this.addEventListener('cut', this.onDOMCut.bind(this));
133
+ this.addEventListener('dragover', this.onDOMDragOver.bind(this));
134
+ this.addEventListener('dragstart', this.onDOMDragStart.bind(this));
135
+ this.addEventListener('dragend', this.onDOMDragEnd.bind(this));
136
+ this.addEventListener('drop', this.onDOMDrop.bind(this));
137
+ this.addEventListener('focus', this.onDOMFocus.bind(this));
138
+ this.addEventListener('keydown', this.onDOMKeydown.bind(this));
139
+ this.addEventListener('paste', this.onDOMPaste.bind(this));
140
+ BEFORE_INPUT_EVENTS.forEach(event => {
141
+ this.addEventListener(event.name, () => { });
142
+ });
143
+ }
144
+ toNativeSelection() {
145
+ try {
146
+ const { selection } = this.editor;
147
+ const root = AngularEditor.findDocumentOrShadowRoot(this.editor);
148
+ const domSelection = root.getSelection();
149
+ if (this.isComposing || !domSelection || !AngularEditor.isFocused(this.editor)) {
150
+ return;
151
+ }
152
+ const hasDomSelection = domSelection.type !== 'None';
153
+ // If the DOM selection is properly unset, we're done.
154
+ if (!selection && !hasDomSelection) {
155
+ return;
156
+ }
157
+ // If the DOM selection is already correct, we're done.
158
+ // verify that the dom selection is in the editor
159
+ const editorElement = EDITOR_TO_ELEMENT.get(this.editor);
160
+ let hasDomSelectionInEditor = false;
161
+ if (editorElement.contains(domSelection.anchorNode) && editorElement.contains(domSelection.focusNode)) {
162
+ hasDomSelectionInEditor = true;
163
+ }
164
+ // If the DOM selection is in the editor and the editor selection is already correct, we're done.
165
+ if (hasDomSelection &&
166
+ hasDomSelectionInEditor &&
167
+ selection &&
168
+ hasStringTarget(domSelection) &&
169
+ Range.equals(AngularEditor.toSlateRange(this.editor, domSelection), selection)) {
170
+ return;
171
+ }
172
+ // when <Editable/> is being controlled through external value
173
+ // then its children might just change - DOM responds to it on its own
174
+ // but Slate's value is not being updated through any operation
175
+ // and thus it doesn't transform selection on its own
176
+ if (selection && !AngularEditor.hasRange(this.editor, selection)) {
177
+ this.editor.selection = AngularEditor.toSlateRange(this.editor, domSelection);
178
+ return;
179
+ }
180
+ // Otherwise the DOM selection is out of sync, so update it.
181
+ const el = AngularEditor.toDOMNode(this.editor, this.editor);
182
+ this.isUpdatingSelection = true;
183
+ const newDomRange = selection && AngularEditor.toDOMRange(this.editor, selection);
184
+ if (newDomRange) {
185
+ // COMPAT: Since the DOM range has no concept of backwards/forwards
186
+ // we need to check and do the right thing here.
187
+ if (Range.isBackward(selection)) {
188
+ // eslint-disable-next-line max-len
189
+ domSelection.setBaseAndExtent(newDomRange.endContainer, newDomRange.endOffset, newDomRange.startContainer, newDomRange.startOffset);
190
+ }
191
+ else {
192
+ // eslint-disable-next-line max-len
193
+ domSelection.setBaseAndExtent(newDomRange.startContainer, newDomRange.startOffset, newDomRange.endContainer, newDomRange.endOffset);
194
+ }
195
+ }
196
+ else {
197
+ domSelection.removeAllRanges();
198
+ }
199
+ setTimeout(() => {
200
+ // COMPAT: In Firefox, it's not enough to create a range, you also need
201
+ // to focus the contenteditable element too. (2016/11/16)
202
+ if (newDomRange && IS_FIREFOX) {
203
+ el.focus();
204
+ }
205
+ this.isUpdatingSelection = false;
206
+ });
207
+ }
208
+ catch (error) {
209
+ this.editor.onError({ code: SlateErrorCode.ToNativeSelectionError, nativeError: error });
210
+ }
211
+ }
212
+ onChange() {
213
+ this.forceFlush();
214
+ this.onChangeCallback(this.editor.children);
215
+ }
216
+ ngAfterViewChecked() {
217
+ timeDebug('editable ngAfterViewChecked');
218
+ }
219
+ ngDoCheck() {
220
+ timeDebug('editable ngDoCheck');
221
+ }
222
+ forceFlush() {
223
+ timeDebug('start data sync');
224
+ this.detectContext();
225
+ this.cdr.detectChanges();
226
+ // repair collaborative editing when Chinese input is interrupted by other users' cursors
227
+ // when the DOMElement where the selection is located is removed
228
+ // the compositionupdate and compositionend events will no longer be fired
229
+ // so isComposing needs to be corrected
230
+ // need exec after this.cdr.detectChanges() to render HTML
231
+ // need exec before this.toNativeSelection() to correct native selection
232
+ if (this.isComposing) {
233
+ // Composition input text be not rendered when user composition input with selection is expanded
234
+ // At this time, the following matching conditions are met, assign isComposing to false, and the status is wrong
235
+ // this time condition is true and isComposiing is assigned false
236
+ // Therefore, need to wait for the composition input text to be rendered before performing condition matching
237
+ setTimeout(() => {
238
+ const textNode = Node.get(this.editor, this.editor.selection.anchor.path);
239
+ const textDOMNode = AngularEditor.toDOMNode(this.editor, textNode);
240
+ let textContent = '';
241
+ // skip decorate text
242
+ textDOMNode.querySelectorAll('[editable-text]').forEach((stringDOMNode) => {
243
+ let text = stringDOMNode.textContent;
244
+ const zeroChar = '\uFEFF';
245
+ // remove zero with char
246
+ if (text.startsWith(zeroChar)) {
247
+ text = text.slice(1);
248
+ }
249
+ if (text.endsWith(zeroChar)) {
250
+ text = text.slice(0, text.length - 1);
251
+ }
252
+ textContent += text;
253
+ });
254
+ if (Node.string(textNode).endsWith(textContent)) {
255
+ this.isComposing = false;
256
+ }
257
+ }, 0);
258
+ }
259
+ this.toNativeSelection();
260
+ timeDebug('end data sync');
261
+ }
262
+ initializeContext() {
263
+ this.context = {
264
+ parent: this.editor,
265
+ selection: this.editor.selection,
266
+ decorations: this.generateDecorations(),
267
+ decorate: this.decorate,
268
+ readonly: this.readonly
269
+ };
270
+ }
271
+ initializeViewContext() {
272
+ this.viewContext = {
273
+ editor: this.editor,
274
+ renderElement: this.renderElement,
275
+ renderLeaf: this.renderLeaf,
276
+ renderText: this.renderText,
277
+ trackBy: this.trackBy,
278
+ isStrictDecorate: this.isStrictDecorate,
279
+ templateComponent: this.templateComponent
280
+ };
281
+ }
282
+ detectContext() {
283
+ const decorations = this.generateDecorations();
284
+ if (this.context.selection !== this.editor.selection ||
285
+ this.context.decorate !== this.decorate ||
286
+ this.context.readonly !== this.readonly ||
287
+ !isDecoratorRangeListEqual(this.context.decorations, decorations)) {
288
+ this.context = {
289
+ parent: this.editor,
290
+ selection: this.editor.selection,
291
+ decorations: decorations,
292
+ decorate: this.decorate,
293
+ readonly: this.readonly
294
+ };
295
+ }
296
+ }
297
+ composePlaceholderDecorate(editor) {
298
+ if (this.placeholderDecorate) {
299
+ return this.placeholderDecorate(editor) || [];
300
+ }
301
+ if (this.placeholder &&
302
+ editor.children.length === 1 &&
303
+ Array.from(Node.texts(editor)).length === 1 &&
304
+ Node.string(editor) === '') {
305
+ const start = Editor.start(editor, []);
306
+ return [
307
+ {
308
+ placeholder: this.placeholder,
309
+ anchor: start,
310
+ focus: start,
311
+ },
312
+ ];
313
+ }
314
+ else {
315
+ return [];
316
+ }
317
+ }
318
+ generateDecorations() {
319
+ const decorations = this.decorate([this.editor, []]);
320
+ const placeholderDecorations = this.isComposing
321
+ ? []
322
+ : this.composePlaceholderDecorate(this.editor);
323
+ decorations.push(...placeholderDecorations);
324
+ return decorations;
325
+ }
326
+ //#region event proxy
327
+ addEventListener(eventName, listener, target = this.elementRef.nativeElement) {
328
+ this.manualListeners.push(this.renderer2.listen(target, eventName, (event) => {
329
+ const beforeInputEvent = extractBeforeInputEvent(event.type, null, event, event.target);
330
+ if (beforeInputEvent) {
331
+ this.onFallbackBeforeInput(beforeInputEvent);
332
+ }
333
+ listener(event);
334
+ }));
335
+ }
336
+ toSlateSelection() {
337
+ if (!this.isComposing && !this.isUpdatingSelection && !this.isDraggingInternally) {
338
+ try {
339
+ const root = AngularEditor.findDocumentOrShadowRoot(this.editor);
340
+ const { activeElement } = root;
341
+ const el = AngularEditor.toDOMNode(this.editor, this.editor);
342
+ const domSelection = root.getSelection();
343
+ if (activeElement === el || hasEditableTarget(this.editor, activeElement)) {
344
+ this.latestElement = activeElement;
345
+ IS_FOCUSED.set(this.editor, true);
346
+ }
347
+ else {
348
+ IS_FOCUSED.delete(this.editor);
349
+ }
350
+ if (!domSelection) {
351
+ return Transforms.deselect(this.editor);
352
+ }
353
+ const editorElement = EDITOR_TO_ELEMENT.get(this.editor);
354
+ const hasDomSelectionInEditor = editorElement.contains(domSelection.anchorNode) && editorElement.contains(domSelection.focusNode);
355
+ if (!hasDomSelectionInEditor) {
356
+ Transforms.deselect(this.editor);
357
+ return;
358
+ }
359
+ // try to get the selection directly, because some terrible case can be normalize for normalizeDOMPoint
360
+ // for example, double-click the last cell of the table to select a non-editable DOM
361
+ const range = AngularEditor.toSlateRange(this.editor, domSelection);
362
+ if (this.editor.selection && Range.equals(range, this.editor.selection) && !hasStringTarget(domSelection)) {
363
+ // force adjust DOMSelection
364
+ this.toNativeSelection();
365
+ }
366
+ else {
367
+ Transforms.select(this.editor, range);
368
+ }
369
+ }
370
+ catch (error) {
371
+ this.editor.onError({ code: SlateErrorCode.ToSlateSelectionError, nativeError: error });
372
+ }
373
+ }
374
+ }
375
+ onDOMBeforeInput(event) {
376
+ const editor = this.editor;
377
+ if (!this.readonly && hasEditableTarget(editor, event.target) && !this.isDOMEventHandled(event, this.beforeInput)) {
378
+ try {
379
+ const { selection } = editor;
380
+ const { inputType: type } = event;
381
+ const data = event.dataTransfer || event.data || undefined;
382
+ event.preventDefault();
383
+ // COMPAT: If the selection is expanded, even if the command seems like
384
+ // a delete forward/backward command it should delete the selection.
385
+ if (selection && Range.isExpanded(selection) && type.startsWith('delete')) {
386
+ const direction = type.endsWith('Backward') ? 'backward' : 'forward';
387
+ Editor.deleteFragment(editor, { direction });
388
+ return;
389
+ }
390
+ switch (type) {
391
+ case 'deleteByComposition':
392
+ case 'deleteByCut':
393
+ case 'deleteByDrag': {
394
+ Editor.deleteFragment(editor);
395
+ break;
396
+ }
397
+ case 'deleteContent':
398
+ case 'deleteContentForward': {
399
+ Editor.deleteForward(editor);
400
+ break;
401
+ }
402
+ case 'deleteContentBackward': {
403
+ Editor.deleteBackward(editor);
404
+ break;
405
+ }
406
+ case 'deleteEntireSoftLine': {
407
+ Editor.deleteBackward(editor, { unit: 'line' });
408
+ Editor.deleteForward(editor, { unit: 'line' });
409
+ break;
410
+ }
411
+ case 'deleteHardLineBackward': {
412
+ Editor.deleteBackward(editor, { unit: 'block' });
413
+ break;
414
+ }
415
+ case 'deleteSoftLineBackward': {
416
+ Editor.deleteBackward(editor, { unit: 'line' });
417
+ break;
418
+ }
419
+ case 'deleteHardLineForward': {
420
+ Editor.deleteForward(editor, { unit: 'block' });
421
+ break;
422
+ }
423
+ case 'deleteSoftLineForward': {
424
+ Editor.deleteForward(editor, { unit: 'line' });
425
+ break;
426
+ }
427
+ case 'deleteWordBackward': {
428
+ Editor.deleteBackward(editor, { unit: 'word' });
429
+ break;
430
+ }
431
+ case 'deleteWordForward': {
432
+ Editor.deleteForward(editor, { unit: 'word' });
433
+ break;
434
+ }
435
+ case 'insertLineBreak':
436
+ case 'insertParagraph': {
437
+ Editor.insertBreak(editor);
438
+ break;
439
+ }
440
+ case 'insertFromComposition': {
441
+ // COMPAT: in safari, `compositionend` event is dispatched after
442
+ // the beforeinput event with the inputType "insertFromComposition" has been dispatched.
443
+ // https://www.w3.org/TR/input-events-2/
444
+ // so the following code is the right logic
445
+ // because DOM selection in sync will be exec before `compositionend` event
446
+ // isComposing is true will prevent DOM selection being update correctly.
447
+ this.isComposing = false;
448
+ preventInsertFromComposition(event, this.editor);
449
+ }
450
+ case 'insertFromDrop':
451
+ case 'insertFromPaste':
452
+ case 'insertFromYank':
453
+ case 'insertReplacementText':
454
+ case 'insertText': {
455
+ // use a weak comparison instead of 'instanceof' to allow
456
+ // programmatic access of paste events coming from external windows
457
+ // like cypress where cy.window does not work realibly
458
+ if (data?.constructor.name === 'DataTransfer') {
459
+ AngularEditor.insertData(editor, data);
460
+ }
461
+ else if (typeof data === 'string') {
462
+ Editor.insertText(editor, data);
463
+ }
464
+ break;
465
+ }
466
+ }
467
+ }
468
+ catch (error) {
469
+ this.editor.onError({ code: SlateErrorCode.OnDOMBeforeInputError, nativeError: error });
470
+ }
471
+ }
472
+ }
473
+ onDOMBlur(event) {
474
+ if (this.readonly ||
475
+ this.isUpdatingSelection ||
476
+ !hasEditableTarget(this.editor, event.target) ||
477
+ this.isDOMEventHandled(event, this.blur)) {
478
+ return;
479
+ }
480
+ const window = AngularEditor.getWindow(this.editor);
481
+ // COMPAT: If the current `activeElement` is still the previous
482
+ // one, this is due to the window being blurred when the tab
483
+ // itself becomes unfocused, so we want to abort early to allow to
484
+ // editor to stay focused when the tab becomes focused again.
485
+ const root = AngularEditor.findDocumentOrShadowRoot(this.editor);
486
+ if (this.latestElement === root.activeElement) {
487
+ return;
488
+ }
489
+ const { relatedTarget } = event;
490
+ const el = AngularEditor.toDOMNode(this.editor, this.editor);
491
+ // COMPAT: The event should be ignored if the focus is returning
492
+ // to the editor from an embedded editable element (eg. an <input>
493
+ // element inside a void node).
494
+ if (relatedTarget === el) {
495
+ return;
496
+ }
497
+ // COMPAT: The event should be ignored if the focus is moving from
498
+ // the editor to inside a void node's spacer element.
499
+ if (isDOMElement(relatedTarget) && relatedTarget.hasAttribute('data-slate-spacer')) {
500
+ return;
501
+ }
502
+ // COMPAT: The event should be ignored if the focus is moving to a
503
+ // non- editable section of an element that isn't a void node (eg.
504
+ // a list item of the check list example).
505
+ if (relatedTarget != null && isDOMNode(relatedTarget) && AngularEditor.hasDOMNode(this.editor, relatedTarget)) {
506
+ const node = AngularEditor.toSlateNode(this.editor, relatedTarget);
507
+ if (Element.isElement(node) && !this.editor.isVoid(node)) {
508
+ return;
509
+ }
510
+ }
511
+ IS_FOCUSED.delete(this.editor);
512
+ }
513
+ onDOMClick(event) {
514
+ if (!this.readonly &&
515
+ hasTarget(this.editor, event.target) &&
516
+ !this.isDOMEventHandled(event, this.click) &&
517
+ isDOMNode(event.target)) {
518
+ const node = AngularEditor.toSlateNode(this.editor, event.target);
519
+ const path = AngularEditor.findPath(this.editor, node);
520
+ const start = Editor.start(this.editor, path);
521
+ const end = Editor.end(this.editor, path);
522
+ const startVoid = Editor.void(this.editor, { at: start });
523
+ const endVoid = Editor.void(this.editor, { at: end });
524
+ if (startVoid && endVoid && Path.equals(startVoid[1], endVoid[1])) {
525
+ const range = Editor.range(this.editor, start);
526
+ Transforms.select(this.editor, range);
527
+ }
528
+ }
529
+ }
530
+ onDOMCompositionEnd(event) {
531
+ if (!event.data && !Range.isCollapsed(this.editor.selection)) {
532
+ Transforms.delete(this.editor);
533
+ }
534
+ if (hasEditableTarget(this.editor, event.target) && !this.isDOMEventHandled(event, this.compositionEnd)) {
535
+ // COMPAT: In Chrome/Firefox, `beforeinput` events for compositions
536
+ // aren't correct and never fire the "insertFromComposition"
537
+ // type that we need. So instead, insert whenever a composition
538
+ // ends since it will already have been committed to the DOM.
539
+ if (this.isComposing === true && !IS_SAFARI && event.data) {
540
+ preventInsertFromComposition(event, this.editor);
541
+ Editor.insertText(this.editor, event.data);
542
+ }
543
+ // COMPAT: In Firefox 87.0 CompositionEnd fire twice
544
+ // so we need avoid repeat isnertText by isComposing === true,
545
+ this.isComposing = false;
546
+ }
547
+ this.detectContext();
548
+ this.cdr.detectChanges();
549
+ }
550
+ onDOMCompositionStart(event) {
551
+ const { selection } = this.editor;
552
+ if (selection) {
553
+ // solve the problem of cross node Chinese input
554
+ if (Range.isExpanded(selection)) {
555
+ Editor.deleteFragment(this.editor);
556
+ this.forceFlush();
557
+ }
558
+ }
559
+ if (hasEditableTarget(this.editor, event.target) && !this.isDOMEventHandled(event, this.compositionStart)) {
560
+ this.isComposing = true;
561
+ }
562
+ this.detectContext();
563
+ this.cdr.detectChanges();
564
+ }
565
+ onDOMCopy(event) {
566
+ const window = AngularEditor.getWindow(this.editor);
567
+ const isOutsideSlate = !hasStringTarget(window.getSelection()) && isTargetInsideVoid(this.editor, event.target);
568
+ if (!isOutsideSlate && hasTarget(this.editor, event.target) && !this.isDOMEventHandled(event, this.copy)) {
569
+ event.preventDefault();
570
+ AngularEditor.setFragmentData(this.editor, event.clipboardData, 'copy');
571
+ }
572
+ }
573
+ onDOMCut(event) {
574
+ if (!this.readonly && hasEditableTarget(this.editor, event.target) && !this.isDOMEventHandled(event, this.cut)) {
575
+ event.preventDefault();
576
+ AngularEditor.setFragmentData(this.editor, event.clipboardData, 'cut');
577
+ const { selection } = this.editor;
578
+ if (selection) {
579
+ AngularEditor.deleteCutData(this.editor);
580
+ }
581
+ }
582
+ }
583
+ onDOMDragOver(event) {
584
+ if (hasTarget(this.editor, event.target) && !this.isDOMEventHandled(event, this.dragOver)) {
585
+ // Only when the target is void, call `preventDefault` to signal
586
+ // that drops are allowed. Editable content is droppable by
587
+ // default, and calling `preventDefault` hides the cursor.
588
+ const node = AngularEditor.toSlateNode(this.editor, event.target);
589
+ if (Editor.isVoid(this.editor, node)) {
590
+ event.preventDefault();
591
+ }
592
+ }
593
+ }
594
+ onDOMDragStart(event) {
595
+ if (!this.readonly && hasTarget(this.editor, event.target) && !this.isDOMEventHandled(event, this.dragStart)) {
596
+ const node = AngularEditor.toSlateNode(this.editor, event.target);
597
+ const path = AngularEditor.findPath(this.editor, node);
598
+ const voidMatch = Editor.isVoid(this.editor, node) ||
599
+ Editor.void(this.editor, { at: path, voids: true });
600
+ // If starting a drag on a void node, make sure it is selected
601
+ // so that it shows up in the selection's fragment.
602
+ if (voidMatch) {
603
+ const range = Editor.range(this.editor, path);
604
+ Transforms.select(this.editor, range);
605
+ }
606
+ this.isDraggingInternally = true;
607
+ AngularEditor.setFragmentData(this.editor, event.dataTransfer, 'drag');
608
+ }
609
+ }
610
+ onDOMDrop(event) {
611
+ const editor = this.editor;
612
+ if (!this.readonly && hasTarget(this.editor, event.target) && !this.isDOMEventHandled(event, this.drop)) {
613
+ event.preventDefault();
614
+ // Keep a reference to the dragged range before updating selection
615
+ const draggedRange = editor.selection;
616
+ // Find the range where the drop happened
617
+ const range = AngularEditor.findEventRange(editor, event);
618
+ const data = event.dataTransfer;
619
+ Transforms.select(editor, range);
620
+ if (this.isDraggingInternally) {
621
+ if (draggedRange) {
622
+ Transforms.delete(editor, {
623
+ at: draggedRange,
624
+ });
625
+ }
626
+ this.isDraggingInternally = false;
627
+ }
628
+ AngularEditor.insertData(editor, data);
629
+ // When dragging from another source into the editor, it's possible
630
+ // that the current editor does not have focus.
631
+ if (!AngularEditor.isFocused(editor)) {
632
+ AngularEditor.focus(editor);
633
+ }
634
+ }
635
+ }
636
+ onDOMDragEnd(event) {
637
+ if (!this.readonly && this.isDraggingInternally && hasTarget(this.editor, event.target) && !this.isDOMEventHandled(event, this.dragEnd)) {
638
+ this.isDraggingInternally = false;
639
+ }
640
+ }
641
+ onDOMFocus(event) {
642
+ if (!this.readonly &&
643
+ !this.isUpdatingSelection &&
644
+ hasEditableTarget(this.editor, event.target) &&
645
+ !this.isDOMEventHandled(event, this.focus)) {
646
+ const el = AngularEditor.toDOMNode(this.editor, this.editor);
647
+ const root = AngularEditor.findDocumentOrShadowRoot(this.editor);
648
+ this.latestElement = root.activeElement;
649
+ // COMPAT: If the editor has nested editable elements, the focus
650
+ // can go to them. In Firefox, this must be prevented because it
651
+ // results in issues with keyboard navigation. (2017/03/30)
652
+ if (IS_FIREFOX && event.target !== el) {
653
+ el.focus();
654
+ return;
655
+ }
656
+ IS_FOCUSED.set(this.editor, true);
657
+ }
658
+ }
659
+ onDOMKeydown(event) {
660
+ const editor = this.editor;
661
+ if (!this.readonly &&
662
+ hasEditableTarget(editor, event.target) &&
663
+ !this.isComposing &&
664
+ !this.isDOMEventHandled(event, this.keydown)) {
665
+ const nativeEvent = event;
666
+ const { selection } = editor;
667
+ const element = editor.children[selection !== null ? selection.focus.path[0] : 0];
668
+ const isRTL = getDirection(Node.string(element)) === 'rtl';
669
+ try {
670
+ // COMPAT: Since we prevent the default behavior on
671
+ // `beforeinput` events, the browser doesn't think there's ever
672
+ // any history stack to undo or redo, so we have to manage these
673
+ // hotkeys ourselves. (2019/11/06)
674
+ if (Hotkeys.isRedo(nativeEvent)) {
675
+ event.preventDefault();
676
+ if (HistoryEditor.isHistoryEditor(editor)) {
677
+ editor.redo();
678
+ }
679
+ return;
680
+ }
681
+ if (Hotkeys.isUndo(nativeEvent)) {
682
+ event.preventDefault();
683
+ if (HistoryEditor.isHistoryEditor(editor)) {
684
+ editor.undo();
685
+ }
686
+ return;
687
+ }
688
+ // COMPAT: Certain browsers don't handle the selection updates
689
+ // properly. In Chrome, the selection isn't properly extended.
690
+ // And in Firefox, the selection isn't properly collapsed.
691
+ // (2017/10/17)
692
+ if (Hotkeys.isMoveLineBackward(nativeEvent)) {
693
+ event.preventDefault();
694
+ Transforms.move(editor, { unit: 'line', reverse: true });
695
+ return;
696
+ }
697
+ if (Hotkeys.isMoveLineForward(nativeEvent)) {
698
+ event.preventDefault();
699
+ Transforms.move(editor, { unit: 'line' });
700
+ return;
701
+ }
702
+ if (Hotkeys.isExtendLineBackward(nativeEvent)) {
703
+ event.preventDefault();
704
+ Transforms.move(editor, {
705
+ unit: 'line',
706
+ edge: 'focus',
707
+ reverse: true
708
+ });
709
+ return;
710
+ }
711
+ if (Hotkeys.isExtendLineForward(nativeEvent)) {
712
+ event.preventDefault();
713
+ Transforms.move(editor, { unit: 'line', edge: 'focus' });
714
+ return;
715
+ }
716
+ // COMPAT: If a void node is selected, or a zero-width text node
717
+ // adjacent to an inline is selected, we need to handle these
718
+ // hotkeys manually because browsers won't be able to skip over
719
+ // the void node with the zero-width space not being an empty
720
+ // string.
721
+ if (Hotkeys.isMoveBackward(nativeEvent)) {
722
+ event.preventDefault();
723
+ if (selection && Range.isCollapsed(selection)) {
724
+ Transforms.move(editor, { reverse: !isRTL });
725
+ }
726
+ else {
727
+ Transforms.collapse(editor, { edge: 'start' });
728
+ }
729
+ return;
730
+ }
731
+ if (Hotkeys.isMoveForward(nativeEvent)) {
732
+ event.preventDefault();
733
+ if (selection && Range.isCollapsed(selection)) {
734
+ Transforms.move(editor, { reverse: isRTL });
735
+ }
736
+ else {
737
+ Transforms.collapse(editor, { edge: 'end' });
738
+ }
739
+ return;
740
+ }
741
+ if (Hotkeys.isMoveWordBackward(nativeEvent)) {
742
+ event.preventDefault();
743
+ if (selection && Range.isExpanded(selection)) {
744
+ Transforms.collapse(editor, { edge: 'focus' });
745
+ }
746
+ Transforms.move(editor, { unit: 'word', reverse: !isRTL });
747
+ return;
748
+ }
749
+ if (Hotkeys.isMoveWordForward(nativeEvent)) {
750
+ event.preventDefault();
751
+ if (selection && Range.isExpanded(selection)) {
752
+ Transforms.collapse(editor, { edge: 'focus' });
753
+ }
754
+ Transforms.move(editor, { unit: 'word', reverse: isRTL });
755
+ return;
756
+ }
757
+ // COMPAT: Certain browsers don't support the `beforeinput` event, so we
758
+ // fall back to guessing at the input intention for hotkeys.
759
+ // COMPAT: In iOS, some of these hotkeys are handled in the
760
+ if (!HAS_BEFORE_INPUT_SUPPORT) {
761
+ // We don't have a core behavior for these, but they change the
762
+ // DOM if we don't prevent them, so we have to.
763
+ if (Hotkeys.isBold(nativeEvent) || Hotkeys.isItalic(nativeEvent) || Hotkeys.isTransposeCharacter(nativeEvent)) {
764
+ event.preventDefault();
765
+ return;
766
+ }
767
+ if (Hotkeys.isSplitBlock(nativeEvent)) {
768
+ event.preventDefault();
769
+ Editor.insertBreak(editor);
770
+ return;
771
+ }
772
+ if (Hotkeys.isDeleteBackward(nativeEvent)) {
773
+ event.preventDefault();
774
+ if (selection && Range.isExpanded(selection)) {
775
+ Editor.deleteFragment(editor, { direction: 'backward' });
776
+ }
777
+ else {
778
+ Editor.deleteBackward(editor);
779
+ }
780
+ return;
781
+ }
782
+ if (Hotkeys.isDeleteForward(nativeEvent)) {
783
+ event.preventDefault();
784
+ if (selection && Range.isExpanded(selection)) {
785
+ Editor.deleteFragment(editor, { direction: 'forward' });
786
+ }
787
+ else {
788
+ Editor.deleteForward(editor);
789
+ }
790
+ return;
791
+ }
792
+ if (Hotkeys.isDeleteLineBackward(nativeEvent)) {
793
+ event.preventDefault();
794
+ if (selection && Range.isExpanded(selection)) {
795
+ Editor.deleteFragment(editor, { direction: 'backward' });
796
+ }
797
+ else {
798
+ Editor.deleteBackward(editor, { unit: 'line' });
799
+ }
800
+ return;
801
+ }
802
+ if (Hotkeys.isDeleteLineForward(nativeEvent)) {
803
+ event.preventDefault();
804
+ if (selection && Range.isExpanded(selection)) {
805
+ Editor.deleteFragment(editor, { direction: 'forward' });
806
+ }
807
+ else {
808
+ Editor.deleteForward(editor, { unit: 'line' });
809
+ }
810
+ return;
811
+ }
812
+ if (Hotkeys.isDeleteWordBackward(nativeEvent)) {
813
+ event.preventDefault();
814
+ if (selection && Range.isExpanded(selection)) {
815
+ Editor.deleteFragment(editor, { direction: 'backward' });
816
+ }
817
+ else {
818
+ Editor.deleteBackward(editor, { unit: 'word' });
819
+ }
820
+ return;
821
+ }
822
+ if (Hotkeys.isDeleteWordForward(nativeEvent)) {
823
+ event.preventDefault();
824
+ if (selection && Range.isExpanded(selection)) {
825
+ Editor.deleteFragment(editor, { direction: 'forward' });
826
+ }
827
+ else {
828
+ Editor.deleteForward(editor, { unit: 'word' });
829
+ }
830
+ return;
831
+ }
832
+ }
833
+ else {
834
+ if (IS_CHROME || IS_SAFARI) {
835
+ // COMPAT: Chrome and Safari support `beforeinput` event but do not fire
836
+ // an event when deleting backwards in a selected void inline node
837
+ if (selection &&
838
+ (Hotkeys.isDeleteBackward(nativeEvent) ||
839
+ Hotkeys.isDeleteForward(nativeEvent)) &&
840
+ Range.isCollapsed(selection)) {
841
+ const currentNode = Node.parent(editor, selection.anchor.path);
842
+ if (Element.isElement(currentNode) &&
843
+ Editor.isVoid(editor, currentNode) &&
844
+ Editor.isInline(editor, currentNode)) {
845
+ event.preventDefault();
846
+ Editor.deleteBackward(editor, { unit: 'block' });
847
+ return;
848
+ }
849
+ }
850
+ }
851
+ }
852
+ }
853
+ catch (error) {
854
+ this.editor.onError({ code: SlateErrorCode.OnDOMKeydownError, nativeError: error });
855
+ }
856
+ }
857
+ }
858
+ onDOMPaste(event) {
859
+ // COMPAT: Certain browsers don't support the `beforeinput` event, so we
860
+ // fall back to React's `onPaste` here instead.
861
+ // COMPAT: Firefox, Chrome and Safari are not emitting `beforeinput` events
862
+ // when "paste without formatting" option is used.
863
+ // This unfortunately needs to be handled with paste events instead.
864
+ if (!this.isDOMEventHandled(event, this.paste) &&
865
+ (!HAS_BEFORE_INPUT_SUPPORT || isPlainTextOnlyPaste(event) || forceOnDOMPaste) &&
866
+ !this.readonly &&
867
+ hasEditableTarget(this.editor, event.target)) {
868
+ event.preventDefault();
869
+ AngularEditor.insertData(this.editor, event.clipboardData);
870
+ }
871
+ }
872
+ onFallbackBeforeInput(event) {
873
+ // COMPAT: Certain browsers don't support the `beforeinput` event, so we
874
+ // fall back to React's leaky polyfill instead just for it. It
875
+ // only works for the `insertText` input type.
876
+ if (!HAS_BEFORE_INPUT_SUPPORT &&
877
+ !this.readonly &&
878
+ !this.isDOMEventHandled(event.nativeEvent, this.beforeInput) &&
879
+ hasEditableTarget(this.editor, event.nativeEvent.target)) {
880
+ event.nativeEvent.preventDefault();
881
+ try {
882
+ const text = event.data;
883
+ if (!Range.isCollapsed(this.editor.selection)) {
884
+ Editor.deleteFragment(this.editor);
885
+ }
886
+ // just handle Non-IME input
887
+ if (!this.isComposing) {
888
+ Editor.insertText(this.editor, text);
889
+ }
890
+ }
891
+ catch (error) {
892
+ this.editor.onError({ code: SlateErrorCode.ToNativeSelectionError, nativeError: error });
893
+ }
894
+ }
895
+ }
896
+ isDOMEventHandled(event, handler) {
897
+ if (!handler) {
898
+ return false;
899
+ }
900
+ handler(event);
901
+ return event.defaultPrevented;
902
+ }
903
+ //#endregion
904
+ ngOnDestroy() {
905
+ NODE_TO_ELEMENT.delete(this.editor);
906
+ this.manualListeners.forEach(manualListener => {
907
+ manualListener();
908
+ });
909
+ this.destroy$.complete();
910
+ EDITOR_TO_ON_CHANGE.delete(this.editor);
911
+ }
912
+ }
913
+ SlateEditableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: SlateEditableComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
914
+ SlateEditableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.8", type: SlateEditableComponent, selector: "slate-editable", inputs: { editor: "editor", renderElement: "renderElement", renderLeaf: "renderLeaf", renderText: "renderText", decorate: "decorate", placeholderDecorate: "placeholderDecorate", isStrictDecorate: "isStrictDecorate", trackBy: "trackBy", readonly: "readonly", placeholder: "placeholder", beforeInput: "beforeInput", blur: "blur", click: "click", compositionEnd: "compositionEnd", compositionStart: "compositionStart", copy: "copy", cut: "cut", dragOver: "dragOver", dragStart: "dragStart", dragEnd: "dragEnd", drop: "drop", focus: "focus", keydown: "keydown", paste: "paste", spellCheck: "spellCheck", autoCorrect: "autoCorrect", autoCapitalize: "autoCapitalize" }, host: { properties: { "attr.contenteditable": "readonly ? undefined : true", "attr.role": "readonly ? undefined : 'textbox'", "attr.spellCheck": "!hasBeforeInputSupport ? false : spellCheck", "attr.autoCorrect": "!hasBeforeInputSupport ? 'false' : autoCorrect", "attr.autoCapitalize": "!hasBeforeInputSupport ? 'false' : autoCapitalize", "attr.data-slate-editor": "this.dataSlateEditor", "attr.data-slate-node": "this.dataSlateNode", "attr.data-gramm": "this.dataGramm" }, classAttribute: "slate-editable-container" }, providers: [{
915
+ provide: NG_VALUE_ACCESSOR,
916
+ useExisting: forwardRef(() => SlateEditableComponent),
917
+ multi: true
918
+ }], viewQueries: [{ propertyName: "templateComponent", first: true, predicate: ["templateComponent"], descendants: true, static: true }, { propertyName: "templateElementRef", first: true, predicate: ["templateComponent"], descendants: true, read: ElementRef, static: true }], usesOnChanges: true, ngImport: i0, template: "<slate-children [children]=\"editor.children\" [context]=\"context\" [viewContext]=\"viewContext\"></slate-children>\n<slate-string-template #templateComponent></slate-string-template>", components: [{ type: i1.SlateChildrenComponent, selector: "slate-children", inputs: ["children", "context", "viewContext"] }, { type: i2.SlateStringTemplateComponent, selector: "slate-string-template" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
919
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.8", ngImport: i0, type: SlateEditableComponent, decorators: [{
920
+ type: Component,
921
+ args: [{ selector: 'slate-editable', host: {
922
+ class: 'slate-editable-container',
923
+ '[attr.contenteditable]': 'readonly ? undefined : true',
924
+ '[attr.role]': `readonly ? undefined : 'textbox'`,
925
+ '[attr.spellCheck]': `!hasBeforeInputSupport ? false : spellCheck`,
926
+ '[attr.autoCorrect]': `!hasBeforeInputSupport ? 'false' : autoCorrect`,
927
+ '[attr.autoCapitalize]': `!hasBeforeInputSupport ? 'false' : autoCapitalize`
928
+ }, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{
929
+ provide: NG_VALUE_ACCESSOR,
930
+ useExisting: forwardRef(() => SlateEditableComponent),
931
+ multi: true
932
+ }], template: "<slate-children [children]=\"editor.children\" [context]=\"context\" [viewContext]=\"viewContext\"></slate-children>\n<slate-string-template #templateComponent></slate-string-template>" }]
933
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.Injector }]; }, propDecorators: { editor: [{
934
+ type: Input
935
+ }], renderElement: [{
936
+ type: Input
937
+ }], renderLeaf: [{
938
+ type: Input
939
+ }], renderText: [{
940
+ type: Input
941
+ }], decorate: [{
942
+ type: Input
943
+ }], placeholderDecorate: [{
944
+ type: Input
945
+ }], isStrictDecorate: [{
946
+ type: Input
947
+ }], trackBy: [{
948
+ type: Input
949
+ }], readonly: [{
950
+ type: Input
951
+ }], placeholder: [{
952
+ type: Input
953
+ }], beforeInput: [{
954
+ type: Input
955
+ }], blur: [{
956
+ type: Input
957
+ }], click: [{
958
+ type: Input
959
+ }], compositionEnd: [{
960
+ type: Input
961
+ }], compositionStart: [{
962
+ type: Input
963
+ }], copy: [{
964
+ type: Input
965
+ }], cut: [{
966
+ type: Input
967
+ }], dragOver: [{
968
+ type: Input
969
+ }], dragStart: [{
970
+ type: Input
971
+ }], dragEnd: [{
972
+ type: Input
973
+ }], drop: [{
974
+ type: Input
975
+ }], focus: [{
976
+ type: Input
977
+ }], keydown: [{
978
+ type: Input
979
+ }], paste: [{
980
+ type: Input
981
+ }], spellCheck: [{
982
+ type: Input
983
+ }], autoCorrect: [{
984
+ type: Input
985
+ }], autoCapitalize: [{
986
+ type: Input
987
+ }], dataSlateEditor: [{
988
+ type: HostBinding,
989
+ args: ['attr.data-slate-editor']
990
+ }], dataSlateNode: [{
991
+ type: HostBinding,
992
+ args: ['attr.data-slate-node']
993
+ }], dataGramm: [{
994
+ type: HostBinding,
995
+ args: ['attr.data-gramm']
996
+ }], templateComponent: [{
997
+ type: ViewChild,
998
+ args: ['templateComponent', { static: true }]
999
+ }], templateElementRef: [{
1000
+ type: ViewChild,
1001
+ args: ['templateComponent', { static: true, read: ElementRef }]
1002
+ }] } });
1003
+ /**
1004
+ * Check if the target is editable and in the editor.
1005
+ */
1006
+ const hasEditableTarget = (editor, target) => {
1007
+ return isDOMNode(target) && AngularEditor.hasDOMNode(editor, target, { editable: true });
1008
+ };
1009
+ /**
1010
+ * Check if two DOM range objects are equal.
1011
+ */
1012
+ const isRangeEqual = (a, b) => {
1013
+ return ((a.startContainer === b.startContainer &&
1014
+ a.startOffset === b.startOffset &&
1015
+ a.endContainer === b.endContainer &&
1016
+ a.endOffset === b.endOffset) ||
1017
+ (a.startContainer === b.endContainer &&
1018
+ a.startOffset === b.endOffset &&
1019
+ a.endContainer === b.startContainer &&
1020
+ a.endOffset === b.startOffset));
1021
+ };
1022
+ /**
1023
+ * Check if the target is in the editor.
1024
+ */
1025
+ const hasTarget = (editor, target) => {
1026
+ return isDOMNode(target) && AngularEditor.hasDOMNode(editor, target);
1027
+ };
1028
+ /**
1029
+ * Check if the target is inside void and in the editor.
1030
+ */
1031
+ const isTargetInsideVoid = (editor, target) => {
1032
+ const slateNode = hasTarget(editor, target) && AngularEditor.toSlateNode(editor, target);
1033
+ return Editor.isVoid(editor, slateNode);
1034
+ };
1035
+ const hasStringTarget = (domSelection) => {
1036
+ return (domSelection.anchorNode.parentElement.hasAttribute('data-slate-string') || domSelection.anchorNode.parentElement.hasAttribute('data-slate-zero-width')) &&
1037
+ (domSelection.focusNode.parentElement.hasAttribute('data-slate-string') || domSelection.focusNode.parentElement.hasAttribute('data-slate-zero-width'));
1038
+ };
1039
+ /**
1040
+ * remove default insert from composition
1041
+ * @param text
1042
+ */
1043
+ const preventInsertFromComposition = (event, editor) => {
1044
+ const types = ['compositionend', 'insertFromComposition'];
1045
+ if (!types.includes(event.type)) {
1046
+ return;
1047
+ }
1048
+ const insertText = event.data;
1049
+ const window = AngularEditor.getWindow(editor);
1050
+ const domSelection = window.getSelection();
1051
+ // ensure text node insert composition input text
1052
+ if (insertText && domSelection.anchorNode instanceof Text && domSelection.anchorNode.textContent.endsWith(insertText)) {
1053
+ const textNode = domSelection.anchorNode;
1054
+ textNode.splitText(textNode.length - insertText.length).remove();
1055
+ }
1056
+ };
1057
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcGFja2FnZXMvc3JjL2NvbXBvbmVudHMvZWRpdGFibGUvZWRpdGFibGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vcGFja2FnZXMvc3JjL2NvbXBvbmVudHMvZWRpdGFibGUvZWRpdGFibGUuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILFNBQVMsRUFFVCxLQUFLLEVBQ0wsU0FBUyxFQUNULFdBQVcsRUFFWCxVQUFVLEVBQ1YsdUJBQXVCLEVBS3ZCLFVBQVUsRUFLYixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxlQUFlLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUosT0FBTyxFQUFxQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFhLElBQUksRUFBYyxNQUFNLE9BQU8sQ0FBQztBQUNqSCxPQUFPLFlBQVksTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzdELE9BQU8sRUFHSCxTQUFTLEVBR1QsWUFBWSxFQUNaLG9CQUFvQixFQUVwQixjQUFjLEVBQ2pCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBb0MsU0FBUyxFQUFFLHdCQUF3QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdkksT0FBTyxPQUFPLE1BQU0scUJBQXFCLENBQUM7QUFDMUMsT0FBTyxFQUFvQix1QkFBdUIsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBQ3RHLE9BQU8sRUFB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QUFDLFVBQVUsWUFBWSxJQUFJLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFO1FBQ25ILE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUM7UUFDekMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztLQUNwRTtBQUNMLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQ29tcG9uZW50LFxuICAgIE9uSW5pdCxcbiAgICBJbnB1dCxcbiAgICBWaWV3Q2hpbGQsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgUmVuZGVyZXIyLFxuICAgIEVsZW1lbnRSZWYsXG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgT25EZXN0cm95LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIE5nWm9uZSxcbiAgICBJbmplY3RvcixcbiAgICBmb3J3YXJkUmVmLFxuICAgIE9uQ2hhbmdlcyxcbiAgICBTaW1wbGVDaGFuZ2VzLFxuICAgIEFmdGVyVmlld0NoZWNrZWQsXG4gICAgRG9DaGVja1xufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5PREVfVE9fRUxFTUVOVCwgSVNfRk9DVVNFRCwgRURJVE9SX1RPX0VMRU1FTlQsIEVMRU1FTlRfVE9fTk9ERSwgSVNfUkVBRE9OTFksIEVESVRPUl9UT19PTl9DSEFOR0UsIEVESVRPUl9UT19XSU5ET1cgfSBmcm9tICcuLi8uLi91dGlscy93ZWFrLW1hcHMnO1xuaW1wb3J0IHsgVGV4dCBhcyBTbGF0ZVRleHQsIEVsZW1lbnQsIFRyYW5zZm9ybXMsIEVkaXRvciwgUmFuZ2UsIFBhdGgsIE5vZGVFbnRyeSwgTm9kZSwgRGVzY2VuZGFudCB9IGZyb20gJ3NsYXRlJztcbmltcG9ydCBnZXREaXJlY3Rpb24gZnJvbSAnZGlyZWN0aW9uJztcbmltcG9ydCB7IEFuZ3VsYXJFZGl0b3IgfSBmcm9tICcuLi8uLi9wbHVnaW5zL2FuZ3VsYXItZWRpdG9yJztcbmltcG9ydCB7XG4gICAgRE9NRWxlbWVudCxcbiAgICBET01Ob2RlLFxuICAgIGlzRE9NTm9kZSxcbiAgICBET01TdGF0aWNSYW5nZSxcbiAgICBET01SYW5nZSxcbiAgICBpc0RPTUVsZW1lbnQsXG4gICAgaXNQbGFpblRleHRPbmx5UGFzdGUsXG4gICAgRE9NU2VsZWN0aW9uLFxuICAgIGdldERlZmF1bHRWaWV3XG59IGZyb20gJy4uLy4uL3V0aWxzL2RvbSc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBJU19GSVJFRk9YLCBJU19TQUZBUkksIElTX0VER0VfTEVHQUNZLCBJU19DSFJPTUVfTEVHQUNZLCBJU19DSFJPTUUsIEhBU19CRUZPUkVfSU5QVVRfU1VQUE9SVCB9IGZyb20gJy4uLy4uL3V0aWxzL2Vudmlyb25tZW50JztcbmltcG9ydCBIb3RrZXlzIGZyb20gJy4uLy4uL3V0aWxzL2hvdGtleXMnO1xuaW1wb3J0IHsgQmVmb3JlSW5wdXRFdmVudCwgZXh0cmFjdEJlZm9yZUlucHV0RXZlbnQgfSBmcm9tICcuLi8uLi9jdXN0b20tZXZlbnQvQmVmb3JlSW5wdXRFdmVudFBsdWdpbic7XG5pbXBvcnQgeyBCRUZPUkVfSU5QVVRfRVZFTlRTIH0gZnJvbSAnLi4vLi4vY3VzdG9tLWV2ZW50L2JlZm9yZS1pbnB1dC1wb2x5ZmlsbCc7XG5pbXBvcnQgeyBTbGF0ZUVycm9yQ29kZSB9IGZyb20gJy4uLy4uL3R5cGVzL2Vycm9yJztcbmltcG9ydCBEZWJ1ZyBmcm9tICdkZWJ1Zyc7XG5pbXBvcnQgeyBTbGF0ZVN0cmluZ1RlbXBsYXRlQ29tcG9uZW50IH0gZnJvbSAnLi4vc3RyaW5nL3RlbXBsYXRlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFNsYXRlQ2hpbGRyZW5Db250ZXh0LCBTbGF0ZVZpZXdDb250ZXh0IH0gZnJvbSAnLi4vLi4vdmlldy9jb250ZXh0JztcbmltcG9ydCB7IFZpZXdUeXBlIH0gZnJvbSAnLi4vLi4vdHlwZXMvdmlldyc7XG5pbXBvcnQgeyBIaXN0b3J5RWRpdG9yIH0gZnJvbSAnc2xhdGUtaGlzdG9yeSc7XG5pbXBvcnQgeyBpc0RlY29yYXRvclJhbmdlTGlzdEVxdWFsIH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgY2hlY2ssIG5vcm1hbGl6ZSB9IGZyb20gJy4uLy4uL3V0aWxzL2dsb2JhbC1ub3JtYWxpemUnO1xuaW1wb3J0IHsgU2xhdGVQbGFjZWhvbGRlciB9IGZyb20gJy4uLy4uL3R5cGVzL2ZlYXR1cmUnO1xuXG5jb25zdCB0aW1lRGVidWcgPSBEZWJ1Zygnc2xhdGUtYW5ndWxhci10aW1lJyk7XG5cbi8vIG5vdCBjb3JyZWN0bHkgY2xpcGJvYXJkRGF0YSBvbiBiZWZvcmVpbnB1dFxuY29uc3QgZm9yY2VPbkRPTVBhc3RlID0gSVNfU0FGQVJJO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ3NsYXRlLWVkaXRhYmxlJyxcbiAgICBob3N0OiB7XG4gICAgICAgIGNsYXNzOiAnc2xhdGUtZWRpdGFibGUtY29udGFpbmVyJyxcbiAgICAgICAgJ1thdHRyLmNvbnRlbnRlZGl0YWJsZV0nOiAncmVhZG9ubHkgPyB1bmRlZmluZWQgOiB0cnVlJyxcbiAgICAgICAgJ1thdHRyLnJvbGVdJzogYHJlYWRvbmx5ID8gdW5kZWZpbmVkIDogJ3RleHRib3gnYCxcbiAgICAgICAgJ1thdHRyLnNwZWxsQ2hlY2tdJzogYCFoYXNCZWZvcmVJbnB1dFN1cHBvcnQgPyBmYWxzZSA6IHNwZWxsQ2hlY2tgLFxuICAgICAgICAnW2F0dHIuYXV0b0NvcnJlY3RdJzogYCFoYXNCZWZvcmVJbnB1dFN1cHBvcnQgPyAnZmFsc2UnIDogYXV0b0NvcnJlY3RgLFxuICAgICAgICAnW2F0dHIuYXV0b0NhcGl0YWxpemVdJzogYCFoYXNCZWZvcmVJbnB1dFN1cHBvcnQgPyAnZmFsc2UnIDogYXV0b0NhcGl0YWxpemVgXG4gICAgfSxcbiAgICB0ZW1wbGF0ZVVybDogJ2VkaXRhYmxlLmNvbXBvbmVudC5odG1sJyxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgICBwcm92aWRlcnM6IFt7XG4gICAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBTbGF0ZUVkaXRhYmxlQ29tcG9uZW50KSxcbiAgICAgICAgbXVsdGk6IHRydWVcbiAgICB9XVxufSlcbmV4cG9ydCBjbGFzcyBTbGF0ZUVkaXRhYmxlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSwgQWZ0ZXJWaWV3Q2hlY2tlZCwgRG9DaGVjayB7XG4gICAgdmlld0NvbnRleHQ6IFNsYXRlVmlld0NvbnRleHQ7XG4gICAgY29udGV4dDogU2xhdGVDaGlsZHJlbkNvbnRleHQ7XG5cbiAgICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcblxuICAgIGlzQ29tcG9zaW5nID0gZmFsc2U7XG4gICAgaXNEcmFnZ2luZ0ludGVybmFsbHkgPSBmYWxzZTtcbiAgICBpc1VwZGF0aW5nU2VsZWN0aW9uID0gZmFsc2U7XG4gICAgbGF0ZXN0RWxlbWVudCA9IG51bGwgYXMgRE9NRWxlbWVudCB8IG51bGw7XG5cbiAgICBwcm90ZWN0ZWQgbWFudWFsTGlzdGVuZXJzOiAoKCkgPT4gdm9pZClbXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBpbml0aWFsaXplZDogYm9vbGVhbjtcblxuICAgIHByaXZhdGUgb25Ub3VjaGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSAoKSA9PiB7IH07XG5cbiAgICBwcml2YXRlIG9uQ2hhbmdlQ2FsbGJhY2s6IChfOiBhbnkpID0+IHZvaWQgPSAoKSA9PiB7IH07XG5cbiAgICBASW5wdXQoKSBlZGl0b3I6IEFuZ3VsYXJFZGl0b3I7XG5cbiAgICBASW5wdXQoKSByZW5kZXJFbGVtZW50OiAoZWxlbWVudDogRWxlbWVudCkgPT4gVmlld1R5cGUgfCBudWxsO1xuXG4gICAgQElucHV0KCkgcmVuZGVyTGVhZjogKHRleHQ6IFNsYXRlVGV4dCkgPT4gVmlld1R5cGUgfCBudWxsO1xuXG4gICAgQElucHV0KCkgcmVuZGVyVGV4dDogKHRleHQ6IFNsYXRlVGV4dCkgPT4gVmlld1R5cGUgfCBudWxsO1xuXG4gICAgQElucHV0KCkgZGVjb3JhdGU6IChlbnRyeTogTm9kZUVudHJ5KSA9PiBSYW5nZVtdID0gKCkgPT4gW107XG5cbiAgICBASW5wdXQoKSBwbGFjZWhvbGRlckRlY29yYXRlOiAoZWRpdG9yOiBFZGl0b3IpID0+IFNsYXRlUGxhY2Vob2xkZXJbXTtcblxuICAgIEBJbnB1dCgpIGlzU3RyaWN0RGVjb3JhdGU6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgQElucHV0KCkgdHJhY2tCeTogKG5vZGU6IEVsZW1lbnQpID0+IGFueSA9ICgpID0+IG51bGw7XG5cbiAgICBASW5wdXQoKSByZWFkb25seSA9IGZhbHNlO1xuXG4gICAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZztcblxuICAgIC8vI3JlZ2lvbiBpbnB1dCBldmVudCBoYW5kbGVyXG4gICAgQElucHV0KCkgYmVmb3JlSW5wdXQ6IChldmVudDogRXZlbnQpID0+IHZvaWQ7XG4gICAgQElucHV0KCkgYmx1cjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZDtcbiAgICBASW5wdXQoKSBjbGljazogKGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuICAgIEBJbnB1dCgpIGNvbXBvc2l0aW9uRW5kOiAoZXZlbnQ6IENvbXBvc2l0aW9uRXZlbnQpID0+IHZvaWQ7XG4gICAgQElucHV0KCkgY29tcG9zaXRpb25TdGFydDogKGV2ZW50OiBDb21wb3NpdGlvbkV2ZW50KSA9PiB2b2lkO1xuICAgIEBJbnB1dCgpIGNvcHk6IChldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IHZvaWQ7XG4gICAgQElucHV0KCkgY3V0OiAoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiB2b2lkO1xuICAgIEBJbnB1dCgpIGRyYWdPdmVyOiAoZXZlbnQ6IERyYWdFdmVudCkgPT4gdm9pZDtcbiAgICBASW5wdXQoKSBkcmFnU3RhcnQ6IChldmVudDogRHJhZ0V2ZW50KSA9PiB2b2lkO1xuICAgIEBJbnB1dCgpIGRyYWdFbmQ6IChldmVudDogRHJhZ0V2ZW50KSA9PiB2b2lkO1xuICAgIEBJbnB1dCgpIGRyb3A6IChldmVudDogRHJhZ0V2ZW50KSA9PiB2b2lkO1xuICAgIEBJbnB1dCgpIGZvY3VzOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkO1xuICAgIEBJbnB1dCgpIGtleWRvd246IChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gdm9pZDtcbiAgICBASW5wdXQoKSBwYXN0ZTogKGV2ZW50OiBDbGlwYm9hcmRFdmVudCkgPT4gdm9pZDtcbiAgICAvLyNlbmRyZWdpb25cblxuICAgIC8vI3JlZ2lvbiBET00gYXR0clxuICAgIEBJbnB1dCgpIHNwZWxsQ2hlY2sgPSBmYWxzZTtcbiAgICBASW5wdXQoKSBhdXRvQ29ycmVjdCA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIGF1dG9DYXBpdGFsaXplID0gZmFsc2U7XG5cbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuZGF0YS1zbGF0ZS1lZGl0b3InKSBkYXRhU2xhdGVFZGl0b3IgPSB0cnVlO1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5kYXRhLXNsYXRlLW5vZGUnKSBkYXRhU2xhdGVOb2RlID0gJ3ZhbHVlJztcbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuZGF0YS1ncmFtbScpIGRhdGFHcmFtbSA9IGZhbHNlO1xuXG4gICAgZ2V0IGhhc0JlZm9yZUlucHV0U3VwcG9ydCgpIHtcbiAgICAgICAgcmV0dXJuIEhBU19CRUZPUkVfSU5QVVRfU1VQUE9SVDtcbiAgICB9XG4gICAgLy8jZW5kcmVnaW9uXG5cbiAgICBAVmlld0NoaWxkKCd0ZW1wbGF0ZUNvbXBvbmVudCcsIHsgc3RhdGljOiB0cnVlIH0pIHRlbXBsYXRlQ29tcG9uZW50OiBTbGF0ZVN0cmluZ1RlbXBsYXRlQ29tcG9uZW50O1xuICAgIEBWaWV3Q2hpbGQoJ3RlbXBsYXRlQ29tcG9uZW50JywgeyBzdGF0aWM6IHRydWUsIHJlYWQ6IEVsZW1lbnRSZWYgfSkgdGVtcGxhdGVFbGVtZW50UmVmOiBFbGVtZW50UmVmPGFueT47XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHVibGljIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgICAgIHB1YmxpYyByZW5kZXJlcjI6IFJlbmRlcmVyMixcbiAgICAgICAgcHVibGljIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICAgICAgIHByaXZhdGUgaW5qZWN0b3I6IEluamVjdG9yXG4gICAgKSB7IH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmVkaXRvci5pbmplY3RvciA9IHRoaXMuaW5qZWN0b3I7XG4gICAgICAgIHRoaXMuZWRpdG9yLmNoaWxkcmVuID0gW107XG4gICAgICAgIGxldCB3aW5kb3cgPSBnZXREZWZhdWx0Vmlldyh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCk7XG4gICAgICAgIEVESVRPUl9UT19XSU5ET1cuc2V0KHRoaXMuZWRpdG9yLCB3aW5kb3cpO1xuICAgICAgICBFRElUT1JfVE9fRUxFTUVOVC5zZXQodGhpcy5lZGl0b3IsIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgICAgICAgTk9ERV9UT19FTEVNRU5ULnNldCh0aGlzLmVkaXRvciwgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuICAgICAgICBFTEVNRU5UX1RPX05PREUuc2V0KHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCB0aGlzLmVkaXRvcik7XG4gICAgICAgIElTX1JFQURPTkxZLnNldCh0aGlzLmVkaXRvciwgdGhpcy5yZWFkb25seSk7XG4gICAgICAgIEVESVRPUl9UT19PTl9DSEFOR0Uuc2V0KHRoaXMuZWRpdG9yLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMub25DaGFuZ2UoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWV3Q29udGV4dCgpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVDb250ZXh0KCk7XG5cbiAgICAgICAgLy8gcmVtb3ZlIHVudXNlZCBET00sIGp1c3Qga2VlcCB0ZW1wbGF0ZUNvbXBvbmVudCBpbnN0YW5jZVxuICAgICAgICB0aGlzLnRlbXBsYXRlRWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnJlbW92ZSgpO1xuXG4gICAgICAgIC8vIGFkZCBicm93c2VyIGNsYXNzXG4gICAgICAgIGxldCBicm93c2VyQ2xhc3MgPSBJU19GSVJFRk9YID8gJ2ZpcmVmb3gnIDogKElTX1NBRkFSSSA/ICdzYWZhcmknIDogJycpO1xuICAgICAgICBicm93c2VyQ2xhc3MgJiYgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZChicm93c2VyQ2xhc3MpO1xuICAgIH1cblxuICAgIG5nT25DaGFuZ2VzKHNpbXBsZUNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICAgICAgaWYgKCF0aGlzLmluaXRpYWxpemVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGVjb3JhdGVDaGFuZ2UgPSBzaW1wbGVDaGFuZ2VzWydkZWNvcmF0ZSddO1xuICAgICAgICBpZiAoZGVjb3JhdGVDaGFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMuZm9yY2VGbHVzaCgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlYWRvbmx5Q2hhbmdlID0gc2ltcGxlQ2hhbmdlc1sncmVhZG9ubHknXTtcbiAgICAgICAgaWYgKHJlYWRvbmx5Q2hhbmdlKSB7XG4gICAgICAgICAgICBJU19SRUFET05MWS5zZXQodGhpcy5lZGl0b3IsIHRoaXMucmVhZG9ubHkpO1xuICAgICAgICAgICAgdGhpcy5kZXRlY3RDb250ZXh0KCk7XG4gICAgICAgICAgICB0aGlzLnRvU2xhdGVTZWxlY3Rpb24oKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSkge1xuICAgICAgICB0aGlzLm9uQ2hhbmdlQ2FsbGJhY2sgPSBmbjtcbiAgICB9XG4gICAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSkge1xuICAgICAgICB0aGlzLm9uVG91Y2hlZENhbGxiYWNrID0gZm47XG4gICAgfVxuXG4gICAgd3JpdGVWYWx1ZSh2YWx1ZTogRWxlbWVudFtdKSB7XG4gICAgICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChjaGVjayh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVkaXRvci5jaGlsZHJlbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVkaXRvci5vbkVycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogU2xhdGVFcnJvckNvZGUuSW52YWxpZFZhbHVlRXJyb3IsXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdpbml0aWFsaXplIGludmFsaWQgZGF0YScsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHZhbHVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lZGl0b3IuY2hpbGRyZW4gPSBub3JtYWxpemUodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5pbml0aWFsaXplQ29udGV4dCgpO1xuICAgICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpbml0aWFsaXplKCkge1xuICAgICAgICB0aGlzLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgICAgY29uc3Qgd2luZG93ID0gQW5ndWxhckVkaXRvci5nZXRXaW5kb3codGhpcy5lZGl0b3IpO1xuICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgICAnc2VsZWN0aW9uY2hhbmdlJyxcbiAgICAgICAgICAgIGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvU2xhdGVTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB3aW5kb3cuZG9jdW1lbnRcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKEhBU19CRUZPUkVfSU5QVVRfU1VQUE9SVCkge1xuICAgICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdiZWZvcmVpbnB1dCcsIHRoaXMub25ET01CZWZvcmVJbnB1dC5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2JsdXInLCB0aGlzLm9uRE9NQmx1ci5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMub25ET01DbGljay5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjb21wb3NpdGlvbmVuZCcsIHRoaXMub25ET01Db21wb3NpdGlvbkVuZC5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdjb21wb3NpdGlvbnN0YXJ0JywgdGhpcy5vbkRPTUNvbXBvc2l0aW9uU3RhcnQuYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignY29weScsIHRoaXMub25ET01Db3B5LmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2N1dCcsIHRoaXMub25ET01DdXQuYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCB0aGlzLm9uRE9NRHJhZ092ZXIuYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ3N0YXJ0JywgdGhpcy5vbkRPTURyYWdTdGFydC5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdkcmFnZW5kJywgdGhpcy5vbkRPTURyYWdFbmQuYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcignZHJvcCcsIHRoaXMub25ET01Ecm9wLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgdGhpcy5vbkRPTUZvY3VzLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLm9uRE9NS2V5ZG93bi5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCdwYXN0ZScsIHRoaXMub25ET01QYXN0ZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgQkVGT1JFX0lOUFVUX0VWRU5UUy5mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcihldmVudC5uYW1lLCAoKSA9PiB7IH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB0b05hdGl2ZVNlbGVjdGlvbigpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHsgc2VsZWN0aW9uIH0gPSB0aGlzLmVkaXRvcjtcbiAgICAgICAgICAgIGNvbnN0IHJvb3QgPSBBbmd1bGFyRWRpdG9yLmZpbmREb2N1bWVudE9yU2hhZG93Um9vdCh0aGlzLmVkaXRvcilcbiAgICAgICAgICAgIGNvbnN0IGRvbVNlbGVjdGlvbiA9IChyb290IGFzIERvY3VtZW50KS5nZXRTZWxlY3Rpb24oKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuaXNDb21wb3NpbmcgfHwgIWRvbVNlbGVjdGlvbiB8fCAhQW5ndWxhckVkaXRvci5pc0ZvY3VzZWQodGhpcy5lZGl0b3IpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBoYXNEb21TZWxlY3Rpb24gPSBkb21TZWxlY3Rpb24udHlwZSAhPT0gJ05vbmUnO1xuXG4gICAgICAgICAgICAvLyBJZiB0aGUgRE9NIHNlbGVjdGlvbiBpcyBwcm9wZXJseSB1bnNldCwgd2UncmUgZG9uZS5cbiAgICAgICAgICAgIGlmICghc2VsZWN0aW9uICYmICFoYXNEb21TZWxlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIHRoZSBET00gc2VsZWN0aW9uIGlzIGFscmVhZHkgY29ycmVjdCwgd2UncmUgZG9uZS5cbiAgICAgICAgICAgIC8vIHZlcmlmeSB0aGF0IHRoZSBkb20gc2VsZWN0aW9uIGlzIGluIHRoZSBlZGl0b3JcbiAgICAgICAgICAgIGNvbnN0IGVkaXRvckVsZW1lbnQgPSBFRElUT1JfVE9fRUxFTUVOVC5nZXQodGhpcy5lZGl0b3IpITtcbiAgICAgICAgICAgIGxldCBoYXNEb21TZWxlY3Rpb25JbkVkaXRvciA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGVkaXRvckVsZW1lbnQuY29udGFpbnMoZG9tU2VsZWN0aW9uLmFuY2hvck5vZGUpICYmIGVkaXRvckVsZW1lbnQuY29udGFpbnMoZG9tU2VsZWN0aW9uLmZvY3VzTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBoYXNEb21TZWxlY3Rpb25JbkVkaXRvciA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIHRoZSBET00gc2VsZWN0aW9uIGlzIGluIHRoZSBlZGl0b3IgYW5kIHRoZSBlZGl0b3Igc2VsZWN0aW9uIGlzIGFscmVhZHkgY29ycmVjdCwgd2UncmUgZG9uZS5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBoYXNEb21TZWxlY3Rpb24gJiZcbiAgICAgICAgICAgICAgICBoYXNEb21TZWxlY3Rpb25JbkVkaXRvciAmJlxuICAgICAgICAgICAgICAgIHNlbGVjdGlvbiAmJlxuICAgICAgICAgICAgICAgIGhhc1N0cmluZ1RhcmdldChkb21TZWxlY3Rpb24pICYmXG4gICAgICAgICAgICAgICAgUmFuZ2UuZXF1YWxzKEFuZ3VsYXJFZGl0b3IudG9TbGF0ZVJhbmdlKHRoaXMuZWRpdG9yLCBkb21TZWxlY3Rpb24pLCBzZWxlY3Rpb24pXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHdoZW4gPEVkaXRhYmxlLz4gaXMgYmVpbmcgY29udHJvbGxlZCB0aHJvdWdoIGV4dGVybmFsIHZhbHVlXG4gICAgICAgICAgICAvLyB0aGVuIGl0cyBjaGlsZHJlbiBtaWdodCBqdXN0IGNoYW5nZSAtIERPTSByZXNwb25kcyB0byBpdCBvbiBpdHMgb3duXG4gICAgICAgICAgICAvLyBidXQgU2xhdGUncyB2YWx1ZSBpcyBub3QgYmVpbmcgdXBkYXRlZCB0aHJvdWdoIGFueSBvcGVyYXRpb25cbiAgICAgICAgICAgIC8vIGFuZCB0aHVzIGl0IGRvZXNuJ3QgdHJhbnNmb3JtIHNlbGVjdGlvbiBvbiBpdHMgb3duXG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uICYmICFBbmd1bGFyRWRpdG9yLmhhc1JhbmdlKHRoaXMuZWRpdG9yLCBzZWxlY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lZGl0b3Iuc2VsZWN0aW9uID0gQW5ndWxhckVkaXRvci50b1NsYXRlUmFuZ2UodGhpcy5lZGl0b3IsIGRvbVNlbGVjdGlvbik7XG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIE90aGVyd2lzZSB0aGUgRE9NIHNlbGVjdGlvbiBpcyBvdXQgb2Ygc3luYywgc28gdXBkYXRlIGl0LlxuICAgICAgICAgICAgY29uc3QgZWwgPSBBbmd1bGFyRWRpdG9yLnRvRE9NTm9kZSh0aGlzLmVkaXRvciwgdGhpcy5lZGl0b3IpO1xuICAgICAgICAgICAgdGhpcy5pc1VwZGF0aW5nU2VsZWN0aW9uID0gdHJ1ZTtcblxuICAgICAgICAgICAgY29uc3QgbmV3RG9tUmFuZ2UgPSBzZWxlY3Rpb24gJiYgQW5ndWxhckVkaXRvci50b0RPTVJhbmdlKHRoaXMuZWRpdG9yLCBzZWxlY3Rpb24pO1xuXG4gICAgICAgICAgICBpZiAobmV3RG9tUmFuZ2UpIHtcbiAgICAgICAgICAgICAgICAvLyBDT01QQVQ6IFNpbmNlIHRoZSBET00gcmFuZ2UgaGFzIG5vIGNvbmNlcHQgb2YgYmFja3dhcmRzL2ZvcndhcmRzXG4gICAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBjaGVjayBhbmQgZG8gdGhlIHJpZ2h0IHRoaW5nIGhlcmUuXG4gICAgICAgICAgICAgICAgaWYgKFJhbmdlLmlzQmFja3dhcmQoc2VsZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICAgICAgICAgICAgICBkb21TZWxlY3Rpb24uc2V0QmFzZUFuZEV4dGVudChcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0RvbVJhbmdlLmVuZENvbnRhaW5lcixcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0RvbVJhbmdlLmVuZE9mZnNldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0RvbVJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3RG9tUmFuZ2Uuc3RhcnRPZmZzZXRcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICAgICAgICAgICAgICBkb21TZWxlY3Rpb24uc2V0QmFzZUFuZEV4dGVudChcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld0RvbVJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3RG9tUmFuZ2Uuc3RhcnRPZmZzZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdEb21SYW5nZS5lbmRDb250YWluZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdEb21SYW5nZS5lbmRPZmZzZXRcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRvbVNlbGVjdGlvbi5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQ09NUEFUOiBJbiBGaXJlZm94LCBpdCdzIG5vdCBlbm91Z2ggdG8gY3JlYXRlIGEgcmFuZ2UsIHlvdSBhbHNvIG5lZWRcbiAgICAgICAgICAgICAgICAvLyB0byBmb2N1cyB0aGUgY29udGVudGVkaXRhYmxlIGVsZW1lbnQgdG9vLiAoMjAxNi8xMS8xNilcbiAgICAgICAgICAgICAgICBpZiAobmV3RG9tUmFuZ2UgJiYgSVNfRklSRUZPWCkge1xuICAgICAgICAgICAgICAgICAgICBlbC5mb2N1cygpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuaXNVcGRhdGluZ1NlbGVjdGlvbiA9IGZhbHNlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmVkaXRvci5vbkVycm9yKHsgY29kZTogU2xhdGVFcnJvckNvZGUuVG9OYXRpdmVTZWxlY3Rpb25FcnJvciwgbmF0aXZlRXJyb3I6IGVycm9yIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkNoYW5nZSgpIHtcbiAgICAgICAgdGhpcy5mb3JjZUZsdXNoKCk7XG4gICAgICAgIHRoaXMub25DaGFuZ2VDYWxsYmFjayh0aGlzLmVkaXRvci5jaGlsZHJlbik7XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdDaGVja2VkKCkge1xuICAgICAgICB0aW1lRGVidWcoJ2VkaXRhYmxlIG5nQWZ0ZXJWaWV3Q2hlY2tlZCcpO1xuICAgIH1cblxuICAgIG5nRG9DaGVjaygpIHtcbiAgICAgICAgdGltZURlYnVnKCdlZGl0YWJsZSBuZ0RvQ2hlY2snKTtcbiAgICB9XG5cbiAgICBmb3JjZUZsdXNoKCkge1xuICAgICAgICB0aW1lRGVidWcoJ3N0YXJ0IGRhdGEgc3luYycpO1xuICAgICAgICB0aGlzLmRldGVjdENvbnRleHQoKTtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAvLyByZXBhaXIgY29sbGFib3JhdGl2ZSBlZGl0aW5nIHdoZW4gQ2hpbmVzZSBpbnB1dCBpcyBpbnRlcnJ1cHRlZCBieSBvdGhlciB1c2VycycgY3Vyc29yc1xuICAgICAgICAvLyB3aGVuIHRoZSBET01FbGVtZW50IHdoZXJlIHRoZSBzZWxlY3Rpb24gaXMgbG9jYXRlZCBpcyByZW1vdmVkXG4gICAgICAgIC8vIHRoZSBjb21wb3NpdGlvbnVwZGF0ZSBhbmQgY29tcG9zaXRpb25lbmQgZXZlbnRzIHdpbGwgbm8gbG9uZ2VyIGJlIGZpcmVkXG4gICAgICAgIC8vIHNvIGlzQ29tcG9zaW5nIG5lZWRzIHRvIGJlIGNvcnJlY3RlZFxuICAgICAgICAvLyBuZWVkIGV4ZWMgYWZ0ZXIgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpIHRvIHJlbmRlciBIVE1MXG4gICAgICAgIC8vIG5lZWQgZXhlYyBiZWZvcmUgdGhpcy50b05hdGl2ZVNlbGVjdGlvbigpIHRvIGNvcnJlY3QgbmF0aXZlIHNlbGVjdGlvblxuICAgICAgICBpZiAodGhpcy5pc0NvbXBvc2luZykge1xuICAgICAgICAgICAgLy8gQ29tcG9zaXRpb24gaW5wdXQgdGV4dCBiZSBub3QgcmVuZGVyZWQgd2hlbiB1c2VyIGNvbXBvc2l0aW9uIGlucHV0IHdpdGggc2VsZWN0aW9uIGlzIGV4cGFuZGVkXG4gICAgICAgICAgICAvLyBBdCB0aGlzIHRpbWUsIHRoZSBmb2xsb3dpbmcgbWF0Y2hpbmcgY29uZGl0aW9ucyBhcmUgbWV0LCBhc3NpZ24gaXNDb21wb3NpbmcgdG8gZmFsc2UsIGFuZCB0aGUgc3RhdHVzIGlzIHdyb25nXG4gICAgICAgICAgICAvLyB0aGlzIHRpbWUgY29uZGl0aW9uIGlzIHRydWUgYW5kIGlzQ29tcG9zaWluZyBpcyBhc3NpZ25lZCBmYWxzZVxuICAgICAgICAgICAgLy8gVGhlcmVmb3JlLCBuZWVkIHRvIHdhaXQgZm9yIHRoZSBjb21wb3NpdGlvbiBpbnB1dCB0ZXh0IHRvIGJlIHJlbmRlcmVkIGJlZm9yZSBwZXJmb3JtaW5nIGNvbmRpdGlvbiBtYXRjaGluZ1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGV4dE5vZGUgPSBOb2RlLmdldCh0aGlzLmVkaXRvciwgdGhpcy5lZGl0b3Iuc2VsZWN0aW9uLmFuY2hvci5wYXRoKTtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0RE9NTm9kZSA9IEFuZ3VsYXJFZGl0b3IudG9ET01Ob2RlKHRoaXMuZWRpdG9yLCB0ZXh0Tm9kZSk7XG4gICAgICAgICAgICAgICAgbGV0IHRleHRDb250ZW50ID0gJyc7XG4gICAgICAgICAgICAgICAgLy8gc2tpcCBkZWNvcmF0ZSB0ZXh0XG4gICAgICAgICAgICAgICAgdGV4dERPTU5vZGUucXVlcnlTZWxlY3RvckFsbCgnW2VkaXRhYmxlLXRleHRdJykuZm9yRWFjaCgoc3RyaW5nRE9NTm9kZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgdGV4dCA9IHN0cmluZ0RPTU5vZGUudGV4dENvbnRlbnQ7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHplcm9DaGFyID0gJ1xcdUZFRkYnO1xuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgemVybyB3aXRoIGNoYXJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRleHQuc3RhcnRzV2l0aCh6ZXJvQ2hhcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0LnNsaWNlKDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0ZXh0LmVuZHNXaXRoKHplcm9DaGFyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHRleHQuc2xpY2UoMCwgdGV4dC5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0ZXh0Q29udGVudCArPSB0ZXh0O1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChOb2RlLnN0cmluZyh0ZXh0Tm9kZSkuZW5kc1dpdGgodGV4dENvbnRlbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNDb21wb3NpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRvTmF0aXZlU2VsZWN0aW9uKCk7XG4gICAgICAgIHRpbWVEZWJ1ZygnZW5kIGRhdGEgc3luYycpO1xuICAgIH1cblxuICAgIGluaXRpYWxpemVDb250ZXh0KCkge1xuICAgICAgICB0aGlzLmNvbnRleHQgPSB7XG4gICAgICAgICAgICBwYXJlbnQ6IHRoaXMuZWRpdG9yLFxuICAgICAgICAgICAgc2VsZWN0aW9uOiB0aGlzLmVkaXRvci5zZWxlY3Rpb24sXG4gICAgICAgICAgICBkZWNvcmF0aW9uczogdGhpcy5nZW5lcmF0ZURlY29yYXRpb25zKCksXG4gICAgICAgICAgICBkZWNvcmF0ZTogdGhpcy5kZWNvcmF0ZSxcbiAgICAgICAgICAgIHJlYWRvbmx5OiB0aGlzLnJlYWRvbmx5XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaW5pdGlhbGl6ZVZpZXdDb250ZXh0KCkge1xuICAgICAgICB0aGlzLnZpZXdDb250ZXh0ID0ge1xuICAgICAgICAgICAgZWRpdG9yOiB0aGlzLmVkaXRvcixcbiAgICAgICAgICAgIHJlbmRlckVsZW1lbnQ6IHRoaXMucmVuZGVyRWxlbWVudCxcbiAgICAgICAgICAgIHJlbmRlckxlYWY6IHRoaXMucmVuZGVyTGVhZixcbiAgICAgICAgICAgIHJlbmRlclRleHQ6IHRoaXMucmVuZGVyVGV4dCxcbiAgICAgICAgICAgIHRyYWNrQnk6IHRoaXMudHJhY2tCeSxcbiAgICAgICAgICAgIGlzU3RyaWN0RGVjb3JhdGU6IHRoaXMuaXNTdHJpY3REZWNvcmF0ZSxcbiAgICAgICAgICAgIHRlbXBsYXRlQ29tcG9uZW50OiB0aGlzLnRlbXBsYXRlQ29tcG9uZW50XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZGV0ZWN0Q29udGV4dCgpIHtcbiAgICAgICAgY29uc3QgZGVjb3JhdGlvbnMgPSB0aGlzLmdlbmVyYXRlRGVjb3JhdGlvbnMoKTtcbiAgICAgICAgaWYgKHRoaXMuY29udGV4dC5zZWxlY3Rpb24gIT09IHRoaXMuZWRpdG9yLnNlbGVjdGlvbiB8fFxuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmRlY29yYXRlICE9PSB0aGlzLmRlY29yYXRlIHx8XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQucmVhZG9ubHkgIT09IHRoaXMucmVhZG9ubHkgfHxcbiAgICAgICAgICAgICFpc0RlY29yYXRvclJhbmdlTGlzdEVxdWFsKHRoaXMuY29udGV4dC5kZWNvcmF0aW9ucywgZGVjb3JhdGlvbnMpKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQgPSB7XG4gICAgICAgICAgICAgICAgcGFyZW50OiB0aGlzLmVkaXRvcixcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb246IHRoaXMuZWRpdG9yLnNlbGVjdGlvbixcbiAgICAgICAgICAgICAgICBkZWNvcmF0aW9uczogZGVjb3JhdGlvbnMsXG4gICAgICAgICAgICAgICAgZGVjb3JhdGU6IHRoaXMuZGVjb3JhdGUsXG4gICAgICAgICAgICAgICAgcmVhZG9ubHk6IHRoaXMucmVhZG9ubHlcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb21wb3NlUGxhY2Vob2xkZXJEZWNvcmF0ZShlZGl0b3I6IEVkaXRvcikge1xuICAgICAgICBpZiAodGhpcy5wbGFjZWhvbGRlckRlY29yYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wbGFjZWhvbGRlckRlY29yYXRlKGVkaXRvcikgfHwgW107XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnBsYWNlaG9sZGVyICYmXG4gICAgICAgICAgICBlZGl0b3IuY2hpbGRyZW4ubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICBBcnJheS5mcm9tKE5vZGUudGV4dHMoZWRpdG9yKSkubGVuZ3RoID09PSAxICYmXG4gICAgICAgICAgICBOb2RlLnN0cmluZyhlZGl0b3IpID09PSAnJ1xuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gRWRpdG9yLnN0YXJ0KGVkaXRvciwgW10pXG4gICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IHRoaXMucGxhY2Vob2xkZXIsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvcjogc3RhcnQsXG4gICAgICAgICAgICAgICAgICAgIGZvY3VzOiBzdGFydCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFtdXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZW5lcmF0ZURlY29yYXRpb25zKCkge1xuICAgICAgICBjb25zdCBkZWNvcmF0aW9ucyA9IHRoaXMuZGVjb3JhdGUoW3RoaXMuZWRpdG9yLCBbXV0pO1xuICAgICAgICBjb25zdCBwbGFjZWhvbGRlckRlY29yYXRpb25zID0gdGhpcy5pc0NvbXBvc2luZ1xuICAgICAgICAgICAgPyBbXVxuICAgICAgICAgICAgOiB0aGlzLmNvbXBvc2VQbGFjZWhvbGRlckRlY29yYXRlKHRoaXMuZWRpdG9yKVxuICAgICAgICBkZWNvcmF0aW9ucy5wdXNoKC4uLnBsYWNlaG9sZGVyRGVjb3JhdGlvbnMpO1xuICAgICAgICByZXR1cm4gZGVjb3JhdGlvbnM7XG4gICAgfVxuXG4gICAgLy8jcmVnaW9uIGV2ZW50IHByb3h5XG4gICAgcHJpdmF0ZSBhZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZTogc3RyaW5nLCBsaXN0ZW5lcjogRXZlbnRMaXN0ZW5lciwgdGFyZ2V0OiBIVE1MRWxlbWVudCB8IERvY3VtZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5tYW51YWxMaXN0ZW5lcnMucHVzaChcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIyLmxpc3Rlbih0YXJnZXQsIGV2ZW50TmFtZSwgKGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJlZm9yZUlucHV0RXZlbnQgPSBleHRyYWN0QmVmb3JlSW5wdXRFdmVudChldmVudC50eXBlLCBudWxsLCBldmVudCwgZXZlbnQudGFyZ2V0KTtcbiAgICAgICAgICAgICAgICBpZiAoYmVmb3JlSW5wdXRFdmVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRmFsbGJhY2tCZWZvcmVJbnB1dChiZWZvcmVJbnB1dEV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIoZXZlbnQpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHRvU2xhdGVTZWxlY3Rpb24oKSB7XG4gICAgICAgIGlmICghdGhpcy5pc0NvbXBvc2luZyAmJiAhdGhpcy5pc1VwZGF0aW5nU2VsZWN0aW9uICYmICF0aGlzLmlzRHJhZ2dpbmdJbnRlcm5hbGx5KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJvb3QgPSBBbmd1bGFyRWRpdG9yLmZpbmREb2N1bWVudE9yU2hhZG93Um9vdCh0aGlzLmVkaXRvcilcbiAgICAgICAgICAgICAgICBjb25zdCB7IGFjdGl2ZUVsZW1lbnQgfSA9IHJvb3Q7XG4gICAgICAgICAgICAgICAgY29uc3QgZWwgPSBBbmd1bGFyRWRpdG9yLnRvRE9NTm9kZSh0aGlzLmVkaXRvciwgdGhpcy5lZGl0b3IpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRvbVNlbGVjdGlvbiA9IChyb290IGFzIERvY3VtZW50KS5nZXRTZWxlY3Rpb24oKTtcblxuICAgICAgICAgICAgICAgIGlmIChhY3RpdmVFbGVtZW50ID09PSBlbCB8fCBoYXNFZGl0YWJsZVRhcmdldCh0aGlzLmVkaXRvciwgYWN0aXZlRWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXRlc3RFbGVtZW50ID0gYWN0aXZlRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgSVNfRk9DVVNFRC5zZXQodGhpcy5lZGl0b3IsIHRydWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIElTX0ZPQ1VTRUQuZGVsZXRlKHRoaXMuZWRpdG9yKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIWRvbVNlbGVjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gVHJhbnNmb3Jtcy5kZXNlbGVjdCh0aGlzLmVkaXRvcik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgZWRpdG9yRWxlbWVudCA9IEVESVRPUl9UT19FTEVNRU5ULmdldCh0aGlzLmVkaXRvcik7XG4gICAgICAgICAgICAgICAgY29uc3QgaGFzRG9tU2VsZWN0aW9uSW5FZGl0b3IgPSBlZGl0b3JFbGVtZW50LmNvbnRhaW5zKGRvbVNlbGVjdGlvbi5hbmNob3JOb2RlKSAmJiBlZGl0b3JFbGVtZW50LmNvbnRhaW5zKGRvbVNlbGVjdGlvbi5mb2N1c05vZGUpO1xuICAgICAgICAgICAgICAgIGlmICghaGFzRG9tU2VsZWN0aW9uSW5FZGl0b3IpIHtcbiAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5kZXNlbGVjdCh0aGlzLmVkaXRvcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyB0cnkgdG8gZ2V0IHRoZSBzZWxlY3Rpb24gZGlyZWN0bHksIGJlY2F1c2Ugc29tZSB0ZXJyaWJsZSBjYXNlIGNhbiBiZSBub3JtYWxpemUgZm9yIG5vcm1hbGl6ZURPTVBvaW50XG4gICAgICAgICAgICAgICAgLy8gZm9yIGV4YW1wbGUsIGRvdWJsZS1jbGljayB0aGUgbGFzdCBjZWxsIG9mIHRoZSB0YWJsZSB0byBzZWxlY3QgYSBub24tZWRpdGFibGUgRE9NXG4gICAgICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSBBbmd1bGFyRWRpdG9yLnRvU2xhdGVSYW5nZSh0aGlzLmVkaXRvciwgZG9tU2VsZWN0aW9uKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5lZGl0b3Iuc2VsZWN0aW9uICYmIFJhbmdlLmVxdWFscyhyYW5nZSwgdGhpcy5lZGl0b3Iuc2VsZWN0aW9uKSAmJiAhaGFzU3RyaW5nVGFyZ2V0KGRvbVNlbGVjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZm9yY2UgYWRqdXN0IERPTVNlbGVjdGlvblxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvTmF0aXZlU2VsZWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5zZWxlY3QodGhpcy5lZGl0b3IsIHJhbmdlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yLm9uRXJyb3IoeyBjb2RlOiBTbGF0ZUVycm9yQ29kZS5Ub1NsYXRlU2VsZWN0aW9uRXJyb3IsIG5hdGl2ZUVycm9yOiBlcnJvciB9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkRPTUJlZm9yZUlucHV0KFxuICAgICAgICBldmVudDogRXZlbnQgJiB7XG4gICAgICAgICAgICBpbnB1dFR5cGU6IHN0cmluZztcbiAgICAgICAgICAgIGlzQ29tcG9zaW5nOiBib29sZWFuO1xuICAgICAgICAgICAgZGF0YTogc3RyaW5nIHwgbnVsbDtcbiAgICAgICAgICAgIGRhdGFUcmFuc2ZlcjogRGF0YVRyYW5zZmVyIHwgbnVsbDtcbiAgICAgICAgICAgIGdldFRhcmdldFJhbmdlcygpOiBET01TdGF0aWNSYW5nZVtdO1xuICAgICAgICB9XG4gICAgKSB7XG4gICAgICAgIGNvbnN0IGVkaXRvciA9IHRoaXMuZWRpdG9yO1xuICAgICAgICBpZiAoIXRoaXMucmVhZG9ubHkgJiYgaGFzRWRpdGFibGVUYXJnZXQoZWRpdG9yLCBldmVudC50YXJnZXQpICYmICF0aGlzLmlzRE9NRXZlbnRIYW5kbGVkKGV2ZW50LCB0aGlzLmJlZm9yZUlucHV0KSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gZWRpdG9yO1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgaW5wdXRUeXBlOiB0eXBlIH0gPSBldmVudDtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gZXZlbnQuZGF0YVRyYW5zZmVyIHx8IGV2ZW50LmRhdGEgfHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAvLyBDT01QQVQ6IElmIHRoZSBzZWxlY3Rpb24gaXMgZXhwYW5kZWQsIGV2ZW4gaWYgdGhlIGNvbW1hbmQgc2VlbXMgbGlrZVxuICAgICAgICAgICAgICAgIC8vIGEgZGVsZXRlIGZvcndhcmQvYmFja3dhcmQgY29tbWFuZCBpdCBzaG91bGQgZGVsZXRlIHRoZSBzZWxlY3Rpb24uXG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbiAmJiBSYW5nZS5pc0V4cGFuZGVkKHNlbGVjdGlvbikgJiYgdHlwZS5zdGFydHNXaXRoKCdkZWxldGUnKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkaXJlY3Rpb24gPSB0eXBlLmVuZHNXaXRoKCdCYWNrd2FyZCcpID8gJ2JhY2t3YXJkJyA6ICdmb3J3YXJkJztcbiAgICAgICAgICAgICAgICAgICAgRWRpdG9yLmRlbGV0ZUZyYWdtZW50KGVkaXRvciwgeyBkaXJlY3Rpb24gfSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZGVsZXRlQnlDb21wb3NpdGlvbic6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2RlbGV0ZUJ5Q3V0JzpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZGVsZXRlQnlEcmFnJzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgRWRpdG9yLmRlbGV0ZUZyYWdtZW50KGVkaXRvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2RlbGV0ZUNvbnRlbnQnOlxuICAgICAgICAgICAgICAgICAgICBjYXNlICdkZWxldGVDb250ZW50Rm9yd2FyZCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEVkaXRvci5kZWxldGVGb3J3YXJkKGVkaXRvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2RlbGV0ZUNvbnRlbnRCYWNrd2FyZCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEVkaXRvci5kZWxldGVCYWNrd2FyZChlZGl0b3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICdkZWxldGVFbnRpcmVTb2Z0TGluZSc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEVkaXRvci5kZWxldGVCYWNrd2FyZChlZGl0b3IsIHsgdW5pdDogJ2xpbmUnIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgRWRpdG9yLmRlbGV0ZUZvcndhcmQoZWRpdG9yLCB7IHVuaXQ6ICdsaW5lJyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZGVsZXRlSGFyZExpbmVCYWNrd2FyZCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEVkaXRvci5kZWxldGVCYWNrd2FyZChlZGl0b3IsIHsgdW5pdDogJ2Jsb2NrJyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZGVsZXRlU29mdExpbmVCYWNrd2FyZCc6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEVkaXRvci5kZWxldGVCYWNrd2FyZChlZGl0b3IsIHsgdW5pdDogJ2xpbmUnIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjYXNlICdkZWxldGVIYXJkTGluZUZvcndhcmQnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuZGVsZXRlRm9yd2FyZChlZGl0b3IsIHsgdW5pdDogJ2Jsb2NrJyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZGVsZXRlU29mdExpbmVGb3J3YXJkJzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgRWRpdG9yLmRlbGV0ZUZvcndhcmQoZWRpdG9yLCB7IHVuaXQ6ICdsaW5lJyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnZGVsZXRlV29yZEJhY2t3YXJkJzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgRWRpdG9yLmRlbGV0ZUJhY2t3YXJkKGVkaXRvciwgeyB1bml0OiAnd29yZCcgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2RlbGV0ZVdvcmRGb3J3YXJkJzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgRWRpdG9yLmRlbGV0ZUZvcndhcmQoZWRpdG9yLCB7IHVuaXQ6ICd3b3JkJyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnaW5zZXJ0TGluZUJyZWFrJzpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnaW5zZXJ0UGFyYWdyYXBoJzoge1xuICAgICAgICAgICAgICAgICAgICAgICAgRWRpdG9yLmluc2VydEJyZWFrKGVkaXRvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2luc2VydEZyb21Db21wb3NpdGlvbic6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENPTVBBVDogaW4gc2FmYXJpLCBgY29tcG9zaXRpb25lbmRgIGV2ZW50IGlzIGRpc3BhdGNoZWQgYWZ0ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoZSBiZWZvcmVpbnB1dCBldmVudCB3aXRoIHRoZSBpbnB1dFR5cGUgXCJpbnNlcnRGcm9tQ29tcG9zaXRpb25cIiBoYXMgYmVlbiBkaXNwYXRjaGVkLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSL2lucHV0LWV2ZW50cy0yL1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc28gdGhlIGZvbGxvd2luZyBjb2RlIGlzIHRoZSByaWdodCBsb2dpY1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBET00gc2VsZWN0aW9uIGluIHN5bmMgd2lsbCBiZSBleGVjIGJlZm9yZSBgY29tcG9zaXRpb25lbmRgIGV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpc0NvbXBvc2luZyBpcyB0cnVlIHdpbGwgcHJldmVudCBET00gc2VsZWN0aW9uIGJlaW5nIHVwZGF0ZSBjb3JyZWN0bHkuXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzQ29tcG9zaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcmV2ZW50SW5zZXJ0RnJvbUNvbXBvc2l0aW9uKGV2ZW50LCB0aGlzLmVkaXRvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnaW5zZXJ0RnJvbURyb3AnOlxuICAgICAgICAgICAgICAgICAgICBjYXNlICdpbnNlcnRGcm9tUGFzdGUnOlxuICAgICAgICAgICAgICAgICAgICBjYXNlICdpbnNlcnRGcm9tWWFuayc6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2luc2VydFJlcGxhY2VtZW50VGV4dCc6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2luc2VydFRleHQnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2UgYSB3ZWFrIGNvbXBhcmlzb24gaW5zdGVhZCBvZiAnaW5zdGFuY2VvZicgdG8gYWxsb3dcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHByb2dyYW1tYXRpYyBhY2Nlc3Mgb2YgcGFzdGUgZXZlbnRzIGNvbWluZyBmcm9tIGV4dGVybmFsIHdpbmRvd3NcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxpa2UgY3lwcmVzcyB3aGVyZSBjeS53aW5kb3cgZG9lcyBub3Qgd29yayByZWFsaWJseVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGE/LmNvbnN0cnVjdG9yLm5hbWUgPT09ICdEYXRhVHJhbnNmZXInKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQW5ndWxhckVkaXRvci5pbnNlcnREYXRhKGVkaXRvciwgZGF0YSBhcyBEYXRhVHJhbnNmZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuaW5zZXJ0VGV4dChlZGl0b3IsIGRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHRoaXMuZWRpdG9yLm9uRXJyb3IoeyBjb2RlOiBTbGF0ZUVycm9yQ29kZS5PbkRPTUJlZm9yZUlucHV0RXJyb3IsIG5hdGl2ZUVycm9yOiBlcnJvciB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgb25ET01CbHVyKGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHRoaXMucmVhZG9ubHkgfHxcbiAgICAgICAgICAgIHRoaXMuaXNVcGRhdGluZ1NlbGVjdGlvbiB8fFxuICAgICAgICAgICAgIWhhc0VkaXRhYmxlVGFyZ2V0KHRoaXMuZWRpdG9yLCBldmVudC50YXJnZXQpIHx8XG4gICAgICAgICAgICB0aGlzLmlzRE9NRXZlbnRIYW5kbGVkKGV2ZW50LCB0aGlzLmJsdXIpXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgd2luZG93ID0gQW5ndWxhckVkaXRvci5nZXRXaW5kb3codGhpcy5lZGl0b3IpO1xuXG4gICAgICAgIC8vIENPTVBBVDogSWYgdGhlIGN1cnJlbnQgYGFjdGl2ZUVsZW1lbnRgIGlzIHN0aWxsIHRoZSBwcmV2aW91c1xuICAgICAgICAvLyBvbmUsIHRoaXMgaXMgZHVlIHRvIHRoZSB3aW5kb3cgYmVpbmcgYmx1cnJlZCB3aGVuIHRoZSB0YWJcbiAgICAgICAgLy8gaXRzZWxmIGJlY29tZXMgdW5mb2N1c2VkLCBzbyB3ZSB3YW50IHRvIGFib3J0IGVhcmx5IHRvIGFsbG93IHRvXG4gICAgICAgIC8vIGVkaXRvciB0byBzdGF5IGZvY3VzZWQgd2hlbiB0aGUgdGFiIGJlY29tZXMgZm9jdXNlZCBhZ2Fpbi5cbiAgICAgICAgY29uc3Qgcm9vdCA9IEFuZ3VsYXJFZGl0b3IuZmluZERvY3VtZW50T3JTaGFkb3dSb290KHRoaXMuZWRpdG9yKTtcbiAgICAgICAgaWYgKHRoaXMubGF0ZXN0RWxlbWVudCA9PT0gcm9vdC5hY3RpdmVFbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IHJlbGF0ZWRUYXJnZXQgfSA9IGV2ZW50O1xuICAgICAgICBjb25zdCBlbCA9IEFuZ3VsYXJFZGl0b3IudG9ET01Ob2RlKHRoaXMuZWRpdG9yLCB0aGlzLmVkaXRvcik7XG5cbiAgICAgICAgLy8gQ09NUEFUOiBUaGUgZXZlbnQgc2hvdWxkIGJlIGlnbm9yZWQgaWYgdGhlIGZvY3VzIGlzIHJldHVybmluZ1xuICAgICAgICAvLyB0byB0aGUgZWRpdG9yIGZyb20gYW4gZW1iZWRkZWQgZWRpdGFibGUgZWxlbWVudCAoZWcuIGFuIDxpbnB1dD5cbiAgICAgICAgLy8gZWxlbWVudCBpbnNpZGUgYSB2b2lkIG5vZGUpLlxuICAgICAgICBpZiAocmVsYXRlZFRhcmdldCA9PT0gZWwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENPTVBBVDogVGhlIGV2ZW50IHNob3VsZCBiZSBpZ25vcmVkIGlmIHRoZSBmb2N1cyBpcyBtb3ZpbmcgZnJvbVxuICAgICAgICAvLyB0aGUgZWRpdG9yIHRvIGluc2lkZSBhIHZvaWQgbm9kZSdzIHNwYWNlciBlbGVtZW50LlxuICAgICAgICBpZiAoaXNET01FbGVtZW50KHJlbGF0ZWRUYXJnZXQpICYmIHJlbGF0ZWRUYXJnZXQuaGFzQXR0cmlidXRlKCdkYXRhLXNsYXRlLXNwYWNlcicpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDT01QQVQ6IFRoZSBldmVudCBzaG91bGQgYmUgaWdub3JlZCBpZiB0aGUgZm9jdXMgaXMgbW92aW5nIHRvIGFcbiAgICAgICAgLy8gbm9uLSBlZGl0YWJsZSBzZWN0aW9uIG9mIGFuIGVsZW1lbnQgdGhhdCBpc24ndCBhIHZvaWQgbm9kZSAoZWcuXG4gICAgICAgIC8vIGEgbGlzdCBpdGVtIG9mIHRoZSBjaGVjayBsaXN0IGV4YW1wbGUpLlxuICAgICAgICBpZiAocmVsYXRlZFRhcmdldCAhPSBudWxsICYmIGlzRE9NTm9kZShyZWxhdGVkVGFyZ2V0KSAmJiBBbmd1bGFyRWRpdG9yLmhhc0RPTU5vZGUodGhpcy5lZGl0b3IsIHJlbGF0ZWRUYXJnZXQpKSB7XG4gICAgICAgICAgICBjb25zdCBub2RlID0gQW5ndWxhckVkaXRvci50b1NsYXRlTm9kZSh0aGlzLmVkaXRvciwgcmVsYXRlZFRhcmdldCk7XG5cbiAgICAgICAgICAgIGlmIChFbGVtZW50LmlzRWxlbWVudChub2RlKSAmJiAhdGhpcy5lZGl0b3IuaXNWb2lkKG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgSVNfRk9DVVNFRC5kZWxldGUodGhpcy5lZGl0b3IpO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25ET01DbGljayhldmVudDogTW91c2VFdmVudCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICAhdGhpcy5yZWFkb25seSAmJlxuICAgICAgICAgICAgaGFzVGFyZ2V0KHRoaXMuZWRpdG9yLCBldmVudC50YXJnZXQpICYmXG4gICAgICAgICAgICAhdGhpcy5pc0RPTUV2ZW50SGFuZGxlZChldmVudCwgdGhpcy5jbGljaykgJiZcbiAgICAgICAgICAgIGlzRE9NTm9kZShldmVudC50YXJnZXQpXG4gICAgICAgICkge1xuICAgICAgICAgICAgY29uc3Qgbm9kZSA9IEFuZ3VsYXJFZGl0b3IudG9TbGF0ZU5vZGUodGhpcy5lZGl0b3IsIGV2ZW50LnRhcmdldCk7XG4gICAgICAgICAgICBjb25zdCBwYXRoID0gQW5ndWxhckVkaXRvci5maW5kUGF0aCh0aGlzLmVkaXRvciwgbm9kZSk7XG4gICAgICAgICAgICBjb25zdCBzdGFydCA9IEVkaXRvci5zdGFydCh0aGlzLmVkaXRvciwgcGF0aCk7XG4gICAgICAgICAgICBjb25zdCBlbmQgPSBFZGl0b3IuZW5kKHRoaXMuZWRpdG9yLCBwYXRoKTtcblxuICAgICAgICAgICAgY29uc3Qgc3RhcnRWb2lkID0gRWRpdG9yLnZvaWQodGhpcy5lZGl0b3IsIHsgYXQ6IHN0YXJ0IH0pO1xuICAgICAgICAgICAgY29uc3QgZW5kVm9pZCA9IEVkaXRvci52b2lkKHRoaXMuZWRpdG9yLCB7IGF0OiBlbmQgfSk7XG5cbiAgICAgICAgICAgIGlmIChzdGFydFZvaWQgJiYgZW5kVm9pZCAmJiBQYXRoLmVxdWFscyhzdGFydFZvaWRbMV0sIGVuZFZvaWRbMV0pKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSBFZGl0b3IucmFuZ2UodGhpcy5lZGl0b3IsIHN0YXJ0KTtcbiAgICAgICAgICAgICAgICBUcmFuc2Zvcm1zLnNlbGVjdCh0aGlzLmVkaXRvciwgcmFuZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkRPTUNvbXBvc2l0aW9uRW5kKGV2ZW50OiBDb21wb3NpdGlvbkV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQuZGF0YSAmJiAhUmFuZ2UuaXNDb2xsYXBzZWQodGhpcy5lZGl0b3Iuc2VsZWN0aW9uKSkge1xuICAgICAgICAgICAgVHJhbnNmb3Jtcy5kZWxldGUodGhpcy5lZGl0b3IpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNFZGl0YWJsZVRhcmdldCh0aGlzLmVkaXRvciwgZXZlbnQudGFyZ2V0KSAmJiAhdGhpcy5pc0RPTUV2ZW50SGFuZGxlZChldmVudCwgdGhpcy5jb21wb3NpdGlvbkVuZCkpIHtcbiAgICAgICAgICAgIC8vIENPTVBBVDogSW4gQ2hyb21lL0ZpcmVmb3gsIGBiZWZvcmVpbnB1dGAgZXZlbnRzIGZvciBjb21wb3NpdGlvbnNcbiAgICAgICAgICAgIC8vIGFyZW4ndCBjb3JyZWN0IGFuZCBuZXZlciBmaXJlIHRoZSBcImluc2VydEZyb21Db21wb3NpdGlvblwiXG4gICAgICAgICAgICAvLyB0eXBlIHRoYXQgd2UgbmVlZC4gU28gaW5zdGVhZCwgaW5zZXJ0IHdoZW5ldmVyIGEgY29tcG9zaXRpb25cbiAgICAgICAgICAgIC8vIGVuZHMgc2luY2UgaXQgd2lsbCBhbHJlYWR5IGhhdmUgYmVlbiBjb21taXR0ZWQgdG8gdGhlIERPTS5cbiAgICAgICAgICAgIGlmICh0aGlzLmlzQ29tcG9zaW5nID09PSB0cnVlICYmICFJU19TQUZBUkkgJiYgZXZlbnQuZGF0YSkge1xuICAgICAgICAgICAgICAgIHByZXZlbnRJbnNlcnRGcm9tQ29tcG9zaXRpb24oZXZlbnQsIHRoaXMuZWRpdG9yKTtcbiAgICAgICAgICAgICAgICBFZGl0b3IuaW5zZXJ0VGV4dCh0aGlzLmVkaXRvciwgZXZlbnQuZGF0YSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENPTVBBVDogSW4gRmlyZWZveCA4Ny4wIENvbXBvc2l0aW9uRW5kIGZpcmUgdHdpY2VcbiAgICAgICAgICAgIC8vIHNvIHdlIG5lZWQgYXZvaWQgcmVwZWF0IGlzbmVydFRleHQgYnkgaXNDb21wb3NpbmcgPT09IHRydWUsXG4gICAgICAgICAgICB0aGlzLmlzQ29tcG9zaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZXRlY3RDb250ZXh0KCk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uRE9NQ29tcG9zaXRpb25TdGFydChldmVudDogQ29tcG9zaXRpb25FdmVudCkge1xuICAgICAgICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gdGhpcy5lZGl0b3I7XG5cbiAgICAgICAgaWYgKHNlbGVjdGlvbikge1xuICAgICAgICAgICAgLy8gc29sdmUgdGhlIHByb2JsZW0gb2YgY3Jvc3Mgbm9kZSBDaGluZXNlIGlucHV0XG4gICAgICAgICAgICBpZiAoUmFuZ2UuaXNFeHBhbmRlZChzZWxlY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgRWRpdG9yLmRlbGV0ZUZyYWdtZW50KHRoaXMuZWRpdG9yKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZvcmNlRmx1c2goKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaGFzRWRpdGFibGVUYXJnZXQodGhpcy5lZGl0b3IsIGV2ZW50LnRhcmdldCkgJiYgIXRoaXMuaXNET01FdmVudEhhbmRsZWQoZXZlbnQsIHRoaXMuY29tcG9zaXRpb25TdGFydCkpIHtcbiAgICAgICAgICAgIHRoaXMuaXNDb21wb3NpbmcgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGV0ZWN0Q29udGV4dCgpO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkRPTUNvcHkoZXZlbnQ6IENsaXBib2FyZEV2ZW50KSB7XG4gICAgICAgIGNvbnN0IHdpbmRvdyA9IEFuZ3VsYXJFZGl0b3IuZ2V0V2luZG93KHRoaXMuZWRpdG9yKTtcbiAgICAgICAgY29uc3QgaXNPdXRzaWRlU2xhdGUgPSAhaGFzU3RyaW5nVGFyZ2V0KHdpbmRvdy5nZXRTZWxlY3Rpb24oKSkgJiYgaXNUYXJnZXRJbnNpZGVWb2lkKHRoaXMuZWRpdG9yLCBldmVudC50YXJnZXQpO1xuICAgICAgICBpZiAoIWlzT3V0c2lkZVNsYXRlICYmIGhhc1RhcmdldCh0aGlzLmVkaXRvciwgZXZlbnQudGFyZ2V0KSAmJiAhdGhpcy5pc0RPTUV2ZW50SGFuZGxlZChldmVudCwgdGhpcy5jb3B5KSkge1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIEFuZ3VsYXJFZGl0b3Iuc2V0RnJhZ21lbnREYXRhKHRoaXMuZWRpdG9yLCBldmVudC5jbGlwYm9hcmREYXRhLCAnY29weScpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkRPTUN1dChldmVudDogQ2xpcGJvYXJkRXZlbnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlYWRvbmx5ICYmIGhhc0VkaXRhYmxlVGFyZ2V0KHRoaXMuZWRpdG9yLCBldmVudC50YXJnZXQpICYmICF0aGlzLmlzRE9NRXZlbnRIYW5kbGVkKGV2ZW50LCB0aGlzLmN1dCkpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBBbmd1bGFyRWRpdG9yLnNldEZyYWdtZW50RGF0YSh0aGlzLmVkaXRvciwgZXZlbnQuY2xpcGJvYXJkRGF0YSwgJ2N1dCcpO1xuICAgICAgICAgICAgY29uc3QgeyBzZWxlY3Rpb24gfSA9IHRoaXMuZWRpdG9yO1xuXG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgQW5ndWxhckVkaXRvci5kZWxldGVDdXREYXRhKHRoaXMuZWRpdG9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgb25ET01EcmFnT3ZlcihldmVudDogRHJhZ0V2ZW50KSB7XG4gICAgICAgIGlmIChoYXNUYXJnZXQodGhpcy5lZGl0b3IsIGV2ZW50LnRhcmdldCkgJiYgIXRoaXMuaXNET01FdmVudEhhbmRsZWQoZXZlbnQsIHRoaXMuZHJhZ092ZXIpKSB7XG4gICAgICAgICAgICAvLyBPbmx5IHdoZW4gdGhlIHRhcmdldCBpcyB2b2lkLCBjYWxsIGBwcmV2ZW50RGVmYXVsdGAgdG8gc2lnbmFsXG4gICAgICAgICAgICAvLyB0aGF0IGRyb3BzIGFyZSBhbGxvd2VkLiBFZGl0YWJsZSBjb250ZW50IGlzIGRyb3BwYWJsZSBieVxuICAgICAgICAgICAgLy8gZGVmYXVsdCwgYW5kIGNhbGxpbmcgYHByZXZlbnREZWZhdWx0YCBoaWRlcyB0aGUgY3Vyc29yLlxuICAgICAgICAgICAgY29uc3Qgbm9kZSA9IEFuZ3VsYXJFZGl0b3IudG9TbGF0ZU5vZGUodGhpcy5lZGl0b3IsIGV2ZW50LnRhcmdldCk7XG5cbiAgICAgICAgICAgIGlmIChFZGl0b3IuaXNWb2lkKHRoaXMuZWRpdG9yLCBub2RlKSkge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uRE9NRHJhZ1N0YXJ0KGV2ZW50OiBEcmFnRXZlbnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLnJlYWRvbmx5ICYmIGhhc1RhcmdldCh0aGlzLmVkaXRvciwgZXZlbnQudGFyZ2V0KSAmJiAhdGhpcy5pc0RPTUV2ZW50SGFuZGxlZChldmVudCwgdGhpcy5kcmFnU3RhcnQpKSB7XG4gICAgICAgICAgICBjb25zdCBub2RlID0gQW5ndWxhckVkaXRvci50b1NsYXRlTm9kZSh0aGlzLmVkaXRvciwgZXZlbnQudGFyZ2V0KTtcbiAgICAgICAgICAgIGNvbnN0IHBhdGggPSBBbmd1bGFyRWRpdG9yLmZpbmRQYXRoKHRoaXMuZWRpdG9yLCBub2RlKTtcbiAgICAgICAgICAgIGNvbnN0IHZvaWRNYXRjaCA9XG4gICAgICAgICAgICAgICAgRWRpdG9yLmlzVm9pZCh0aGlzLmVkaXRvciwgbm9kZSkgfHxcbiAgICAgICAgICAgICAgICBFZGl0b3Iudm9pZCh0aGlzLmVkaXRvciwgeyBhdDogcGF0aCwgdm9pZHM6IHRydWUgfSk7XG5cbiAgICAgICAgICAgIC8vIElmIHN0YXJ0aW5nIGEgZHJhZyBvbiBhIHZvaWQgbm9kZSwgbWFrZSBzdXJlIGl0IGlzIHNlbGVjdGVkXG4gICAgICAgICAgICAvLyBzbyB0aGF0IGl0IHNob3dzIHVwIGluIHRoZSBzZWxlY3Rpb24ncyBmcmFnbWVudC5cbiAgICAgICAgICAgIGlmICh2b2lkTWF0Y2gpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByYW5nZSA9IEVkaXRvci5yYW5nZSh0aGlzLmVkaXRvciwgcGF0aCk7XG4gICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5zZWxlY3QodGhpcy5lZGl0b3IsIHJhbmdlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nSW50ZXJuYWxseSA9IHRydWU7XG5cbiAgICAgICAgICAgIEFuZ3VsYXJFZGl0b3Iuc2V0RnJhZ21lbnREYXRhKHRoaXMuZWRpdG9yLCBldmVudC5kYXRhVHJhbnNmZXIsICdkcmFnJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uRE9NRHJvcChldmVudDogRHJhZ0V2ZW50KSB7XG4gICAgICAgIGNvbnN0IGVkaXRvciA9IHRoaXMuZWRpdG9yO1xuICAgICAgICBpZiAoIXRoaXMucmVhZG9ubHkgJiYgaGFzVGFyZ2V0KHRoaXMuZWRpdG9yLCBldmVudC50YXJnZXQpICYmICF0aGlzLmlzRE9NRXZlbnRIYW5kbGVkKGV2ZW50LCB0aGlzLmRyb3ApKSB7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgLy8gS2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgZHJhZ2dlZCByYW5nZSBiZWZvcmUgdXBkYXRpbmcgc2VsZWN0aW9uXG4gICAgICAgICAgICBjb25zdCBkcmFnZ2VkUmFuZ2UgPSBlZGl0b3Iuc2VsZWN0aW9uO1xuXG4gICAgICAgICAgICAvLyBGaW5kIHRoZSByYW5nZSB3aGVyZSB0aGUgZHJvcCBoYXBwZW5lZFxuICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSBBbmd1bGFyRWRpdG9yLmZpbmRFdmVudFJhbmdlKGVkaXRvciwgZXZlbnQpO1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IGV2ZW50LmRhdGFUcmFuc2ZlcjtcblxuICAgICAgICAgICAgVHJhbnNmb3Jtcy5zZWxlY3QoZWRpdG9yLCByYW5nZSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmlzRHJhZ2dpbmdJbnRlcm5hbGx5KSB7XG4gICAgICAgICAgICAgICAgaWYgKGRyYWdnZWRSYW5nZSkge1xuICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1zLmRlbGV0ZShlZGl0b3IsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0OiBkcmFnZ2VkUmFuZ2UsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZ0ludGVybmFsbHkgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgQW5ndWxhckVkaXRvci5pbnNlcnREYXRhKGVkaXRvciwgZGF0YSk7XG5cbiAgICAgICAgICAgIC8vIFdoZW4gZHJhZ2dpbmcgZnJvbSBhbm90aGVyIHNvdXJjZSBpbnRvIHRoZSBlZGl0b3IsIGl0J3MgcG9zc2libGVcbiAgICAgICAgICAgIC8vIHRoYXQgdGhlIGN1cnJlbnQgZWRpdG9yIGRvZXMgbm90IGhhdmUgZm9jdXMuXG4gICAgICAgICAgICBpZiAoIUFuZ3VsYXJFZGl0b3IuaXNGb2N1c2VkKGVkaXRvcikpIHtcbiAgICAgICAgICAgICAgICBBbmd1bGFyRWRpdG9yLmZvY3VzKGVkaXRvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uRE9NRHJhZ0VuZChldmVudDogRHJhZ0V2ZW50KSB7XG4gICAgICAgIGlmICghdGhpcy5yZWFkb25seSAmJiB0aGlzLmlzRHJhZ2dpbmdJbnRlcm5hbGx5ICYmIGhhc1RhcmdldCh0aGlzLmVkaXRvciwgZXZlbnQudGFyZ2V0KSAmJiAhdGhpcy5pc0RPTUV2ZW50SGFuZGxlZChldmVudCwgdGhpcy5kcmFnRW5kKSkge1xuICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nSW50ZXJuYWxseSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkRPTUZvY3VzKGV2ZW50OiBFdmVudCkge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICAhdGhpcy5yZWFkb25seSAmJlxuICAgICAgICAgICAgIXRoaXMuaXNVcGRhdGluZ1NlbGVjdGlvbiAmJlxuICAgICAgICAgICAgaGFzRWRpdGFibGVUYXJnZXQodGhpcy5lZGl0b3IsIGV2ZW50LnRhcmdldCkgJiZcbiAgICAgICAgICAgICF0aGlzLmlzRE9NRXZlbnRIYW5kbGVkKGV2ZW50LCB0aGlzLmZvY3VzKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IGVsID0gQW5ndWxhckVkaXRvci50b0RPTU5vZGUodGhpcy5lZGl0b3IsIHRoaXMuZWRpdG9yKTtcbiAgICAgICAgICAgIGNvbnN0IHJvb3QgPSBBbmd1bGFyRWRpdG9yLmZpbmREb2N1bWVudE9yU2hhZG93Um9vdCh0aGlzLmVkaXRvcik7XG4gICAgICAgICAgICB0aGlzLmxhdGVzdEVsZW1lbnQgPSByb290LmFjdGl2ZUVsZW1lbnRcblxuICAgICAgICAgICAgLy8gQ09NUEFUOiBJZiB0aGUgZWRpdG9yIGhhcyBuZXN0ZWQgZWRpdGFibGUgZWxlbWVudHMsIHRoZSBmb2N1c1xuICAgICAgICAgICAgLy8gY2FuIGdvIHRvIHRoZW0uIEluIEZpcmVmb3gsIHRoaXMgbXVzdCBiZSBwcmV2ZW50ZWQgYmVjYXVzZSBpdFxuICAgICAgICAgICAgLy8gcmVzdWx0cyBpbiBpc3N1ZXMgd2l0aCBrZXlib2FyZCBuYXZpZ2F0aW9uLiAoMjAxNy8wMy8zMClcbiAgICAgICAgICAgIGlmIChJU19GSVJFRk9YICYmIGV2ZW50LnRhcmdldCAhPT0gZWwpIHtcbiAgICAgICAgICAgICAgICBlbC5mb2N1cygpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgSVNfRk9DVVNFRC5zZXQodGhpcy5lZGl0b3IsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkRPTUtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgY29uc3QgZWRpdG9yID0gdGhpcy5lZGl0b3I7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgICF0aGlzLnJlYWRvbmx5ICYmXG4gICAgICAgICAgICBoYXNFZGl0YWJsZVRhcmdldChlZGl0b3IsIGV2ZW50LnRhcmdldCkgJiZcbiAgICAgICAgICAgICF0aGlzLmlzQ29tcG9zaW5nICYmXG4gICAgICAgICAgICAhdGhpcy5pc0RPTUV2ZW50SGFuZGxlZChldmVudCwgdGhpcy5rZXlkb3duKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUV2ZW50ID0gZXZlbnQ7XG4gICAgICAgICAgICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gZWRpdG9yO1xuXG4gICAgICAgICAgICBjb25zdCBlbGVtZW50ID1cbiAgICAgICAgICAgICAgICBlZGl0b3IuY2hpbGRyZW5bXG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uICE9PSBudWxsID8gc2VsZWN0aW9uLmZvY3VzLnBhdGhbMF0gOiAwXG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgY29uc3QgaXNSVEwgPSBnZXREaXJlY3Rpb24oTm9kZS5zdHJpbmcoZWxlbWVudCkpID09PSAncnRsJztcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBDT01QQVQ6IFNpbmNlIHdlIHByZXZlbnQgdGhlIGRlZmF1bHQgYmVoYXZpb3Igb25cbiAgICAgICAgICAgICAgICAvLyBgYmVmb3JlaW5wdXRgIGV2ZW50cywgdGhlIGJyb3dzZXIgZG9lc24ndCB0aGluayB0aGVyZSdzIGV2ZXJcbiAgICAgICAgICAgICAgICAvLyBhbnkgaGlzdG9yeSBzdGFjayB0byB1bmRvIG9yIHJlZG8sIHNvIHdlIGhhdmUgdG8gbWFuYWdlIHRoZXNlXG4gICAgICAgICAgICAgICAgLy8gaG90a2V5cyBvdXJzZWx2ZXMuICgyMDE5LzExLzA2KVxuICAgICAgICAgICAgICAgIGlmIChIb3RrZXlzLmlzUmVkbyhuYXRpdmVFdmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoSGlzdG9yeUVkaXRvci5pc0hpc3RvcnlFZGl0b3IoZWRpdG9yKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWRpdG9yLnJlZG8oKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoSG90a2V5cy5pc1VuZG8obmF0aXZlRXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKEhpc3RvcnlFZGl0b3IuaXNIaXN0b3J5RWRpdG9yKGVkaXRvcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVkaXRvci51bmRvKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQ09NUEFUOiBDZXJ0YWluIGJyb3dzZXJzIGRvbid0IGhhbmRsZSB0aGUgc2VsZWN0aW9uIHVwZGF0ZXNcbiAgICAgICAgICAgICAgICAvLyBwcm9wZXJseS4gSW4gQ2hyb21lLCB0aGUgc2VsZWN0aW9uIGlzbid0IHByb3Blcmx5IGV4dGVuZGVkLlxuICAgICAgICAgICAgICAgIC8vIEFuZCBpbiBGaXJlZm94LCB0aGUgc2VsZWN0aW9uIGlzbid0IHByb3Blcmx5IGNvbGxhcHNlZC5cbiAgICAgICAgICAgICAgICAvLyAoMjAxNy8xMC8xNylcbiAgICAgICAgICAgICAgICBpZiAoSG90a2V5cy5pc01vdmVMaW5lQmFja3dhcmQobmF0aXZlRXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybXMubW92ZShlZGl0b3IsIHsgdW5pdDogJ2xpbmUnLCByZXZlcnNlOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKEhvdGtleXMuaXNNb3ZlTGluZUZvcndhcmQobmF0aXZlRXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybXMubW92ZShlZGl0b3IsIHsgdW5pdDogJ2xpbmUnIH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKEhvdGtleXMuaXNFeHRlbmRMaW5lQmFja3dhcmQobmF0aXZlRXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybXMubW92ZShlZGl0b3IsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVuaXQ6ICdsaW5lJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2U6ICdmb2N1cycsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXZlcnNlOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKEhvdGtleXMuaXNFeHRlbmRMaW5lRm9yd2FyZChuYXRpdmVFdmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5tb3ZlKGVkaXRvciwgeyB1bml0OiAnbGluZScsIGVkZ2U6ICdmb2N1cycgfSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBDT01QQVQ6IElmIGEgdm9pZCBub2RlIGlzIHNlbGVjdGVkLCBvciBhIHplcm8td2lkdGggdGV4dCBub2RlXG4gICAgICAgICAgICAgICAgLy8gYWRqYWNlbnQgdG8gYW4gaW5saW5lIGlzIHNlbGVjdGVkLCB3ZSBuZWVkIHRvIGhhbmRsZSB0aGVzZVxuICAgICAgICAgICAgICAgIC8vIGhvdGtleXMgbWFudWFsbHkgYmVjYXVzZSBicm93c2VycyB3b24ndCBiZSBhYmxlIHRvIHNraXAgb3ZlclxuICAgICAgICAgICAgICAgIC8vIHRoZSB2b2lkIG5vZGUgd2l0aCB0aGUgemVyby13aWR0aCBzcGFjZSBub3QgYmVpbmcgYW4gZW1wdHlcbiAgICAgICAgICAgICAgICAvLyBzdHJpbmcuXG4gICAgICAgICAgICAgICAgaWYgKEhvdGtleXMuaXNNb3ZlQmFja3dhcmQobmF0aXZlRXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbiAmJiBSYW5nZS5pc0NvbGxhcHNlZChzZWxlY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1zLm1vdmUoZWRpdG9yLCB7IHJldmVyc2U6ICFpc1JUTCB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybXMuY29sbGFwc2UoZWRpdG9yLCB7IGVkZ2U6ICdzdGFydCcgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKEhvdGtleXMuaXNNb3ZlRm9yd2FyZChuYXRpdmVFdmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uICYmIFJhbmdlLmlzQ29sbGFwc2VkKHNlbGVjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybXMubW92ZShlZGl0b3IsIHsgcmV2ZXJzZTogaXNSVEwgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBUcmFuc2Zvcm1zLmNvbGxhcHNlKGVkaXRvciwgeyBlZGdlOiAnZW5kJyB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoSG90a2V5cy5pc01vdmVXb3JkQmFja3dhcmQobmF0aXZlRXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbiAmJiBSYW5nZS5pc0V4cGFuZGVkKHNlbGVjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybXMuY29sbGFwc2UoZWRpdG9yLCB7IGVkZ2U6ICdmb2N1cycgfSlcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIFRyYW5zZm9ybXMubW92ZShlZGl0b3IsIHsgdW5pdDogJ3dvcmQnLCByZXZlcnNlOiAhaXNSVEwgfSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoSG90a2V5cy5pc01vdmVXb3JkRm9yd2FyZChuYXRpdmVFdmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uICYmIFJhbmdlLmlzRXhwYW5kZWQoc2VsZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5jb2xsYXBzZShlZGl0b3IsIHsgZWRnZTogJ2ZvY3VzJyB9KVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgVHJhbnNmb3Jtcy5tb3ZlKGVkaXRvciwgeyB1bml0OiAnd29yZCcsIHJldmVyc2U6IGlzUlRMIH0pO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQ09NUEFUOiBDZXJ0YWluIGJyb3dzZXJzIGRvbid0IHN1cHBvcnQgdGhlIGBiZWZvcmVpbnB1dGAgZXZlbnQsIHNvIHdlXG4gICAgICAgICAgICAgICAgLy8gZmFsbCBiYWNrIHRvIGd1ZXNzaW5nIGF0IHRoZSBpbnB1dCBpbnRlbnRpb24gZm9yIGhvdGtleXMuXG4gICAgICAgICAgICAgICAgLy8gQ09NUEFUOiBJbiBpT1MsIHNvbWUgb2YgdGhlc2UgaG90a2V5cyBhcmUgaGFuZGxlZCBpbiB0aGVcbiAgICAgICAgICAgICAgICBpZiAoIUhBU19CRUZPUkVfSU5QVVRfU1VQUE9SVCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBXZSBkb24ndCBoYXZlIGEgY29yZSBiZWhhdmlvciBmb3IgdGhlc2UsIGJ1dCB0aGV5IGNoYW5nZSB0aGVcbiAgICAgICAgICAgICAgICAgICAgLy8gRE9NIGlmIHdlIGRvbid0IHByZXZlbnQgdGhlbSwgc28gd2UgaGF2ZSB0by5cbiAgICAgICAgICAgICAgICAgICAgaWYgKEhvdGtleXMuaXNCb2xkKG5hdGl2ZUV2ZW50KSB8fCBIb3RrZXlzLmlzSXRhbGljKG5hdGl2ZUV2ZW50KSB8fCBIb3RrZXlzLmlzVHJhbnNwb3NlQ2hhcmFjdGVyKG5hdGl2ZUV2ZW50KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChIb3RrZXlzLmlzU3BsaXRCbG9jayhuYXRpdmVFdmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuaW5zZXJ0QnJlYWsoZWRpdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChIb3RrZXlzLmlzRGVsZXRlQmFja3dhcmQobmF0aXZlRXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uICYmIFJhbmdlLmlzRXhwYW5kZWQoc2VsZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVkaXRvci5kZWxldGVGcmFnbWVudChlZGl0b3IsIHsgZGlyZWN0aW9uOiAnYmFja3dhcmQnIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuZGVsZXRlQmFja3dhcmQoZWRpdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKEhvdGtleXMuaXNEZWxldGVGb3J3YXJkKG5hdGl2ZUV2ZW50KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbiAmJiBSYW5nZS5pc0V4cGFuZGVkKHNlbGVjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuZGVsZXRlRnJhZ21lbnQoZWRpdG9yLCB7IGRpcmVjdGlvbjogJ2ZvcndhcmQnIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuZGVsZXRlRm9yd2FyZChlZGl0b3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoSG90a2V5cy5pc0RlbGV0ZUxpbmVCYWNrd2FyZChuYXRpdmVFdmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rpb24gJiYgUmFuZ2UuaXNFeHBhbmRlZChzZWxlY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRWRpdG9yLmRlbGV0ZUZyYWdtZW50KGVkaXRvciwgeyBkaXJlY3Rpb246ICdiYWNrd2FyZCcgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVkaXRvci5kZWxldGVCYWNrd2FyZChlZGl0b3IsIHsgdW5pdDogJ2xpbmUnIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoSG90a2V5cy5pc0RlbGV0ZUxpbmVGb3J3YXJkKG5hdGl2ZUV2ZW50KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbiAmJiBSYW5nZS5pc0V4cGFuZGVkKHNlbGVjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuZGVsZXRlRnJhZ21lbnQoZWRpdG9yLCB7IGRpcmVjdGlvbjogJ2ZvcndhcmQnIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuZGVsZXRlRm9yd2FyZChlZGl0b3IsIHsgdW5pdDogJ2xpbmUnIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoSG90a2V5cy5pc0RlbGV0ZVdvcmRCYWNrd2FyZChuYXRpdmVFdmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rpb24gJiYgUmFuZ2UuaXNFeHBhbmRlZChzZWxlY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRWRpdG9yLmRlbGV0ZUZyYWdtZW50KGVkaXRvciwgeyBkaXJlY3Rpb246ICdiYWNrd2FyZCcgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVkaXRvci5kZWxldGVCYWNrd2FyZChlZGl0b3IsIHsgdW5pdDogJ3dvcmQnIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoSG90a2V5cy5pc0RlbGV0ZVdvcmRGb3J3YXJkKG5hdGl2ZUV2ZW50KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbiAmJiBSYW5nZS5pc0V4cGFuZGVkKHNlbGVjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuZGVsZXRlRnJhZ21lbnQoZWRpdG9yLCB7IGRpcmVjdGlvbjogJ2ZvcndhcmQnIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuZGVsZXRlRm9yd2FyZChlZGl0b3IsIHsgdW5pdDogJ3dvcmQnIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoSVNfQ0hST01FIHx8IElTX1NBRkFSSSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ09NUEFUOiBDaHJvbWUgYW5kIFNhZmFyaSBzdXBwb3J0IGBiZWZvcmVpbnB1dGAgZXZlbnQgYnV0IGRvIG5vdCBmaXJlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbiBldmVudCB3aGVuIGRlbGV0aW5nIGJhY2t3YXJkcyBpbiBhIHNlbGVjdGVkIHZvaWQgaW5saW5lIG5vZGVcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb24gJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSG90a2V5cy5pc0RlbGV0ZUJhY2t3YXJkKG5hdGl2ZUV2ZW50KSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIb3RrZXlzLmlzRGVsZXRlRm9yd2FyZChuYXRpdmVFdmVudCkpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmFuZ2UuaXNDb2xsYXBzZWQoc2VsZWN0aW9uKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudE5vZGUgPSBOb2RlLnBhcmVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWRpdG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3Rpb24uYW5jaG9yLnBhdGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbGVtZW50LmlzRWxlbWVudChjdXJyZW50Tm9kZSkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRWRpdG9yLmlzVm9pZChlZGl0b3IsIGN1cnJlbnROb2RlKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuaXNJbmxpbmUoZWRpdG9yLCBjdXJyZW50Tm9kZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFZGl0b3IuZGVsZXRlQmFja3dhcmQoZWRpdG9yLCB7IHVuaXQ6ICdibG9jaycgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVkaXRvci5vbkVycm9yKHsgY29kZTogU2xhdGVFcnJvckNvZGUuT25ET01LZXlkb3duRXJyb3IsIG5hdGl2ZUVycm9yOiBlcnJvciB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgb25ET01QYXN0ZShldmVudDogQ2xpcGJvYXJkRXZlbnQpIHtcbiAgICAgICAgLy8gQ09NUEFUOiBDZXJ0YWluIGJyb3dzZXJzIGRvbid0IHN1cHBvcnQgdGhlIGBiZWZvcmVpbnB1dGAgZXZlbnQsIHNvIHdlXG4gICAgICAgIC8vIGZhbGwgYmFjayB0byBSZWFjdCdzIGBvblBhc3RlYCBoZXJlIGluc3RlYWQuXG4gICAgICAgIC8vIENPTVBBVDogRmlyZWZveCwgQ2hyb21lIGFuZCBTYWZhcmkgYXJlIG5vdCBlbWl0dGluZyBgYmVmb3JlaW5wdXRgIGV2ZW50c1xuICAgICAgICAvLyB3aGVuIFwicGFzdGUgd2l0aG91dCBmb3JtYXR0aW5nXCIgb3B0aW9uIGlzIHVzZWQuXG4gICAgICAgIC8vIFRoaXMgdW5mb3J0dW5hdGVseSBuZWVkcyB0byBiZSBoYW5kbGVkIHdpdGggcGFzdGUgZXZlbnRzIGluc3RlYWQuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgICF0aGlzLmlzRE9NRXZlbnRIYW5kbGVkKGV2ZW50LCB0aGlzLnBhc3RlKSAmJlxuICAgICAgICAgICAgKCFIQVNfQkVGT1JFX0lOUFVUX1NVUFBPUlQgfHwgaXNQbGFpblRleHRPbmx5UGFzdGUoZXZlbnQpIHx8IGZvcmNlT25ET01QYXN0ZSkgJiZcbiAgICAgICAgICAgICF0aGlzLnJlYWRvbmx5ICYmXG4gICAgICAgICAgICBoYXNFZGl0YWJsZVRhcmdldCh0aGlzLmVkaXRvciwgZXZlbnQudGFyZ2V0KVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBBbmd1bGFyRWRpdG9yLmluc2VydERhdGEodGhpcy5lZGl0b3IsIGV2ZW50LmNsaXBib2FyZERhdGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkZhbGxiYWNrQmVmb3JlSW5wdXQoZXZlbnQ6IEJlZm9yZUlucHV0RXZlbnQpIHtcbiAgICAgICAgLy8gQ09NUEFUOiBDZXJ0YWluIGJyb3dzZXJzIGRvbid0IHN1cHBvcnQgdGhlIGBiZWZvcmVpbnB1dGAgZXZlbnQsIHNvIHdlXG4gICAgICAgIC8vIGZhbGwgYmFjayB0byBSZWFjdCdzIGxlYWt5IHBvbHlmaWxsIGluc3RlYWQganVzdCBmb3IgaXQuIEl0XG4gICAgICAgIC8vIG9ubHkgd29ya3MgZm9yIHRoZSBgaW5zZXJ0VGV4dGAgaW5wdXQgdHlwZS5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgIUhBU19CRUZPUkVfSU5QVVRfU1VQUE9SVCAmJlxuICAgICAgICAgICAgIXRoaXMucmVhZG9ubHkgJiZcbiAgICAgICAgICAgICF0aGlzLmlzRE9NRXZlbnRIYW5kbGVkKGV2ZW50Lm5hdGl2ZUV2ZW50LCB0aGlzLmJlZm9yZUlucHV0KSAmJlxuICAgICAgICAgICAgaGFzRWRpdGFibGVUYXJnZXQodGhpcy5lZGl0b3IsIGV2ZW50Lm5hdGl2ZUV2ZW50LnRhcmdldClcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBldmVudC5uYXRpdmVFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gZXZlbnQuZGF0YTtcbiAgICAgICAgICAgICAgICBpZiAoIVJhbmdlLmlzQ29sbGFwc2VkKHRoaXMuZWRpdG9yLnNlbGVjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgRWRpdG9yLmRlbGV0ZUZyYWdtZW50KHRoaXMuZWRpdG9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8ganVzdCBoYW5kbGUgTm9uLUlNRSBpbnB1dFxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc0NvbXBvc2luZykge1xuICAgICAgICAgICAgICAgICAgICBFZGl0b3IuaW5zZXJ0VGV4dCh0aGlzLmVkaXRvciwgdGV4dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVkaXRvci5vbkVycm9yKHsgY29kZTogU2xhdGVFcnJvckNvZGUuVG9OYXRpdmVTZWxlY3Rpb25FcnJvciwgbmF0aXZlRXJyb3I6IGVycm9yIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc0RPTUV2ZW50SGFuZGxlZChldmVudDogRXZlbnQsIGhhbmRsZXI/OiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkKSB7XG4gICAgICAgIGlmICghaGFuZGxlcikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGhhbmRsZXIoZXZlbnQpO1xuICAgICAgICByZXR1cm4gZXZlbnQuZGVmYXVsdFByZXZlbnRlZDtcbiAgICB9XG4gICAgLy8jZW5kcmVnaW9uXG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgTk9ERV9UT19FTEVNRU5ULmRlbGV0ZSh0aGlzLmVkaXRvcik7XG4gICAgICAgIHRoaXMubWFudWFsTGlzdGVuZXJzLmZvckVhY2gobWFudWFsTGlzdGVuZXIgPT4ge1xuICAgICAgICAgICAgbWFudWFsTGlzdGVuZXIoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgICAgICAgRURJVE9SX1RPX09OX0NIQU5HRS5kZWxldGUodGhpcy5lZGl0b3IpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBDaGVjayBpZiB0aGUgdGFyZ2V0IGlzIGVkaXRhYmxlIGFuZCBpbiB0aGUgZWRpdG9yLlxuICovXG5cbmNvbnN0IGhhc0VkaXRhYmxlVGFyZ2V0ID0gKGVkaXRvcjogQW5ndWxhckVkaXRvciwgdGFyZ2V0OiBFdmVudFRhcmdldCB8IG51bGwpOiB0YXJnZXQgaXMgRE9NTm9kZSA9PiB7XG4gICAgcmV0dXJuIGlzRE9NTm9kZSh0YXJnZXQpICYmIEFuZ3VsYXJFZGl0b3IuaGFzRE9NTm9kZShlZGl0b3IsIHRhcmdldCwgeyBlZGl0YWJsZTogdHJ1ZSB9KTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgdHdvIERPTSByYW5nZSBvYmplY3RzIGFyZSBlcXVhbC5cbiAqL1xuY29uc3QgaXNSYW5nZUVxdWFsID0gKGE6IERPTVJhbmdlLCBiOiBET01SYW5nZSkgPT4ge1xuICAgIHJldHVybiAoXG4gICAgICAgIChhLnN0YXJ0Q29udGFpbmVyID09PSBiLnN0YXJ0Q29udGFpbmVyICYmXG4gICAgICAgICAgICBhLnN0YXJ0T2Zmc2V0ID09PSBiLnN0YXJ0T2Zmc2V0ICYmXG4gICAgICAgICAgICBhLmVuZENvbnRhaW5lciA9PT0gYi5lbmRDb250YWluZXIgJiZcbiAgICAgICAgICAgIGEuZW5kT2Zmc2V0ID09PSBiLmVuZE9mZnNldCkgfHxcbiAgICAgICAgKGEuc3RhcnRDb250YWluZXIgPT09IGIuZW5kQ29udGFpbmVyICYmXG4gICAgICAgICAgICBhLnN0YXJ0T2Zmc2V0ID09PSBiLmVuZE9mZnNldCAmJlxuICAgICAgICAgICAgYS5lbmRDb250YWluZXIgPT09IGIuc3RhcnRDb250YWluZXIgJiZcbiAgICAgICAgICAgIGEuZW5kT2Zmc2V0ID09PSBiLnN0YXJ0T2Zmc2V0KVxuICAgICk7XG59O1xuXG4vKipcbiAqIENoZWNrIGlmIHRoZSB0YXJnZXQgaXMgaW4gdGhlIGVkaXRvci5cbiAqL1xuXG5jb25zdCBoYXNUYXJnZXQgPSAoZWRpdG9yOiBBbmd1bGFyRWRpdG9yLCB0YXJnZXQ6IEV2ZW50VGFyZ2V0IHwgbnVsbCk6IHRhcmdldCBpcyBET01Ob2RlID0+IHtcbiAgICByZXR1cm4gaXNET01Ob2RlKHRhcmdldCkgJiYgQW5ndWxhckVkaXRvci5oYXNET01Ob2RlKGVkaXRvciwgdGFyZ2V0KTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhlIHRhcmdldCBpcyBpbnNpZGUgdm9pZCBhbmQgaW4gdGhlIGVkaXRvci5cbiAqL1xuXG5jb25zdCBpc1RhcmdldEluc2lkZVZvaWQgPSAoZWRpdG9yOiBBbmd1bGFyRWRpdG9yLCB0YXJnZXQ6IEV2ZW50VGFyZ2V0IHwgbnVsbCk6IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IHNsYXRlTm9kZSA9IGhhc1RhcmdldChlZGl0b3IsIHRhcmdldCkgJiYgQW5ndWxhckVkaXRvci50b1NsYXRlTm9kZShlZGl0b3IsIHRhcmdldCk7XG4gICAgcmV0dXJuIEVkaXRvci5pc1ZvaWQoZWRpdG9yLCBzbGF0ZU5vZGUpO1xufTtcblxuY29uc3QgaGFzU3RyaW5nVGFyZ2V0ID0gKGRvbVNlbGVjdGlvbjogRE9NU2VsZWN0aW9uKSA9PiB7XG4gICAgcmV0dXJuIChkb21TZWxlY3Rpb24uYW5jaG9yTm9kZS5wYXJlbnRFbGVtZW50Lmhhc0F0dHJpYnV0ZSgnZGF0YS1zbGF0ZS1zdHJpbmcnKSB8fCBkb21TZWxlY3Rpb24uYW5jaG9yTm9kZS5wYXJlbnRFbGVtZW50Lmhhc0F0dHJpYnV0ZSgnZGF0YS1zbGF0ZS16ZXJvLXdpZHRoJykpICYmXG4gICAgICAgIChkb21TZWxlY3Rpb24uZm9jdXNOb2RlLnBhcmVudEVsZW1lbnQuaGFzQXR0cmlidXRlKCdkYXRhLXNsYXRlLXN0cmluZycpIHx8IGRvbVNlbGVjdGlvbi5mb2N1c05vZGUucGFyZW50RWxlbWVudC5oYXNBdHRyaWJ1dGUoJ2RhdGEtc2xhdGUtemVyby13aWR0aCcpKTtcbn1cblxuLyoqXG4gKiByZW1vdmUgZGVmYXVsdCBpbnNlcnQgZnJvbSBjb21wb3NpdGlvblxuICogQHBhcmFtIHRleHRcbiAqL1xuY29uc3QgcHJldmVudEluc2VydEZyb21Db21wb3NpdGlvbiA9IChldmVudDogRXZlbnQsIGVkaXRvcjogQW5ndWxhckVkaXRvcikgPT4ge1xuICAgIGNvbnN0IHR5cGVzID0gWydjb21wb3NpdGlvbmVuZCcsICdpbnNlcnRGcm9tQ29tcG9zaXRpb24nXTtcbiAgICBpZiAoIXR5cGVzLmluY2x1ZGVzKGV2ZW50LnR5cGUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaW5zZXJ0VGV4dCA9IChldmVudCBhcyBDb21wb3NpdGlvbkV2ZW50KS5kYXRhO1xuICAgIGNvbnN0IHdpbmRvdyA9IEFuZ3VsYXJFZGl0b3IuZ2V0V2luZG93KGVkaXRvcik7XG4gICAgY29uc3QgZG9tU2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIC8vIGVuc3VyZSB0ZXh0IG5vZGUgaW5zZXJ0IGNvbXBvc2l0aW9uIGlucHV0IHRleHRcbiAgICBpZiAoaW5zZXJ0VGV4dCAmJiBkb21TZWxlY3Rpb24uYW5jaG9yTm9kZSBpbnN0YW5jZW9mIFRleHQgJiYgZG9tU2VsZWN0aW9uLmFuY2hvck5vZGUudGV4dENvbnRlbnQuZW5kc1dpdGgoaW5zZXJ0VGV4dCkpIHtcbiAgICAgICAgY29uc3QgdGV4dE5vZGUgPSBkb21TZWxlY3Rpb24uYW5jaG9yTm9kZTtcbiAgICAgICAgdGV4dE5vZGUuc3BsaXRUZXh0KHRleHROb2RlLmxlbmd0aCAtIGluc2VydFRleHQubGVuZ3RoKS5yZW1vdmUoKTtcbiAgICB9XG59XG4iLCI8c2xhdGUtY2hpbGRyZW4gW2NoaWxkcmVuXT1cImVkaXRvci5jaGlsZHJlblwiIFtjb250ZXh0XT1cImNvbnRleHRcIiBbdmlld0NvbnRleHRdPVwidmlld0NvbnRleHRcIj48L3NsYXRlLWNoaWxkcmVuPlxuPHNsYXRlLXN0cmluZy10ZW1wbGF0ZSAjdGVtcGxhdGVDb21wb25lbnQ+PC9zbGF0ZS1zdHJpbmctdGVtcGxhdGU+Il19