@textbus/collaborate 3.0.0-alpha.4 → 3.0.0-alpha.44

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,713 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- var __metadata = (this && this.__metadata) || function (k, v) {
8
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
- };
10
- var __param = (this && this.__param) || function (paramIndex, decorator) {
11
- return function (target, key) { decorator(target, key, paramIndex); }
12
- };
13
- import { Inject, Injectable } from '@tanbo/di';
14
- import { delay, filter, map, Subject } from '@tanbo/stream';
15
- import { ChangeOrigin, ContentType, Controller, Factory, HISTORY_STACK_SIZE, makeError, RootComponentRef, Scheduler, Selection, Slot, Starter } from '@textbus/core';
16
- import { Array as YArray, Doc as YDoc, Map as YMap, Text as YText, UndoManager, createAbsolutePositionFromRelativePosition, createRelativePositionFromTypeIndex } from 'yjs';
17
- import { CollaborateCursor } from './collaborate-cursor';
18
- import { createUnknownComponent } from './unknown.component';
19
- const collaborateErrorFn = makeError('Collaborate');
20
- class ContentMap {
21
- constructor() {
22
- this.slotAndYTextMap = new WeakMap();
23
- this.yTextAndSLotMap = new WeakMap();
24
- }
25
- set(key, value) {
26
- if (key instanceof Slot) {
27
- this.slotAndYTextMap.set(key, value);
28
- this.yTextAndSLotMap.set(value, key);
29
- }
30
- else {
31
- this.slotAndYTextMap.set(value, key);
32
- this.yTextAndSLotMap.set(key, value);
33
- }
34
- }
35
- get(key) {
36
- if (key instanceof Slot) {
37
- return this.slotAndYTextMap.get(key) || null;
38
- }
39
- return this.yTextAndSLotMap.get(key) || null;
40
- }
41
- delete(key) {
42
- if (key instanceof Slot) {
43
- const v = this.slotAndYTextMap.get(key);
44
- this.slotAndYTextMap.delete(key);
45
- if (v) {
46
- this.yTextAndSLotMap.delete(v);
47
- }
48
- }
49
- else {
50
- const v = this.yTextAndSLotMap.get(key);
51
- this.yTextAndSLotMap.delete(key);
52
- if (v) {
53
- this.slotAndYTextMap.delete(v);
54
- }
55
- }
56
- }
57
- }
58
- let Collaborate = class Collaborate {
59
- constructor(stackSize, rootComponentRef, collaborateCursor, controller, scheduler, factory, selection, starter) {
60
- this.stackSize = stackSize;
61
- this.rootComponentRef = rootComponentRef;
62
- this.collaborateCursor = collaborateCursor;
63
- this.controller = controller;
64
- this.scheduler = scheduler;
65
- this.factory = factory;
66
- this.selection = selection;
67
- this.starter = starter;
68
- this.yDoc = new YDoc();
69
- this.backEvent = new Subject();
70
- this.forwardEvent = new Subject();
71
- this.changeEvent = new Subject();
72
- this.pushEvent = new Subject();
73
- this.manager = null;
74
- this.subscriptions = [];
75
- this.updateFromRemote = false;
76
- this.contentSyncCaches = new WeakMap();
77
- this.slotStateSyncCaches = new WeakMap();
78
- this.slotsSyncCaches = new WeakMap();
79
- this.componentStateSyncCaches = new WeakMap();
80
- this.selectionChangeEvent = new Subject();
81
- this.contentMap = new ContentMap();
82
- this.updateRemoteActions = [];
83
- this.noRecord = {};
84
- this.onSelectionChange = this.selectionChangeEvent.asObservable().pipe(delay());
85
- this.onBack = this.backEvent.asObservable();
86
- this.onForward = this.forwardEvent.asObservable();
87
- this.onChange = this.changeEvent.asObservable();
88
- this.onPush = this.pushEvent.asObservable();
89
- }
90
- get canBack() {
91
- var _a;
92
- return ((_a = this.manager) === null || _a === void 0 ? void 0 : _a.canUndo()) || false;
93
- }
94
- get canForward() {
95
- var _a;
96
- return ((_a = this.manager) === null || _a === void 0 ? void 0 : _a.canRedo()) || false;
97
- }
98
- listen() {
99
- const root = this.yDoc.getMap('RootComponent');
100
- const rootComponent = this.rootComponentRef.component;
101
- this.manager = new UndoManager(root, {
102
- trackedOrigins: new Set([this.yDoc])
103
- });
104
- const cursorKey = 'cursor-position';
105
- this.manager.on('stack-item-added', event => {
106
- event.stackItem.meta.set(cursorKey, this.getRelativeCursorLocation());
107
- if (this.manager.undoStack.length > this.stackSize) {
108
- this.manager.undoStack.shift();
109
- }
110
- if (event.origin === this.yDoc) {
111
- this.pushEvent.next();
112
- }
113
- this.changeEvent.next();
114
- });
115
- this.manager.on('stack-item-popped', event => {
116
- const position = event.stackItem.meta.get(cursorKey);
117
- if (position) {
118
- this.restoreCursorLocation(position);
119
- }
120
- });
121
- this.subscriptions.push(this.selection.onChange.subscribe(() => {
122
- const paths = this.selection.getPaths();
123
- this.selectionChangeEvent.next(paths);
124
- }), this.scheduler.onDocChanged.pipe(map(item => {
125
- return item.filter(i => {
126
- return i.from !== ChangeOrigin.Remote;
127
- });
128
- }), filter(item => {
129
- return item.length;
130
- })).subscribe(() => {
131
- const updates = [];
132
- let update = null;
133
- for (const item of this.updateRemoteActions) {
134
- if (!update) {
135
- update = {
136
- record: item.record,
137
- actions: []
138
- };
139
- updates.push(update);
140
- }
141
- if (update.record === item.record) {
142
- update.actions.push(item.action);
143
- }
144
- else {
145
- update = {
146
- record: item.record,
147
- actions: [item.action]
148
- };
149
- updates.push(update);
150
- }
151
- }
152
- this.updateRemoteActions = [];
153
- for (const item of updates) {
154
- this.yDoc.transact(() => {
155
- item.actions.forEach(fn => {
156
- fn();
157
- });
158
- }, item.record ? this.yDoc : this.noRecord);
159
- }
160
- }));
161
- this.syncRootComponent(root, rootComponent);
162
- }
163
- updateRemoteSelection(paths) {
164
- this.collaborateCursor.draw(paths);
165
- }
166
- back() {
167
- var _a;
168
- if (this.canBack) {
169
- (_a = this.manager) === null || _a === void 0 ? void 0 : _a.undo();
170
- this.backEvent.next();
171
- }
172
- }
173
- forward() {
174
- var _a;
175
- if (this.canForward) {
176
- (_a = this.manager) === null || _a === void 0 ? void 0 : _a.redo();
177
- this.forwardEvent.next();
178
- }
179
- }
180
- clear() {
181
- var _a;
182
- (_a = this.manager) === null || _a === void 0 ? void 0 : _a.clear();
183
- this.changeEvent.next();
184
- }
185
- destroy() {
186
- var _a;
187
- this.subscriptions.forEach(i => i.unsubscribe());
188
- this.collaborateCursor.destroy();
189
- (_a = this.manager) === null || _a === void 0 ? void 0 : _a.destroy();
190
- }
191
- syncRootComponent(root, rootComponent) {
192
- let slots = root.get('slots');
193
- if (!slots) {
194
- slots = new YArray();
195
- rootComponent.slots.toArray().forEach(i => {
196
- const sharedSlot = this.createSharedSlotBySlot(i);
197
- slots.push([sharedSlot]);
198
- });
199
- this.yDoc.transact(() => {
200
- root.set('state', rootComponent.state);
201
- root.set('slots', slots);
202
- });
203
- }
204
- else if (slots.length === 0) {
205
- rootComponent.updateState(() => {
206
- return root.get('state');
207
- });
208
- this.yDoc.transact(() => {
209
- rootComponent.slots.toArray().forEach(i => {
210
- const sharedSlot = this.createSharedSlotBySlot(i);
211
- slots.push([sharedSlot]);
212
- });
213
- });
214
- }
215
- else {
216
- rootComponent.updateState(() => {
217
- return root.get('state');
218
- });
219
- rootComponent.slots.clean();
220
- slots.forEach(sharedSlot => {
221
- const slot = this.createSlotBySharedSlot(sharedSlot);
222
- this.syncSlotContent(sharedSlot.get('content'), slot);
223
- this.syncSlotState(sharedSlot, slot);
224
- rootComponent.slots.insert(slot);
225
- });
226
- }
227
- this.syncComponentState(root, rootComponent);
228
- this.syncComponentSlots(slots, rootComponent);
229
- }
230
- restoreCursorLocation(position) {
231
- const anchorPosition = createAbsolutePositionFromRelativePosition(position.anchor, this.yDoc);
232
- const focusPosition = createAbsolutePositionFromRelativePosition(position.focus, this.yDoc);
233
- if (anchorPosition && focusPosition) {
234
- const focusSlot = this.contentMap.get(focusPosition.type);
235
- const anchorSlot = this.contentMap.get(anchorPosition.type);
236
- if (focusSlot && anchorSlot) {
237
- this.selection.setBaseAndExtent(anchorSlot, anchorPosition.index, focusSlot, focusPosition.index);
238
- return;
239
- }
240
- }
241
- this.selection.unSelect();
242
- }
243
- getRelativeCursorLocation() {
244
- const { anchorSlot, anchorOffset, focusSlot, focusOffset } = this.selection;
245
- if (anchorSlot) {
246
- const anchorYText = this.contentMap.get(anchorSlot);
247
- if (anchorYText) {
248
- const anchorPosition = createRelativePositionFromTypeIndex(anchorYText, anchorOffset);
249
- if (focusSlot) {
250
- const focusYText = this.contentMap.get(focusSlot);
251
- if (focusYText) {
252
- const focusPosition = createRelativePositionFromTypeIndex(focusYText, focusOffset);
253
- return {
254
- focus: focusPosition,
255
- anchor: anchorPosition
256
- };
257
- }
258
- }
259
- }
260
- }
261
- return null;
262
- }
263
- syncSlotContent(content, slot) {
264
- this.contentMap.set(slot, content);
265
- const syncRemote = (ev, tr) => {
266
- this.runRemoteUpdate(tr, () => {
267
- slot.retain(0);
268
- ev.keysChanged.forEach(key => {
269
- const updateType = ev.keys.get(key).action;
270
- if (updateType === 'update' || updateType === 'add') {
271
- const attribute = this.factory.getAttribute(key);
272
- if (attribute) {
273
- slot.setAttribute(attribute, content.getAttribute(key));
274
- }
275
- }
276
- else if (updateType === 'delete') {
277
- const attribute = this.factory.getAttribute(key);
278
- if (attribute) {
279
- slot.removeAttribute(attribute);
280
- }
281
- }
282
- });
283
- ev.delta.forEach(action => {
284
- if (Reflect.has(action, 'retain')) {
285
- if (action.attributes) {
286
- const formats = remoteFormatsToLocal(this.factory, action.attributes);
287
- if (formats.length) {
288
- slot.retain(action.retain, formats);
289
- }
290
- slot.retain(slot.index + action.retain);
291
- }
292
- else {
293
- slot.retain(action.retain);
294
- }
295
- }
296
- else if (action.insert) {
297
- const index = slot.index;
298
- let length = 1;
299
- if (typeof action.insert === 'string') {
300
- length = action.insert.length;
301
- slot.insert(action.insert, remoteFormatsToLocal(this.factory, action.attributes));
302
- }
303
- else {
304
- const sharedComponent = action.insert;
305
- const canInsertInlineComponent = slot.schema.includes(ContentType.InlineComponent);
306
- const component = this.createComponentBySharedComponent(sharedComponent, canInsertInlineComponent);
307
- this.syncComponentSlots(sharedComponent.get('slots'), component);
308
- this.syncComponentState(sharedComponent, component);
309
- slot.insert(component);
310
- }
311
- if (this.selection.isSelected) {
312
- if (slot === this.selection.anchorSlot && this.selection.anchorOffset > index) {
313
- this.selection.setAnchor(slot, this.selection.anchorOffset + length);
314
- }
315
- if (slot === this.selection.focusSlot && this.selection.focusOffset > index) {
316
- this.selection.setFocus(slot, this.selection.focusOffset + length);
317
- }
318
- }
319
- }
320
- else if (action.delete) {
321
- const index = slot.index;
322
- slot.retain(slot.index);
323
- slot.delete(action.delete);
324
- if (this.selection.isSelected) {
325
- if (slot === this.selection.anchorSlot && this.selection.anchorOffset >= index) {
326
- this.selection.setAnchor(slot, this.selection.startOffset - action.delete);
327
- }
328
- if (slot === this.selection.focusSlot && this.selection.focusOffset >= index) {
329
- this.selection.setFocus(slot, this.selection.focusOffset - action.delete);
330
- }
331
- }
332
- }
333
- });
334
- });
335
- };
336
- content.observe(syncRemote);
337
- const sub = slot.onContentChange.pipe(filter(() => {
338
- return !this.scheduler.ignoreChanges;
339
- })).subscribe(actions => {
340
- this.runLocalUpdate(() => {
341
- var _a;
342
- let offset = 0;
343
- let length = 0;
344
- for (const action of actions) {
345
- if (action.type === 'retain') {
346
- const formats = action.formats;
347
- if (formats) {
348
- const keys = Object.keys(formats);
349
- let length = keys.length;
350
- keys.forEach(key => {
351
- const formatter = this.factory.getFormatter(key);
352
- if (!formatter) {
353
- length--;
354
- Reflect.deleteProperty(formats, key);
355
- }
356
- });
357
- if (length) {
358
- content.format(offset, action.offset, formats);
359
- }
360
- }
361
- else {
362
- offset = action.offset;
363
- }
364
- }
365
- else if (action.type === 'insert') {
366
- const delta = content.toDelta();
367
- const isEmpty = delta.length === 1 && delta[0].insert === Slot.emptyPlaceholder;
368
- if (typeof action.content === 'string') {
369
- length = action.content.length;
370
- content.insert(offset, action.content, action.formats || {});
371
- }
372
- else {
373
- length = 1;
374
- const sharedComponent = this.createSharedComponentByComponent(action.ref);
375
- content.insertEmbed(offset, sharedComponent, action.formats || {});
376
- }
377
- if (isEmpty && offset === 0) {
378
- content.delete(content.length - 1, 1);
379
- }
380
- offset += length;
381
- }
382
- else if (action.type === 'delete') {
383
- const delta = content.toDelta();
384
- if (content.length) {
385
- content.delete(offset, action.count);
386
- }
387
- if (content.length === 0) {
388
- content.insert(0, '\n', (_a = delta[0]) === null || _a === void 0 ? void 0 : _a.attributes);
389
- }
390
- }
391
- else if (action.type === 'attrSet') {
392
- content.setAttribute(action.name, action.value);
393
- }
394
- else if (action.type === 'attrRemove') {
395
- content.removeAttribute(action.name);
396
- }
397
- }
398
- });
399
- });
400
- sub.add(slot.onChildComponentRemove.subscribe(components => {
401
- components.forEach(c => {
402
- this.cleanSubscriptionsByComponent(c);
403
- });
404
- }));
405
- this.contentSyncCaches.set(slot, () => {
406
- content.unobserve(syncRemote);
407
- sub.unsubscribe();
408
- });
409
- }
410
- syncSlotState(remoteSlot, slot) {
411
- const syncRemote = (ev, tr) => {
412
- this.runRemoteUpdate(tr, () => {
413
- ev.keysChanged.forEach(key => {
414
- if (key === 'state') {
415
- const state = ev.target.get('state');
416
- slot.updateState(draft => {
417
- if (typeof draft === 'object' && draft !== null) {
418
- Object.assign(draft, state);
419
- }
420
- else {
421
- return state;
422
- }
423
- });
424
- }
425
- });
426
- });
427
- };
428
- remoteSlot.observe(syncRemote);
429
- const sub = slot.onStateChange.pipe(filter(() => {
430
- return !this.scheduler.ignoreChanges;
431
- })).subscribe(change => {
432
- this.runLocalUpdate(() => {
433
- remoteSlot.set('state', change.newState);
434
- }, change.record);
435
- });
436
- this.slotStateSyncCaches.set(slot, () => {
437
- remoteSlot.unobserve(syncRemote);
438
- sub.unsubscribe();
439
- });
440
- }
441
- syncComponentSlots(remoteSlots, component) {
442
- const slots = component.slots;
443
- const syncRemote = (ev, tr) => {
444
- this.runRemoteUpdate(tr, () => {
445
- let index = 0;
446
- slots.retain(index);
447
- ev.delta.forEach(action => {
448
- if (Reflect.has(action, 'retain')) {
449
- index += action.retain;
450
- slots.retain(index);
451
- }
452
- else if (action.insert) {
453
- action.insert.forEach(item => {
454
- const slot = this.createSlotBySharedSlot(item);
455
- slots.insert(slot);
456
- this.syncSlotContent(item.get('content'), slot);
457
- this.syncSlotState(item, slot);
458
- index++;
459
- });
460
- }
461
- else if (action.delete) {
462
- slots.retain(index);
463
- slots.delete(action.delete);
464
- }
465
- });
466
- });
467
- };
468
- remoteSlots.observe(syncRemote);
469
- const sub = slots.onChange.pipe(filter(() => {
470
- return !this.scheduler.ignoreChanges;
471
- })).subscribe(operations => {
472
- this.runLocalUpdate(() => {
473
- const applyActions = operations.apply;
474
- let index;
475
- applyActions.forEach(action => {
476
- if (action.type === 'retain') {
477
- index = action.offset;
478
- }
479
- else if (action.type === 'insertSlot') {
480
- const sharedSlot = this.createSharedSlotBySlot(action.ref);
481
- remoteSlots.insert(index, [sharedSlot]);
482
- index++;
483
- }
484
- else if (action.type === 'delete') {
485
- remoteSlots.delete(index, action.count);
486
- }
487
- });
488
- });
489
- });
490
- sub.add(slots.onChildSlotRemove.subscribe(slots => {
491
- slots.forEach(slot => {
492
- this.cleanSubscriptionsBySlot(slot);
493
- });
494
- }));
495
- this.slotsSyncCaches.set(component, () => {
496
- remoteSlots.unobserve(syncRemote);
497
- sub.unsubscribe();
498
- });
499
- }
500
- syncComponentState(remoteComponent, component) {
501
- const syncRemote = (ev, tr) => {
502
- this.runRemoteUpdate(tr, () => {
503
- ev.keysChanged.forEach(key => {
504
- if (key === 'state') {
505
- const state = ev.target.get('state');
506
- component.updateState(draft => {
507
- if (typeof draft === 'object' && draft !== null) {
508
- Object.assign(draft, state);
509
- }
510
- else {
511
- return state;
512
- }
513
- });
514
- }
515
- });
516
- });
517
- };
518
- remoteComponent.observe(syncRemote);
519
- const sub = component.onStateChange.pipe(filter(() => {
520
- return !this.scheduler.ignoreChanges;
521
- })).subscribe(change => {
522
- this.runLocalUpdate(() => {
523
- remoteComponent.set('state', change.newState);
524
- }, change.record);
525
- });
526
- this.componentStateSyncCaches.set(component, () => {
527
- remoteComponent.unobserve(syncRemote);
528
- sub.unsubscribe();
529
- });
530
- }
531
- runLocalUpdate(fn, record = true) {
532
- if (this.updateFromRemote || this.controller.readonly) {
533
- return;
534
- }
535
- this.updateRemoteActions.push({
536
- record,
537
- action: fn
538
- });
539
- }
540
- runRemoteUpdate(tr, fn) {
541
- if (tr.origin === this.yDoc) {
542
- return;
543
- }
544
- this.updateFromRemote = true;
545
- if (tr.origin === this.manager) {
546
- this.scheduler.historyApplyTransact(fn);
547
- }
548
- else {
549
- this.scheduler.remoteUpdateTransact(fn);
550
- }
551
- this.updateFromRemote = false;
552
- }
553
- createSharedComponentByComponent(component) {
554
- const sharedComponent = new YMap();
555
- sharedComponent.set('state', component.state);
556
- sharedComponent.set('name', component.name);
557
- const sharedSlots = new YArray();
558
- sharedComponent.set('slots', sharedSlots);
559
- component.slots.toArray().forEach(slot => {
560
- const sharedSlot = this.createSharedSlotBySlot(slot);
561
- sharedSlots.push([sharedSlot]);
562
- });
563
- this.syncComponentSlots(sharedSlots, component);
564
- this.syncComponentState(sharedComponent, component);
565
- return sharedComponent;
566
- }
567
- createSharedSlotBySlot(slot) {
568
- const sharedSlot = new YMap();
569
- sharedSlot.set('schema', slot.schema);
570
- sharedSlot.set('state', slot.state);
571
- const sharedContent = new YText();
572
- sharedSlot.set('content', sharedContent);
573
- let offset = 0;
574
- slot.toDelta().forEach(i => {
575
- let formats = {};
576
- if (i.formats) {
577
- i.formats.forEach(item => {
578
- formats[item[0].name] = item[1];
579
- });
580
- }
581
- else {
582
- formats = null;
583
- }
584
- if (typeof i.insert === 'string') {
585
- sharedContent.insert(offset, i.insert, formats);
586
- }
587
- else {
588
- const sharedComponent = this.createSharedComponentByComponent(i.insert);
589
- sharedContent.insertEmbed(offset, sharedComponent, formats);
590
- }
591
- offset += i.insert.length;
592
- });
593
- slot.getAttributes().forEach(item => {
594
- sharedContent.setAttribute(item[0].name, item[1]);
595
- });
596
- this.syncSlotContent(sharedContent, slot);
597
- this.syncSlotState(sharedSlot, slot);
598
- return sharedSlot;
599
- }
600
- createComponentBySharedComponent(yMap, canInsertInlineComponent) {
601
- const sharedSlots = yMap.get('slots');
602
- const slots = [];
603
- sharedSlots.forEach(sharedSlot => {
604
- const slot = this.createSlotBySharedSlot(sharedSlot);
605
- slots.push(slot);
606
- });
607
- const name = yMap.get('name');
608
- const state = yMap.get('state');
609
- const instance = this.factory.createComponentByData(name, {
610
- state,
611
- slots
612
- });
613
- if (instance) {
614
- instance.slots.toArray().forEach((slot, index) => {
615
- let sharedSlot = sharedSlots.get(index);
616
- if (!sharedSlot) {
617
- sharedSlot = this.createSharedSlotBySlot(slot);
618
- sharedSlots.push([sharedSlot]);
619
- }
620
- this.syncSlotState(sharedSlot, slot);
621
- this.syncSlotContent(sharedSlot.get('content'), slot);
622
- });
623
- return instance;
624
- }
625
- return createUnknownComponent(name, canInsertInlineComponent).createInstance(this.starter);
626
- }
627
- createSlotBySharedSlot(sharedSlot) {
628
- const content = sharedSlot.get('content');
629
- const delta = content.toDelta();
630
- const slot = this.factory.createSlot({
631
- schema: sharedSlot.get('schema'),
632
- state: sharedSlot.get('state'),
633
- attributes: {},
634
- formats: {},
635
- content: []
636
- });
637
- const attrs = content.getAttributes();
638
- Object.keys(attrs).forEach(key => {
639
- const attribute = this.factory.getAttribute(key);
640
- if (attribute) {
641
- slot.setAttribute(attribute, attrs[key]);
642
- }
643
- });
644
- for (const action of delta) {
645
- if (action.insert) {
646
- if (typeof action.insert === 'string') {
647
- const formats = remoteFormatsToLocal(this.factory, action.attributes);
648
- slot.insert(action.insert, formats);
649
- }
650
- else {
651
- const sharedComponent = action.insert;
652
- const canInsertInlineComponent = slot.schema.includes(ContentType.InlineComponent);
653
- const component = this.createComponentBySharedComponent(sharedComponent, canInsertInlineComponent);
654
- slot.insert(component, remoteFormatsToLocal(this.factory, action.attributes));
655
- this.syncComponentSlots(sharedComponent.get('slots'), component);
656
- this.syncComponentState(sharedComponent, component);
657
- }
658
- }
659
- else {
660
- throw collaborateErrorFn('unexpected delta action.');
661
- }
662
- }
663
- return slot;
664
- }
665
- cleanSubscriptionsBySlot(slot) {
666
- this.contentMap.delete(slot);
667
- [this.contentSyncCaches.get(slot), this.slotStateSyncCaches.get(slot)].forEach(fn => {
668
- if (fn) {
669
- fn();
670
- }
671
- });
672
- slot.sliceContent().forEach(i => {
673
- if (typeof i !== 'string') {
674
- this.cleanSubscriptionsByComponent(i);
675
- }
676
- });
677
- }
678
- cleanSubscriptionsByComponent(component) {
679
- [this.slotsSyncCaches.get(component), this.componentStateSyncCaches.get(component)].forEach(fn => {
680
- if (fn) {
681
- fn();
682
- }
683
- });
684
- component.slots.toArray().forEach(slot => {
685
- this.cleanSubscriptionsBySlot(slot);
686
- });
687
- }
688
- };
689
- Collaborate = __decorate([
690
- Injectable(),
691
- __param(0, Inject(HISTORY_STACK_SIZE)),
692
- __metadata("design:paramtypes", [Number, RootComponentRef,
693
- CollaborateCursor,
694
- Controller,
695
- Scheduler,
696
- Factory,
697
- Selection,
698
- Starter])
699
- ], Collaborate);
700
- export { Collaborate };
701
- function remoteFormatsToLocal(factory, attrs) {
702
- const formats = [];
703
- if (attrs) {
704
- Object.keys(attrs).forEach(key => {
705
- const formatter = factory.getFormatter(key);
706
- if (formatter) {
707
- formats.push([formatter, attrs[key]]);
708
- }
709
- });
710
- }
711
- return formats;
712
- }
713
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGFib3JhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29sbGFib3JhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDOUMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFjLE9BQU8sRUFBZ0IsTUFBTSxlQUFlLENBQUE7QUFDckYsT0FBTyxFQUNMLFlBQVksRUFFWixXQUFXLEVBQ1gsVUFBVSxFQUNWLE9BQU8sRUFHUCxrQkFBa0IsRUFDbEIsU0FBUyxFQUNULGdCQUFnQixFQUNoQixTQUFTLEVBQ1QsU0FBUyxFQUVULElBQUksRUFDSixPQUFPLEVBQ1IsTUFBTSxlQUFlLENBQUE7QUFDdEIsT0FBTyxFQUNMLEtBQUssSUFBSSxNQUFNLEVBQ2YsR0FBRyxJQUFJLElBQUksRUFDWCxHQUFHLElBQUksSUFBSSxFQUVYLElBQUksSUFBSSxLQUFLLEVBRWIsV0FBVyxFQUNYLDBDQUEwQyxFQUMxQyxtQ0FBbUMsRUFDcEMsTUFBTSxLQUFLLENBQUE7QUFFWixPQUFPLEVBQUUsaUJBQWlCLEVBQW1CLE1BQU0sc0JBQXNCLENBQUE7QUFDekUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFFNUQsTUFBTSxrQkFBa0IsR0FBRyxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUE7QUFPbkQsTUFBTSxVQUFVO0lBQWhCO1FBQ1Usb0JBQWUsR0FBRyxJQUFJLE9BQU8sRUFBZSxDQUFBO1FBQzVDLG9CQUFlLEdBQUcsSUFBSSxPQUFPLEVBQWUsQ0FBQTtJQXNDdEQsQ0FBQztJQWxDQyxHQUFHLENBQUMsR0FBUSxFQUFFLEtBQVU7UUFDdEIsSUFBSSxHQUFHLFlBQVksSUFBSSxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENB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Q0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUE7YUFDdEM7UUFDSCxDQUFDLENBQUMsQ0FBQTtLQUNIO0lBQ0QsT0FBTyxPQUFPLENBQUE7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0B0YW5iby9kaSdcbmltcG9ydCB7IGRlbGF5LCBmaWx0ZXIsIG1hcCwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAnQHRhbmJvL3N0cmVhbSdcbmltcG9ydCB7XG4gIENoYW5nZU9yaWdpbixcbiAgQ29tcG9uZW50SW5zdGFuY2UsXG4gIENvbnRlbnRUeXBlLFxuICBDb250cm9sbGVyLFxuICBGYWN0b3J5LFxuICBGb3JtYXRzLFxuICBIaXN0b3J5LFxuICBISVNUT1JZX1NUQUNLX1NJWkUsXG4gIG1ha2VFcnJvcixcbiAgUm9vdENvbXBvbmVudFJlZixcbiAgU2NoZWR1bGVyLFxuICBTZWxlY3Rpb24sXG4gIFNlbGVjdGlvblBhdGhzLFxuICBTbG90LFxuICBTdGFydGVyXG59IGZyb20gJ0B0ZXh0YnVzL2NvcmUnXG5pbXBvcnQge1xuICBBcnJheSBhcyBZQXJyYXksXG4gIERvYyBhcyBZRG9jLFxuICBNYXAgYXMgWU1hcCxcbiAgUmVsYXRpdmVQb3NpdGlvbixcbiAgVGV4dCBhcyBZVGV4dCxcbiAgVHJhbnNhY3Rpb24sXG4gIFVuZG9NYW5hZ2VyLFxuICBjcmVhdGVBYnNvbHV0ZVBvc2l0aW9uRnJvbVJlbGF0aXZlUG9zaXRpb24sXG4gIGNyZWF0ZVJlbGF0aXZlUG9zaXRpb25Gcm9tVHlwZUluZGV4XG59IGZyb20gJ3lqcydcblxuaW1wb3J0IHsgQ29sbGFib3JhdGVDdXJzb3IsIFJlbW90ZVNlbGVjdGlvbiB9IGZyb20gJy4vY29sbGFib3JhdGUtY3Vyc29yJ1xuaW1wb3J0IHsgY3JlYXRlVW5rbm93bkNvbXBvbmVudCB9IGZyb20gJy4vdW5rbm93bi5jb21wb25lbnQnXG5cbmNvbnN0IGNvbGxhYm9yYXRlRXJyb3JGbiA9IG1ha2VFcnJvcignQ29sbGFib3JhdGUnKVxuXG5pbnRlcmZhY2UgQ3Vyc29yUG9zaXRpb24ge1xuICBhbmNob3I6IFJlbGF0aXZlUG9zaXRpb25cbiAgZm9jdXM6IFJlbGF0aXZlUG9zaXRpb25cbn1cblxuY2xhc3MgQ29udGVudE1hcCB7XG4gIHByaXZhdGUgc2xvdEFuZFlUZXh0TWFwID0gbmV3IFdlYWtNYXA8U2xvdCwgWVRleHQ+KClcbiAgcHJpdmF0ZSB5VGV4dEFuZFNMb3RNYXAgPSBuZXcgV2Vha01hcDxZVGV4dCwgU2xvdD4oKVxuXG4gIHNldChrZXk6IFNsb3QsIHZhbHVlOiBZVGV4dCk6IHZvaWRcbiAgc2V0KGtleTogWVRleHQsIHZhbHVlOiBTbG90KTogdm9pZFxuICBzZXQoa2V5OiBhbnksIHZhbHVlOiBhbnkpIHtcbiAgICBpZiAoa2V5IGluc3RhbmNlb2YgU2xvdCkge1xuICAgICAgdGhpcy5zbG90QW5kWVRleHRNYXAuc2V0KGtleSwgdmFsdWUpXG4gICAgICB0aGlzLnlUZXh0QW5kU0xvdE1hcC5zZXQodmFsdWUsIGtleSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zbG90QW5kWVRleHRNYXAuc2V0KHZhbHVlLCBrZXkpXG4gICAgICB0aGlzLnlUZXh0QW5kU0xvdE1hcC5zZXQoa2V5LCB2YWx1ZSlcbiAgICB9XG4gIH1cblxuICBnZXQoa2V5OiBTbG90KTogWVRleHQgfCBudWxsXG4gIGdldChrZXk6IFlUZXh0KTogU2xvdCB8IG51bGxcbiAgZ2V0KGtleTogYW55KSB7XG4gICAgaWYgKGtleSBpbnN0YW5jZW9mIFNsb3QpIHtcbiAgICAgIHJldHVybiB0aGlzLnNsb3RBbmRZVGV4dE1hcC5nZXQoa2V5KSB8fCBudWxsXG4gICAgfVxuICAgIHJldHVybiB0aGlzLnlUZXh0QW5kU0xvdE1hcC5nZXQoa2V5KSB8fCBudWxsXG4gIH1cblxuICBkZWxldGUoa2V5OiBTbG90IHwgWVRleHQpIHtcbiAgICBpZiAoa2V5IGluc3RhbmNlb2YgU2xvdCkge1xuICAgICAgY29uc3QgdiA9IHRoaXMuc2xvdEFuZFlUZXh0TWFwLmdldChrZXkpXG4gICAgICB0aGlzLnNsb3RBbmRZVGV4dE1hcC5kZWxldGUoa2V5KVxuICAgICAgaWYgKHYpIHtcbiAgICAgICAgdGhpcy55VGV4dEFuZFNMb3RNYXAuZGVsZXRlKHYpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHYgPSB0aGlzLnlUZXh0QW5kU0xvdE1hcC5nZXQoa2V5KVxuICAgICAgdGhpcy55VGV4dEFuZFNMb3RNYXAuZGVsZXRlKGtleSlcbiAgICAgIGlmICh2KSB7XG4gICAgICAgIHRoaXMuc2xvdEFuZFlUZXh0TWFwLmRlbGV0ZSh2KVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5pbnRlcmZhY2UgVXBkYXRlIHtcbiAgcmVjb3JkOiBib29sZWFuXG4gIGFjdGlvbnM6IEFycmF5PCgpID0+IHZvaWQ+XG59XG5cbmludGVyZmFjZSBVcGRhdGVJdGVtIHtcbiAgcmVjb3JkOiBib29sZWFuXG5cbiAgYWN0aW9uKCk6IHZvaWRcbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIENvbGxhYm9yYXRlIGltcGxlbWVudHMgSGlzdG9yeSB7XG4gIG9uU2VsZWN0aW9uQ2hhbmdlOiBPYnNlcnZhYmxlPFNlbGVjdGlvblBhdGhzPlxuICB5RG9jID0gbmV3IFlEb2MoKVxuICBvbkJhY2s6IE9ic2VydmFibGU8dm9pZD5cbiAgb25Gb3J3YXJkOiBPYnNlcnZhYmxlPHZvaWQ+XG4gIG9uQ2hhbmdlOiBPYnNlcnZhYmxlPHZvaWQ+XG4gIG9uUHVzaDogT2JzZXJ2YWJsZTx2b2lkPlxuXG4gIGdldCBjYW5CYWNrKCkge1xuICAgIHJldHVybiB0aGlzLm1hbmFnZXI/LmNhblVuZG8oKSB8fCBmYWxzZVxuICB9XG5cbiAgZ2V0IGNhbkZvcndhcmQoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFuYWdlcj8uY2FuUmVkbygpIHx8IGZhbHNlXG4gIH1cblxuICBwcm90ZWN0ZWQgYmFja0V2ZW50ID0gbmV3IFN1YmplY3Q8dm9pZD4oKVxuICBwcm90ZWN0ZWQgZm9yd2FyZEV2ZW50ID0gbmV3IFN1YmplY3Q8dm9pZD4oKVxuICBwcm90ZWN0ZWQgY2hhbmdlRXZlbnQgPSBuZXcgU3ViamVjdDx2b2lkPigpXG4gIHByb3RlY3RlZCBwdXNoRXZlbnQgPSBuZXcgU3ViamVjdDx2b2lkPigpXG5cbiAgcHJvdGVjdGVkIG1hbmFnZXI6IFVuZG9NYW5hZ2VyIHwgbnVsbCA9IG51bGxcblxuICBwcm90ZWN0ZWQgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXVxuICBwcm90ZWN0ZWQgdXBkYXRlRnJvbVJlbW90ZSA9IGZhbHNlXG5cbiAgcHJvdGVjdGVkIGNvbnRlbnRTeW5jQ2FjaGVzID0gbmV3IFdlYWtNYXA8U2xvdCwgKCkgPT4gdm9pZD4oKVxuICBwcm90ZWN0ZWQgc2xvdFN0YXRlU3luY0NhY2hlcyA9IG5ldyBXZWFrTWFwPFNsb3QsICgpID0+IHZvaWQ+KClcbiAgcHJvdGVjdGVkIHNsb3RzU3luY0NhY2hlcyA9IG5ldyBXZWFrTWFwPENvbXBvbmVudEluc3RhbmNlLCAoKSA9PiB2b2lkPigpXG4gIHByb3RlY3RlZCBjb21wb25lbnRTdGF0ZVN5bmNDYWNoZXMgPSBuZXcgV2Vha01hcDxDb21wb25lbnRJbnN0YW5jZSwgKCkgPT4gdm9pZD4oKVxuXG4gIHByb3RlY3RlZCBzZWxlY3Rpb25DaGFuZ2VFdmVudCA9IG5ldyBTdWJqZWN0PFNlbGVjdGlvblBhdGhzPigpXG4gIHByb3RlY3RlZCBjb250ZW50TWFwID0gbmV3IENvbnRlbnRNYXAoKVxuXG4gIHByb3RlY3RlZCB1cGRhdGVSZW1vdGVBY3Rpb25zOiBBcnJheTxVcGRhdGVJdGVtPiA9IFtdXG4gIHByb3RlY3RlZCBub1JlY29yZCA9IHt9XG5cbiAgY29uc3RydWN0b3IoQEluamVjdChISVNUT1JZX1NUQUNLX1NJWkUpIHByb3RlY3RlZCBzdGFja1NpemU6IG51bWJlcixcbiAgICAgICAgICAgICAgcHJvdGVjdGVkIHJvb3RDb21wb25lbnRSZWY6IFJvb3RDb21wb25lbnRSZWYsXG4gICAgICAgICAgICAgIHByb3RlY3RlZCBjb2xsYWJvcmF0ZUN1cnNvcjogQ29sbGFib3JhdGVDdXJzb3IsXG4gICAgICAgICAgICAgIHByb3RlY3RlZCBjb250cm9sbGVyOiBDb250cm9sbGVyLFxuICAgICAgICAgICAgICBwcm90ZWN0ZWQgc2NoZWR1bGVyOiBTY2hlZHVsZXIsXG4gICAgICAgICAgICAgIHByb3RlY3RlZCBmYWN0b3J5OiBGYWN0b3J5LFxuICAgICAgICAgICAgICBwcm90ZWN0ZWQgc2VsZWN0aW9uOiBTZWxlY3Rpb24sXG4gICAgICAgICAgICAgIHByb3RlY3RlZCBzdGFydGVyOiBTdGFydGVyKSB7XG4gICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZSA9IHRoaXMuc2VsZWN0aW9uQ2hhbmdlRXZlbnQuYXNPYnNlcnZhYmxlKCkucGlwZShkZWxheSgpKVxuICAgIHRoaXMub25CYWNrID0gdGhpcy5iYWNrRXZlbnQuYXNPYnNlcnZhYmxlKClcbiAgICB0aGlzLm9uRm9yd2FyZCA9IHRoaXMuZm9yd2FyZEV2ZW50LmFzT2JzZXJ2YWJsZSgpXG4gICAgdGhpcy5vbkNoYW5nZSA9IHRoaXMuY2hhbmdlRXZlbnQuYXNPYnNlcnZhYmxlKClcbiAgICB0aGlzLm9uUHVzaCA9IHRoaXMucHVzaEV2ZW50LmFzT2JzZXJ2YWJsZSgpXG4gIH1cblxuICBsaXN0ZW4oKSB7XG4gICAgY29uc3Qgcm9vdCA9IHRoaXMueURvYy5nZXRNYXAoJ1Jvb3RDb21wb25lbnQnKVxuICAgIGNvbnN0IHJvb3RDb21wb25lbnQgPSB0aGlzLnJvb3RDb21wb25lbnRSZWYuY29tcG9uZW50IVxuICAgIHRoaXMubWFuYWdlciA9IG5ldyBVbmRvTWFuYWdlcihyb290LCB7XG4gICAgICB0cmFja2VkT3JpZ2luczogbmV3IFNldDxhbnk+KFt0aGlzLnlEb2NdKVxuICAgIH0pXG4gICAgY29uc3QgY3Vyc29yS2V5ID0gJ2N1cnNvci1wb3NpdGlvbidcbiAgICB0aGlzLm1hbmFnZXIub24oJ3N0YWNrLWl0ZW0tYWRkZWQnLCBldmVudCA9PiB7XG4gICAgICBldmVudC5zdGFja0l0ZW0ubWV0YS5zZXQoY3Vyc29yS2V5LCB0aGlzLmdldFJlbGF0aXZlQ3Vyc29yTG9jYXRpb24oKSlcbiAgICAgIGlmICh0aGlzLm1hbmFnZXIhLnVuZG9TdGFjay5sZW5ndGggPiB0aGlzLnN0YWNrU2l6ZSkge1xuICAgICAgICB0aGlzLm1hbmFnZXIhLnVuZG9TdGFjay5zaGlmdCgpXG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQub3JpZ2luID09PSB0aGlzLnlEb2MpIHtcbiAgICAgICAgdGhpcy5wdXNoRXZlbnQubmV4dCgpXG4gICAgICB9XG4gICAgICB0aGlzLmNoYW5nZUV2ZW50Lm5leHQoKVxuICAgIH0pXG4gICAgdGhpcy5tYW5hZ2VyLm9uKCdzdGFjay1pdGVtLXBvcHBlZCcsIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gZXZlbnQuc3RhY2tJdGVtLm1ldGEuZ2V0KGN1cnNvcktleSkgYXMgQ3Vyc29yUG9zaXRpb25cbiAgICAgIGlmIChwb3NpdGlvbikge1xuICAgICAgICB0aGlzLnJlc3RvcmVDdXJzb3JMb2NhdGlvbihwb3NpdGlvbilcbiAgICAgIH1cbiAgICB9KVxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgdGhpcy5zZWxlY3Rpb24ub25DaGFuZ2Uuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgY29uc3QgcGF0aHMgPSB0aGlzLnNlbGVjdGlvbi5nZXRQYXRocygpXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uQ2hhbmdlRXZlbnQubmV4dChwYXRocylcbiAgICAgIH0pLFxuICAgICAgdGhpcy5zY2hlZHVsZXIub25Eb2NDaGFuZ2VkLnBpcGUoXG4gICAgICAgIG1hcChpdGVtID0+IHtcbiAgICAgICAgICByZXR1cm4gaXRlbS5maWx0ZXIoaSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gaS5mcm9tICE9PSBDaGFuZ2VPcmlnaW4uUmVtb3RlXG4gICAgICAgICAgfSlcbiAgICAgICAgfSksXG4gICAgICAgIGZpbHRlcihpdGVtID0+IHtcbiAgICAgICAgICByZXR1cm4gaXRlbS5sZW5ndGhcbiAgICAgICAgfSlcbiAgICAgICkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgY29uc3QgdXBkYXRlczogVXBkYXRlW10gPSBbXVxuXG4gICAgICAgIGxldCB1cGRhdGU6IFVwZGF0ZSB8IG51bGwgPSBudWxsXG5cbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHRoaXMudXBkYXRlUmVtb3RlQWN0aW9ucykge1xuICAgICAgICAgIGlmICghdXBkYXRlKSB7XG4gICAgICAgICAgICB1cGRhdGUgPSB7XG4gICAgICAgICAgICAgIHJlY29yZDogaXRlbS5yZWNvcmQsXG4gICAgICAgICAgICAgIGFjdGlvbnM6IFtdXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB1cGRhdGVzLnB1c2godXBkYXRlKVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodXBkYXRlLnJlY29yZCA9PT0gaXRlbS5yZWNvcmQpIHtcbiAgICAgICAgICAgIHVwZGF0ZS5hY3Rpb25zLnB1c2goaXRlbS5hY3Rpb24pXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHVwZGF0ZSA9IHtcbiAgICAgICAgICAgICAgcmVjb3JkOiBpdGVtLnJlY29yZCxcbiAgICAgICAgICAgICAgYWN0aW9uczogW2l0ZW0uYWN0aW9uXVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdXBkYXRlcy5wdXNoKHVwZGF0ZSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnVwZGF0ZVJlbW90ZUFjdGlvbnMgPSBbXVxuXG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiB1cGRhdGVzKSB7XG4gICAgICAgICAgdGhpcy55RG9jLnRyYW5zYWN0KCgpID0+IHtcbiAgICAgICAgICAgIGl0ZW0uYWN0aW9ucy5mb3JFYWNoKGZuID0+IHtcbiAgICAgICAgICAgICAgZm4oKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9LCBpdGVtLnJlY29yZCA/IHRoaXMueURvYyA6IHRoaXMubm9SZWNvcmQpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKVxuICAgIHRoaXMuc3luY1Jvb3RDb21wb25lbnQocm9vdCwgcm9vdENvbXBvbmVudClcbiAgfVxuXG4gIHVwZGF0ZVJlbW90ZVNlbGVjdGlvbihwYXRoczogUmVtb3RlU2VsZWN0aW9uW10pIHtcbiAgICB0aGlzLmNvbGxhYm9yYXRlQ3Vyc29yLmRyYXcocGF0aHMpXG4gIH1cblxuICBiYWNrKCkge1xuICAgIGlmICh0aGlzLmNhbkJhY2spIHtcbiAgICAgIHRoaXMubWFuYWdlcj8udW5kbygpXG4gICAgICB0aGlzLmJhY2tFdmVudC5uZXh0KClcbiAgICB9XG4gIH1cblxuICBmb3J3YXJkKCkge1xuICAgIGlmICh0aGlzLmNhbkZvcndhcmQpIHtcbiAgICAgIHRoaXMubWFuYWdlcj8ucmVkbygpXG4gICAgICB0aGlzLmZvcndhcmRFdmVudC5uZXh0KClcbiAgICB9XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICB0aGlzLm1hbmFnZXI/LmNsZWFyKClcbiAgICB0aGlzLmNoYW5nZUV2ZW50Lm5leHQoKVxuICB9XG5cbiAgZGVzdHJveSgpIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaChpID0+IGkudW5zdWJzY3JpYmUoKSlcbiAgICB0aGlzLmNvbGxhYm9yYXRlQ3Vyc29yLmRlc3Ryb3koKVxuICAgIHRoaXMubWFuYWdlcj8uZGVzdHJveSgpXG4gIH1cblxuICBwcm90ZWN0ZWQgc3luY1Jvb3RDb21wb25lbnQocm9vdDogWU1hcDxhbnk+LCByb290Q29tcG9uZW50OiBDb21wb25lbnRJbnN0YW5jZSkge1xuICAgIGxldCBzbG90cyA9IHJvb3QuZ2V0KCdzbG90cycpIGFzIFlBcnJheTxZTWFwPGFueT4+XG4gICAgaWYgKCFzbG90cykge1xuICAgICAgc2xvdHMgPSBuZXcgWUFycmF5KClcbiAgICAgIHJvb3RDb21wb25lbnQuc2xvdHMudG9BcnJheSgpLmZvckVhY2goaSA9PiB7XG4gICAgICAgIGNvbnN0IHNoYXJlZFNsb3QgPSB0aGlzLmNyZWF0ZVNoYXJlZFNsb3RCeVNsb3QoaSlcbiAgICAgICAgc2xvdHMucHVzaChbc2hhcmVkU2xvdF0pXG4gICAgICB9KVxuICAgICAgdGhpcy55RG9jLnRyYW5zYWN0KCgpID0+IHtcbiAgICAgICAgcm9vdC5zZXQoJ3N0YXRlJywgcm9vdENvbXBvbmVudC5zdGF0ZSlcbiAgICAgICAgcm9vdC5zZXQoJ3Nsb3RzJywgc2xvdHMpXG4gICAgICB9KVxuICAgIH0gZWxzZSBpZiAoc2xvdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByb290Q29tcG9uZW50LnVwZGF0ZVN0YXRlKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHJvb3QuZ2V0KCdzdGF0ZScpXG4gICAgICB9KVxuICAgICAgdGhpcy55RG9jLnRyYW5zYWN0KCgpID0+IHtcbiAgICAgICAgcm9vdENvbXBvbmVudC5zbG90cy50b0FycmF5KCkuZm9yRWFjaChpID0+IHtcbiAgICAgICAgICBjb25zdCBzaGFyZWRTbG90ID0gdGhpcy5jcmVhdGVTaGFyZWRTbG90QnlTbG90KGkpXG4gICAgICAgICAgc2xvdHMucHVzaChbc2hhcmVkU2xvdF0pXG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICByb290Q29tcG9uZW50LnVwZGF0ZVN0YXRlKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHJvb3QuZ2V0KCdzdGF0ZScpXG4gICAgICB9KVxuICAgICAgcm9vdENvbXBvbmVudC5zbG90cy5jbGVhbigpXG4gICAgICBzbG90cy5mb3JFYWNoKHNoYXJlZFNsb3QgPT4ge1xuICAgICAgICBjb25zdCBzbG90ID0gdGhpcy5jcmVhdGVTbG90QnlTaGFyZWRTbG90KHNoYXJlZFNsb3QpXG4gICAgICAgIHRoaXMuc3luY1Nsb3RDb250ZW50KHNoYXJlZFNsb3QuZ2V0KCdjb250ZW50JyksIHNsb3QpXG4gICAgICAgIHRoaXMuc3luY1Nsb3RTdGF0ZShzaGFyZWRTbG90LCBzbG90KVxuICAgICAgICByb290Q29tcG9uZW50LnNsb3RzLmluc2VydChzbG90KVxuICAgICAgfSlcbiAgICB9XG4gICAgdGhpcy5zeW5jQ29tcG9uZW50U3RhdGUocm9vdCwgcm9vdENvbXBvbmVudClcbiAgICB0aGlzLnN5bmNDb21wb25lbnRTbG90cyhzbG90cywgcm9vdENvbXBvbmVudClcbiAgfVxuXG4gIHByb3RlY3RlZCByZXN0b3JlQ3Vyc29yTG9jYXRpb24ocG9zaXRpb246IEN1cnNvclBvc2l0aW9uKSB7XG4gICAgY29uc3QgYW5jaG9yUG9zaXRpb24gPSBjcmVhdGVBYnNvbHV0ZVBvc2l0aW9uRnJvbVJlbGF0aXZlUG9zaXRpb24ocG9zaXRpb24uYW5jaG9yLCB0aGlzLnlEb2MpXG4gICAgY29uc3QgZm9jdXNQb3NpdGlvbiA9IGNyZWF0ZUFic29sdXRlUG9zaXRpb25Gcm9tUmVsYXRpdmVQb3NpdGlvbihwb3NpdGlvbi5mb2N1cywgdGhpcy55RG9jKVxuICAgIGlmIChhbmNob3JQb3NpdGlvbiAmJiBmb2N1c1Bvc2l0aW9uKSB7XG4gICAgICBjb25zdCBmb2N1c1Nsb3QgPSB0aGlzLmNvbnRlbnRNYXAuZ2V0KGZvY3VzUG9zaXRpb24udHlwZSBhcyBZVGV4dClcbiAgICAgIGNvbnN0IGFuY2hvclNsb3QgPSB0aGlzLmNvbnRlbnRNYXAuZ2V0KGFuY2hvclBvc2l0aW9uLnR5cGUgYXMgWVRleHQpXG4gICAgICBpZiAoZm9jdXNTbG90ICYmIGFuY2hvclNsb3QpIHtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb24uc2V0QmFzZUFuZEV4dGVudChhbmNob3JTbG90LCBhbmNob3JQb3NpdGlvbi5pbmRleCwgZm9jdXNTbG90LCBmb2N1c1Bvc2l0aW9uLmluZGV4KVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5zZWxlY3Rpb24udW5TZWxlY3QoKVxuICB9XG5cbiAgcHJvdGVjdGVkIGdldFJlbGF0aXZlQ3Vyc29yTG9jYXRpb24oKTogQ3Vyc29yUG9zaXRpb24gfCBudWxsIHtcbiAgICBjb25zdCB7IGFuY2hvclNsb3QsIGFuY2hvck9mZnNldCwgZm9jdXNTbG90LCBmb2N1c09mZnNldCB9ID0gdGhpcy5zZWxlY3Rpb25cbiAgICBpZiAoYW5jaG9yU2xvdCkge1xuICAgICAgY29uc3QgYW5jaG9yWVRleHQgPSB0aGlzLmNvbnRlbnRNYXAuZ2V0KGFuY2hvclNsb3QpXG4gICAgICBpZiAoYW5jaG9yWVRleHQpIHtcbiAgICAgICAgY29uc3QgYW5jaG9yUG9zaXRpb24gPSBjcmVhdGVSZWxhdGl2ZVBvc2l0aW9uRnJvbVR5cGVJbmRleChhbmNob3JZVGV4dCwgYW5jaG9yT2Zmc2V0ISlcbiAgICAgICAgaWYgKGZvY3VzU2xvdCkge1xuICAgICAgICAgIGNvbnN0IGZvY3VzWVRleHQgPSB0aGlzLmNvbnRlbnRNYXAuZ2V0KGZvY3VzU2xvdClcbiAgICAgICAgICBpZiAoZm9jdXNZVGV4dCkge1xuICAgICAgICAgICAgY29uc3QgZm9jdXNQb3NpdGlvbiA9IGNyZWF0ZVJlbGF0aXZlUG9zaXRpb25Gcm9tVHlwZUluZGV4KGZvY3VzWVRleHQsIGZvY3VzT2Zmc2V0ISlcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGZvY3VzOiBmb2N1c1Bvc2l0aW9uLFxuICAgICAgICAgICAgICBhbmNob3I6IGFuY2hvclBvc2l0aW9uXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBwcm90ZWN0ZWQgc3luY1Nsb3RDb250ZW50KGNvbnRlbnQ6IFlUZXh0LCBzbG90OiBTbG90KSB7XG4gICAgdGhpcy5jb250ZW50TWFwLnNldChzbG90LCBjb250ZW50KVxuICAgIGNvbnN0IHN5bmNSZW1vdGUgPSAoZXYsIHRyKSA9PiB7XG4gICAgICB0aGlzLnJ1blJlbW90ZVVwZGF0ZSh0ciwgKCkgPT4ge1xuICAgICAgICBzbG90LnJldGFpbigwKVxuICAgICAgICBldi5rZXlzQ2hhbmdlZC5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgY29uc3QgdXBkYXRlVHlwZSA9IGV2LmtleXMuZ2V0KGtleSkuYWN0aW9uXG4gICAgICAgICAgaWYgKHVwZGF0ZVR5cGUgPT09ICd1cGRhdGUnIHx8IHVwZGF0ZVR5cGUgPT09ICdhZGQnKSB7XG4gICAgICAgICAgICBjb25zdCBhdHRyaWJ1dGUgPSB0aGlzLmZhY3RvcnkuZ2V0QXR0cmlidXRlKGtleSlcbiAgICAgICAgICAgIGlmIChhdHRyaWJ1dGUpIHtcbiAgICAgICAgICAgICAgc2xvdC5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlLCBjb250ZW50LmdldEF0dHJpYnV0ZShrZXkpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAodXBkYXRlVHlwZSA9PT0gJ2RlbGV0ZScpIHtcbiAgICAgICAgICAgIGNvbnN0IGF0dHJpYnV0ZSA9IHRoaXMuZmFjdG9yeS5nZXRBdHRyaWJ1dGUoa2V5KVxuICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZSkge1xuICAgICAgICAgICAgICBzbG90LnJlbW92ZUF0dHJpYnV0ZShhdHRyaWJ1dGUpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICBldi5kZWx0YS5mb3JFYWNoKGFjdGlvbiA9PiB7XG4gICAgICAgICAgaWYgKFJlZmxlY3QuaGFzKGFjdGlvbiwgJ3JldGFpbicpKSB7XG4gICAgICAgICAgICBpZiAoYWN0aW9uLmF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgICAgY29uc3QgZm9ybWF0cyA9IHJlbW90ZUZvcm1hdHNUb0xvY2FsKHRoaXMuZmFjdG9yeSwgYWN0aW9uLmF0dHJpYnV0ZXMpXG4gICAgICAgICAgICAgIGlmIChmb3JtYXRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHNsb3QucmV0YWluKGFjdGlvbi5yZXRhaW4hLCBmb3JtYXRzKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHNsb3QucmV0YWluKHNsb3QuaW5kZXggKyBhY3Rpb24ucmV0YWluKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc2xvdC5yZXRhaW4oYWN0aW9uLnJldGFpbilcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi5pbnNlcnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc2xvdC5pbmRleFxuICAgICAgICAgICAgbGV0IGxlbmd0aCA9IDFcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYWN0aW9uLmluc2VydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgbGVuZ3RoID0gYWN0aW9uLmluc2VydC5sZW5ndGhcbiAgICAgICAgICAgICAgc2xvdC5pbnNlcnQoYWN0aW9uLmluc2VydCwgcmVtb3RlRm9ybWF0c1RvTG9jYWwodGhpcy5mYWN0b3J5LCBhY3Rpb24uYXR0cmlidXRlcykpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zdCBzaGFyZWRDb21wb25lbnQgPSBhY3Rpb24uaW5zZXJ0IGFzIFlNYXA8YW55PlxuICAgICAgICAgICAgICBjb25zdCBjYW5JbnNlcnRJbmxpbmVDb21wb25lbnQgPSBzbG90LnNjaGVtYS5pbmNsdWRlcyhDb250ZW50VHlwZS5JbmxpbmVDb21wb25lbnQpXG4gICAgICAgICAgICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuY3JlYXRlQ29tcG9uZW50QnlTaGFyZWRDb21wb25lbnQoc2hhcmVkQ29tcG9uZW50LCBjYW5JbnNlcnRJbmxpbmVDb21wb25lbnQpXG4gICAgICAgICAgICAgIHRoaXMuc3luY0NvbXBvbmVudFNsb3RzKHNoYXJlZENvbXBvbmVudC5nZXQoJ3Nsb3RzJyksIGNvbXBvbmVudClcbiAgICAgICAgICAgICAgdGhpcy5zeW5jQ29tcG9uZW50U3RhdGUoc2hhcmVkQ29tcG9uZW50LCBjb21wb25lbnQpXG4gICAgICAgICAgICAgIHNsb3QuaW5zZXJ0KGNvbXBvbmVudClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGlvbi5pc1NlbGVjdGVkKSB7XG4gICAgICAgICAgICAgIGlmIChzbG90ID09PSB0aGlzLnNlbGVjdGlvbi5hbmNob3JTbG90ICYmIHRoaXMuc2VsZWN0aW9uLmFuY2hvck9mZnNldCEgPiBpbmRleCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uLnNldEFuY2hvcihzbG90LCB0aGlzLnNlbGVjdGlvbi5hbmNob3JPZmZzZXQhICsgbGVuZ3RoKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChzbG90ID09PSB0aGlzLnNlbGVjdGlvbi5mb2N1c1Nsb3QgJiYgdGhpcy5zZWxlY3Rpb24uZm9jdXNPZmZzZXQhID4gaW5kZXgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGlvbi5zZXRGb2N1cyhzbG90LCB0aGlzLnNlbGVjdGlvbi5mb2N1c09mZnNldCEgKyBsZW5ndGgpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi5kZWxldGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc2xvdC5pbmRleFxuICAgICAgICAgICAgc2xvdC5yZXRhaW4oc2xvdC5pbmRleClcbiAgICAgICAgICAgIHNsb3QuZGVsZXRlKGFjdGlvbi5kZWxldGUpXG4gICAgICAgICAgICBpZiAodGhpcy5zZWxlY3Rpb24uaXNTZWxlY3RlZCkge1xuICAgICAgICAgICAgICBpZiAoc2xvdCA9PT0gdGhpcy5zZWxlY3Rpb24uYW5jaG9yU2xvdCAmJiB0aGlzLnNlbGVjdGlvbi5hbmNob3JPZmZzZXQhID49IGluZGV4KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb24uc2V0QW5jaG9yKHNsb3QsIHRoaXMuc2VsZWN0aW9uLnN0YXJ0T2Zmc2V0ISAtIGFjdGlvbi5kZWxldGUpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKHNsb3QgPT09IHRoaXMuc2VsZWN0aW9uLmZvY3VzU2xvdCAmJiB0aGlzLnNlbGVjdGlvbi5mb2N1c09mZnNldCEgPj0gaW5kZXgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGlvbi5zZXRGb2N1cyhzbG90LCB0aGlzLnNlbGVjdGlvbi5mb2N1c09mZnNldCEgLSBhY3Rpb24uZGVsZXRlKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICB9XG4gICAgY29udGVudC5vYnNlcnZlKHN5bmNSZW1vdGUpXG5cbiAgICBjb25zdCBzdWIgPSBzbG90Lm9uQ29udGVudENoYW5nZS5waXBlKGZpbHRlcigoKSA9PiB7XG4gICAgICByZXR1cm4gIXRoaXMuc2NoZWR1bGVyLmlnbm9yZUNoYW5nZXNcbiAgICB9KSkuc3Vic2NyaWJlKGFjdGlvbnMgPT4ge1xuICAgICAgdGhpcy5ydW5Mb2NhbFVwZGF0ZSgoKSA9PiB7XG4gICAgICAgIGxldCBvZmZzZXQgPSAwXG4gICAgICAgIGxldCBsZW5ndGggPSAwXG4gICAgICAgIGZvciAoY29uc3QgYWN0aW9uIG9mIGFjdGlvbnMpIHtcbiAgICAgICAgICBpZiAoYWN0aW9uLnR5cGUgPT09ICdyZXRhaW4nKSB7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXRzID0gYWN0aW9uLmZvcm1hdHNcbiAgICAgICAgICAgIGlmIChmb3JtYXRzKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhmb3JtYXRzKVxuICAgICAgICAgICAgICBsZXQgbGVuZ3RoID0ga2V5cy5sZW5ndGhcbiAgICAgICAgICAgICAga2V5cy5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVyID0gdGhpcy5mYWN0b3J5LmdldEZvcm1hdHRlcihrZXkpXG4gICAgICAgICAgICAgICAgaWYgKCFmb3JtYXR0ZXIpIHtcbiAgICAgICAgICAgICAgICAgIGxlbmd0aC0tXG4gICAgICAgICAgICAgICAgICBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KGZvcm1hdHMsIGtleSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIGlmIChsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb250ZW50LmZvcm1hdChvZmZzZXQsIGFjdGlvbi5vZmZzZXQsIGZvcm1hdHMpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG9mZnNldCA9IGFjdGlvbi5vZmZzZXRcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi50eXBlID09PSAnaW5zZXJ0Jykge1xuICAgICAgICAgICAgY29uc3QgZGVsdGEgPSBjb250ZW50LnRvRGVsdGEoKVxuICAgICAgICAgICAgY29uc3QgaXNFbXB0eSA9IGRlbHRhLmxlbmd0aCA9PT0gMSAmJiBkZWx0YVswXS5pbnNlcnQgPT09IFNsb3QuZW1wdHlQbGFjZWhvbGRlclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBhY3Rpb24uY29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgbGVuZ3RoID0gYWN0aW9uLmNvbnRlbnQubGVuZ3RoXG4gICAgICAgICAgICAgIGNvbnRlbnQuaW5zZXJ0KG9mZnNldCwgYWN0aW9uLmNvbnRlbnQsIGFjdGlvbi5mb3JtYXRzIHx8IHt9KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgbGVuZ3RoID0gMVxuICAgICAgICAgICAgICBjb25zdCBzaGFyZWRDb21wb25lbnQgPSB0aGlzLmNyZWF0ZVNoYXJlZENvbXBvbmVudEJ5Q29tcG9uZW50KGFjdGlvbi5yZWYgYXMgQ29tcG9uZW50SW5zdGFuY2UpXG4gICAgICAgICAgICAgIGNvbnRlbnQuaW5zZXJ0RW1iZWQob2Zmc2V0LCBzaGFyZWRDb21wb25lbnQsIGFjdGlvbi5mb3JtYXRzIHx8IHt9KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaXNFbXB0eSAmJiBvZmZzZXQgPT09IDApIHtcbiAgICAgICAgICAgICAgY29udGVudC5kZWxldGUoY29udGVudC5sZW5ndGggLSAxLCAxKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb2Zmc2V0ICs9IGxlbmd0aFxuICAgICAgICAgIH0gZWxzZSBpZiAoYWN0aW9uLnR5cGUgPT09ICdkZWxldGUnKSB7XG4gICAgICAgICAgICBjb25zdCBkZWx0YSA9IGNvbnRlbnQudG9EZWx0YSgpXG4gICAgICAgICAgICBpZiAoY29udGVudC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY29udGVudC5kZWxldGUob2Zmc2V0LCBhY3Rpb24uY291bnQpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY29udGVudC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgY29udGVudC5pbnNlcnQoMCwgJ1xcbicsIGRlbHRhWzBdPy5hdHRyaWJ1dGVzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoYWN0aW9uLnR5cGUgPT09ICdhdHRyU2V0Jykge1xuICAgICAgICAgICAgY29udGVudC5zZXRBdHRyaWJ1dGUoYWN0aW9uLm5hbWUsIGFjdGlvbi52YWx1ZSlcbiAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi50eXBlID09PSAnYXR0clJlbW92ZScpIHtcbiAgICAgICAgICAgIGNvbnRlbnQucmVtb3ZlQXR0cmlidXRlKGFjdGlvbi5uYW1lKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9KVxuXG4gICAgc3ViLmFkZChzbG90Lm9uQ2hpbGRDb21wb25lbnRSZW1vdmUuc3Vic2NyaWJlKGNvbXBvbmVudHMgPT4ge1xuICAgICAgY29tcG9uZW50cy5mb3JFYWNoKGMgPT4ge1xuICAgICAgICB0aGlzLmNsZWFuU3Vic2NyaXB0aW9uc0J5Q29tcG9uZW50KGMpXG4gICAgICB9KVxuICAgIH0pKVxuICAgIHRoaXMuY29udGVudFN5bmNDYWNoZXMuc2V0KHNsb3QsICgpID0+IHtcbiAgICAgIGNvbnRlbnQudW5vYnNlcnZlKHN5bmNSZW1vdGUpXG4gICAgICBzdWIudW5zdWJzY3JpYmUoKVxuICAgIH0pXG4gIH1cblxuICBwcm90ZWN0ZWQgc3luY1Nsb3RTdGF0ZShyZW1vdGVTbG90OiBZTWFwPGFueT4sIHNsb3Q6IFNsb3QpIHtcbiAgICBjb25zdCBzeW5jUmVtb3RlID0gKGV2LCB0cikgPT4ge1xuICAgICAgdGhpcy5ydW5SZW1vdGVVcGRhdGUodHIsICgpID0+IHtcbiAgICAgICAgZXYua2V5c0NoYW5nZWQuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgIGlmIChrZXkgPT09ICdzdGF0ZScpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXRlID0gKGV2LnRhcmdldCBhcyBZTWFwPGFueT4pLmdldCgnc3RhdGUnKVxuICAgICAgICAgICAgc2xvdC51cGRhdGVTdGF0ZShkcmFmdCA9PiB7XG4gICAgICAgICAgICAgIGlmICh0eXBlb2YgZHJhZnQgPT09ICdvYmplY3QnICYmIGRyYWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihkcmFmdCwgc3RhdGUpXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRlXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICB9XG4gICAgcmVtb3RlU2xvdC5vYnNlcnZlKHN5bmNSZW1vdGUpXG5cbiAgICBjb25zdCBzdWIgPSBzbG90Lm9uU3RhdGVDaGFuZ2UucGlwZShmaWx0ZXIoKCkgPT4ge1xuICAgICAgcmV0dXJuICF0aGlzLnNjaGVkdWxlci5pZ25vcmVDaGFuZ2VzXG4gICAgfSkpLnN1YnNjcmliZShjaGFuZ2UgPT4ge1xuICAgICAgdGhpcy5ydW5Mb2NhbFVwZGF0ZSgoKSA9PiB7XG4gICAgICAgIHJlbW90ZVNsb3Quc2V0KCdzdGF0ZScsIGNoYW5nZS5uZXdTdGF0ZSlcbiAgICAgIH0sIGNoYW5nZS5yZWNvcmQpXG4gICAgfSlcbiAgICB0aGlzLnNsb3RTdGF0ZVN5bmNDYWNoZXMuc2V0KHNsb3QsICgpID0+IHtcbiAgICAgIHJlbW90ZVNsb3QudW5vYnNlcnZlKHN5bmNSZW1vdGUpXG4gICAgICBzdWIudW5zdWJzY3JpYmUoKVxuICAgIH0pXG4gIH1cblxuICBwcm90ZWN0ZWQgc3luY0NvbXBvbmVudFNsb3RzKHJlbW90ZVNsb3RzOiBZQXJyYXk8YW55PiwgY29tcG9uZW50OiBDb21wb25lbnRJbnN0YW5jZSkge1xuICAgIGNvbnN0IHNsb3RzID0gY29tcG9uZW50LnNsb3RzXG4gICAgY29uc3Qgc3luY1JlbW90ZSA9IChldiwgdHIpID0+IHtcbiAgICAgIHRoaXMucnVuUmVtb3RlVXBkYXRlKHRyLCAoKSA9PiB7XG4gICAgICAgIGxldCBpbmRleCA9IDBcbiAgICAgICAgc2xvdHMucmV0YWluKGluZGV4KVxuICAgICAgICBldi5kZWx0YS5mb3JFYWNoKGFjdGlvbiA9PiB7XG4gICAgICAgICAgaWYgKFJlZmxlY3QuaGFzKGFjdGlvbiwgJ3JldGFpbicpKSB7XG4gICAgICAgICAgICBpbmRleCArPSBhY3Rpb24ucmV0YWluXG4gICAgICAgICAgICBzbG90cy5yZXRhaW4oaW5kZXgpXG4gICAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24uaW5zZXJ0KSB7XG4gICAgICAgICAgICAoYWN0aW9uLmluc2VydCBhcyBBcnJheTxZTWFwPGFueT4+KS5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgICBjb25zdCBzbG90ID0gdGhpcy5jcmVhdGVTbG90QnlTaGFyZWRTbG90KGl0ZW0pXG4gICAgICAgICAgICAgIHNsb3RzLmluc2VydChzbG90KVxuICAgICAgICAgICAgICB0aGlzLnN5bmNTbG90Q29udGVudChpdGVtLmdldCgnY29udGVudCcpLCBzbG90KVxuICAgICAgICAgICAgICB0aGlzLnN5bmNTbG90U3RhdGUoaXRlbSwgc2xvdClcbiAgICAgICAgICAgICAgaW5kZXgrK1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi5kZWxldGUpIHtcbiAgICAgICAgICAgIHNsb3RzLnJldGFpbihpbmRleClcbiAgICAgICAgICAgIHNsb3RzLmRlbGV0ZShhY3Rpb24uZGVsZXRlKVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgfVxuICAgIHJlbW90ZVNsb3RzLm9ic2VydmUoc3luY1JlbW90ZSlcblxuICAgIGNvbnN0IHN1YiA9IHNsb3RzLm9uQ2hhbmdlLnBpcGUoZmlsdGVyKCgpID0+IHtcbiAgICAgIHJldHVybiAhdGhpcy5zY2hlZHVsZXIuaWdub3JlQ2hhbmdlc1xuICAgIH0pKS5zdWJzY3JpYmUob3BlcmF0aW9ucyA9PiB7XG4gICAgICB0aGlzLnJ1bkxvY2FsVXBkYXRlKCgpID0+IHtcbiAgICAgICAgY29uc3QgYXBwbHlBY3Rpb25zID0gb3BlcmF0aW9ucy5hcHBseVxuICAgICAgICBsZXQgaW5kZXg6IG51bWJlclxuICAgICAgICBhcHBseUFjdGlvbnMuZm9yRWFjaChhY3Rpb24gPT4ge1xuICAgICAgICAgIGlmIChhY3Rpb24udHlwZSA9PT0gJ3JldGFpbicpIHtcbiAgICAgICAgICAgIGluZGV4ID0gYWN0aW9uLm9mZnNldFxuICAgICAgICAgIH0gZWxzZSBpZiAoYWN0aW9uLnR5cGUgPT09ICdpbnNlcnRTbG90Jykge1xuICAgICAgICAgICAgY29uc3Qgc2hhcmVkU2xvdCA9IHRoaXMuY3JlYXRlU2hhcmVkU2xvdEJ5U2xvdChhY3Rpb24ucmVmKVxuICAgICAgICAgICAgcmVtb3RlU2xvdHMuaW5zZXJ0KGluZGV4LCBbc2hhcmVkU2xvdF0pXG4gICAgICAgICAgICBpbmRleCsrXG4gICAgICAgICAgfSBlbHNlIGlmIChhY3Rpb24udHlwZSA9PT0gJ2RlbGV0ZScpIHtcbiAgICAgICAgICAgIHJlbW90ZVNsb3RzLmRlbGV0ZShpbmRleCwgYWN0aW9uLmNvdW50KVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgfSlcblxuICAgIHN1Yi5hZGQoc2xvdHMub25DaGlsZFNsb3RSZW1vdmUuc3Vic2NyaWJlKHNsb3RzID0+IHtcbiAgICAgIHNsb3RzLmZvckVhY2goc2xvdCA9PiB7XG4gICAgICAgIHRoaXMuY2xlYW5TdWJzY3JpcHRpb25zQnlTbG90KHNsb3QpXG4gICAgICB9KVxuICAgIH0pKVxuXG4gICAgdGhpcy5zbG90c1N5bmNDYWNoZXMuc2V0KGNvbXBvbmVudCwgKCkgPT4ge1xuICAgICAgcmVtb3RlU2xvdHMudW5vYnNlcnZlKHN5bmNSZW1vdGUpXG4gICAgICBzdWIudW5zdWJzY3JpYmUoKVxuICAgIH0pXG4gIH1cblxuICBwcm90ZWN0ZWQgc3luY0NvbXBvbmVudFN0YXRlKHJlbW90ZUNvbXBvbmVudDogWU1hcDxhbnk+LCBjb21wb25lbnQ6IENvbXBvbmVudEluc3RhbmNlKSB7XG4gICAgY29uc3Qgc3luY1JlbW90ZSA9IChldiwgdHIpID0+IHtcbiAgICAgIHRoaXMucnVuUmVtb3RlVXBkYXRlKHRyLCAoKSA9PiB7XG4gICAgICAgIGV2LmtleXNDaGFuZ2VkLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICBpZiAoa2V5ID09PSAnc3RhdGUnKSB7XG4gICAgICAgICAgICBjb25zdCBzdGF0ZSA9IChldi50YXJnZXQgYXMgWU1hcDxhbnk+KS5nZXQoJ3N0YXRlJylcbiAgICAgICAgICAgIGNvbXBvbmVudC51cGRhdGVTdGF0ZShkcmFmdCA9PiB7XG4gICAgICAgICAgICAgIGlmICh0eXBlb2YgZHJhZnQgPT09ICdvYmplY3QnICYmIGRyYWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihkcmFmdCwgc3RhdGUpXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRlXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICB9XG4gICAgcmVtb3RlQ29tcG9uZW50Lm9ic2VydmUoc3luY1JlbW90ZSlcblxuICAgIGNvbnN0IHN1YiA9IGNvbXBvbmVudC5vblN0YXRlQ2hhbmdlLnBpcGUoZmlsdGVyKCgpID0+IHtcbiAgICAgIHJldHVybiAhdGhpcy5zY2hlZHVsZXIuaWdub3JlQ2hhbmdlc1xuICAgIH0pKS5zdWJzY3JpYmUoY2hhbmdlID0+IHtcbiAgICAgIHRoaXMucnVuTG9jYWxVcGRhdGUoKCkgPT4ge1xuICAgICAgICByZW1vdGVDb21wb25lbnQuc2V0KCdzdGF0ZScsIGNoYW5nZS5uZXdTdGF0ZSlcbiAgICAgIH0sIGNoYW5nZS5yZWNvcmQpXG4gICAgfSlcbiAgICB0aGlzLmNvbXBvbmVudFN0YXRlU3luY0NhY2hlcy5zZXQoY29tcG9uZW50LCAoKSA9PiB7XG4gICAgICByZW1vdGVDb21wb25lbnQudW5vYnNlcnZlKHN5bmNSZW1vdGUpXG4gICAgICBzdWIudW5zdWJzY3JpYmUoKVxuICAgIH0pXG4gIH1cblxuICBwcm90ZWN0ZWQgcnVuTG9jYWxVcGRhdGUoZm46ICgpID0+IHZvaWQsIHJlY29yZCA9IHRydWUpIHtcbiAgICBpZiAodGhpcy51cGRhdGVGcm9tUmVtb3RlIHx8IHRoaXMuY29udHJvbGxlci5yZWFkb25seSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIHRoaXMudXBkYXRlUmVtb3RlQWN0aW9ucy5wdXNoKHtcbiAgICAgIHJlY29yZCxcbiAgICAgIGFjdGlvbjogZm5cbiAgICB9KVxuICB9XG5cbiAgcHJvdGVjdGVkIHJ1blJlbW90ZVVwZGF0ZSh0cjogVHJhbnNhY3Rpb24sIGZuOiAoKSA9PiB2b2lkKSB7XG4gICAgaWYgKHRyLm9yaWdpbiA9PT0gdGhpcy55RG9jKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgdGhpcy51cGRhdGVGcm9tUmVtb3RlID0gdHJ1ZVxuICAgIGlmICh0ci5vcmlnaW4gPT09IHRoaXMubWFuYWdlcikge1xuICAgICAgdGhpcy5zY2hlZHVsZXIuaGlzdG9yeUFwcGx5VHJhbnNhY3QoZm4pXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2NoZWR1bGVyLnJlbW90ZVVwZGF0ZVRyYW5zYWN0KGZuKVxuICAgIH1cbiAgICB0aGlzLnVwZGF0ZUZyb21SZW1vdGUgPSBmYWxzZVxuICB9XG5cbiAgcHJvdGVjdGVkIGNyZWF0ZVNoYXJlZENvbXBvbmVudEJ5Q29tcG9uZW50KGNvbXBvbmVudDogQ29tcG9uZW50SW5zdGFuY2UpOiBZTWFwPGFueT4ge1xuICAgIGNvbnN0IHNoYXJlZENvbXBvbmVudCA9IG5ldyBZTWFwKClcbiAgICBzaGFyZWRDb21wb25lbnQuc2V0KCdzdGF0ZScsIGNvbXBvbmVudC5zdGF0ZSlcbiAgICBzaGFyZWRDb21wb25lbnQuc2V0KCduYW1lJywgY29tcG9uZW50Lm5hbWUpXG4gICAgY29uc3Qgc2hhcmVkU2xvdHMgPSBuZXcgWUFycmF5KClcbiAgICBzaGFyZWRDb21wb25lbnQuc2V0KCdzbG90cycsIHNoYXJlZFNsb3RzKVxuICAgIGNvbXBvbmVudC5zbG90cy50b0FycmF5KCkuZm9yRWFjaChzbG90ID0+IHtcbiAgICAgIGNvbnN0IHNoYXJlZFNsb3QgPSB0aGlzLmNyZWF0ZVNoYXJlZFNsb3RCeVNsb3Qoc2xvdClcbiAgICAgIHNoYXJlZFNsb3RzLnB1c2goW3NoYXJlZFNsb3RdKVxuICAgIH0pXG4gICAgdGhpcy5zeW5jQ29tcG9uZW50U2xvdHMoc2hhcmVkU2xvdHMsIGNvbXBvbmVudClcbiAgICB0aGlzLnN5bmNDb21wb25lbnRTdGF0ZShzaGFyZWRDb21wb25lbnQsIGNvbXBvbmVudClcbiAgICByZXR1cm4gc2hhcmVkQ29tcG9uZW50XG4gIH1cblxuICBwcm90ZWN0ZWQgY3JlYXRlU2hhcmVkU2xvdEJ5U2xvdChzbG90OiBTbG90KTogWU1hcDxhbnk+IHtcbiAgICBjb25zdCBzaGFyZWRTbG90ID0gbmV3IFlNYXAoKVxuICAgIHNoYXJlZFNsb3Quc2V0KCdzY2hlbWEnLCBzbG90LnNjaGVtYSlcbiAgICBzaGFyZWRTbG90LnNldCgnc3RhdGUnLCBzbG90LnN0YXRlKVxuICAgIGNvbnN0IHNoYXJlZENvbnRlbnQgPSBuZXcgWVRleHQoKVxuICAgIHNoYXJlZFNsb3Quc2V0KCdjb250ZW50Jywgc2hhcmVkQ29udGVudClcbiAgICBsZXQgb2Zmc2V0ID0gMFxuICAgIHNsb3QudG9EZWx0YSgpLmZvckVhY2goaSA9PiB7XG4gICAgICBsZXQgZm9ybWF0czogYW55ID0ge31cbiAgICAgIGlmIChpLmZvcm1hdHMpIHtcbiAgICAgICAgaS5mb3JtYXRzLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgZm9ybWF0c1tpdGVtWzBdLm5hbWVdID0gaXRlbVsxXVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9ybWF0cyA9IG51bGxcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgaS5pbnNlcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHNoYXJlZENvbnRlbnQuaW5zZXJ0KG9mZnNldCwgaS5pbnNlcnQsIGZvcm1hdHMpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBzaGFyZWRDb21wb25lbnQgPSB0aGlzLmNyZWF0ZVNoYXJlZENvbXBvbmVudEJ5Q29tcG9uZW50KGkuaW5zZXJ0KVxuICAgICAgICBzaGFyZWRDb250ZW50Lmluc2VydEVtYmVkKG9mZnNldCwgc2hhcmVkQ29tcG9uZW50LCBmb3JtYXRzKVxuICAgICAgfVxuICAgICAgb2Zmc2V0ICs9IGkuaW5zZXJ0Lmxlbmd0aFxuICAgIH0pXG4gICAgc2xvdC5nZXRBdHRyaWJ1dGVzKCkuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIHNoYXJlZENvbnRlbnQuc2V0QXR0cmlidXRlKGl0ZW1bMF0ubmFtZSwgaXRlbVsxXSlcbiAgICB9KVxuICAgIHRoaXMuc3luY1Nsb3RDb250ZW50KHNoYXJlZENvbnRlbnQsIHNsb3QpXG4gICAgdGhpcy5zeW5jU2xvdFN0YXRlKHNoYXJlZFNsb3QsIHNsb3QpXG4gICAgcmV0dXJuIHNoYXJlZFNsb3RcbiAgfVxuXG4gIHByb3RlY3RlZCBjcmVhdGVDb21wb25lbnRCeVNoYXJlZENvbXBvbmVudCh5TWFwOiBZTWFwPGFueT4sIGNhbkluc2VydElubGluZUNvbXBvbmVudDogYm9vbGVhbik6IENvbXBvbmVudEluc3RhbmNlIHtcbiAgICBjb25zdCBzaGFyZWRTbG90cyA9IHlNYXAuZ2V0KCdzbG90cycpIGFzIFlBcnJheTxZTWFwPGFueT4+XG4gICAgY29uc3Qgc2xvdHM6IFNsb3RbXSA9IFtdXG4gICAgc2hhcmVkU2xvdHMuZm9yRWFjaChzaGFyZWRTbG90ID0+IHtcbiAgICAgIGNvbnN0IHNsb3QgPSB0aGlzLmNyZWF0ZVNsb3RCeVNoYXJlZFNsb3Qoc2hhcmVkU2xvdClcbiAgICAgIHNsb3RzLnB1c2goc2xvdClcbiAgICB9KVxuICAgIGNvbnN0IG5hbWUgPSB5TWFwLmdldCgnbmFtZScpXG4gICAgY29uc3Qgc3RhdGUgPSB5TWFwLmdldCgnc3RhdGUnKVxuICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5mYWN0b3J5LmNyZWF0ZUNvbXBvbmVudEJ5RGF0YShuYW1lLCB7XG4gICAgICBzdGF0ZSxcbiAgICAgIHNsb3RzXG4gICAgfSlcbiAgICBpZiAoaW5zdGFuY2UpIHtcbiAgICAgIGluc3RhbmNlLnNsb3RzLnRvQXJyYXkoKS5mb3JFYWNoKChzbG90LCBpbmRleCkgPT4ge1xuICAgICAgICBsZXQgc2hhcmVkU2xvdCA9IHNoYXJlZFNsb3RzLmdldChpbmRleClcbiAgICAgICAgaWYgKCFzaGFyZWRTbG90KSB7XG4gICAgICAgICAgc2hhcmVkU2xvdCA9IHRoaXMuY3JlYXRlU2hhcmVkU2xvdEJ5U2xvdChzbG90KVxuICAgICAgICAgIHNoYXJlZFNsb3RzLnB1c2goW3NoYXJlZFNsb3RdKVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3luY1Nsb3RTdGF0ZShzaGFyZWRTbG90LCBzbG90KVxuICAgICAgICB0aGlzLnN5bmNTbG90Q29udGVudChzaGFyZWRTbG90LmdldCgnY29udGVudCcpLCBzbG90KVxuICAgICAgfSlcbiAgICAgIHJldHVybiBpbnN0YW5jZVxuICAgIH1cbiAgICByZXR1cm4gY3JlYXRlVW5rbm93bkNvbXBvbmVudChuYW1lLCBjYW5JbnNlcnRJbmxpbmVDb21wb25lbnQpLmNyZWF0ZUluc3RhbmNlKHRoaXMuc3RhcnRlcilcbiAgfVxuXG4gIHByb3RlY3RlZCBjcmVhdGVTbG90QnlTaGFyZWRTbG90KHNoYXJlZFNsb3Q6IFlNYXA8YW55Pik6IFNsb3Qge1xuICAgIGNvbnN0IGNvbnRlbnQgPSBzaGFyZWRTbG90LmdldCgnY29udGVudCcpIGFzIFlUZXh0XG4gICAgY29uc3QgZGVsdGEgPSBjb250ZW50LnRvRGVsdGEoKVxuXG4gICAgY29uc3Qgc2xvdCA9IHRoaXMuZmFjdG9yeS5jcmVhdGVTbG90KHtcbiAgICAgIHNjaGVtYTogc2hhcmVkU2xvdC5nZXQoJ3NjaGVtYScpLFxuICAgICAgc3RhdGU6IHNoYXJlZFNsb3QuZ2V0KCdzdGF0ZScpLFxuICAgICAgYXR0cmlidXRlczoge30sXG4gICAgICBmb3JtYXRzOiB7fSxcbiAgICAgIGNvbnRlbnQ6IFtdXG4gICAgfSlcblxuICAgIGNvbnN0IGF0dHJzID0gY29udGVudC5nZXRBdHRyaWJ1dGVzKClcbiAgICBPYmplY3Qua2V5cyhhdHRycykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgY29uc3QgYXR0cmlidXRlID0gdGhpcy5mYWN0b3J5LmdldEF0dHJpYnV0ZShrZXkpXG4gICAgICBpZiAoYXR0cmlidXRlKSB7XG4gICAgICAgIHNsb3Quc2V0QXR0cmlidXRlKGF0dHJpYnV0ZSwgYXR0cnNba2V5XSlcbiAgICAgIH1cbiAgICB9KVxuICAgIGZvciAoY29uc3QgYWN0aW9uIG9mIGRlbHRhKSB7XG4gICAgICBpZiAoYWN0aW9uLmluc2VydCkge1xuICAgICAgICBpZiAodHlwZW9mIGFjdGlvbi5pbnNlcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgY29uc3QgZm9ybWF0cyA9IHJlbW90ZUZvcm1hdHNUb0xvY2FsKHRoaXMuZmFjdG9yeSwgYWN0aW9uLmF0dHJpYnV0ZXMpXG4gICAgICAgICAgc2xvdC5pbnNlcnQoYWN0aW9uLmluc2VydCwgZm9ybWF0cylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBzaGFyZWRDb21wb25lbnQgPSBhY3Rpb24uaW5zZXJ0IGFzIFlNYXA8YW55PlxuICAgICAgICAgIGNvbnN0IGNhbkluc2VydElubGluZUNvbXBvbmVudCA9IHNsb3Quc2NoZW1hLmluY2x1ZGVzKENvbnRlbnRUeXBlLklubGluZUNvbXBvbmVudClcbiAgICAgICAgICBjb25zdCBjb21wb25lbnQgPSB0aGlzLmNyZWF0ZUNvbXBvbmVudEJ5U2hhcmVkQ29tcG9uZW50KHNoYXJlZENvbXBvbmVudCwgY2FuSW5zZXJ0SW5saW5lQ29tcG9uZW50KVxuICAgICAgICAgIHNsb3QuaW5zZXJ0KGNvbXBvbmVudCwgcmVtb3RlRm9ybWF0c1RvTG9jYWwodGhpcy5mYWN0b3J5LCBhY3Rpb24uYXR0cmlidXRlcykpXG4gICAgICAgICAgdGhpcy5zeW5jQ29tcG9uZW50U2xvdHMoc2hhcmVkQ29tcG9uZW50LmdldCgnc2xvdHMnKSwgY29tcG9uZW50KVxuICAgICAgICAgIHRoaXMuc3luY0NvbXBvbmVudFN0YXRlKHNoYXJlZENvbXBvbmVudCwgY29tcG9uZW50KVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBjb2xsYWJvcmF0ZUVycm9yRm4oJ3VuZXhwZWN0ZWQgZGVsdGEgYWN0aW9uLicpXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzbG90XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xlYW5TdWJzY3JpcHRpb25zQnlTbG90KHNsb3Q6IFNsb3QpIHtcbiAgICB0aGlzLmNvbnRlbnRNYXAuZGVsZXRlKHNsb3QpO1xuICAgIFt0aGlzLmNvbnRlbnRTeW5jQ2FjaGVzLmdldChzbG90KSwgdGhpcy5zbG90U3RhdGVTeW5jQ2FjaGVzLmdldChzbG90KV0uZm9yRWFjaChmbiA9PiB7XG4gICAgICBpZiAoZm4pIHtcbiAgICAgICAgZm4oKVxuICAgICAgfVxuICAgIH0pXG4gICAgc2xvdC5zbGljZUNvbnRlbnQoKS5mb3JFYWNoKGkgPT4ge1xuICAgICAgaWYgKHR5cGVvZiBpICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLmNsZWFuU3Vic2NyaXB0aW9uc0J5Q29tcG9uZW50KGkpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIHByb3RlY3RlZCBjbGVhblN1YnNjcmlwdGlvbnNCeUNvbXBvbmVudChjb21wb25lbnQ6IENvbXBvbmVudEluc3RhbmNlKSB7XG4gICAgW3RoaXMuc2xvdHNTeW5jQ2FjaGVzLmdldChjb21wb25lbnQpLCB0aGlzLmNvbXBvbmVudFN0YXRlU3luY0NhY2hlcy5nZXQoY29tcG9uZW50KV0uZm9yRWFjaChmbiA9PiB7XG4gICAgICBpZiAoZm4pIHtcbiAgICAgICAgZm4oKVxuICAgICAgfVxuICAgIH0pXG4gICAgY29tcG9uZW50LnNsb3RzLnRvQXJyYXkoKS5mb3JFYWNoKHNsb3QgPT4ge1xuICAgICAgdGhpcy5jbGVhblN1YnNjcmlwdGlvbnNCeVNsb3Qoc2xvdClcbiAgICB9KVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlbW90ZUZvcm1hdHNUb0xvY2FsKGZhY3Rvcnk6IEZhY3RvcnksIGF0dHJzPzogYW55LCkge1xuICBjb25zdCBmb3JtYXRzOiBGb3JtYXRzID0gW11cbiAgaWYgKGF0dHJzKSB7XG4gICAgT2JqZWN0LmtleXMoYXR0cnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGNvbnN0IGZvcm1hdHRlciA9IGZhY3RvcnkuZ2V0Rm9ybWF0dGVyKGtleSlcbiAgICAgIGlmIChmb3JtYXR0ZXIpIHtcbiAgICAgICAgZm9ybWF0cy5wdXNoKFtmb3JtYXR0ZXIsIGF0dHJzW2tleV1dKVxuICAgICAgfVxuICAgIH0pXG4gIH1cbiAgcmV0dXJuIGZvcm1hdHNcbn1cbiJdfQ==