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