@libs-ui/components-inputs-mention 0.2.78

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.
@@ -0,0 +1,504 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { Directive, ElementRef, effect, inject, input, output, signal, untracked } from "@angular/core";
3
+ import { LibsUiDynamicComponentService } from "@libs-ui/services-dynamic-component";
4
+ import { get, isNil, uuid } from "@libs-ui/utils";
5
+ import { Subject, fromEvent } from "rxjs";
6
+ import { takeUntil, tap } from "rxjs/operators";
7
+ import { KEY_BACKSPACE, KEY_BUFFERED, KEY_DOWN, KEY_ENTER, KEY_ESCAPE, KEY_SHIFT, KEY_SPACE, KEY_TAB, KEY_UP } from "./defines/keyboard.define";
8
+ import { DEFAULT_CONFIG, buildTemplate } from "./defines/template.define";
9
+ import { getCaretPosition, getTextBeforeCursor, getValue, getWindowSelection, insertTextAtCaret, insertValue, setCaretPosition } from "./defines/utils.define";
10
+ import { LibsUiComponentsInputsMentionListComponent } from "./list/list.component";
11
+ import * as i0 from "@angular/core";
12
+ export class LibsUiComponentsInputsMentionDirective {
13
+ /* PROPERTY */
14
+ listComponentRef = signal(undefined);
15
+ nodesInsert = signal(new Set());
16
+ activeConfig = signal(undefined);
17
+ triggerChars = signal({});
18
+ searchString = signal('');
19
+ startPos = signal(undefined);
20
+ startNode = signal(undefined);
21
+ searchList = signal(undefined);
22
+ searching = signal(false);
23
+ iframe = signal(undefined);
24
+ lastKeyCode = signal(undefined);
25
+ isEditor = signal(false);
26
+ iframeId = signal(undefined);
27
+ element = inject(ElementRef);
28
+ dynamicComponentService = inject(LibsUiDynamicComponentService);
29
+ onDestroy = new Subject();
30
+ /* INPUT */
31
+ mentionConfig = input();
32
+ mentionListTemplate = input();
33
+ /* OUTPUT */
34
+ outSearchTerm = output();
35
+ outItemSelected = output();
36
+ outToggle = output();
37
+ outInsertMention = output();
38
+ outFunctionControl = output();
39
+ constructor() {
40
+ effect(() => {
41
+ this.mentionConfig();
42
+ untracked(() => this.updateConfig());
43
+ });
44
+ }
45
+ ngAfterViewInit() {
46
+ setTimeout(() => {
47
+ if (!this.mentionConfig()) {
48
+ return;
49
+ }
50
+ const isContentEditable = this.element.nativeElement.getAttribute('contenteditable');
51
+ this.isEditor.set(!isContentEditable);
52
+ const element = !this.isEditor() ? this.element.nativeElement : this.element.nativeElement.querySelector('.ql-editor[contenteditable="true"]');
53
+ element.addEventListener('keydown', (event) => {
54
+ this.handlerKeydown.bind(this)(event, element);
55
+ });
56
+ element.addEventListener('input', (event) => {
57
+ this.handlerInput.bind(this)(event, element);
58
+ });
59
+ element.addEventListener('blur', (event) => {
60
+ this.handlerBlur.bind(this)(event);
61
+ });
62
+ element.addEventListener('click', (event) => {
63
+ this.handlerFocus.bind(this)(event, element);
64
+ });
65
+ this.outFunctionControl.emit({
66
+ addMention: () => {
67
+ insertTextAtCaret(element, `${this.mentionConfig()?.triggerChar}`);
68
+ setTimeout(() => {
69
+ this.handlerKeydown({ key: this.mentionConfig()?.triggerChar, keyCode: KEY_BACKSPACE, shiftKey: true, inputEvent: true }, element);
70
+ }, 500);
71
+ }
72
+ });
73
+ });
74
+ }
75
+ /* FUNCTIONS */
76
+ updateConfig() {
77
+ const mentionConfig = this.mentionConfig();
78
+ if (!mentionConfig) {
79
+ return;
80
+ }
81
+ this.triggerChars.set({});
82
+ this.addConfig(mentionConfig);
83
+ if (mentionConfig.mention) {
84
+ mentionConfig.mention.forEach(config => this.addConfig(config));
85
+ }
86
+ }
87
+ addConfig(config) {
88
+ const defaults = Object.assign({}, DEFAULT_CONFIG);
89
+ const labelKey = config.labelKey || 'label';
90
+ config = Object.assign(defaults, config);
91
+ if (config.items && config.items.length > 0) {
92
+ if (typeof config.items[0] === 'string') {
93
+ config.items.forEach((label) => {
94
+ const object = {};
95
+ object[labelKey] = label;
96
+ return object;
97
+ });
98
+ }
99
+ if (labelKey) {
100
+ // remove items without an labelKey (as it's required to filter the list)
101
+ config.items = config.items.filter(e => e[labelKey]);
102
+ if (!config.disableSort) {
103
+ config.items.sort((a, b) => (a[labelKey] || '').localeCompare((b[labelKey] || '')));
104
+ }
105
+ }
106
+ }
107
+ this.triggerChars.update(item => ({
108
+ ...item,
109
+ [config.triggerChar || '@']: config
110
+ }));
111
+ if (this.activeConfig() && this.activeConfig()?.triggerChar === config.triggerChar) {
112
+ this.activeConfig.set(config);
113
+ this.updateSearchList();
114
+ }
115
+ }
116
+ setIframe(iframe) {
117
+ this.iframe.set(iframe);
118
+ }
119
+ stopEvent(event) {
120
+ if (get(event, 'wasClick')) {
121
+ return;
122
+ }
123
+ event.preventDefault();
124
+ event.stopPropagation();
125
+ event.stopImmediatePropagation();
126
+ }
127
+ handlerBlur(event) {
128
+ setTimeout(() => {
129
+ this.stopEvent(event);
130
+ this.stopSearch();
131
+ }, 100);
132
+ }
133
+ handlerInput(event, nativeElement = this.element.nativeElement) {
134
+ const data = get(event, 'data');
135
+ if (this.lastKeyCode() === KEY_BUFFERED && data) {
136
+ const keyCode = data.charCodeAt(0);
137
+ this.handlerKeydown({ keyCode, inputEvent: true }, nativeElement);
138
+ }
139
+ }
140
+ handlerKeydown(event, nativeElement = this.element.nativeElement) {
141
+ this.lastKeyCode.set(event.keyCode);
142
+ if (event.isComposing || event.keyCode === KEY_BUFFERED) {
143
+ return;
144
+ }
145
+ const val = getValue(nativeElement);
146
+ let pos = getCaretPosition(nativeElement, this.iframe());
147
+ let charPressed = event.key;
148
+ if (!this.isEditor()) {
149
+ if (event.keyCode === KEY_BACKSPACE) {
150
+ this.appendEmptyToLastNode(pos, val.length, nativeElement);
151
+ }
152
+ setTimeout(() => {
153
+ this.addNodeZeroWidthSpace(nativeElement);
154
+ }, 0);
155
+ }
156
+ if (!charPressed) {
157
+ const charCode = event.which || event.keyCode;
158
+ charPressed = String.fromCharCode(event.which || event.keyCode);
159
+ if (!event.shiftKey && (charCode >= 65 && charCode <= 90)) {
160
+ charPressed = String.fromCharCode(charCode + 32);
161
+ }
162
+ }
163
+ if (event.keyCode === KEY_ENTER && event.wasClick && pos < (this.startPos() || 0)) {
164
+ pos = this.startNode().length;
165
+ setCaretPosition(this.startNode(), pos, this.iframe());
166
+ }
167
+ const config = this.triggerChars()[charPressed];
168
+ if (config) {
169
+ this.activeConfig.set(config);
170
+ this.startPos.set(event.inputEvent ? pos - 1 : pos);
171
+ this.startNode.set(getWindowSelection(this.iframe())?.anchorNode);
172
+ this.searching.set(true);
173
+ this.searchString.set('');
174
+ this.showSearchList(nativeElement);
175
+ this.updateSearchList();
176
+ if (config.returnTrigger) {
177
+ this.outSearchTerm.emit(config.triggerChar);
178
+ }
179
+ return;
180
+ }
181
+ setTimeout(() => {
182
+ for (const itemSet of this.nodesInsert()) {
183
+ if (!nativeElement.contains(itemSet.elementSpan)) {
184
+ itemSet.subscription?.unsubscribe();
185
+ this.nodesInsert().delete(itemSet);
186
+ }
187
+ }
188
+ });
189
+ const startPos = this.startPos();
190
+ if (isNil(startPos) || startPos < 0 || !this.searching()) {
191
+ return;
192
+ }
193
+ const searchList = this.searchList();
194
+ if (pos <= startPos) {
195
+ if (searchList) {
196
+ searchList.hidden.set(true);
197
+ }
198
+ return;
199
+ }
200
+ if (event.keyCode === KEY_SHIFT || event.metaKey || event.altKey || event.ctrlKey || pos <= startPos) {
201
+ return;
202
+ }
203
+ if (!this.activeConfig()?.allowSpace && event.keyCode === KEY_SPACE) {
204
+ this.startPos.set(-1);
205
+ }
206
+ else if (event.keyCode === KEY_BACKSPACE && pos > 0) {
207
+ pos--;
208
+ if (pos === this.startPos()) {
209
+ this.stopSearch();
210
+ }
211
+ }
212
+ else if (searchList?.hidden()) {
213
+ if (event.keyCode === KEY_TAB || event.keyCode === KEY_ENTER) {
214
+ this.stopSearch();
215
+ return;
216
+ }
217
+ }
218
+ else if (!searchList?.hidden() && this.activeConfig()) {
219
+ if (event.keyCode === KEY_TAB || event.keyCode === KEY_ENTER) {
220
+ this.stopEvent(event);
221
+ // emit the selected list item
222
+ this.outItemSelected.emit(searchList?.ActiveItem);
223
+ // optional function to format the selected item before inserting the text
224
+ this.insertMention(nativeElement, pos);
225
+ // fire input event so angular bindings are updated
226
+ if ("Event" in window) {
227
+ // this seems backwards, but fire the event from this elements nativeElement (not the
228
+ // one provided that may be in an iframe, as it won't be propogate)
229
+ // Create the event using the modern Event constructor
230
+ const evt = new Event(this.iframe() ? "change" : "input", {
231
+ bubbles: true,
232
+ cancelable: false
233
+ });
234
+ // Dispatch the event on the native element
235
+ nativeElement.dispatchEvent(evt);
236
+ }
237
+ this.startPos.set(-1);
238
+ this.stopSearch();
239
+ return false;
240
+ }
241
+ if (event.keyCode === KEY_ESCAPE) {
242
+ this.stopEvent(event);
243
+ this.stopSearch();
244
+ return false;
245
+ }
246
+ if (event.keyCode === KEY_DOWN) {
247
+ this.stopEvent(event);
248
+ searchList?.activateNextItem();
249
+ return false;
250
+ }
251
+ if (event.keyCode === KEY_UP) {
252
+ this.stopEvent(event);
253
+ searchList?.activatePreviousItem();
254
+ return false;
255
+ }
256
+ }
257
+ if (charPressed.length !== 1 && event.keyCode !== KEY_BACKSPACE) {
258
+ this.stopEvent(event);
259
+ return false;
260
+ }
261
+ if (!this.searching()) {
262
+ return;
263
+ }
264
+ let mention = val.substring((this.startPos() || 0) + 1, pos);
265
+ if (event.keyCode !== KEY_BACKSPACE && !event.inputEvent) {
266
+ mention += charPressed;
267
+ }
268
+ const searchString = mention.replace(String.fromCharCode(160), ' ').replace(String.fromCharCode(0), '');
269
+ this.searchString.set(searchString.trim());
270
+ const limitSpaceSearchQuery = this.activeConfig()?.limitSpaceSearchQuery;
271
+ if (limitSpaceSearchQuery && (searchString.split(' ').length - 1) > limitSpaceSearchQuery) {
272
+ this.searchString.set('');
273
+ }
274
+ if (this.activeConfig()?.returnTrigger) {
275
+ const triggerChar = (this.searchString() || event.keyCode === KEY_BACKSPACE) ? val.substring(this.startPos(), (this.startPos() || 0) + 1) : '';
276
+ this.outSearchTerm.emit(triggerChar + this.searchString());
277
+ this.updateSearchList();
278
+ return;
279
+ }
280
+ this.outSearchTerm.emit(this.searchString());
281
+ this.updateSearchList();
282
+ }
283
+ handlerFocus(e, nativeElement = this.element.nativeElement) {
284
+ e?.stopPropagation();
285
+ setTimeout(() => {
286
+ const node = getWindowSelection(this.iframe())?.anchorNode;
287
+ if (node?.nodeType !== 3) {
288
+ this.stopSearch();
289
+ return;
290
+ }
291
+ const textBeforeCursor = getTextBeforeCursor() || '';
292
+ const triggerChars = Object.keys(this.triggerChars()).map((key) => {
293
+ return {
294
+ key: key,
295
+ config: this.triggerChars()[key],
296
+ index: textBeforeCursor.lastIndexOf(key)
297
+ };
298
+ });
299
+ const matchingCharacters = triggerChars.reduce((pre, current) => pre && current && current.index > pre.index ? current : pre);
300
+ if (matchingCharacters.index < 0) {
301
+ this.stopSearch();
302
+ return;
303
+ }
304
+ const search = textBeforeCursor?.substring(matchingCharacters.index, textBeforeCursor.length);
305
+ if (!search) {
306
+ this.stopSearch();
307
+ return;
308
+ }
309
+ const pos = getCaretPosition(nativeElement, this.iframe());
310
+ this.activeConfig.set(matchingCharacters.config);
311
+ this.startPos.set(pos - (textBeforeCursor.length - matchingCharacters.index));
312
+ this.searchString.set(search.replace(matchingCharacters.key, ''));
313
+ this.searching.set(true);
314
+ this.handlerKeydown({ keyCode: ''.charCodeAt(0), inputEvent: false }, nativeElement);
315
+ const divElement = document.createElement("div");
316
+ divElement.style.width = 'max-content';
317
+ divElement.style.position = 'absolute';
318
+ divElement.innerText = search;
319
+ document.body.appendChild(divElement);
320
+ let iframe = undefined;
321
+ try {
322
+ iframe = this.mentionConfig()?.iframe ? window.parent.document.getElementById(this.mentionConfig()?.iframe) : undefined;
323
+ }
324
+ catch (error) {
325
+ console.log(error);
326
+ }
327
+ const searchList = this.searchList();
328
+ if (searchList) {
329
+ searchList.position(nativeElement, iframe, divElement.getBoundingClientRect().width);
330
+ }
331
+ divElement.remove();
332
+ nativeElement.normalize();
333
+ });
334
+ }
335
+ stopSearch() {
336
+ const searchList = this.searchList();
337
+ if (searchList && !searchList.hidden()) {
338
+ searchList.hidden.set(true);
339
+ this.outToggle.emit(false);
340
+ }
341
+ this.activeConfig.set(undefined);
342
+ this.searching.set(false);
343
+ }
344
+ updateSearchList() {
345
+ const matches = [];
346
+ const activeConfig = this.activeConfig();
347
+ const searchString = this.searchString();
348
+ const searchList = this.searchList();
349
+ // disabling the search relies on the async operation to do the filtering
350
+ if (activeConfig && activeConfig.items && !activeConfig.disableSearch && !isNil(searchString) && activeConfig.labelKey && activeConfig.mentionFilter) {
351
+ matches.push(...activeConfig.mentionFilter(searchString, activeConfig.items));
352
+ }
353
+ // update the search list
354
+ if (!searchList) {
355
+ return;
356
+ }
357
+ searchList.items.set(matches);
358
+ searchList.hidden.set(!matches.length);
359
+ searchList.activeIndex.set(0);
360
+ searchList.scrollContent();
361
+ this.outToggle.emit(matches.length ? true : false);
362
+ }
363
+ showSearchList(nativeElement) {
364
+ let iframe = undefined;
365
+ const mentionConfig = this.mentionConfig();
366
+ try {
367
+ iframe = mentionConfig?.iframe ? window.parent.document.getElementById(mentionConfig?.iframe) : undefined;
368
+ }
369
+ catch (error) {
370
+ console.log(error);
371
+ }
372
+ if (!mentionConfig) {
373
+ return;
374
+ }
375
+ this.outToggle.emit(true);
376
+ let firstTime = false;
377
+ if (!this.listComponentRef()) {
378
+ firstTime = true;
379
+ this.listComponentRef.set(this.dynamicComponentService.resolveComponentFactory(LibsUiComponentsInputsMentionListComponent));
380
+ this.searchList.set(this.listComponentRef()?.instance);
381
+ }
382
+ this.searchList()?.labelKey.set(this.activeConfig()?.labelKey || '');
383
+ this.searchList()?.styleOff.set(this.mentionConfig()?.disableStyle || false);
384
+ this.searchList()?.activeIndex.set(0);
385
+ this.searchList()?.zIndex.set(this.mentionConfig()?.zIndex || 2500);
386
+ this.searchList()?.isIframe.set(iframe ? true : false);
387
+ this.searchList()?.parentHandlerKeyDown.set(this.handlerKeydown.bind(this));
388
+ this.searchList()?.position(nativeElement, iframe);
389
+ if (firstTime && this.listComponentRef()) {
390
+ this.iframeId.set(this.dynamicComponentService.addToBody(this.listComponentRef(), iframe ? true : false));
391
+ }
392
+ }
393
+ destroyListSearch() {
394
+ this.dynamicComponentService.remove(this.listComponentRef, this.iframeId());
395
+ this.listComponentRef.set(undefined);
396
+ }
397
+ appendEmptyToLastNode(position, length, nativeElement = this.element.nativeElement) {
398
+ const empty = document.createTextNode('\u00A0');
399
+ const selection = getWindowSelection(this.iframe());
400
+ const anchorNode = selection?.anchorNode;
401
+ if (this.isEditor()) {
402
+ const parentNode = anchorNode?.parentNode;
403
+ if (parentNode && parentNode.getAttribute && parentNode.getAttribute('id')) {
404
+ if (!parentNode.nextSibling || !parentNode.nextSibling.textContent?.length) {
405
+ parentNode?.parentNode?.insertBefore(empty, parentNode.nextSibling);
406
+ }
407
+ const range = document.createRange();
408
+ const sel = window.getSelection();
409
+ range.setStart(parentNode.nextSibling, 0);
410
+ range.collapse(true);
411
+ sel?.removeAllRanges();
412
+ sel?.addRange(range);
413
+ }
414
+ return;
415
+ }
416
+ let preNode = null;
417
+ const anchorOffset = selection?.anchorOffset;
418
+ if (!anchorNode || !anchorOffset) {
419
+ return;
420
+ }
421
+ if (anchorNode.nodeName.toLowerCase() !== '#text') {
422
+ nativeElement.appendChild(empty);
423
+ return;
424
+ }
425
+ for (let i = 0; i < nativeElement.childNodes.length; i++) {
426
+ const node = nativeElement.childNodes[i];
427
+ if (anchorNode.nodeType === 3 && anchorNode === node && preNode && preNode.getAttribute && preNode.getAttribute('id') && (!anchorNode.textContent?.length || anchorNode.textContent.length === 1) && position === length) {
428
+ nativeElement.appendChild(empty);
429
+ break;
430
+ }
431
+ preNode = node;
432
+ }
433
+ }
434
+ addNodeZeroWidthSpace(nativeElement = this.element.nativeElement) {
435
+ const empty = document.createTextNode('\u200b');
436
+ let preNode = null;
437
+ for (let i = 0; i < nativeElement.childNodes.length; i++) {
438
+ const node = nativeElement.childNodes[i];
439
+ if (preNode && preNode.getAttribute && preNode.getAttribute('id') && node && node.getAttribute && node.getAttribute('id')) {
440
+ nativeElement.insertBefore(empty, preNode.nextSibling);
441
+ }
442
+ preNode = node;
443
+ }
444
+ }
445
+ insertMention(nativeElement, pos) {
446
+ const activeConfig = this.activeConfig();
447
+ if (!activeConfig) {
448
+ return;
449
+ }
450
+ const searchList = this.searchList();
451
+ let text = '';
452
+ const feId = uuid();
453
+ const id = searchList?.ActiveItem.id || uuid();
454
+ const itemActive = searchList?.ActiveItem;
455
+ const { triggerChar, mentionEventName, mentionActionByEvent } = activeConfig;
456
+ if (activeConfig.mentionSelect) {
457
+ text = activeConfig.mentionSelect(searchList?.ActiveItem, activeConfig.triggerChar);
458
+ }
459
+ if (!this.isEditor()) {
460
+ let span = document.createElement('TEXTAREA');
461
+ span.innerText = text;
462
+ text = span.innerHTML;
463
+ span.remove();
464
+ text = buildTemplate(text, id, feId);
465
+ span = insertValue(nativeElement, this.startPos() || 0, pos, text, this.iframe());
466
+ if (span) {
467
+ const data = {
468
+ elementSpan: span,
469
+ subscription: undefined,
470
+ item: itemActive,
471
+ triggerChar: triggerChar,
472
+ manualAdd: true
473
+ };
474
+ this.nodesInsert().add(data);
475
+ if (mentionEventName) {
476
+ data.subscription = fromEvent(span, mentionEventName).pipe(tap(e => e.stopPropagation()), takeUntil(this.onDestroy)).subscribe(() => {
477
+ if (mentionActionByEvent) {
478
+ mentionActionByEvent(itemActive, triggerChar);
479
+ }
480
+ });
481
+ }
482
+ }
483
+ }
484
+ else {
485
+ this.outInsertMention.emit({ data: { id, value: text, feId }, lengthKey: pos - (this.startPos() || 0) });
486
+ }
487
+ }
488
+ ngOnDestroy() {
489
+ this.destroyListSearch();
490
+ this.onDestroy.next();
491
+ this.onDestroy.complete();
492
+ }
493
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsMentionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
494
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.13", type: LibsUiComponentsInputsMentionDirective, isStandalone: true, selector: "[LibsUiComponentsInputsMentionDirective]", inputs: { mentionConfig: { classPropertyName: "mentionConfig", publicName: "mentionConfig", isSignal: true, isRequired: false, transformFunction: null }, mentionListTemplate: { classPropertyName: "mentionListTemplate", publicName: "mentionListTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { outSearchTerm: "outSearchTerm", outItemSelected: "outItemSelected", outToggle: "outToggle", outInsertMention: "outInsertMention", outFunctionControl: "outFunctionControl" }, ngImport: i0 });
495
+ }
496
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsInputsMentionDirective, decorators: [{
497
+ type: Directive,
498
+ args: [{
499
+ // eslint-disable-next-line @angular-eslint/directive-selector
500
+ selector: '[LibsUiComponentsInputsMentionDirective]',
501
+ standalone: true
502
+ }]
503
+ }], ctorParameters: () => [] });
504
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVudGlvbi5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvaW5wdXRzL21lbnRpb24vc3JjL21lbnRpb24uZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHVEQUF1RDtBQUN2RCxPQUFPLEVBQStCLFNBQVMsRUFBRSxVQUFVLEVBQTBCLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTdKLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDaEosT0FBTyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsbUJBQW1CLEVBQUUsUUFBUSxFQUFFLGtCQUFrQixFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRS9KLE9BQU8sRUFBRSwwQ0FBMEMsRUFBRSxNQUFNLHVCQUF1QixDQUFDOztBQU9uRixNQUFNLE9BQU8sc0NBQXNDO0lBRWpELGNBQWM7SUFDTixnQkFBZ0IsR0FBRyxNQUFN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R0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDM0csQ0FBQztJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzVCLENBQUM7d0dBbGlCVSxzQ0FBc0M7NEZBQXRDLHNDQUFzQzs7NEZBQXRDLHNDQUFzQztrQkFMbEQsU0FBUzttQkFBQztvQkFDVCw4REFBOEQ7b0JBQzlELFFBQVEsRUFBRSwwQ0FBMEM7b0JBQ3BELFVBQVUsRUFBRSxJQUFJO2lCQUNqQiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbmltcG9ydCB7IEFmdGVyVmlld0luaXQsIENvbXBvbmVudFJlZiwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBPbkRlc3Ryb3ksIFRlbXBsYXRlUmVmLCBlZmZlY3QsIGluamVjdCwgaW5wdXQsIG91dHB1dCwgc2lnbmFsLCB1bnRyYWNrZWQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgSUV2ZW50LCBUWVBFX1RFTVBMQVRFX1JFRiB9IGZyb20gXCJAbGlicy11aS9pbnRlcmZhY2VzLXR5cGVzXCI7XG5pbXBvcnQgeyBMaWJzVWlEeW5hbWljQ29tcG9uZW50U2VydmljZSB9IGZyb20gXCJAbGlicy11aS9zZXJ2aWNlcy1keW5hbWljLWNvbXBvbmVudFwiO1xuaW1wb3J0IHsgZ2V0LCBpc05pbCwgdXVpZCB9IGZyb20gXCJAbGlicy11aS91dGlsc1wiO1xuaW1wb3J0IHsgU3ViamVjdCwgZnJvbUV2ZW50IH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IHRha2VVbnRpbCwgdGFwIH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5pbXBvcnQgeyBLRVlfQkFDS1NQQUNFLCBLRVlfQlVGRkVSRUQsIEtFWV9ET1dOLCBLRVlfRU5URVIsIEtFWV9FU0NBUEUsIEtFWV9TSElGVCwgS0VZX1NQQUNFLCBLRVlfVEFCLCBLRVlfVVAgfSBmcm9tIFwiLi9kZWZpbmVzL2tleWJvYXJkLmRlZmluZVwiO1xuaW1wb3J0IHsgREVGQVVMVF9DT05GSUcsIGJ1aWxkVGVtcGxhdGUgfSBmcm9tIFwiLi9kZWZpbmVzL3RlbXBsYXRlLmRlZmluZVwiO1xuaW1wb3J0IHsgZ2V0Q2FyZXRQb3NpdGlvbiwgZ2V0VGV4dEJlZm9yZUN1cnNvciwgZ2V0VmFsdWUsIGdldFdpbmRvd1NlbGVjdGlvbiwgaW5zZXJ0VGV4dEF0Q2FyZXQsIGluc2VydFZhbHVlLCBzZXRDYXJldFBvc2l0aW9uIH0gZnJvbSBcIi4vZGVmaW5lcy91dGlscy5kZWZpbmVcIjtcbmltcG9ydCB7IElNZW50aW9uQ29uZmlnLCBJTWVudGlvbkZ1bmN0aW9uQ29udHJvbEV2ZW50LCBJTWVudGlvbkluc2VydCwgSU5vZGVJbnNlcnQgfSBmcm9tIFwiLi9pbnRlcmZhY2VzL21lbnRpb24uaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBMaWJzVWlDb21wb25lbnRzSW5wdXRzTWVudGlvbkxpc3RDb21wb25lbnQgfSBmcm9tIFwiLi9saXN0L2xpc3QuY29tcG9uZW50XCI7XG5cbkBEaXJlY3RpdmUoe1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2RpcmVjdGl2ZS1zZWxlY3RvclxuICBzZWxlY3RvcjogJ1tMaWJzVWlDb21wb25lbnRzSW5wdXRzTWVudGlvbkRpcmVjdGl2ZV0nLFxuICBzdGFuZGFsb25lOiB0cnVlXG59KVxuZXhwb3J0IGNsYXNzIExpYnNVaUNvbXBvbmVudHNJbnB1dHNNZW50aW9uRGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcblxuICAvKiBQUk9QRVJUWSAqL1xuICBwcml2YXRlIGxpc3RDb21wb25lbnRSZWYgPSBzaWduYWw8Q29tcG9uZW50UmVmPExpYnNVaUNvbXBvbmVudHNJbnB1dHNNZW50aW9uTGlzdENvbXBvbmVudD4gfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgbm9kZXNJbnNlcnQgPSBzaWduYWw8U2V0PElOb2RlSW5zZXJ0Pj4obmV3IFNldCgpKTtcbiAgcHJpdmF0ZSBhY3RpdmVDb25maWcgPSBzaWduYWw8SU1lbnRpb25Db25maWcgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgdHJpZ2dlckNoYXJzID0gc2lnbmFsPFJlY29yZDxzdHJpbmcsIElNZW50aW9uQ29uZmlnPj4oe30pO1xuICBwcml2YXRlIHNlYXJjaFN0cmluZyA9IHNpZ25hbDxzdHJpbmc+KCcnKTtcbiAgcHJpdmF0ZSBzdGFydFBvcyA9IHNpZ25hbDxudW1iZXIgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgc3RhcnROb2RlID0gc2lnbmFsPGFueT4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSBzZWFyY2hMaXN0ID0gc2lnbmFsPExpYnNVaUNvbXBvbmVudHNJbnB1dHNNZW50aW9uTGlzdENvbXBvbmVudCB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgcHJpdmF0ZSBzZWFyY2hpbmcgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIGlmcmFtZSA9IHNpZ25hbDxhbnk+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgbGFzdEtleUNvZGUgPSBzaWduYWw8bnVtYmVyIHwgdW5kZWZpbmVkPih1bmRlZmluZWQpO1xuICBwcml2YXRlIGlzRWRpdG9yID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcHJpdmF0ZSBpZnJhbWVJZCA9IHNpZ25hbDxzdHJpbmcgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZCk7XG4gIHByaXZhdGUgZWxlbWVudCA9IGluamVjdChFbGVtZW50UmVmKTtcbiAgcHJpdmF0ZSBkeW5hbWljQ29tcG9uZW50U2VydmljZSA9IGluamVjdChMaWJzVWlEeW5hbWljQ29tcG9uZW50U2VydmljZSk7XG4gIHByaXZhdGUgb25EZXN0cm95ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvKiBJTlBVVCAqL1xuICByZWFkb25seSBtZW50aW9uQ29uZmlnID0gaW5wdXQ8SU1lbnRpb25Db25maWc+KCk7XG4gIHJlYWRvbmx5IG1lbnRpb25MaXN0VGVtcGxhdGUgPSBpbnB1dDxUZW1wbGF0ZVJlZjxUWVBFX1RFTVBMQVRFX1JFRj4+KCk7XG5cbiAgLyogT1VUUFVUICovXG4gIHJlYWRvbmx5IG91dFNlYXJjaFRlcm0gPSBvdXRwdXQ8c3RyaW5nIHwgdW5kZWZpbmVkPigpO1xuICByZWFkb25seSBvdXRJdGVtU2VsZWN0ZWQgPSBvdXRwdXQ8dW5rbm93bj4oKTtcbiAgcmVhZG9ubHkgb3V0VG9nZ2xlID0gb3V0cHV0PGJvb2xlYW4+KCk7XG4gIHJlYWRvbmx5IG91dEluc2VydE1lbnRpb24gPSBvdXRwdXQ8SU1lbnRpb25JbnNlcnQ+KCk7XG4gIHJlYWRvbmx5IG91dEZ1bmN0aW9uQ29udHJvbCA9IG91dHB1dDxJTWVudGlvbkZ1bmN0aW9uQ29udHJvbEV2ZW50PigpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICB0aGlzLm1lbnRpb25Db25maWcoKTtcbiAgICAgIHVudHJhY2tlZCgoKSA9PiB0aGlzLnVwZGF0ZUNvbmZpZygpKTtcbiAgICB9KVxuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLm1lbnRpb25Db25maWcoKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBpc0NvbnRlbnRFZGl0YWJsZSA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LmdldEF0dHJpYnV0ZSgnY29udGVudGVkaXRhYmxlJyk7XG5cbiAgICAgIHRoaXMuaXNFZGl0b3Iuc2V0KCFpc0NvbnRlbnRFZGl0YWJsZSk7XG4gICAgICBjb25zdCBlbGVtZW50ID0gIXRoaXMuaXNFZGl0b3IoKSA/IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50IDogdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLnFsLWVkaXRvcltjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJdJyk7XG5cbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChldmVudDogRXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5oYW5kbGVyS2V5ZG93bi5iaW5kKHRoaXMpKGV2ZW50LCBlbGVtZW50KTtcbiAgICAgIH0pO1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIChldmVudDogRXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5oYW5kbGVySW5wdXQuYmluZCh0aGlzKShldmVudCwgZWxlbWVudCk7XG4gICAgICB9KTtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIChldmVudDogRXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5oYW5kbGVyQmx1ci5iaW5kKHRoaXMpKGV2ZW50KTtcbiAgICAgIH0pO1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIChldmVudDogRXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5oYW5kbGVyRm9jdXMuYmluZCh0aGlzKShldmVudCwgZWxlbWVudCk7XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5vdXRGdW5jdGlvbkNvbnRyb2wuZW1pdCh7XG4gICAgICAgIGFkZE1lbnRpb246ICgpID0+IHtcbiAgICAgICAgICBpbnNlcnRUZXh0QXRDYXJldChlbGVtZW50LCBgJHt0aGlzLm1lbnRpb25Db25maWcoKT8udHJpZ2dlckNoYXJ9YCk7XG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZXJLZXlkb3duKHsga2V5OiB0aGlzLm1lbnRpb25Db25maWcoKT8udHJpZ2dlckNoYXIsIGtleUNvZGU6IEtFWV9CQUNLU1BBQ0UsIHNoaWZ0S2V5OiB0cnVlLCBpbnB1dEV2ZW50OiB0cnVlIH0sIGVsZW1lbnQpO1xuICAgICAgICAgIH0sIDUwMCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyogRlVOQ1RJT05TICovXG4gIHByb3RlY3RlZCB1cGRhdGVDb25maWcoKSB7XG4gICAgY29uc3QgbWVudGlvbkNvbmZpZyA9IHRoaXMubWVudGlvbkNvbmZpZygpO1xuICAgIGlmICghbWVudGlvbkNvbmZpZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnRyaWdnZXJDaGFycy5zZXQoe30pO1xuICAgIHRoaXMuYWRkQ29uZmlnKG1lbnRpb25Db25maWcpO1xuICAgIGlmIChtZW50aW9uQ29uZmlnLm1lbnRpb24pIHtcbiAgICAgIG1lbnRpb25Db25maWcubWVudGlvbi5mb3JFYWNoKGNvbmZpZyA9PiB0aGlzLmFkZENvbmZpZyhjb25maWcpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFkZENvbmZpZyhjb25maWc6IElNZW50aW9uQ29uZmlnKSB7XG4gICAgY29uc3QgZGVmYXVsdHMgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX0NPTkZJRyk7XG4gICAgY29uc3QgbGFiZWxLZXkgPSBjb25maWcubGFiZWxLZXkgfHwgJ2xhYmVsJztcbiAgICBjb25maWcgPSBPYmplY3QuYXNzaWduKGRlZmF1bHRzLCBjb25maWcpO1xuICAgIGlmIChjb25maWcuaXRlbXMgJiYgY29uZmlnLml0ZW1zLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICh0eXBlb2YgY29uZmlnLml0ZW1zWzBdID09PSAnc3RyaW5nJykge1xuICAgICAgICBjb25maWcuaXRlbXMuZm9yRWFjaCgobGFiZWwpID0+IHtcbiAgICAgICAgICBjb25zdCBvYmplY3Q6IFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4+ID0ge307XG5cbiAgICAgICAgICBvYmplY3RbbGFiZWxLZXldID0gbGFiZWw7XG5cbiAgICAgICAgICByZXR1cm4gb2JqZWN0O1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChsYWJlbEtleSkge1xuICAgICAgICAvLyByZW1vdmUgaXRlbXMgd2l0aG91dCBhbiBsYWJlbEtleSAoYXMgaXQncyByZXF1aXJlZCB0byBmaWx0ZXIgdGhlIGxpc3QpXG4gICAgICAgIGNvbmZpZy5pdGVtcyA9IGNvbmZpZy5pdGVtcy5maWx0ZXIoZSA9PiBlW2xhYmVsS2V5XSk7XG4gICAgICAgIGlmICghY29uZmlnLmRpc2FibGVTb3J0KSB7XG4gICAgICAgICAgY29uZmlnLml0ZW1zLnNvcnQoKGEsIGIpID0+IChhW2xhYmVsS2V5XSB8fCAnJykubG9jYWxlQ29tcGFyZSgoYltsYWJlbEtleV0gfHwgJycpKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy50cmlnZ2VyQ2hhcnMudXBkYXRlKGl0ZW0gPT4gKHtcbiAgICAgIC4uLml0ZW0sXG4gICAgICBbY29uZmlnLnRyaWdnZXJDaGFyIHx8ICdAJ106IGNvbmZpZ1xuICAgIH0pKVxuICAgIGlmICh0aGlzLmFjdGl2ZUNvbmZpZygpICYmIHRoaXMuYWN0aXZlQ29uZmlnKCk/LnRyaWdnZXJDaGFyID09PSBjb25maWcudHJpZ2dlckNoYXIpIHtcbiAgICAgIHRoaXMuYWN0aXZlQ29uZmlnLnNldChjb25maWcpO1xuICAgICAgdGhpcy51cGRhdGVTZWFyY2hMaXN0KCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHNldElmcmFtZShpZnJhbWU6IEhUTUxJRnJhbWVFbGVtZW50KSB7XG4gICAgdGhpcy5pZnJhbWUuc2V0KGlmcmFtZSk7XG4gIH1cblxuICBwcml2YXRlIHN0b3BFdmVudChldmVudDogRXZlbnQpIHtcbiAgICBpZiAoZ2V0KGV2ZW50LCAnd2FzQ2xpY2snKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJCbHVyKGV2ZW50OiBFdmVudCkge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5zdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgdGhpcy5zdG9wU2VhcmNoKCk7XG4gICAgfSwgMTAwKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVySW5wdXQoZXZlbnQ6IEV2ZW50LCBuYXRpdmVFbGVtZW50OiBIVE1MSW5wdXRFbGVtZW50ID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICBjb25zdCBkYXRhID0gZ2V0KGV2ZW50LCAnZGF0YScpO1xuICAgIGlmICh0aGlzLmxhc3RLZXlDb2RlKCkgPT09IEtFWV9CVUZGRVJFRCAmJiBkYXRhKSB7XG4gICAgICBjb25zdCBrZXlDb2RlID0gZGF0YS5jaGFyQ29kZUF0KDApO1xuICAgICAgdGhpcy5oYW5kbGVyS2V5ZG93bih7IGtleUNvZGUsIGlucHV0RXZlbnQ6IHRydWUgfSwgbmF0aXZlRWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGhhbmRsZXJLZXlkb3duKGV2ZW50OiBhbnksIG5hdGl2ZUVsZW1lbnQ6IEhUTUxJbnB1dEVsZW1lbnQgPSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudCk6IGFueSB7XG4gICAgdGhpcy5sYXN0S2V5Q29kZS5zZXQoZXZlbnQua2V5Q29kZSk7XG4gICAgaWYgKGV2ZW50LmlzQ29tcG9zaW5nIHx8IGV2ZW50LmtleUNvZGUgPT09IEtFWV9CVUZGRVJFRCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbDogYW55ID0gZ2V0VmFsdWUobmF0aXZlRWxlbWVudCk7XG4gICAgbGV0IHBvczogYW55ID0gZ2V0Q2FyZXRQb3NpdGlvbihuYXRpdmVFbGVtZW50LCB0aGlzLmlmcmFtZSgpKTtcbiAgICBsZXQgY2hhclByZXNzZWQgPSBldmVudC5rZXk7XG5cbiAgICBpZiAoIXRoaXMuaXNFZGl0b3IoKSkge1xuICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IEtFWV9CQUNLU1BBQ0UpIHtcbiAgICAgICAgdGhpcy5hcHBlbmRFbXB0eVRvTGFzdE5vZGUocG9zLCB2YWwubGVuZ3RoLCBuYXRpdmVFbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuYWRkTm9kZVplcm9XaWR0aFNwYWNlKG5hdGl2ZUVsZW1lbnQpO1xuICAgICAgfSwgMCk7XG4gICAgfVxuICAgIGlmICghY2hhclByZXNzZWQpIHtcbiAgICAgIGNvbnN0IGNoYXJDb2RlID0gZXZlbnQud2hpY2ggfHwgZXZlbnQua2V5Q29kZTtcblxuICAgICAgY2hhclByZXNzZWQgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGV2ZW50LndoaWNoIHx8IGV2ZW50LmtleUNvZGUpO1xuICAgICAgaWYgKCFldmVudC5zaGlmdEtleSAmJiAoY2hhckNvZGUgPj0gNjUgJiYgY2hhckNvZGUgPD0gOTApKSB7XG4gICAgICAgIGNoYXJQcmVzc2VkID0gU3RyaW5nLmZyb21DaGFyQ29kZShjaGFyQ29kZSArIDMyKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gS0VZX0VOVEVSICYmIGV2ZW50Lndhc0NsaWNrICYmIHBvcyA8ICh0aGlzLnN0YXJ0UG9zKCkgfHwgMCkpIHtcbiAgICAgIHBvcyA9IHRoaXMuc3RhcnROb2RlKCkubGVuZ3RoO1xuICAgICAgc2V0Q2FyZXRQb3NpdGlvbih0aGlzLnN0YXJ0Tm9kZSgpLCBwb3MsIHRoaXMuaWZyYW1lKCkpO1xuICAgIH1cbiAgICBjb25zdCBjb25maWcgPSB0aGlzLnRyaWdnZXJDaGFycygpW2NoYXJQcmVzc2VkXTtcblxuICAgIGlmIChjb25maWcpIHtcbiAgICAgIHRoaXMuYWN0aXZlQ29uZmlnLnNldChjb25maWcpO1xuICAgICAgdGhpcy5zdGFydFBvcy5zZXQoZXZlbnQuaW5wdXRFdmVudCA/IHBvcyAtIDEgOiBwb3MpO1xuICAgICAgdGhpcy5zdGFydE5vZGUuc2V0KGdldFdpbmRvd1NlbGVjdGlvbih0aGlzLmlmcmFtZSgpKT8uYW5jaG9yTm9kZSk7XG4gICAgICB0aGlzLnNlYXJjaGluZy5zZXQodHJ1ZSk7XG4gICAgICB0aGlzLnNlYXJjaFN0cmluZy5zZXQoJycpO1xuICAgICAgdGhpcy5zaG93U2VhcmNoTGlzdChuYXRpdmVFbGVtZW50KTtcbiAgICAgIHRoaXMudXBkYXRlU2VhcmNoTGlzdCgpO1xuICAgICAgaWYgKGNvbmZpZy5yZXR1cm5UcmlnZ2VyKSB7XG4gICAgICAgIHRoaXMub3V0U2VhcmNoVGVybS5lbWl0KGNvbmZpZy50cmlnZ2VyQ2hhcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW1TZXQgb2YgdGhpcy5ub2Rlc0luc2VydCgpKSB7XG4gICAgICAgIGlmICghbmF0aXZlRWxlbWVudC5jb250YWlucyhpdGVtU2V0LmVsZW1lbnRTcGFuKSkge1xuICAgICAgICAgIGl0ZW1TZXQuc3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICAgIHRoaXMubm9kZXNJbnNlcnQoKS5kZWxldGUoaXRlbVNldCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBzdGFydFBvcyA9IHRoaXMuc3RhcnRQb3MoKTtcbiAgICBpZiAoaXNOaWwoc3RhcnRQb3MpIHx8IHN0YXJ0UG9zIDwgMCB8fCAhdGhpcy5zZWFyY2hpbmcoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzZWFyY2hMaXN0ID0gdGhpcy5zZWFyY2hMaXN0KCk7XG4gICAgaWYgKHBvcyA8PSBzdGFydFBvcykge1xuICAgICAgaWYgKHNlYXJjaExpc3QpIHtcbiAgICAgICAgc2VhcmNoTGlzdC5oaWRkZW4uc2V0KHRydWUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gS0VZX1NISUZUIHx8IGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuYWx0S2V5IHx8IGV2ZW50LmN0cmxLZXkgfHwgcG9zIDw9IHN0YXJ0UG9zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5hY3RpdmVDb25maWcoKT8uYWxsb3dTcGFjZSAmJiBldmVudC5rZXlDb2RlID09PSBLRVlfU1BBQ0UpIHtcbiAgICAgIHRoaXMuc3RhcnRQb3Muc2V0KC0xKTtcbiAgICB9IGVsc2UgaWYgKGV2ZW50LmtleUNvZGUgPT09IEtFWV9CQUNLU1BBQ0UgJiYgcG9zID4gMCkge1xuICAgICAgcG9zLS07XG4gICAgICBpZiAocG9zID09PSB0aGlzLnN0YXJ0UG9zKCkpIHtcbiAgICAgICAgdGhpcy5zdG9wU2VhcmNoKCk7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKHNlYXJjaExpc3Q/LmhpZGRlbigpKSB7XG4gICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gS0VZX1RBQiB8fCBldmVudC5rZXlDb2RlID09PSBLRVlfRU5URVIpIHtcbiAgICAgICAgdGhpcy5zdG9wU2VhcmNoKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAoIXNlYXJjaExpc3Q/LmhpZGRlbigpICYmIHRoaXMuYWN0aXZlQ29uZmlnKCkpIHtcbiAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSBLRVlfVEFCIHx8IGV2ZW50LmtleUNvZGUgPT09IEtFWV9FTlRFUikge1xuICAgICAgICB0aGlzLnN0b3BFdmVudChldmVudCk7XG4gICAgICAgIC8vIGVtaXQgdGhlIHNlbGVjdGVkIGxpc3QgaXRlbVxuICAgICAgICB0aGlzLm91dEl0ZW1TZWxlY3RlZC5lbWl0KHNlYXJjaExpc3Q/LkFjdGl2ZUl0ZW0pO1xuICAgICAgICAvLyBvcHRpb25hbCBmdW5jdGlvbiB0byBmb3JtYXQgdGhlIHNlbGVjdGVkIGl0ZW0gYmVmb3JlIGluc2VydGluZyB0aGUgdGV4dFxuICAgICAgICB0aGlzLmluc2VydE1lbnRpb24obmF0aXZlRWxlbWVudCwgcG9zKTtcbiAgICAgICAgLy8gZmlyZSBpbnB1dCBldmVudCBzbyBhbmd1bGFyIGJpbmRpbmdzIGFyZSB1cGRhdGVkXG4gICAgICAgIGlmIChcIkV2ZW50XCIgaW4gd2luZG93KSB7XG4gICAgICAgICAgLy8gdGhpcyBzZWVtcyBiYWNrd2FyZHMsIGJ1dCBmaXJlIHRoZSBldmVudCBmcm9tIHRoaXMgZWxlbWVudHMgbmF0aXZlRWxlbWVudCAobm90IHRoZVxuICAgICAgICAgIC8vIG9uZSBwcm92aWRlZCB0aGF0IG1heSBiZSBpbiBhbiBpZnJhbWUsIGFzIGl0IHdvbid0IGJlIHByb3BvZ2F0ZSlcbiAgICAgICAgICAvLyBDcmVhdGUgdGhlIGV2ZW50IHVzaW5nIHRoZSBtb2Rlcm4gRXZlbnQgY29uc3RydWN0b3JcbiAgICAgICAgICBjb25zdCBldnQgPSBuZXcgRXZlbnQodGhpcy5pZnJhbWUoKSA/IFwiY2hhbmdlXCIgOiBcImlucHV0XCIsIHtcbiAgICAgICAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICAgICAgICBjYW5jZWxhYmxlOiBmYWxzZVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIC8vIERpc3BhdGNoIHRoZSBldmVudCBvbiB0aGUgbmF0aXZlIGVsZW1lbnRcbiAgICAgICAgICBuYXRpdmVFbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZ0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YXJ0UG9zLnNldCgtMSk7XG4gICAgICAgIHRoaXMuc3RvcFNlYXJjaCgpO1xuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IEtFWV9FU0NBUEUpIHtcbiAgICAgICAgdGhpcy5zdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICB0aGlzLnN0b3BTZWFyY2goKTtcblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQua2V5Q29kZSA9PT0gS0VZX0RPV04pIHtcbiAgICAgICAgdGhpcy5zdG9wRXZlbnQoZXZlbnQpO1xuICAgICAgICBzZWFyY2hMaXN0Py5hY3RpdmF0ZU5leHRJdGVtKCk7XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LmtleUNvZGUgPT09IEtFWV9VUCkge1xuICAgICAgICB0aGlzLnN0b3BFdmVudChldmVudCk7XG4gICAgICAgIHNlYXJjaExpc3Q/LmFjdGl2YXRlUHJldmlvdXNJdGVtKCk7XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoY2hhclByZXNzZWQubGVuZ3RoICE9PSAxICYmIGV2ZW50LmtleUNvZGUgIT09IEtFWV9CQUNLU1BBQ0UpIHtcbiAgICAgIHRoaXMuc3RvcEV2ZW50KGV2ZW50KTtcblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc2VhcmNoaW5nKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IG1lbnRpb24gPSB2YWwuc3Vic3RyaW5nKCh0aGlzLnN0YXJ0UG9zKCkgfHwgMCkgKyAxLCBwb3MpO1xuXG4gICAgaWYgKGV2ZW50LmtleUNvZGUgIT09IEtFWV9CQUNLU1BBQ0UgJiYgIWV2ZW50LmlucHV0RXZlbnQpIHtcbiAgICAgIG1lbnRpb24gKz0gY2hhclByZXNzZWQ7XG4gICAgfVxuICAgIGNvbnN0IHNlYXJjaFN0cmluZyA9IG1lbnRpb24ucmVwbGFjZShTdHJpbmcuZnJvbUNoYXJDb2RlKDE2MCksICcgJykucmVwbGFjZShTdHJpbmcuZnJvbUNoYXJDb2RlKDApLCAnJyk7XG4gICAgdGhpcy5zZWFyY2hTdHJpbmcuc2V0KHNlYXJjaFN0cmluZy50cmltKCkpO1xuICAgIGNvbnN0IGxpbWl0U3BhY2VTZWFyY2hRdWVyeSA9IHRoaXMuYWN0aXZlQ29uZmlnKCk/LmxpbWl0U3BhY2VTZWFyY2hRdWVyeTtcbiAgICBpZiAobGltaXRTcGFjZVNlYXJjaFF1ZXJ5ICYmIChzZWFyY2hTdHJpbmcuc3BsaXQoJyAnKS5sZW5ndGggLSAxKSA+IGxpbWl0U3BhY2VTZWFyY2hRdWVyeSkge1xuICAgICAgdGhpcy5zZWFyY2hTdHJpbmcuc2V0KCcnKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuYWN0aXZlQ29uZmlnKCk/LnJldHVyblRyaWdnZXIpIHtcbiAgICAgIGNvbnN0IHRyaWdnZXJDaGFyID0gKHRoaXMuc2VhcmNoU3RyaW5nKCkgfHwgZXZlbnQua2V5Q29kZSA9PT0gS0VZX0JBQ0tTUEFDRSkgPyB2YWwuc3Vic3RyaW5nKHRoaXMuc3RhcnRQb3MoKSwgKHRoaXMuc3RhcnRQb3MoKSB8fCAwKSArIDEpIDogJyc7XG5cbiAgICAgIHRoaXMub3V0U2VhcmNoVGVybS5lbWl0KHRyaWdnZXJDaGFyICsgdGhpcy5zZWFyY2hTdHJpbmcoKSk7XG4gICAgICB0aGlzLnVwZGF0ZVNlYXJjaExpc3QoKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLm91dFNlYXJjaFRlcm0uZW1pdCh0aGlzLnNlYXJjaFN0cmluZygpKTtcbiAgICB0aGlzLnVwZGF0ZVNlYXJjaExpc3QoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVyRm9jdXMoZT86IEV2ZW50LCBuYXRpdmVFbGVtZW50OiBIVE1MSW5wdXRFbGVtZW50ID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQpIHtcbiAgICBlPy5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNvbnN0IG5vZGUgPSBnZXRXaW5kb3dTZWxlY3Rpb24odGhpcy5pZnJhbWUoKSk/LmFuY2hvck5vZGU7XG5cbiAgICAgIGlmIChub2RlPy5ub2RlVHlwZSAhPT0gMykge1xuICAgICAgICB0aGlzLnN0b3BTZWFyY2goKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCB0ZXh0QmVmb3JlQ3Vyc29yID0gZ2V0VGV4dEJlZm9yZUN1cnNvcigpIHx8ICcnO1xuXG4gICAgICBjb25zdCB0cmlnZ2VyQ2hhcnMgPSBPYmplY3Qua2V5cyh0aGlzLnRyaWdnZXJDaGFycygpKS5tYXAoKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgY29uZmlnOiB0aGlzLnRyaWdnZXJDaGFycygpW2tleV0sXG4gICAgICAgICAgaW5kZXg6IHRleHRCZWZvcmVDdXJzb3IubGFzdEluZGV4T2Yoa2V5KSBhcyBudW1iZXJcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgbWF0Y2hpbmdDaGFyYWN0ZXJzID0gdHJpZ2dlckNoYXJzLnJlZHVjZSgocHJlLCBjdXJyZW50KSA9PiBwcmUgJiYgY3VycmVudCAmJiBjdXJyZW50LmluZGV4ID4gcHJlLmluZGV4ID8gY3VycmVudCA6IHByZSk7XG5cbiAgICAgIGlmIChtYXRjaGluZ0NoYXJhY3RlcnMuaW5kZXggPCAwKSB7XG4gICAgICAgIHRoaXMuc3RvcFNlYXJjaCgpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHNlYXJjaCA9IHRleHRCZWZvcmVDdXJzb3I/LnN1YnN0cmluZyhtYXRjaGluZ0NoYXJhY3RlcnMuaW5kZXgsIHRleHRCZWZvcmVDdXJzb3IubGVuZ3RoKTtcblxuICAgICAgaWYgKCFzZWFyY2gpIHtcbiAgICAgICAgdGhpcy5zdG9wU2VhcmNoKCk7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgcG9zID0gZ2V0Q2FyZXRQb3NpdGlvbihuYXRpdmVFbGVtZW50LCB0aGlzLmlmcmFtZSgpKTtcblxuICAgICAgdGhpcy5hY3RpdmVDb25maWcuc2V0KG1hdGNoaW5nQ2hhcmFjdGVycy5jb25maWcpO1xuICAgICAgdGhpcy5zdGFydFBvcy5zZXQocG9zIC0gKHRleHRCZWZvcmVDdXJzb3IubGVuZ3RoIC0gbWF0Y2hpbmdDaGFyYWN0ZXJzLmluZGV4KSk7XG4gICAgICB0aGlzLnNlYXJjaFN0cmluZy5zZXQoc2VhcmNoLnJlcGxhY2UobWF0Y2hpbmdDaGFyYWN0ZXJzLmtleSwgJycpKTtcbiAgICAgIHRoaXMuc2VhcmNoaW5nLnNldCh0cnVlKTtcbiAgICAgIHRoaXMuaGFuZGxlcktleWRvd24oeyBrZXlDb2RlOiAnJy5jaGFyQ29kZUF0KDApLCBpbnB1dEV2ZW50OiBmYWxzZSB9LCBuYXRpdmVFbGVtZW50KTtcbiAgICAgIGNvbnN0IGRpdkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXG4gICAgICBkaXZFbGVtZW50LnN0eWxlLndpZHRoID0gJ21heC1jb250ZW50JztcbiAgICAgIGRpdkVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgZGl2RWxlbWVudC5pbm5lclRleHQgPSBzZWFyY2g7XG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGRpdkVsZW1lbnQpO1xuICAgICAgbGV0IGlmcmFtZSA9IHVuZGVmaW5lZDtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmcmFtZSA9IHRoaXMubWVudGlvbkNvbmZpZygpPy5pZnJhbWUgPyAod2luZG93LnBhcmVudC5kb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLm1lbnRpb25Db25maWcoKT8uaWZyYW1lIGFzIHN0cmluZykgYXMgSFRNTElGcmFtZUVsZW1lbnQpIDogdW5kZWZpbmVkO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAgfVxuICAgICAgY29uc3Qgc2VhcmNoTGlzdCA9IHRoaXMuc2VhcmNoTGlzdCgpO1xuICAgICAgaWYgKHNlYXJjaExpc3QpIHtcbiAgICAgICAgc2VhcmNoTGlzdC5wb3NpdGlvbihuYXRpdmVFbGVtZW50LCBpZnJhbWUsIGRpdkVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGgpXG4gICAgICB9XG4gICAgICBkaXZFbGVtZW50LnJlbW92ZSgpO1xuICAgICAgbmF0aXZlRWxlbWVudC5ub3JtYWxpemUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RvcFNlYXJjaCgpIHtcbiAgICBjb25zdCBzZWFyY2hMaXN0ID0gdGhpcy5zZWFyY2hMaXN0KCk7XG4gICAgaWYgKHNlYXJjaExpc3QgJiYgIXNlYXJjaExpc3QuaGlkZGVuKCkpIHtcbiAgICAgIHNlYXJjaExpc3QuaGlkZGVuLnNldCh0cnVlKTtcbiAgICAgIHRoaXMub3V0VG9nZ2xlLmVtaXQoZmFsc2UpO1xuICAgIH1cbiAgICB0aGlzLmFjdGl2ZUNvbmZpZy5zZXQodW5kZWZpbmVkKTtcbiAgICB0aGlzLnNlYXJjaGluZy5zZXQoZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVTZWFyY2hMaXN0KCkge1xuICAgIGNvbnN0IG1hdGNoZXM6IGFueVtdID0gW107XG4gICAgY29uc3QgYWN0aXZlQ29uZmlnID0gdGhpcy5hY3RpdmVDb25maWcoKTtcbiAgICBjb25zdCBzZWFyY2hTdHJpbmcgPSB0aGlzLnNlYXJjaFN0cmluZygpO1xuICAgIGNvbnN0IHNlYXJjaExpc3QgPSB0aGlzLnNlYXJjaExpc3QoKTtcbiAgICAvLyBkaXNhYmxpbmcgdGhlIHNlYXJjaCByZWxpZXMgb24gdGhlIGFzeW5jIG9wZXJhdGlvbiB0byBkbyB0aGUgZmlsdGVyaW5nXG4gICAgaWYgKGFjdGl2ZUNvbmZpZyAmJiBhY3RpdmVDb25maWcuaXRlbXMgJiYgIWFjdGl2ZUNvbmZpZy5kaXNhYmxlU2VhcmNoICYmICFpc05pbChzZWFyY2hTdHJpbmcpICYmIGFjdGl2ZUNvbmZpZy5sYWJlbEtleSAmJiBhY3RpdmVDb25maWcubWVudGlvbkZpbHRlcikge1xuICAgICAgbWF0Y2hlcy5wdXNoKC4uLmFjdGl2ZUNvbmZpZy5tZW50aW9uRmlsdGVyKHNlYXJjaFN0cmluZywgYWN0aXZlQ29uZmlnLml0ZW1zKSBhcyBhbnkpO1xuICAgIH1cbiAgICAvLyB1cGRhdGUgdGhlIHNlYXJjaCBsaXN0XG4gICAgaWYgKCFzZWFyY2hMaXN0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHNlYXJjaExpc3QuaXRlbXMuc2V0KG1hdGNoZXMpO1xuICAgIHNlYXJjaExpc3QuaGlkZGVuLnNldCghbWF0Y2hlcy5sZW5ndGgpO1xuICAgIHNlYXJjaExpc3QuYWN0aXZlSW5kZXguc2V0KDApO1xuICAgIHNlYXJjaExpc3Quc2Nyb2xsQ29udGVudCgpO1xuICAgIHRoaXMub3V0VG9nZ2xlLmVtaXQobWF0Y2hlcy5sZW5ndGggPyB0cnVlIDogZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBzaG93U2VhcmNoTGlzdChuYXRpdmVFbGVtZW50OiBIVE1MSW5wdXRFbGVtZW50KSB7XG4gICAgbGV0IGlmcmFtZSA9IHVuZGVmaW5lZDtcbiAgICBjb25zdCBtZW50aW9uQ29uZmlnID0gdGhpcy5tZW50aW9uQ29uZmlnKCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmcmFtZSA9IG1lbnRpb25Db25maWc/LmlmcmFtZSA/IHdpbmRvdy5wYXJlbnQuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQobWVudGlvbkNvbmZpZz8uaWZyYW1lIGFzIHN0cmluZykgYXMgSFRNTElGcmFtZUVsZW1lbnQgOiB1bmRlZmluZWQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICB9XG4gICAgaWYgKCFtZW50aW9uQ29uZmlnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMub3V0VG9nZ2xlLmVtaXQodHJ1ZSk7XG4gICAgbGV0IGZpcnN0VGltZSA9IGZhbHNlO1xuXG4gICAgaWYgKCF0aGlzLmxpc3RDb21wb25lbnRSZWYoKSkge1xuICAgICAgZmlyc3RUaW1lID0gdHJ1ZTtcbiAgICAgIHRoaXMubGlzdENvbXBvbmVudFJlZi5zZXQodGhpcy5keW5hbWljQ29tcG9uZW50U2VydmljZS5yZXNvbHZlQ29tcG9uZW50RmFjdG9yeShMaWJzVWlDb21wb25lbnRzSW5wdXRzTWVudGlvbkxpc3RDb21wb25lbnQpKTtcbiAgICAgIHRoaXMuc2VhcmNoTGlzdC5zZXQodGhpcy5saXN0Q29tcG9uZW50UmVmKCk/Lmluc3RhbmNlKTtcbiAgICB9XG4gICAgdGhpcy5zZWFyY2hMaXN0KCk/LmxhYmVsS2V5LnNldCh0aGlzLmFjdGl2ZUNvbmZpZygpPy5sYWJlbEtleSB8fCAnJyk7XG4gICAgdGhpcy5zZWFyY2hMaXN0KCk/LnN0eWxlT2ZmLnNldCh0aGlzLm1lbnRpb25Db25maWcoKT8uZGlzYWJsZVN0eWxlIHx8IGZhbHNlKTtcbiAgICB0aGlzLnNlYXJjaExpc3QoKT8uYWN0aXZlSW5kZXguc2V0KDApO1xuICAgIHRoaXMuc2VhcmNoTGlzdCgpPy56SW5kZXguc2V0KHRoaXMubWVudGlvbkNvbmZpZygpPy56SW5kZXggfHwgMjUwMCk7XG4gICAgdGhpcy5zZWFyY2hMaXN0KCk/LmlzSWZyYW1lLnNldChpZnJhbWUgPyB0cnVlIDogZmFsc2UpO1xuICAgIHRoaXMuc2VhcmNoTGlzdCgpPy5wYXJlbnRIYW5kbGVyS2V5RG93bi5zZXQodGhpcy5oYW5kbGVyS2V5ZG93bi5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLnNlYXJjaExpc3QoKT8ucG9zaXRpb24obmF0aXZlRWxlbWVudCwgaWZyYW1lKTtcbiAgICBpZiAoZmlyc3RUaW1lICYmIHRoaXMubGlzdENvbXBvbmVudFJlZigpKSB7XG4gICAgICB0aGlzLmlmcmFtZUlkLnNldCh0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLmFkZFRvQm9keSh0aGlzLmxpc3RDb21wb25lbnRSZWYoKSwgaWZyYW1lID8gdHJ1ZSA6IGZhbHNlKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZXN0cm95TGlzdFNlYXJjaCgpIHtcbiAgICB0aGlzLmR5bmFtaWNDb21wb25lbnRTZXJ2aWNlLnJlbW92ZSh0aGlzLmxpc3RDb21wb25lbnRSZWYsIHRoaXMuaWZyYW1lSWQoKSk7XG4gICAgdGhpcy5saXN0Q29tcG9uZW50UmVmLnNldCh1bmRlZmluZWQpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFwcGVuZEVtcHR5VG9MYXN0Tm9kZShwb3NpdGlvbjogbnVtYmVyLCBsZW5ndGg6IG51bWJlciwgbmF0aXZlRWxlbWVudDogSFRNTElucHV0RWxlbWVudCA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50KSB7XG4gICAgY29uc3QgZW1wdHkgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnXFx1MDBBMCcpO1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IGdldFdpbmRvd1NlbGVjdGlvbih0aGlzLmlmcmFtZSgpKTtcbiAgICBjb25zdCBhbmNob3JOb2RlID0gc2VsZWN0aW9uPy5hbmNob3JOb2RlO1xuXG4gICAgaWYgKHRoaXMuaXNFZGl0b3IoKSkge1xuICAgICAgY29uc3QgcGFyZW50Tm9kZSA9IGFuY2hvck5vZGU/LnBhcmVudE5vZGUgYXMgRWxlbWVudDtcblxuICAgICAgaWYgKHBhcmVudE5vZGUgJiYgcGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGUgJiYgcGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGUoJ2lkJykpIHtcbiAgICAgICAgaWYgKCFwYXJlbnROb2RlLm5leHRTaWJsaW5nIHx8ICFwYXJlbnROb2RlLm5leHRTaWJsaW5nLnRleHRDb250ZW50Py5sZW5ndGgpIHtcbiAgICAgICAgICBwYXJlbnROb2RlPy5wYXJlbnROb2RlPy5pbnNlcnRCZWZvcmUoZW1wdHksIHBhcmVudE5vZGUubmV4dFNpYmxpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgICAgY29uc3Qgc2VsID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuXG4gICAgICAgIHJhbmdlLnNldFN0YXJ0KHBhcmVudE5vZGUubmV4dFNpYmxpbmcgYXMgTm9kZSwgMCk7XG4gICAgICAgIHJhbmdlLmNvbGxhcHNlKHRydWUpO1xuICAgICAgICBzZWw/LnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgICBzZWw/LmFkZFJhbmdlKHJhbmdlKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgcHJlTm9kZSA9IG51bGw7XG4gICAgY29uc3QgYW5jaG9yT2Zmc2V0ID0gc2VsZWN0aW9uPy5hbmNob3JPZmZzZXQ7XG5cbiAgICBpZiAoIWFuY2hvck5vZGUgfHwgIWFuY2hvck9mZnNldCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChhbmNob3JOb2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgIT09ICcjdGV4dCcpIHtcbiAgICAgIG5hdGl2ZUVsZW1lbnQuYXBwZW5kQ2hpbGQoZW1wdHkpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYXRpdmVFbGVtZW50LmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5vZGUgPSBuYXRpdmVFbGVtZW50LmNoaWxkTm9kZXNbaV07XG5cbiAgICAgIGlmIChhbmNob3JOb2RlLm5vZGVUeXBlID09PSAzICYmIGFuY2hvck5vZGUgPT09IG5vZGUgJiYgcHJlTm9kZSAmJiBwcmVOb2RlLmdldEF0dHJpYnV0ZSAmJiBwcmVOb2RlLmdldEF0dHJpYnV0ZSgnaWQnKSAmJiAoIWFuY2hvck5vZGUudGV4dENvbnRlbnQ/Lmxlbmd0aCB8fCBhbmNob3JOb2RlLnRleHRDb250ZW50Lmxlbmd0aCA9PT0gMSkgJiYgcG9zaXRpb24gPT09IGxlbmd0aCkge1xuICAgICAgICBuYXRpdmVFbGVtZW50LmFwcGVuZENoaWxkKGVtcHR5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBwcmVOb2RlID0gbm9kZSBhcyBFbGVtZW50O1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhZGROb2RlWmVyb1dpZHRoU3BhY2UobmF0aXZlRWxlbWVudDogSFRNTElucHV0RWxlbWVudCA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50KSB7XG4gICAgY29uc3QgZW1wdHkgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnXFx1MjAwYicpO1xuICAgIGxldCBwcmVOb2RlID0gbnVsbDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmF0aXZlRWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub2RlOiBhbnkgPSBuYXRpdmVFbGVtZW50LmNoaWxkTm9kZXNbaV07XG5cbiAgICAgIGlmIChwcmVOb2RlICYmIHByZU5vZGUuZ2V0QXR0cmlidXRlICYmIHByZU5vZGUuZ2V0QXR0cmlidXRlKCdpZCcpICYmIG5vZGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoJ2lkJykpIHtcbiAgICAgICAgbmF0aXZlRWxlbWVudC5pbnNlcnRCZWZvcmUoZW1wdHksIHByZU5vZGUubmV4dFNpYmxpbmcpO1xuICAgICAgfVxuXG4gICAgICBwcmVOb2RlID0gbm9kZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluc2VydE1lbnRpb24obmF0aXZlRWxlbWVudDogSFRNTElucHV0RWxlbWVudCwgcG9zOiBudW1iZXIpIHtcbiAgICBjb25zdCBhY3RpdmVDb25maWcgPSB0aGlzLmFjdGl2ZUNvbmZpZygpO1xuICAgIGlmICghYWN0aXZlQ29uZmlnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHNlYXJjaExpc3QgPSB0aGlzLnNlYXJjaExpc3QoKTtcbiAgICBsZXQgdGV4dCA9ICcnO1xuICAgIGNvbnN0IGZlSWQgPSB1dWlkKCk7XG4gICAgY29uc3QgaWQgPSBzZWFyY2hMaXN0Py5BY3RpdmVJdGVtLmlkIHx8IHV1aWQoKTtcbiAgICBjb25zdCBpdGVtQWN0aXZlID0gc2VhcmNoTGlzdD8uQWN0aXZlSXRlbTtcbiAgICBjb25zdCB7IHRyaWdnZXJDaGFyLCBtZW50aW9uRXZlbnROYW1lLCBtZW50aW9uQWN0aW9uQnlFdmVudCB9ID0gYWN0aXZlQ29uZmlnO1xuXG4gICAgaWYgKGFjdGl2ZUNvbmZpZy5tZW50aW9uU2VsZWN0KSB7XG4gICAgICB0ZXh0ID0gYWN0aXZlQ29uZmlnLm1lbnRpb25TZWxlY3Qoc2VhcmNoTGlzdD8uQWN0aXZlSXRlbSwgYWN0aXZlQ29uZmlnLnRyaWdnZXJDaGFyKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmlzRWRpdG9yKCkpIHtcbiAgICAgIGxldCBzcGFuOiBIVE1MU3BhbkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdURVhUQVJFQScpO1xuXG4gICAgICBzcGFuLmlubmVyVGV4dCA9IHRleHQ7XG4gICAgICB0ZXh0ID0gc3Bhbi5pbm5lckhUTUw7XG4gICAgICBzcGFuLnJlbW92ZSgpO1xuICAgICAgdGV4dCA9IGJ1aWxkVGVtcGxhdGUodGV4dCwgaWQsIGZlSWQpO1xuICAgICAgc3BhbiA9IGluc2VydFZhbHVlKG5hdGl2ZUVsZW1lbnQsIHRoaXMuc3RhcnRQb3MoKSB8fCAwLCBwb3MsIHRleHQsIHRoaXMuaWZyYW1lKCkpIGFzIEhUTUxTcGFuRWxlbWVudDtcbiAgICAgIGlmIChzcGFuKSB7XG4gICAgICAgIGNvbnN0IGRhdGE6IElOb2RlSW5zZXJ0ID0ge1xuICAgICAgICAgIGVsZW1lbnRTcGFuOiBzcGFuLFxuICAgICAgICAgIHN1YnNjcmlwdGlvbjogdW5kZWZpbmVkLFxuICAgICAgICAgIGl0ZW06IGl0ZW1BY3RpdmUsXG4gICAgICAgICAgdHJpZ2dlckNoYXI6IHRyaWdnZXJDaGFyLFxuICAgICAgICAgIG1hbnVhbEFkZDogdHJ1ZVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMubm9kZXNJbnNlcnQoKS5hZGQoZGF0YSk7XG4gICAgICAgIGlmIChtZW50aW9uRXZlbnROYW1lKSB7XG4gICAgICAgICAgZGF0YS5zdWJzY3JpcHRpb24gPSBmcm9tRXZlbnQ8SUV2ZW50PihzcGFuLCBtZW50aW9uRXZlbnROYW1lKS5waXBlKFxuICAgICAgICAgICAgdGFwKGUgPT4gZS5zdG9wUHJvcGFnYXRpb24oKSksXG4gICAgICAgICAgICB0YWtlVW50aWwodGhpcy5vbkRlc3Ryb3kpXG4gICAgICAgICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKG1lbnRpb25BY3Rpb25CeUV2ZW50KSB7XG4gICAgICAgICAgICAgIG1lbnRpb25BY3Rpb25CeUV2ZW50KGl0ZW1BY3RpdmUsIHRyaWdnZXJDaGFyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMub3V0SW5zZXJ0TWVudGlvbi5lbWl0KHsgZGF0YTogeyBpZCwgdmFsdWU6IHRleHQsIGZlSWQgfSwgbGVuZ3RoS2V5OiBwb3MgLSAodGhpcy5zdGFydFBvcygpIHx8IDApIH0pO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveUxpc3RTZWFyY2goKTtcbiAgICB0aGlzLm9uRGVzdHJveS5uZXh0KCk7XG4gICAgdGhpcy5vbkRlc3Ryb3kuY29tcGxldGUoKTtcbiAgfVxufVxuIl19