@limble/limble-tree 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +1 -0
  2. package/esm2022/lib/components/branch/branch.component.mjs +79 -0
  3. package/{esm2020 → esm2022}/lib/components/dragover-no-change-detect.mjs +4 -4
  4. package/{esm2020 → esm2022}/lib/components/dropzone/dropzone.component.mjs +4 -4
  5. package/{esm2020 → esm2022}/lib/components/root/root.component.mjs +5 -5
  6. package/esm2022/lib/core/tree-branch/tree-branch.mjs +429 -0
  7. package/esm2022/lib/core/tree-node-base.mjs +77 -0
  8. package/esm2022/lib/core/tree-root/tree-root.mjs +193 -0
  9. package/{esm2020 → esm2022}/lib/core/tree-service/tree.service.mjs +4 -4
  10. package/{esm2020 → esm2022}/lib/extras/collapse/collapse.module.mjs +5 -5
  11. package/{esm2020 → esm2022}/lib/extras/collapse/collapse.service.mjs +4 -4
  12. package/esm2022/lib/extras/drag-and-drop/drag-and-drop.mjs +83 -0
  13. package/{esm2020 → esm2022}/lib/extras/drag-and-drop/drag-and-drop.module.mjs +5 -5
  14. package/{esm2020 → esm2022}/lib/extras/drag-and-drop/drag-and-drop.service.mjs +4 -4
  15. package/{esm2020 → esm2022}/lib/extras/drag-and-drop/draggable.directive.mjs +4 -4
  16. package/esm2022/lib/legacy/limble-tree-legacy.module.mjs +20 -0
  17. package/{esm2020 → esm2022}/lib/legacy/limble-tree-root/limble-tree-root.component.mjs +4 -4
  18. package/{esm2020 → esm2022}/lib/limble-tree.module.mjs +5 -5
  19. package/{fesm2020 → fesm2022}/limble-limble-tree.mjs +59 -62
  20. package/fesm2022/limble-limble-tree.mjs.map +1 -0
  21. package/lib/components/branch/branch.component.d.ts +1 -1
  22. package/lib/components/dropzone/dropzone.component.d.ts +1 -1
  23. package/lib/extras/drag-and-drop/draggable.directive.d.ts +1 -1
  24. package/lib/legacy/limble-tree-root/limble-tree-root.component.d.ts +1 -1
  25. package/package.json +7 -13
  26. package/esm2020/lib/components/branch/branch.component.mjs +0 -79
  27. package/esm2020/lib/core/tree-branch/tree-branch.mjs +0 -429
  28. package/esm2020/lib/core/tree-node-base.mjs +0 -80
  29. package/esm2020/lib/core/tree-root/tree-root.mjs +0 -193
  30. package/esm2020/lib/extras/drag-and-drop/drag-and-drop.mjs +0 -83
  31. package/esm2020/lib/legacy/limble-tree-legacy.module.mjs +0 -20
  32. package/fesm2015/limble-limble-tree.mjs +0 -1812
  33. package/fesm2015/limble-limble-tree.mjs.map +0 -1
  34. package/fesm2020/limble-limble-tree.mjs.map +0 -1
  35. /package/{esm2020 → esm2022}/lib/components/branch/index.mjs +0 -0
  36. /package/{esm2020 → esm2022}/lib/components/dropzone/index.mjs +0 -0
  37. /package/{esm2020 → esm2022}/lib/components/host-component.interface.mjs +0 -0
  38. /package/{esm2020 → esm2022}/lib/components/index.mjs +0 -0
  39. /package/{esm2020 → esm2022}/lib/components/node-component.interface.mjs +0 -0
  40. /package/{esm2020 → esm2022}/lib/components/root/index.mjs +0 -0
  41. /package/{esm2020 → esm2022}/lib/core/branch-options.interface.mjs +0 -0
  42. /package/{esm2020 → esm2022}/lib/core/branchable.interface.mjs +0 -0
  43. /package/{esm2020 → esm2022}/lib/core/component-container.interface.mjs +0 -0
  44. /package/{esm2020 → esm2022}/lib/core/configuration/configuration.mjs +0 -0
  45. /package/{esm2020 → esm2022}/lib/core/configuration/index.mjs +0 -0
  46. /package/{esm2020 → esm2022}/lib/core/configuration/tree-options.interface.mjs +0 -0
  47. /package/{esm2020 → esm2022}/lib/core/index.mjs +0 -0
  48. /package/{esm2020 → esm2022}/lib/core/tree-branch/branch-controller.mjs +0 -0
  49. /package/{esm2020 → esm2022}/lib/core/tree-branch/graftable.interface.mjs +0 -0
  50. /package/{esm2020 → esm2022}/lib/core/tree-branch/index.mjs +0 -0
  51. /package/{esm2020 → esm2022}/lib/core/tree-node.interface.mjs +0 -0
  52. /package/{esm2020 → esm2022}/lib/core/tree-plot.interface.mjs +0 -0
  53. /package/{esm2020 → esm2022}/lib/core/tree-root/index.mjs +0 -0
  54. /package/{esm2020 → esm2022}/lib/core/tree-root/root-controller.mjs +0 -0
  55. /package/{esm2020 → esm2022}/lib/core/tree-service/index.mjs +0 -0
  56. /package/{esm2020 → esm2022}/lib/errors/index.mjs +0 -0
  57. /package/{esm2020 → esm2022}/lib/errors/tree-error.mjs +0 -0
  58. /package/{esm2020 → esm2022}/lib/events/drag/drag-end-event.mjs +0 -0
  59. /package/{esm2020 → esm2022}/lib/events/drag/drag-start-event.mjs +0 -0
  60. /package/{esm2020 → esm2022}/lib/events/drag/drop-event.mjs +0 -0
  61. /package/{esm2020 → esm2022}/lib/events/drag/index.mjs +0 -0
  62. /package/{esm2020 → esm2022}/lib/events/general/destruction-event.mjs +0 -0
  63. /package/{esm2020 → esm2022}/lib/events/general/index.mjs +0 -0
  64. /package/{esm2020 → esm2022}/lib/events/index.mjs +0 -0
  65. /package/{esm2020 → esm2022}/lib/events/relational/graft-event.mjs +0 -0
  66. /package/{esm2020 → esm2022}/lib/events/relational/index.mjs +0 -0
  67. /package/{esm2020 → esm2022}/lib/events/relational/prune-event.mjs +0 -0
  68. /package/{esm2020 → esm2022}/lib/events/relational/relational-tree-event.interface.mjs +0 -0
  69. /package/{esm2020 → esm2022}/lib/events/relational/tree-relationship.interface.mjs +0 -0
  70. /package/{esm2020 → esm2022}/lib/events/tree-event.interface.mjs +0 -0
  71. /package/{esm2020 → esm2022}/lib/extras/collapse/collapse.mjs +0 -0
  72. /package/{esm2020 → esm2022}/lib/extras/collapse/index.mjs +0 -0
  73. /package/{esm2020 → esm2022}/lib/extras/drag-and-drop/drag-state.mjs +0 -0
  74. /package/{esm2020 → esm2022}/lib/extras/drag-and-drop/dropzone-renderer.mjs +0 -0
  75. /package/{esm2020 → esm2022}/lib/extras/drag-and-drop/index.mjs +0 -0
  76. /package/{esm2020 → esm2022}/lib/legacy/index.mjs +0 -0
  77. /package/{esm2020 → esm2022}/lib/legacy/legacy-component-obj.interface.mjs +0 -0
  78. /package/{esm2020 → esm2022}/lib/legacy/legacy-tree-data.interface.mjs +0 -0
  79. /package/{esm2020 → esm2022}/lib/legacy/legacy-tree-options.interface.mjs +0 -0
  80. /package/{esm2020 → esm2022}/lib/legacy/legacy-tree.mjs +0 -0
  81. /package/{esm2020 → esm2022}/limble-limble-tree.mjs +0 -0
  82. /package/{esm2020 → esm2022}/public-api.mjs +0 -0
  83. /package/{esm2020 → esm2022}/shared/assert.mjs +0 -0
  84. /package/{esm2020 → esm2022}/shared/has-property.mjs +0 -0
  85. /package/{esm2020 → esm2022}/shared/index.mjs +0 -0
@@ -1,429 +0,0 @@
1
- import { assert } from "../../../shared";
2
- import { TreeError } from "../../errors";
3
- import { dropzoneRenderer } from "../../extras/drag-and-drop";
4
- import { TreeRoot } from "../tree-root";
5
- import { TreeNodeBase } from "../tree-node-base";
6
- import { config } from "../configuration";
7
- import { BranchController } from "./branch-controller";
8
- import { treeCollapser } from "../../extras/collapse";
9
- import { DestructionEvent, GraftEvent, PruneEvent } from "../../events";
10
- /** Represents a standard node in a tree. Renders a BranchComponent.
11
- *
12
- * @remarks
13
- * This class renders a branch component, which does the following:
14
- * 1. Renders a component provided by the user
15
- * 2. Provides a container in which child branches may be rendered
16
- * 3. Contains two Dropzones: one for dropping branches below this branch (as a
17
- * sibling), and one for dropping branches as a first child of this branch.
18
- */
19
- export class TreeBranch {
20
- constructor(parent, branchOptions) {
21
- this.branchOptions = branchOptions;
22
- this.detachedView = null;
23
- this.treeNodeBase = new TreeNodeBase();
24
- const parentBranchesContainer = parent.getBranchesContainer();
25
- assert(parentBranchesContainer !== undefined);
26
- this.branchController = new BranchController(this, parentBranchesContainer);
27
- const hostView = this.branchController.getHostView();
28
- if (parent instanceof TreeBranch &&
29
- parent.branchOptions.defaultCollapsed === true) {
30
- treeCollapser.storePrecollapsedNode(parent, this);
31
- this.detachedView = hostView;
32
- }
33
- else {
34
- parentBranchesContainer.insert(hostView);
35
- this._parent = parent;
36
- this.dispatch(new GraftEvent(this, {
37
- parent: this._parent,
38
- child: this,
39
- index: this._parent.branches().length
40
- }));
41
- this.setIndentation();
42
- }
43
- this.detectChanges();
44
- }
45
- /** @returns All child branches as an array of TreeBranch instances, in order. */
46
- branches() {
47
- return this.treeNodeBase.branches();
48
- }
49
- /**
50
- * Recursively destroys all descendant branches, as well as itself. This
51
- * releases all resources held or consumed by this branch and its descendants.
52
- *
53
- * @remarks
54
- * It is important to call this method when a branch is discarded, otherwise
55
- * the branch will remain in memory and continue to consume resources.
56
- */
57
- destroy() {
58
- if (this.isDestroyed()) {
59
- throw new TreeError("Cannot destroy a destroyed tree branch");
60
- }
61
- this.prune();
62
- treeCollapser.expand(this);
63
- dropzoneRenderer.clearTreeFromRegistry(this);
64
- this.branchController.getHostView().destroy();
65
- this.treeNodeBase.destroy();
66
- this.branchController.destroy();
67
- this.dispatch(new DestructionEvent(this));
68
- }
69
- /** Run Angular change detection on this branch */
70
- detectChanges() {
71
- this.branchController.detectChanges();
72
- }
73
- /**
74
- * Emits the specified TreeEvent.
75
- *
76
- * @remarks
77
- * Caution: It is not recommended to manually emit TreeEvents that are already
78
- * provided by the library. For example, it is not recommended to emit a
79
- * `GraftEvent`, `DestructionEvent`, etc. These events may be used by the tree,
80
- * and emitting them manually may cause unexpected behavior. Instead, we
81
- * recommend implementing the TreeEvent interface with your own custom events
82
- * and dispatching those.
83
- *
84
- * @param event - The TreeEvent that will be emitted.
85
- */
86
- dispatch(event) {
87
- this.treeNodeBase.dispatch(event);
88
- this._parent?.dispatch(event);
89
- }
90
- /**
91
- * @returns
92
- * An observable that emits TreeEvents whenever an event is dispatched
93
- * in this branch or any of its descendant branches.
94
- */
95
- events() {
96
- return this.treeNodeBase.events();
97
- }
98
- /**
99
- * @param index - The index of the child branch to retrieve.
100
- *
101
- * @returns
102
- * The child branch at the specified index, or undefined if there is
103
- * no child branch at the specified index.
104
- */
105
- getBranch(index) {
106
- return this.treeNodeBase.getBranch(index);
107
- }
108
- /** @returns The ViewContainerRef in which child branches are rendered */
109
- getBranchesContainer() {
110
- if (this.isDestroyed()) {
111
- throw new TreeError("Cannot get branches container from a destroyed tree branch");
112
- }
113
- return this.branchController.getBranchesContainer();
114
- }
115
- /** @returns The instance of BranchComponent that is rendered by this class. */
116
- getComponentInstance() {
117
- if (this.isDestroyed()) {
118
- throw new TreeError("Cannot get component instance from a destroyed tree branch");
119
- }
120
- return this.branchController.getComponentInstance();
121
- }
122
- /** @returns The Host View in which the BranchComponent is rendered */
123
- getHostView() {
124
- if (this.isDestroyed()) {
125
- throw new TreeError("Cannot get component host view from a destroyed tree branch");
126
- }
127
- return this.branchController.getHostView();
128
- }
129
- /** @returns The BranchComponent as a native HTML Element */
130
- getNativeElement() {
131
- if (this.isDestroyed()) {
132
- throw new TreeError("Cannot get native element from a destroyed tree branch");
133
- }
134
- return this.branchController.getNativeElement();
135
- }
136
- /**
137
- * @returns
138
- * A ComponentRef containing the instance of the user-provided
139
- * component which is rendered by this branch.
140
- */
141
- getUserlandComponentRef() {
142
- if (this.isDestroyed()) {
143
- throw new TreeError("Cannot get userland component from a destroyed tree branch");
144
- }
145
- return this.branchController.getUserlandComponentRef();
146
- }
147
- /**
148
- * Attaches a branch to a new parent node.
149
- *
150
- * @remarks
151
- * If not already pruned, this method prunes (removes) this branch from its
152
- * current position in the tree; then grafts (reattaches) it as a child of the
153
- * specified parent branch at the specified index. If no index is specified,
154
- * the branch is appended as the last child of the parent. This causes this
155
- * branch's associated BranchComponent to be re-rendered in the DOM at the
156
- * new location.
157
- *
158
- * @param newParent - The new parent branch unto which this branch will be grafted.
159
- * @param index - The index at which this branch will be grafted. If not specified,
160
- * this branch will be appended as the last child of the new parent.
161
- *
162
- * @returns The index at which this branch was grafted.
163
- */
164
- graftTo(newParent, index) {
165
- this.checkGraftLocationValidity(newParent, index);
166
- const ownIndex = this.index();
167
- if (ownIndex !== undefined) {
168
- this.prune();
169
- }
170
- this._parent = newParent;
171
- const newIndex = index ?? newParent.branches().length;
172
- this.reattachView(newIndex);
173
- this.dispatch(new GraftEvent(this, {
174
- parent: newParent,
175
- child: this,
176
- index: newIndex
177
- }));
178
- return newIndex;
179
- }
180
- /**
181
- * Appends a new child branch to this branch. The child branch will render
182
- * the specified component according to the (optional) configuration parameter.
183
- *
184
- * @param component - The component to render in the new child branch.
185
- * @param options - Configuration options for the new child branch.
186
- *
187
- * @returns
188
- * The newly-created child branch.
189
- */
190
- grow(component, options) {
191
- if (this.isDestroyed()) {
192
- throw new TreeError("Cannot grow a branch on a destroyed tree branch");
193
- }
194
- try {
195
- return new TreeBranch(this, { component, ...options });
196
- }
197
- catch (error) {
198
- this.handleUserlandError(error);
199
- }
200
- }
201
- /**
202
- * Determines this branch's index in relation to its sibling branches.
203
- *
204
- * @remarks
205
- * For example, if it is the first child of its parent, this method will return
206
- * 0. If it is the second child of its parent, this method will return 1.
207
- *
208
- * If this branch has no parent, (eg, if this branch has been pruned) this
209
- * method will return undefined.
210
- *
211
- * @returns
212
- * The index of this branch in relation to its sibling branches, or undefined.
213
- */
214
- index() {
215
- if (!this._parent) {
216
- return undefined;
217
- }
218
- const index = this._parent
219
- .branches()
220
- .findIndex((branch) => branch === this);
221
- assert(index >= 0);
222
- return index;
223
- }
224
- /** @returns `true` if the branch is destroyed, `false` otherwise */
225
- isDestroyed() {
226
- return this.treeNodeBase.isDestroyed();
227
- }
228
- /**
229
- * @returns
230
- * The data that was passed into the `branchOptions`' `meta` property
231
- * at construction.
232
- */
233
- meta() {
234
- return this.branchOptions.meta ?? {};
235
- }
236
- /**
237
- * @returns
238
- * This branch's parent node (which may be a TreeBranch or TreeRoot).
239
- * If this branch has no parent, (eg, if this branch has been pruned) this
240
- * method will return undefined.
241
- */
242
- parent() {
243
- return this._parent;
244
- }
245
- /**
246
- * Provides a model describing this branch's descendants.
247
- *
248
- * @returns
249
- * A multi-dimensional Map which describes the shape of this branch's
250
- * descendants.
251
- *
252
- * @example
253
- * A branch with no children will return an empty Map. A branch with
254
- * a single child will return a Map with a single entry, where the key is the index
255
- * of the branch (zero) and the value is an empty Map. A Tree like this:
256
- *
257
- * ```
258
- * ---Branch-------Branch
259
- * /
260
- * Branch-------Branch
261
- * \
262
- * ---Branch
263
- * ```
264
- * Will return a Map of matching shape:
265
- * ```
266
- * Map {
267
- * 0: Map { 0: Map {}},
268
- * 1: Map {},
269
- * 2: Map {}
270
- * }
271
- * ```
272
- */
273
- plot() {
274
- return this.treeNodeBase.plot();
275
- }
276
- /**
277
- * Calculates the branch's position in the tree relative to the Root.
278
- *
279
- * @remarks
280
- * The position is described as an array of numbers, where each number
281
- * represents the index of the branch at that level of the tree.
282
- *
283
- * For example, if this branch is the first child of the Root, this method
284
- * will return [0]. If this branch is the second child of the first child
285
- * of the Root, this method will return [0, 1].
286
- *
287
- * If the branch is not related to a TreeRoot, (such as when it has been
288
- * pruned,) this method will throw an error.
289
- *
290
- * @returns
291
- * An array of numbers which describe the branch's position in the tree
292
- * relative to the Root.
293
- */
294
- position() {
295
- const index = this.index();
296
- if (index === undefined) {
297
- throw new TreeError("branch has no parent. Position cannot be determined.");
298
- }
299
- if (this._parent instanceof TreeBranch) {
300
- const parentPosition = this._parent.position();
301
- return [...parentPosition, index];
302
- }
303
- return [index];
304
- }
305
- /**
306
- * Removes a branch from its tree without destroying it.
307
- *
308
- * @remarks
309
- * Removes this branch from its parent and detaches its associated
310
- * BranchComponent from the DOM. This puts the branch in a "pruned" state,
311
- * which may affect the behavior of other methods.
312
- *
313
- * A pruned branch can be reattached to any other node using the `graftTo` method.
314
- *
315
- * @returns
316
- * Itself, or undefined if it is already in a pruned state.
317
- */
318
- prune() {
319
- if (this.isDestroyed()) {
320
- throw new TreeError("Cannot prune a destroyed tree branch");
321
- }
322
- const parent = this._parent;
323
- const index = this.index();
324
- if (index === undefined || parent === undefined)
325
- return;
326
- const container = parent.getBranchesContainer();
327
- assert(container !== undefined);
328
- this.detachedView = container.detach(index);
329
- assert(this.detachedView !== null);
330
- this.detachedView.detach();
331
- this.dispatch(new PruneEvent(this, {
332
- parent: parent,
333
- child: this,
334
- index: index
335
- }));
336
- this._parent = undefined;
337
- return this;
338
- }
339
- /**
340
- * Get the root of the tree to which this Branch is attached.
341
- *
342
- * @returns
343
- * The TreeRoot of the tree this branch is in. If this branch is
344
- * does not have a root (such as when it has been pruned) this method will
345
- * return undefined.
346
- */
347
- root() {
348
- const parent = this.parent();
349
- if (parent instanceof TreeBranch) {
350
- return parent.root();
351
- }
352
- assert(parent instanceof TreeRoot || parent === undefined);
353
- return parent;
354
- }
355
- /**
356
- * Traverses this branch's descendants in depth-first pre-order, executing
357
- * the provided callback function on each node. Traversal includes this branch.
358
- *
359
- * @param callback - A function to execute on each node.
360
- */
361
- traverse(callback) {
362
- callback(this);
363
- this.treeNodeBase.traverse(callback);
364
- }
365
- checkGraftLocationValidity(newParent, index) {
366
- if (this.isDestroyed()) {
367
- throw new TreeError("Cannot graft a destroyed tree branch");
368
- }
369
- if (newParent.isDestroyed()) {
370
- throw new TreeError("Cannot graft to a destroyed tree branch");
371
- }
372
- if (typeof index === "number" &&
373
- this.indexIsOutOfRange(newParent, index)) {
374
- throw new TreeError(`Cannot graft branch at index ${index} of the parent. Out of range.`);
375
- }
376
- this.traverse((node) => {
377
- if (node === newParent) {
378
- throw new TreeError("Cannot graft a branch to itself or any of its own descendants");
379
- }
380
- });
381
- }
382
- handleUserlandError(error) {
383
- // When an error occurs in a userland component during a tree operation,
384
- // it can cause undefined, bizarre behavior in the tree. To prevent this,
385
- // we destroy the tree and throw an error instead. This helps protect
386
- // the end-user's data from corruption.
387
- this.furthestAncestor().destroy();
388
- this.treeNodeBase.handleUserlandError(error);
389
- }
390
- indexIsOutOfRange(parent, index) {
391
- return index < 0 || index > parent.branches().length;
392
- }
393
- furthestAncestor() {
394
- // eslint-disable-next-line typescript/no-this-alias -- This code is for an iteration, not to make `this` available in other scopes (which is what the rule is intended to protect against).
395
- let node = this;
396
- while (node instanceof TreeBranch) {
397
- const parent = node.parent();
398
- if (parent === undefined)
399
- break;
400
- node = parent;
401
- }
402
- return node;
403
- }
404
- reattachView(index) {
405
- assert(this._parent !== undefined);
406
- assert(this.detachedView !== null);
407
- const container = this._parent.getBranchesContainer();
408
- assert(container !== undefined);
409
- this.detachedView.reattach();
410
- container.insert(this.detachedView, index);
411
- this.detachedView = null;
412
- this.setIndentation();
413
- }
414
- setIndentation() {
415
- assert(this._parent !== undefined);
416
- const root = this._parent.root();
417
- if (root === undefined) {
418
- return;
419
- }
420
- const options = config.getConfig(root);
421
- const branchesContainerEl = this.branchController
422
- .getNativeElement()
423
- .getElementsByClassName("branches-container")
424
- .item(0);
425
- assert(branchesContainerEl instanceof HTMLElement);
426
- branchesContainerEl.style.marginLeft = `${options?.indentation ?? 16}px`;
427
- }
428
- }
429
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1icmFuY2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2NvcmUvdHJlZS1icmFuY2gvdHJlZS1icmFuY2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBU3pDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUd4QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBSzFDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXZELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN0RCxPQUFPLEVBQ0osZ0JBQWdCLEVBQ2hCLFVBQVUsRUFDVixVQUFVLEVBRVosTUFBTSxjQUFjLENBQUM7QUFFdEI7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLE9BQU8sVUFBVTtJQVFwQixZQUNHLE1BQW1DLEVBQ25CLGFBQW1EO1FBQW5ELGtCQUFhLEdBQWIsYUFBYSxDQUFzQztRQU45RCxpQkFBWSxHQUFtQixJQUFJLENBQUM7UUFRekMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sdUJBQXVCLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDOUQsTUFBTSxDQUFDLHVCQUF1QixLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLGdCQUFnQixDQUN6QyxJQUFJLEVBQ0osdUJBQXVC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YXJlZFwiO1xuaW1wb3J0IHR5cGUgeyBPYnNlcnZhYmxlIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB0eXBlIHtcbiAgIENvbXBvbmVudFJlZixcbiAgIFR5cGUsXG4gICBWaWV3Q29udGFpbmVyUmVmLFxuICAgVmlld1JlZlxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgQnJhbmNoQ29tcG9uZW50IH0gZnJvbSBcIi4uLy4uL2NvbXBvbmVudHNcIjtcbmltcG9ydCB7IFRyZWVFcnJvciB9IGZyb20gXCIuLi8uLi9lcnJvcnNcIjtcbmltcG9ydCB7IGRyb3B6b25lUmVuZGVyZXIgfSBmcm9tIFwiLi4vLi4vZXh0cmFzL2RyYWctYW5kLWRyb3BcIjtcbmltcG9ydCB7IFRyZWVSb290IH0gZnJvbSBcIi4uL3RyZWUtcm9vdFwiO1xuaW1wb3J0IHR5cGUgeyBUcmVlTm9kZSB9IGZyb20gXCIuLi90cmVlLW5vZGUuaW50ZXJmYWNlXCI7XG5pbXBvcnQgdHlwZSB7IFRyZWVQbG90IH0gZnJvbSBcIi4uL3RyZWUtcGxvdC5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRyZWVOb2RlQmFzZSB9IGZyb20gXCIuLi90cmVlLW5vZGUtYmFzZVwiO1xuaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcIi4uL2NvbmZpZ3VyYXRpb25cIjtcbmltcG9ydCB0eXBlIHtcbiAgIEJyYW5jaE9wdGlvbnMsXG4gICBGdWxsQnJhbmNoT3B0aW9uc1xufSBmcm9tIFwiLi4vYnJhbmNoLW9wdGlvbnMuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBCcmFuY2hDb250cm9sbGVyIH0gZnJvbSBcIi4vYnJhbmNoLWNvbnRyb2xsZXJcIjtcbmltcG9ydCB0eXBlIHsgR3JhZnRhYmxlIH0gZnJvbSBcIi4vZ3JhZnRhYmxlLmludGVyZmFjZVwiO1xuaW1wb3J0IHsgdHJlZUNvbGxhcHNlciB9IGZyb20gXCIuLi8uLi9leHRyYXMvY29sbGFwc2VcIjtcbmltcG9ydCB7XG4gICBEZXN0cnVjdGlvbkV2ZW50LFxuICAgR3JhZnRFdmVudCxcbiAgIFBydW5lRXZlbnQsXG4gICB0eXBlIFRyZWVFdmVudFxufSBmcm9tIFwiLi4vLi4vZXZlbnRzXCI7XG5cbi8qKiBSZXByZXNlbnRzIGEgc3RhbmRhcmQgbm9kZSBpbiBhIHRyZWUuIFJlbmRlcnMgYSBCcmFuY2hDb21wb25lbnQuXG4gKlxuICogQHJlbWFya3NcbiAqIFRoaXMgY2xhc3MgcmVuZGVycyBhIGJyYW5jaCBjb21wb25lbnQsIHdoaWNoIGRvZXMgdGhlIGZvbGxvd2luZzpcbiAqIDEuIFJlbmRlcnMgYSBjb21wb25lbnQgcHJvdmlkZWQgYnkgdGhlIHVzZXJcbiAqIDIuIFByb3ZpZGVzIGEgY29udGFpbmVyIGluIHdoaWNoIGNoaWxkIGJyYW5jaGVzIG1heSBiZSByZW5kZXJlZFxuICogMy4gQ29udGFpbnMgdHdvIERyb3B6b25lczogb25lIGZvciBkcm9wcGluZyBicmFuY2hlcyBiZWxvdyB0aGlzIGJyYW5jaCAoYXMgYVxuICogc2libGluZyksIGFuZCBvbmUgZm9yIGRyb3BwaW5nIGJyYW5jaGVzIGFzIGEgZmlyc3QgY2hpbGQgb2YgdGhpcyBicmFuY2guXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PlxuICAgaW1wbGVtZW50cyBUcmVlTm9kZTxVc2VybGFuZENvbXBvbmVudD4sIEdyYWZ0YWJsZTxVc2VybGFuZENvbXBvbmVudD5cbntcbiAgIHByaXZhdGUgcmVhZG9ubHkgYnJhbmNoQ29udHJvbGxlcjogQnJhbmNoQ29udHJvbGxlcjxVc2VybGFuZENvbXBvbmVudD47XG4gICBwcml2YXRlIGRldGFjaGVkVmlldzogVmlld1JlZiB8IG51bGwgPSBudWxsO1xuICAgcHJpdmF0ZSBfcGFyZW50OiBUcmVlTm9kZTxVc2VybGFuZENvbXBvbmVudD4gfCB1bmRlZmluZWQ7XG4gICBwcml2YXRlIHJlYWRvbmx5IHRyZWVOb2RlQmFzZTogVHJlZU5vZGVCYXNlPFVzZXJsYW5kQ29tcG9uZW50PjtcblxuICAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgICAgcGFyZW50OiBUcmVlTm9kZTxVc2VybGFuZENvbXBvbmVudD4sXG4gICAgICBwdWJsaWMgcmVhZG9ubHkgYnJhbmNoT3B0aW9uczogRnVsbEJyYW5jaE9wdGlvbnM8VXNlcmxhbmRDb21wb25lbnQ+XG4gICApIHtcbiAgICAgIHRoaXMudHJlZU5vZGVCYXNlID0gbmV3IFRyZWVOb2RlQmFzZSgpO1xuICAgICAgY29uc3QgcGFyZW50QnJhbmNoZXNDb250YWluZXIgPSBwYXJlbnQuZ2V0QnJhbmNoZXNDb250YWluZXIoKTtcbiAgICAgIGFzc2VydChwYXJlbnRCcmFuY2hlc0NvbnRhaW5lciAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIHRoaXMuYnJhbmNoQ29udHJvbGxlciA9IG5ldyBCcmFuY2hDb250cm9sbGVyKFxuICAgICAgICAgdGhpcyxcbiAgICAgICAgIHBhcmVudEJyYW5jaGVzQ29udGFpbmVyXG4gICAgICApO1xuICAgICAgY29uc3QgaG9zdFZpZXcgPSB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZ2V0SG9zdFZpZXcoKTtcbiAgICAgIGlmIChcbiAgICAgICAgIHBhcmVudCBpbnN0YW5jZW9mIFRyZWVCcmFuY2ggJiZcbiAgICAgICAgIHBhcmVudC5icmFuY2hPcHRpb25zLmRlZmF1bHRDb2xsYXBzZWQgPT09IHRydWVcbiAgICAgICkge1xuICAgICAgICAgdHJlZUNvbGxhcHNlci5zdG9yZVByZWNvbGxhcHNlZE5vZGUocGFyZW50LCB0aGlzKTtcbiAgICAgICAgIHRoaXMuZGV0YWNoZWRWaWV3ID0gaG9zdFZpZXc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAgcGFyZW50QnJhbmNoZXNDb250YWluZXIuaW5zZXJ0KGhvc3RWaWV3KTtcbiAgICAgICAgIHRoaXMuX3BhcmVudCA9IHBhcmVudDtcbiAgICAgICAgIHRoaXMuZGlzcGF0Y2goXG4gICAgICAgICAgICBuZXcgR3JhZnRFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICAgICBwYXJlbnQ6IHRoaXMuX3BhcmVudCxcbiAgICAgICAgICAgICAgIGNoaWxkOiB0aGlzLFxuICAgICAgICAgICAgICAgaW5kZXg6IHRoaXMuX3BhcmVudC5icmFuY2hlcygpLmxlbmd0aFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICk7XG4gICAgICAgICB0aGlzLnNldEluZGVudGF0aW9uKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmRldGVjdENoYW5nZXMoKTtcbiAgIH1cblxuICAgLyoqIEByZXR1cm5zIEFsbCBjaGlsZCBicmFuY2hlcyBhcyBhbiBhcnJheSBvZiBUcmVlQnJhbmNoIGluc3RhbmNlcywgaW4gb3JkZXIuICovXG4gICBwdWJsaWMgYnJhbmNoZXMoKTogQXJyYXk8VHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4+IHtcbiAgICAgIHJldHVybiB0aGlzLnRyZWVOb2RlQmFzZS5icmFuY2hlcygpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIFJlY3Vyc2l2ZWx5IGRlc3Ryb3lzIGFsbCBkZXNjZW5kYW50IGJyYW5jaGVzLCBhcyB3ZWxsIGFzIGl0c2VsZi4gVGhpc1xuICAgICogcmVsZWFzZXMgYWxsIHJlc291cmNlcyBoZWxkIG9yIGNvbnN1bWVkIGJ5IHRoaXMgYnJhbmNoIGFuZCBpdHMgZGVzY2VuZGFudHMuXG4gICAgKlxuICAgICogQHJlbWFya3NcbiAgICAqIEl0IGlzIGltcG9ydGFudCB0byBjYWxsIHRoaXMgbWV0aG9kIHdoZW4gYSBicmFuY2ggaXMgZGlzY2FyZGVkLCBvdGhlcndpc2VcbiAgICAqIHRoZSBicmFuY2ggd2lsbCByZW1haW4gaW4gbWVtb3J5IGFuZCBjb250aW51ZSB0byBjb25zdW1lIHJlc291cmNlcy5cbiAgICAqL1xuICAgcHVibGljIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFwiQ2Fubm90IGRlc3Ryb3kgYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIik7XG4gICAgICB9XG4gICAgICB0aGlzLnBydW5lKCk7XG4gICAgICB0cmVlQ29sbGFwc2VyLmV4cGFuZCh0aGlzKTtcbiAgICAgIGRyb3B6b25lUmVuZGVyZXIuY2xlYXJUcmVlRnJvbVJlZ2lzdHJ5KHRoaXMpO1xuICAgICAgdGhpcy5icmFuY2hDb250cm9sbGVyLmdldEhvc3RWaWV3KCkuZGVzdHJveSgpO1xuICAgICAgdGhpcy50cmVlTm9kZUJhc2UuZGVzdHJveSgpO1xuICAgICAgdGhpcy5icmFuY2hDb250cm9sbGVyLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMuZGlzcGF0Y2gobmV3IERlc3RydWN0aW9uRXZlbnQodGhpcykpO1xuICAgfVxuXG4gICAvKiogUnVuIEFuZ3VsYXIgY2hhbmdlIGRldGVjdGlvbiBvbiB0aGlzIGJyYW5jaCAqL1xuICAgcHVibGljIGRldGVjdENoYW5nZXMoKTogdm9pZCB7XG4gICAgICB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIEVtaXRzIHRoZSBzcGVjaWZpZWQgVHJlZUV2ZW50LlxuICAgICpcbiAgICAqIEByZW1hcmtzXG4gICAgKiBDYXV0aW9uOiBJdCBpcyBub3QgcmVjb21tZW5kZWQgdG8gbWFudWFsbHkgZW1pdCBUcmVlRXZlbnRzIHRoYXQgYXJlIGFscmVhZHlcbiAgICAqIHByb3ZpZGVkIGJ5IHRoZSBsaWJyYXJ5LiBGb3IgZXhhbXBsZSwgaXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIGVtaXQgYVxuICAgICogYEdyYWZ0RXZlbnRgLCBgRGVzdHJ1Y3Rpb25FdmVudGAsIGV0Yy4gVGhlc2UgZXZlbnRzIG1heSBiZSB1c2VkIGJ5IHRoZSB0cmVlLFxuICAgICogYW5kIGVtaXR0aW5nIHRoZW0gbWFudWFsbHkgbWF5IGNhdXNlIHVuZXhwZWN0ZWQgYmVoYXZpb3IuIEluc3RlYWQsIHdlXG4gICAgKiByZWNvbW1lbmQgaW1wbGVtZW50aW5nIHRoZSBUcmVlRXZlbnQgaW50ZXJmYWNlIHdpdGggeW91ciBvd24gY3VzdG9tIGV2ZW50c1xuICAgICogYW5kIGRpc3BhdGNoaW5nIHRob3NlLlxuICAgICpcbiAgICAqIEBwYXJhbSBldmVudCAtIFRoZSBUcmVlRXZlbnQgdGhhdCB3aWxsIGJlIGVtaXR0ZWQuXG4gICAgKi9cbiAgIHB1YmxpYyBkaXNwYXRjaChldmVudDogVHJlZUV2ZW50PFVzZXJsYW5kQ29tcG9uZW50Pik6IHZvaWQge1xuICAgICAgdGhpcy50cmVlTm9kZUJhc2UuZGlzcGF0Y2goZXZlbnQpO1xuICAgICAgdGhpcy5fcGFyZW50Py5kaXNwYXRjaChldmVudCk7XG4gICB9XG5cbiAgIC8qKlxuICAgICogQHJldHVybnNcbiAgICAqIEFuIG9ic2VydmFibGUgdGhhdCBlbWl0cyBUcmVlRXZlbnRzIHdoZW5ldmVyIGFuIGV2ZW50IGlzIGRpc3BhdGNoZWRcbiAgICAqIGluIHRoaXMgYnJhbmNoIG9yIGFueSBvZiBpdHMgZGVzY2VuZGFudCBicmFuY2hlcy5cbiAgICAqL1xuICAgcHVibGljIGV2ZW50cygpOiBPYnNlcnZhYmxlPFRyZWVFdmVudDxVc2VybGFuZENvbXBvbmVudD4+IHtcbiAgICAgIHJldHVybiB0aGlzLnRyZWVOb2RlQmFzZS5ldmVudHMoKTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBAcGFyYW0gaW5kZXggLSBUaGUgaW5kZXggb2YgdGhlIGNoaWxkIGJyYW5jaCB0byByZXRyaWV2ZS5cbiAgICAqXG4gICAgKiBAcmV0dXJuc1xuICAgICogVGhlIGNoaWxkIGJyYW5jaCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LCBvciB1bmRlZmluZWQgaWYgdGhlcmUgaXNcbiAgICAqIG5vIGNoaWxkIGJyYW5jaCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LlxuICAgICovXG4gICBwdWJsaWMgZ2V0QnJhbmNoKGluZGV4OiBudW1iZXIpOiBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PiB8IHVuZGVmaW5lZCB7XG4gICAgICByZXR1cm4gdGhpcy50cmVlTm9kZUJhc2UuZ2V0QnJhbmNoKGluZGV4KTtcbiAgIH1cblxuICAgLyoqIEByZXR1cm5zIFRoZSBWaWV3Q29udGFpbmVyUmVmIGluIHdoaWNoIGNoaWxkIGJyYW5jaGVzIGFyZSByZW5kZXJlZCAqL1xuICAgcHVibGljIGdldEJyYW5jaGVzQ29udGFpbmVyKCk6IFZpZXdDb250YWluZXJSZWYgfCB1bmRlZmluZWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcbiAgICAgICAgICAgIFwiQ2Fubm90IGdldCBicmFuY2hlcyBjb250YWluZXIgZnJvbSBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiXG4gICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYnJhbmNoQ29udHJvbGxlci5nZXRCcmFuY2hlc0NvbnRhaW5lcigpO1xuICAgfVxuXG4gICAvKiogQHJldHVybnMgVGhlIGluc3RhbmNlIG9mIEJyYW5jaENvbXBvbmVudCB0aGF0IGlzIHJlbmRlcmVkIGJ5IHRoaXMgY2xhc3MuICovXG4gICBwdWJsaWMgZ2V0Q29tcG9uZW50SW5zdGFuY2UoKTogQnJhbmNoQ29tcG9uZW50PFVzZXJsYW5kQ29tcG9uZW50PiB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgXCJDYW5ub3QgZ2V0IGNvbXBvbmVudCBpbnN0YW5jZSBmcm9tIGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCJcbiAgICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5icmFuY2hDb250cm9sbGVyLmdldENvbXBvbmVudEluc3RhbmNlKCk7XG4gICB9XG5cbiAgIC8qKiBAcmV0dXJucyBUaGUgSG9zdCBWaWV3IGluIHdoaWNoIHRoZSBCcmFuY2hDb21wb25lbnQgaXMgcmVuZGVyZWQgKi9cbiAgIHB1YmxpYyBnZXRIb3N0VmlldygpOiBWaWV3UmVmIHtcbiAgICAgIGlmICh0aGlzLmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICBcIkNhbm5vdCBnZXQgY29tcG9uZW50IGhvc3QgdmlldyBmcm9tIGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCJcbiAgICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5icmFuY2hDb250cm9sbGVyLmdldEhvc3RWaWV3KCk7XG4gICB9XG5cbiAgIC8qKiBAcmV0dXJucyBUaGUgQnJhbmNoQ29tcG9uZW50IGFzIGEgbmF0aXZlIEhUTUwgRWxlbWVudCAqL1xuICAgcHVibGljIGdldE5hdGl2ZUVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcbiAgICAgICAgICAgIFwiQ2Fubm90IGdldCBuYXRpdmUgZWxlbWVudCBmcm9tIGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCJcbiAgICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5icmFuY2hDb250cm9sbGVyLmdldE5hdGl2ZUVsZW1lbnQoKTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBAcmV0dXJuc1xuICAgICogQSBDb21wb25lbnRSZWYgY29udGFpbmluZyB0aGUgaW5zdGFuY2Ugb2YgdGhlIHVzZXItcHJvdmlkZWRcbiAgICAqIGNvbXBvbmVudCB3aGljaCBpcyByZW5kZXJlZCBieSB0aGlzIGJyYW5jaC5cbiAgICAqL1xuICAgcHVibGljIGdldFVzZXJsYW5kQ29tcG9uZW50UmVmKCk6XG4gICAgICB8IENvbXBvbmVudFJlZjxVc2VybGFuZENvbXBvbmVudD5cbiAgICAgIHwgdW5kZWZpbmVkIHtcbiAgICAgIGlmICh0aGlzLmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICBcIkNhbm5vdCBnZXQgdXNlcmxhbmQgY29tcG9uZW50IGZyb20gYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIlxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZ2V0VXNlcmxhbmRDb21wb25lbnRSZWYoKTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBBdHRhY2hlcyBhIGJyYW5jaCB0byBhIG5ldyBwYXJlbnQgbm9kZS5cbiAgICAqXG4gICAgKiBAcmVtYXJrc1xuICAgICogSWYgbm90IGFscmVhZHkgcHJ1bmVkLCB0aGlzIG1ldGhvZCBwcnVuZXMgKHJlbW92ZXMpIHRoaXMgYnJhbmNoIGZyb20gaXRzXG4gICAgKiBjdXJyZW50IHBvc2l0aW9uIGluIHRoZSB0cmVlOyB0aGVuIGdyYWZ0cyAocmVhdHRhY2hlcykgaXQgYXMgYSBjaGlsZCBvZiB0aGVcbiAgICAqIHNwZWNpZmllZCBwYXJlbnQgYnJhbmNoIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguIElmIG5vIGluZGV4IGlzIHNwZWNpZmllZCxcbiAgICAqIHRoZSBicmFuY2ggaXMgYXBwZW5kZWQgYXMgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIHBhcmVudC4gVGhpcyBjYXVzZXMgdGhpc1xuICAgICogYnJhbmNoJ3MgYXNzb2NpYXRlZCBCcmFuY2hDb21wb25lbnQgdG8gYmUgcmUtcmVuZGVyZWQgaW4gdGhlIERPTSBhdCB0aGVcbiAgICAqIG5ldyBsb2NhdGlvbi5cbiAgICAqXG4gICAgKiBAcGFyYW0gbmV3UGFyZW50IC0gVGhlIG5ldyBwYXJlbnQgYnJhbmNoIHVudG8gd2hpY2ggdGhpcyBicmFuY2ggd2lsbCBiZSBncmFmdGVkLlxuICAgICogQHBhcmFtIGluZGV4IC0gVGhlIGluZGV4IGF0IHdoaWNoIHRoaXMgYnJhbmNoIHdpbGwgYmUgZ3JhZnRlZC4gSWYgbm90IHNwZWNpZmllZCxcbiAgICAqIHRoaXMgYnJhbmNoIHdpbGwgYmUgYXBwZW5kZWQgYXMgdGhlIGxhc3QgY2hpbGQgb2YgdGhlIG5ldyBwYXJlbnQuXG4gICAgKlxuICAgICogQHJldHVybnMgVGhlIGluZGV4IGF0IHdoaWNoIHRoaXMgYnJhbmNoIHdhcyBncmFmdGVkLlxuICAgICovXG4gICBwdWJsaWMgZ3JhZnRUbyhcbiAgICAgIG5ld1BhcmVudDogVHJlZU5vZGU8VXNlcmxhbmRDb21wb25lbnQ+LFxuICAgICAgaW5kZXg/OiBudW1iZXJcbiAgICk6IG51bWJlciB7XG4gICAgICB0aGlzLmNoZWNrR3JhZnRMb2NhdGlvblZhbGlkaXR5KG5ld1BhcmVudCwgaW5kZXgpO1xuICAgICAgY29uc3Qgb3duSW5kZXggPSB0aGlzLmluZGV4KCk7XG4gICAgICBpZiAob3duSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgdGhpcy5wcnVuZSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5fcGFyZW50ID0gbmV3UGFyZW50O1xuICAgICAgY29uc3QgbmV3SW5kZXggPSBpbmRleCA/PyBuZXdQYXJlbnQuYnJhbmNoZXMoKS5sZW5ndGg7XG4gICAgICB0aGlzLnJlYXR0YWNoVmlldyhuZXdJbmRleCk7XG4gICAgICB0aGlzLmRpc3BhdGNoKFxuICAgICAgICAgbmV3IEdyYWZ0RXZlbnQodGhpcywge1xuICAgICAgICAgICAgcGFyZW50OiBuZXdQYXJlbnQsXG4gICAgICAgICAgICBjaGlsZDogdGhpcyxcbiAgICAgICAgICAgIGluZGV4OiBuZXdJbmRleFxuICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICByZXR1cm4gbmV3SW5kZXg7XG4gICB9XG5cbiAgIC8qKlxuICAgICogQXBwZW5kcyBhIG5ldyBjaGlsZCBicmFuY2ggdG8gdGhpcyBicmFuY2guIFRoZSBjaGlsZCBicmFuY2ggd2lsbCByZW5kZXJcbiAgICAqIHRoZSBzcGVjaWZpZWQgY29tcG9uZW50IGFjY29yZGluZyB0byB0aGUgKG9wdGlvbmFsKSBjb25maWd1cmF0aW9uIHBhcmFtZXRlci5cbiAgICAqXG4gICAgKiBAcGFyYW0gY29tcG9uZW50IC0gVGhlIGNvbXBvbmVudCB0byByZW5kZXIgaW4gdGhlIG5ldyBjaGlsZCBicmFuY2guXG4gICAgKiBAcGFyYW0gb3B0aW9ucyAtIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgdGhlIG5ldyBjaGlsZCBicmFuY2guXG4gICAgKlxuICAgICogQHJldHVybnNcbiAgICAqIFRoZSBuZXdseS1jcmVhdGVkIGNoaWxkIGJyYW5jaC5cbiAgICAqL1xuICAgcHVibGljIGdyb3coXG4gICAgICBjb21wb25lbnQ6IFR5cGU8VXNlcmxhbmRDb21wb25lbnQ+LFxuICAgICAgb3B0aW9ucz86IEJyYW5jaE9wdGlvbnM8VXNlcmxhbmRDb21wb25lbnQ+XG4gICApOiBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PiB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFwiQ2Fubm90IGdyb3cgYSBicmFuY2ggb24gYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIik7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICAgcmV0dXJuIG5ldyBUcmVlQnJhbmNoKHRoaXMsIHsgY29tcG9uZW50LCAuLi5vcHRpb25zIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgIHRoaXMuaGFuZGxlVXNlcmxhbmRFcnJvcihlcnJvcik7XG4gICAgICB9XG4gICB9XG5cbiAgIC8qKlxuICAgICogRGV0ZXJtaW5lcyB0aGlzIGJyYW5jaCdzIGluZGV4IGluIHJlbGF0aW9uIHRvIGl0cyBzaWJsaW5nIGJyYW5jaGVzLlxuICAgICpcbiAgICAqIEByZW1hcmtzXG4gICAgKiBGb3IgZXhhbXBsZSwgaWYgaXQgaXMgdGhlIGZpcnN0IGNoaWxkIG9mIGl0cyBwYXJlbnQsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuXG4gICAgKiAwLiBJZiBpdCBpcyB0aGUgc2Vjb25kIGNoaWxkIG9mIGl0cyBwYXJlbnQsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIDEuXG4gICAgKlxuICAgICogSWYgdGhpcyBicmFuY2ggaGFzIG5vIHBhcmVudCwgKGVnLCBpZiB0aGlzIGJyYW5jaCBoYXMgYmVlbiBwcnVuZWQpIHRoaXNcbiAgICAqIG1ldGhvZCB3aWxsIHJldHVybiB1bmRlZmluZWQuXG4gICAgKlxuICAgICogQHJldHVybnNcbiAgICAqIFRoZSBpbmRleCBvZiB0aGlzIGJyYW5jaCBpbiByZWxhdGlvbiB0byBpdHMgc2libGluZyBicmFuY2hlcywgb3IgdW5kZWZpbmVkLlxuICAgICovXG4gICBwdWJsaWMgaW5kZXgoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICAgIGlmICghdGhpcy5fcGFyZW50KSB7XG4gICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9wYXJlbnRcbiAgICAgICAgIC5icmFuY2hlcygpXG4gICAgICAgICAuZmluZEluZGV4KChicmFuY2gpID0+IGJyYW5jaCA9PT0gdGhpcyk7XG4gICAgICBhc3NlcnQoaW5kZXggPj0gMCk7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICB9XG5cbiAgIC8qKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGJyYW5jaCBpcyBkZXN0cm95ZWQsIGBmYWxzZWAgb3RoZXJ3aXNlICovXG4gICBwdWJsaWMgaXNEZXN0cm95ZWQoKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gdGhpcy50cmVlTm9kZUJhc2UuaXNEZXN0cm95ZWQoKTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBAcmV0dXJuc1xuICAgICogVGhlIGRhdGEgdGhhdCB3YXMgcGFzc2VkIGludG8gdGhlIGBicmFuY2hPcHRpb25zYCcgYG1ldGFgIHByb3BlcnR5XG4gICAgKiBhdCBjb25zdHJ1Y3Rpb24uXG4gICAgKi9cbiAgIHB1YmxpYyBtZXRhKCk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICAgICAgcmV0dXJuIHRoaXMuYnJhbmNoT3B0aW9ucy5tZXRhID8/IHt9O1xuICAgfVxuXG4gICAvKipcbiAgICAqIEByZXR1cm5zXG4gICAgKiBUaGlzIGJyYW5jaCdzIHBhcmVudCBub2RlICh3aGljaCBtYXkgYmUgYSBUcmVlQnJhbmNoIG9yIFRyZWVSb290KS5cbiAgICAqIElmIHRoaXMgYnJhbmNoIGhhcyBubyBwYXJlbnQsIChlZywgaWYgdGhpcyBicmFuY2ggaGFzIGJlZW4gcHJ1bmVkKSB0aGlzXG4gICAgKiBtZXRob2Qgd2lsbCByZXR1cm4gdW5kZWZpbmVkLlxuICAgICovXG4gICBwdWJsaWMgcGFyZW50KCk6IFRyZWVOb2RlPFVzZXJsYW5kQ29tcG9uZW50PiB8IHVuZGVmaW5lZCB7XG4gICAgICByZXR1cm4gdGhpcy5fcGFyZW50O1xuICAgfVxuXG4gICAvKipcbiAgICAqIFByb3ZpZGVzIGEgbW9kZWwgZGVzY3JpYmluZyB0aGlzIGJyYW5jaCdzIGRlc2NlbmRhbnRzLlxuICAgICpcbiAgICAqIEByZXR1cm5zXG4gICAgKiBBIG11bHRpLWRpbWVuc2lvbmFsIE1hcCB3aGljaCBkZXNjcmliZXMgdGhlIHNoYXBlIG9mIHRoaXMgYnJhbmNoJ3NcbiAgICAqIGRlc2NlbmRhbnRzLlxuICAgICpcbiAgICAqIEBleGFtcGxlXG4gICAgKiBBIGJyYW5jaCB3aXRoIG5vIGNoaWxkcmVuIHdpbGwgcmV0dXJuIGFuIGVtcHR5IE1hcC4gQSBicmFuY2ggd2l0aFxuICAgICogYSBzaW5nbGUgY2hpbGQgd2lsbCByZXR1cm4gYSBNYXAgd2l0aCBhIHNpbmdsZSBlbnRyeSwgd2hlcmUgdGhlIGtleSBpcyB0aGUgaW5kZXhcbiAgICAqIG9mIHRoZSBicmFuY2ggKHplcm8pIGFuZCB0aGUgdmFsdWUgaXMgYW4gZW1wdHkgTWFwLiBBIFRyZWUgbGlrZSB0aGlzOlxuICAgICpcbiAgICAqIGBgYFxuICAgICogICAgICAgICAtLS1CcmFuY2gtLS0tLS0tQnJhbmNoXG4gICAgKiAgICAgICAgL1xuICAgICogQnJhbmNoLS0tLS0tLUJyYW5jaFxuICAgICogICAgICAgIFxcXG4gICAgKiAgICAgICAgIC0tLUJyYW5jaFxuICAgICogYGBgXG4gICAgKiBXaWxsIHJldHVybiBhIE1hcCBvZiBtYXRjaGluZyBzaGFwZTpcbiAgICAqIGBgYFxuICAgICogTWFwIHtcbiAgICAqICAgIDA6IE1hcCB7IDA6IE1hcCB7fX0sXG4gICAgKiAgICAxOiBNYXAge30sXG4gICAgKiAgICAyOiBNYXAge31cbiAgICAqIH1cbiAgICAqIGBgYFxuICAgICovXG4gICBwdWJsaWMgcGxvdCgpOiBUcmVlUGxvdCB7XG4gICAgICByZXR1cm4gdGhpcy50cmVlTm9kZUJhc2UucGxvdCgpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIENhbGN1bGF0ZXMgdGhlIGJyYW5jaCdzIHBvc2l0aW9uIGluIHRoZSB0cmVlIHJlbGF0aXZlIHRvIHRoZSBSb290LlxuICAgICpcbiAgICAqIEByZW1hcmtzXG4gICAgKiBUaGUgcG9zaXRpb24gaXMgZGVzY3JpYmVkIGFzIGFuIGFycmF5IG9mIG51bWJlcnMsIHdoZXJlIGVhY2ggbnVtYmVyXG4gICAgKiByZXByZXNlbnRzIHRoZSBpbmRleCBvZiB0aGUgYnJhbmNoIGF0IHRoYXQgbGV2ZWwgb2YgdGhlIHRyZWUuXG4gICAgKlxuICAgICogRm9yIGV4YW1wbGUsIGlmIHRoaXMgYnJhbmNoIGlzIHRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgUm9vdCwgdGhpcyBtZXRob2RcbiAgICAqIHdpbGwgcmV0dXJuIFswXS4gSWYgdGhpcyBicmFuY2ggaXMgdGhlIHNlY29uZCBjaGlsZCBvZiB0aGUgZmlyc3QgY2hpbGRcbiAgICAqIG9mIHRoZSBSb290LCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBbMCwgMV0uXG4gICAgKlxuICAgICogSWYgdGhlIGJyYW5jaCBpcyBub3QgcmVsYXRlZCB0byBhIFRyZWVSb290LCAoc3VjaCBhcyB3aGVuIGl0IGhhcyBiZWVuXG4gICAgKiBwcnVuZWQsKSB0aGlzIG1ldGhvZCB3aWxsIHRocm93IGFuIGVycm9yLlxuICAgICpcbiAgICAqIEByZXR1cm5zXG4gICAgKiBBbiBhcnJheSBvZiBudW1iZXJzIHdoaWNoIGRlc2NyaWJlIHRoZSBicmFuY2gncyBwb3NpdGlvbiBpbiB0aGUgdHJlZVxuICAgICogcmVsYXRpdmUgdG8gdGhlIFJvb3QuXG4gICAgKi9cbiAgIHB1YmxpYyBwb3NpdGlvbigpOiBBcnJheTxudW1iZXI+IHtcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5pbmRleCgpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICBcImJyYW5jaCBoYXMgbm8gcGFyZW50LiBQb3NpdGlvbiBjYW5ub3QgYmUgZGV0ZXJtaW5lZC5cIlxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9wYXJlbnQgaW5zdGFuY2VvZiBUcmVlQnJhbmNoKSB7XG4gICAgICAgICBjb25zdCBwYXJlbnRQb3NpdGlvbiA9IHRoaXMuX3BhcmVudC5wb3NpdGlvbigpO1xuICAgICAgICAgcmV0dXJuIFsuLi5wYXJlbnRQb3NpdGlvbiwgaW5kZXhdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtpbmRleF07XG4gICB9XG5cbiAgIC8qKlxuICAgICogUmVtb3ZlcyBhIGJyYW5jaCBmcm9tIGl0cyB0cmVlIHdpdGhvdXQgZGVzdHJveWluZyBpdC5cbiAgICAqXG4gICAgKiBAcmVtYXJrc1xuICAgICogUmVtb3ZlcyB0aGlzIGJyYW5jaCBmcm9tIGl0cyBwYXJlbnQgYW5kIGRldGFjaGVzIGl0cyBhc3NvY2lhdGVkXG4gICAgKiBCcmFuY2hDb21wb25lbnQgZnJvbSB0aGUgRE9NLiBUaGlzIHB1dHMgdGhlIGJyYW5jaCBpbiBhIFwicHJ1bmVkXCIgc3RhdGUsXG4gICAgKiB3aGljaCBtYXkgYWZmZWN0IHRoZSBiZWhhdmlvciBvZiBvdGhlciBtZXRob2RzLlxuICAgICpcbiAgICAqIEEgcHJ1bmVkIGJyYW5jaCBjYW4gYmUgcmVhdHRhY2hlZCB0byBhbnkgb3RoZXIgbm9kZSB1c2luZyB0aGUgYGdyYWZ0VG9gIG1ldGhvZC5cbiAgICAqXG4gICAgKiBAcmV0dXJuc1xuICAgICogSXRzZWxmLCBvciB1bmRlZmluZWQgaWYgaXQgaXMgYWxyZWFkeSBpbiBhIHBydW5lZCBzdGF0ZS5cbiAgICAqL1xuICAgcHVibGljIHBydW5lKCk6IHRoaXMgfCB1bmRlZmluZWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBwcnVuZSBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBhcmVudCA9IHRoaXMuX3BhcmVudDtcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5pbmRleCgpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQgfHwgcGFyZW50ID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHBhcmVudC5nZXRCcmFuY2hlc0NvbnRhaW5lcigpO1xuICAgICAgYXNzZXJ0KGNvbnRhaW5lciAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIHRoaXMuZGV0YWNoZWRWaWV3ID0gY29udGFpbmVyLmRldGFjaChpbmRleCk7XG4gICAgICBhc3NlcnQodGhpcy5kZXRhY2hlZFZpZXcgIT09IG51bGwpO1xuICAgICAgdGhpcy5kZXRhY2hlZFZpZXcuZGV0YWNoKCk7XG4gICAgICB0aGlzLmRpc3BhdGNoKFxuICAgICAgICAgbmV3IFBydW5lRXZlbnQodGhpcywge1xuICAgICAgICAgICAgcGFyZW50OiBwYXJlbnQsXG4gICAgICAgICAgICBjaGlsZDogdGhpcyxcbiAgICAgICAgICAgIGluZGV4OiBpbmRleFxuICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICB0aGlzLl9wYXJlbnQgPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gdGhpcztcbiAgIH1cblxuICAgLyoqXG4gICAgKiBHZXQgdGhlIHJvb3Qgb2YgdGhlIHRyZWUgdG8gd2hpY2ggdGhpcyBCcmFuY2ggaXMgYXR0YWNoZWQuXG4gICAgKlxuICAgICogQHJldHVybnNcbiAgICAqIFRoZSBUcmVlUm9vdCBvZiB0aGUgdHJlZSB0aGlzIGJyYW5jaCBpcyBpbi4gSWYgdGhpcyBicmFuY2ggaXNcbiAgICAqIGRvZXMgbm90IGhhdmUgYSByb290IChzdWNoIGFzIHdoZW4gaXQgaGFzIGJlZW4gcHJ1bmVkKSB0aGlzIG1ldGhvZCB3aWxsXG4gICAgKiByZXR1cm4gdW5kZWZpbmVkLlxuICAgICovXG4gICBwdWJsaWMgcm9vdCgpOiBUcmVlUm9vdDxVc2VybGFuZENvbXBvbmVudD4gfCB1bmRlZmluZWQge1xuICAgICAgY29uc3QgcGFyZW50ID0gdGhpcy5wYXJlbnQoKTtcbiAgICAgIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBUcmVlQnJhbmNoKSB7XG4gICAgICAgICByZXR1cm4gcGFyZW50LnJvb3QoKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydChwYXJlbnQgaW5zdGFuY2VvZiBUcmVlUm9vdCB8fCBwYXJlbnQgPT09IHVuZGVmaW5lZCk7XG4gICAgICByZXR1cm4gcGFyZW50O1xuICAgfVxuXG4gICAvKipcbiAgICAqIFRyYXZlcnNlcyB0aGlzIGJyYW5jaCdzIGRlc2NlbmRhbnRzIGluIGRlcHRoLWZpcnN0IHByZS1vcmRlciwgZXhlY3V0aW5nXG4gICAgKiB0aGUgcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24gb24gZWFjaCBub2RlLiBUcmF2ZXJzYWwgaW5jbHVkZXMgdGhpcyBicmFuY2guXG4gICAgKlxuICAgICogQHBhcmFtIGNhbGxiYWNrIC0gQSBmdW5jdGlvbiB0byBleGVjdXRlIG9uIGVhY2ggbm9kZS5cbiAgICAqL1xuICAgcHVibGljIHRyYXZlcnNlKFxuICAgICAgY2FsbGJhY2s6IChub2RlOiBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PikgPT4gdm9pZFxuICAgKTogdm9pZCB7XG4gICAgICBjYWxsYmFjayh0aGlzKTtcbiAgICAgIHRoaXMudHJlZU5vZGVCYXNlLnRyYXZlcnNlKGNhbGxiYWNrKTtcbiAgIH1cblxuICAgcHJpdmF0ZSBjaGVja0dyYWZ0TG9jYXRpb25WYWxpZGl0eShcbiAgICAgIG5ld1BhcmVudDogVHJlZU5vZGU8VXNlcmxhbmRDb21wb25lbnQ+LFxuICAgICAgaW5kZXg/OiBudW1iZXJcbiAgICk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBncmFmdCBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChuZXdQYXJlbnQuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBncmFmdCB0byBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIHR5cGVvZiBpbmRleCA9PT0gXCJudW1iZXJcIiAmJlxuICAgICAgICAgdGhpcy5pbmRleElzT3V0T2ZSYW5nZShuZXdQYXJlbnQsIGluZGV4KVxuICAgICAgKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgYENhbm5vdCBncmFmdCBicmFuY2ggYXQgaW5kZXggJHtpbmRleH0gb2YgdGhlIHBhcmVudC4gT3V0IG9mIHJhbmdlLmBcbiAgICAgICAgICk7XG4gICAgICB9XG4gICAgICB0aGlzLnRyYXZlcnNlKChub2RlKSA9PiB7XG4gICAgICAgICBpZiAobm9kZSA9PT0gbmV3UGFyZW50KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgICAgXCJDYW5ub3QgZ3JhZnQgYSBicmFuY2ggdG8gaXRzZWxmIG9yIGFueSBvZiBpdHMgb3duIGRlc2NlbmRhbnRzXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICB9XG4gICAgICB9KTtcbiAgIH1cblxuICAgcHJpdmF0ZSBoYW5kbGVVc2VybGFuZEVycm9yKGVycm9yOiB1bmtub3duKTogbmV2ZXIge1xuICAgICAgLy8gV2hlbiBhbiBlcnJvciBvY2N1cnMgaW4gYSB1c2VybGFuZCBjb21wb25lbnQgZHVyaW5nIGEgdHJlZSBvcGVyYXRpb24sXG4gICAgICAvLyBpdCBjYW4gY2F1c2UgdW5kZWZpbmVkLCBiaXphcnJlIGJlaGF2aW9yIGluIHRoZSB0cmVlLiBUbyBwcmV2ZW50IHRoaXMsXG4gICAgICAvLyB3ZSBkZXN0cm95IHRoZSB0cmVlIGFuZCB0aHJvdyBhbiBlcnJvciBpbnN0ZWFkLiBUaGlzIGhlbHBzIHByb3RlY3RcbiAgICAgIC8vIHRoZSBlbmQtdXNlcidzIGRhdGEgZnJvbSBjb3JydXB0aW9uLlxuICAgICAgdGhpcy5mdXJ0aGVzdEFuY2VzdG9yKCkuZGVzdHJveSgpO1xuICAgICAgdGhpcy50cmVlTm9kZUJhc2UuaGFuZGxlVXNlcmxhbmRFcnJvcihlcnJvcik7XG4gICB9XG5cbiAgIHByaXZhdGUgaW5kZXhJc091dE9mUmFuZ2UoXG4gICAgICBwYXJlbnQ6IFRyZWVOb2RlPFVzZXJsYW5kQ29tcG9uZW50PixcbiAgICAgIGluZGV4OiBudW1iZXJcbiAgICk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIGluZGV4IDwgMCB8fCBpbmRleCA+IHBhcmVudC5icmFuY2hlcygpLmxlbmd0aDtcbiAgIH1cblxuICAgcHJpdmF0ZSBmdXJ0aGVzdEFuY2VzdG9yKCk6IFRyZWVOb2RlPFVzZXJsYW5kQ29tcG9uZW50PiB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgdHlwZXNjcmlwdC9uby10aGlzLWFsaWFzIC0tIFRoaXMgY29kZSBpcyBmb3IgYW4gaXRlcmF0aW9uLCBub3QgdG8gbWFrZSBgdGhpc2AgYXZhaWxhYmxlIGluIG90aGVyIHNjb3BlcyAod2hpY2ggaXMgd2hhdCB0aGUgcnVsZSBpcyBpbnRlbmRlZCB0byBwcm90ZWN0IGFnYWluc3QpLlxuICAgICAgbGV0IG5vZGU6IFRyZWVOb2RlPFVzZXJsYW5kQ29tcG9uZW50PiA9IHRoaXM7XG4gICAgICB3aGlsZSAobm9kZSBpbnN0YW5jZW9mIFRyZWVCcmFuY2gpIHtcbiAgICAgICAgIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50KCk7XG4gICAgICAgICBpZiAocGFyZW50ID09PSB1bmRlZmluZWQpIGJyZWFrO1xuICAgICAgICAgbm9kZSA9IHBhcmVudDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBub2RlO1xuICAgfVxuXG4gICBwcml2YXRlIHJlYXR0YWNoVmlldyhpbmRleD86IG51bWJlcik6IHZvaWQge1xuICAgICAgYXNzZXJ0KHRoaXMuX3BhcmVudCAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIGFzc2VydCh0aGlzLmRldGFjaGVkVmlldyAhPT0gbnVsbCk7XG4gICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLl9wYXJlbnQuZ2V0QnJhbmNoZXNDb250YWluZXIoKTtcbiAgICAgIGFzc2VydChjb250YWluZXIgIT09IHVuZGVmaW5lZCk7XG4gICAgICB0aGlzLmRldGFjaGVkVmlldy5yZWF0dGFjaCgpO1xuICAgICAgY29udGFpbmVyLmluc2VydCh0aGlzLmRldGFjaGVkVmlldywgaW5kZXgpO1xuICAgICAgdGhpcy5kZXRhY2hlZFZpZXcgPSBudWxsO1xuICAgICAgdGhpcy5zZXRJbmRlbnRhdGlvbigpO1xuICAgfVxuXG4gICBwcml2YXRlIHNldEluZGVudGF0aW9uKCk6IHZvaWQge1xuICAgICAgYXNzZXJ0KHRoaXMuX3BhcmVudCAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIGNvbnN0IHJvb3QgPSB0aGlzLl9wYXJlbnQucm9vdCgpO1xuICAgICAgaWYgKHJvb3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3B0aW9ucyA9IGNvbmZpZy5nZXRDb25maWcocm9vdCk7XG4gICAgICBjb25zdCBicmFuY2hlc0NvbnRhaW5lckVsID0gdGhpcy5icmFuY2hDb250cm9sbGVyXG4gICAgICAgICAuZ2V0TmF0aXZlRWxlbWVudCgpXG4gICAgICAgICAuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImJyYW5jaGVzLWNvbnRhaW5lclwiKVxuICAgICAgICAgLml0ZW0oMCk7XG4gICAgICBhc3NlcnQoYnJhbmNoZXNDb250YWluZXJFbCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KTtcbiAgICAgIGJyYW5jaGVzQ29udGFpbmVyRWwuc3R5bGUubWFyZ2luTGVmdCA9IGAke29wdGlvbnM/LmluZGVudGF0aW9uID8/IDE2fXB4YDtcbiAgIH1cbn1cbiJdfQ==
@@ -1,80 +0,0 @@
1
- import { filter, Subject } from "rxjs";
2
- import { hasProperty } from "../../shared";
3
- import { TreeError } from "../errors";
4
- import { GraftEvent, PruneEvent } from "../events";
5
- export class TreeNodeBase {
6
- constructor() {
7
- this.destroyed = false;
8
- this._branches = [];
9
- this.events$ = new Subject();
10
- this.subscriptions = [
11
- this.graftsToSelf().subscribe((event) => {
12
- this.registerChildRelationship(event.child(), event.index());
13
- }),
14
- this.prunesToSelf().subscribe((event) => {
15
- this.deregisterChildRelationship(event.child());
16
- })
17
- ];
18
- }
19
- branches() {
20
- return [...this._branches];
21
- }
22
- destroy() {
23
- this.branches().forEach((branch) => {
24
- branch.destroy();
25
- });
26
- this.subscriptions.forEach((sub) => {
27
- sub.unsubscribe();
28
- });
29
- this.destroyed = true;
30
- }
31
- dispatch(event) {
32
- this.events$.next(event);
33
- }
34
- events() {
35
- return this.events$;
36
- }
37
- getBranch(index) {
38
- return this._branches[index];
39
- }
40
- handleUserlandError(error) {
41
- const message = hasProperty(error, "message")
42
- ? error.message
43
- : "Unknown error";
44
- throw new TreeError(`Failed to grow branch: ${message}`, {
45
- // This cast to `any` is due to an issue in typescript that has been
46
- // resolved at least by version 4.9.5. When we upgrade our typescript
47
- // version we can remove the cast.
48
- cause: error
49
- });
50
- }
51
- isDestroyed() {
52
- return this.destroyed;
53
- }
54
- plot() {
55
- return new Map(this.branches().map((branch, index) => [index, branch.plot()]));
56
- }
57
- traverse(callback) {
58
- this.branches().forEach((branch) => {
59
- branch.traverse(callback);
60
- });
61
- }
62
- deregisterChildRelationship(child) {
63
- const index = this.branches().findIndex((branch) => branch === child);
64
- this._branches.splice(index, 1);
65
- }
66
- graftsToSelf() {
67
- return this.events().pipe(filter((event) => event instanceof GraftEvent), filter((event) => event.parent().events() === this.events$));
68
- }
69
- prunesToSelf() {
70
- return this.events().pipe(filter((event) => event instanceof PruneEvent), filter((event) => event.parent().events() === this.events$));
71
- }
72
- registerChildRelationship(child, index) {
73
- const branches = this.branches();
74
- if (index < 0 || index > branches.length) {
75
- throw new TreeError(`Can't register child at index ${index}. Out of range.`);
76
- }
77
- this._branches.splice(index, 0, child);
78
- }
79
- }
80
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1ub2RlLWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2NvcmUvdHJlZS1ub2RlLWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBbUIsT0FBTyxFQUFxQixNQUFNLE1BQU0sQ0FBQztBQUMzRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDdEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQWtCLE1BQU0sV0FBVyxDQUFDO0FBS25FLE1BQU0sT0FBTyxZQUFZO0lBUXRCO1FBSFEsY0FBUyxHQUFZLEtBQUssQ0FBQztRQUloQyxJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLGFBQWEsR0FBRztZQUNsQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQ3JDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDaEUsQ0FBQyxDQUFDO1lBQ0YsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO2dCQUNyQyxJQUFJLENBQUMsMkJBQTJCLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbkQsQ0FBQyxDQUFDO1NBQ0osQ0FBQztJQUNMLENBQUM7SUFFTSxRQUFRO1FBQ1osT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFTSxPQUFPO1FB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QUM5QixLQUFvQyxFQUNwQyxLQUFhO1FBRWIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2pDLElBQUksS0FBSyxHQUFHLENBQUMsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRTtZQUN2QyxNQUFNLElBQUksU0FBUyxDQUNoQixpQ0FBaUMsS0FBSyxpQkFBaUIsQ0FDekQsQ0FBQztTQUNKO1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMxQyxDQUFDO0NBQ0giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmaWx0ZXIsIHR5cGUgT2JzZXJ2YWJsZSwgU3ViamVjdCwgdHlwZSBTdWJzY3JpcHRpb24gfSBmcm9tIFwicnhqc1wiO1xuaW1wb3J0IHsgaGFzUHJvcGVydHkgfSBmcm9tIFwiLi4vLi4vc2hhcmVkXCI7XG5pbXBvcnQgeyBUcmVlRXJyb3IgfSBmcm9tIFwiLi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBHcmFmdEV2ZW50LCBQcnVuZUV2ZW50LCB0eXBlIFRyZWVFdmVudCB9IGZyb20gXCIuLi9ldmVudHNcIjtcbmltcG9ydCB7IFRyZWVCcmFuY2ggfSBmcm9tIFwiLi90cmVlLWJyYW5jaFwiO1xuaW1wb3J0IHR5cGUgeyBUcmVlUGxvdCB9IGZyb20gXCIuL3RyZWUtcGxvdC5pbnRlcmZhY2VcIjtcbmltcG9ydCB0eXBlIHsgVHJlZU5vZGUgfSBmcm9tIFwiLi90cmVlLW5vZGUuaW50ZXJmYWNlXCI7XG5cbmV4cG9ydCBjbGFzcyBUcmVlTm9kZUJhc2U8VXNlcmxhbmRDb21wb25lbnQ+XG4gICBpbXBsZW1lbnRzIFBhcnRpYWw8VHJlZU5vZGU8VXNlcmxhbmRDb21wb25lbnQ+Plxue1xuICAgcHJpdmF0ZSByZWFkb25seSBfYnJhbmNoZXM6IEFycmF5PFRyZWVCcmFuY2g8VXNlcmxhbmRDb21wb25lbnQ+PjtcbiAgIHByaXZhdGUgcmVhZG9ubHkgZXZlbnRzJDogU3ViamVjdDxUcmVlRXZlbnQ8VXNlcmxhbmRDb21wb25lbnQ+PjtcbiAgIHByaXZhdGUgZGVzdHJveWVkOiBib29sZWFuID0gZmFsc2U7XG4gICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmlwdGlvbnM6IEFycmF5PFN1YnNjcmlwdGlvbj47XG5cbiAgIHB1YmxpYyBjb25zdHJ1Y3RvcigpIHtcbiAgICAgIHRoaXMuX2JyYW5jaGVzID0gW107XG4gICAgICB0aGlzLmV2ZW50cyQgPSBuZXcgU3ViamVjdCgpO1xuICAgICAgdGhpcy5zdWJzY3JpcHRpb25zID0gW1xuICAgICAgICAgdGhpcy5ncmFmdHNUb1NlbGYoKS5zdWJzY3JpYmUoKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlZ2lzdGVyQ2hpbGRSZWxhdGlvbnNoaXAoZXZlbnQuY2hpbGQoKSwgZXZlbnQuaW5kZXgoKSk7XG4gICAgICAgICB9KSxcbiAgICAgICAgIHRoaXMucHJ1bmVzVG9TZWxmKCkuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kZXJlZ2lzdGVyQ2hpbGRSZWxhdGlvbnNoaXAoZXZlbnQuY2hpbGQoKSk7XG4gICAgICAgICB9KVxuICAgICAgXTtcbiAgIH1cblxuICAgcHVibGljIGJyYW5jaGVzKCk6IEFycmF5PFRyZWVCcmFuY2g8VXNlcmxhbmRDb21wb25lbnQ+PiB7XG4gICAgICByZXR1cm4gWy4uLnRoaXMuX2JyYW5jaGVzXTtcbiAgIH1cblxuICAgcHVibGljIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgICB0aGlzLmJyYW5jaGVzKCkuZm9yRWFjaCgoYnJhbmNoKSA9PiB7XG4gICAgICAgICBicmFuY2guZGVzdHJveSgpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaCgoc3ViKSA9PiB7XG4gICAgICAgICBzdWIudW5zdWJzY3JpYmUoKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5kZXN0cm95ZWQgPSB0cnVlO1xuICAgfVxuXG4gICBwdWJsaWMgZGlzcGF0Y2goZXZlbnQ6IFRyZWVFdmVudDxVc2VybGFuZENvbXBvbmVudD4pOiB2b2lkIHtcbiAgICAgIHRoaXMuZXZlbnRzJC5uZXh0KGV2ZW50KTtcbiAgIH1cblxuICAgcHVibGljIGV2ZW50cygpOiBPYnNlcnZhYmxlPFRyZWVFdmVudDxVc2VybGFuZENvbXBvbmVudD4+IHtcbiAgICAgIHJldHVybiB0aGlzLmV2ZW50cyQ7XG4gICB9XG5cbiAgIHB1YmxpYyBnZXRCcmFuY2goaW5kZXg6IG51bWJlcik6IFRyZWVCcmFuY2g8VXNlcmxhbmRDb21wb25lbnQ+IHwgdW5kZWZpbmVkIHtcbiAgICAgIHJldHVybiB0aGlzLl9icmFuY2hlc1tpbmRleF07XG4gICB9XG5cbiAgIHB1YmxpYyBoYW5kbGVVc2VybGFuZEVycm9yKGVycm9yOiB1bmtub3duKTogbmV2ZXIge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGhhc1Byb3BlcnR5KGVycm9yLCBcIm1lc3NhZ2VcIilcbiAgICAgICAgID8gZXJyb3IubWVzc2FnZVxuICAgICAgICAgOiBcIlVua25vd24gZXJyb3JcIjtcbiAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoYEZhaWxlZCB0byBncm93IGJyYW5jaDogJHttZXNzYWdlfWAsIHtcbiAgICAgICAgIC8vIFRoaXMgY2FzdCB0byBgYW55YCBpcyBkdWUgdG8gYW4gaXNzdWUgaW4gdHlwZXNjcmlwdCB0aGF0IGhhcyBiZWVuXG4gICAgICAgICAvLyByZXNvbHZlZCBhdCBsZWFzdCBieSB2ZXJzaW9uIDQuOS41LiBXaGVuIHdlIHVwZ3JhZGUgb3VyIHR5cGVzY3JpcHRcbiAgICAgICAgIC8vIHZlcnNpb24gd2UgY2FuIHJlbW92ZSB0aGUgY2FzdC5cbiAgICAgICAgIGNhdXNlOiBlcnJvciBhcyBhbnlcbiAgICAgIH0pO1xuICAgfVxuXG4gICBwdWJsaWMgaXNEZXN0cm95ZWQoKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gdGhpcy5kZXN0cm95ZWQ7XG4gICB9XG5cbiAgIHB1YmxpYyBwbG90KCk6IFRyZWVQbG90IHtcbiAgICAgIHJldHVybiBuZXcgTWFwKFxuICAgICAgICAgdGhpcy5icmFuY2hlcygpLm1hcCgoYnJhbmNoLCBpbmRleCkgPT4gW2luZGV4LCBicmFuY2gucGxvdCgpXSlcbiAgICAgICk7XG4gICB9XG5cbiAgIHB1YmxpYyB0cmF2ZXJzZShcbiAgICAgIGNhbGxiYWNrOiAobm9kZTogVHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4pID0+IHZvaWRcbiAgICk6IHZvaWQge1xuICAgICAgdGhpcy5icmFuY2hlcygpLmZvckVhY2goKGJyYW5jaCkgPT4ge1xuICAgICAgICAgYnJhbmNoLnRyYXZlcnNlKGNhbGxiYWNrKTtcbiAgICAgIH0pO1xuICAgfVxuXG4gICBwcml2YXRlIGRlcmVnaXN0ZXJDaGlsZFJlbGF0aW9uc2hpcChcbiAgICAgIGNoaWxkOiBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PlxuICAgKTogdm9pZCB7XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMuYnJhbmNoZXMoKS5maW5kSW5kZXgoKGJyYW5jaCkgPT4gYnJhbmNoID09PSBjaGlsZCk7XG4gICAgICB0aGlzLl9icmFuY2hlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgfVxuXG4gICBwcml2YXRlIGdyYWZ0c1RvU2VsZigpOiBPYnNlcnZhYmxlPEdyYWZ0RXZlbnQ8VXNlcmxhbmRDb21wb25lbnQ+PiB7XG4gICAgICByZXR1cm4gdGhpcy5ldmVudHMoKS5waXBlKFxuICAgICAgICAgZmlsdGVyKFxuICAgICAgICAgICAgKGV2ZW50KTogZXZlbnQgaXMgR3JhZnRFdmVudDxVc2VybGFuZENvbXBvbmVudD4gPT5cbiAgICAgICAgICAgICAgIGV2ZW50IGluc3RhbmNlb2YgR3JhZnRFdmVudFxuICAgICAgICAgKSxcbiAgICAgICAgIGZpbHRlcigoZXZlbnQpID0+IGV2ZW50LnBhcmVudCgpLmV2ZW50cygpID09PSB0aGlzLmV2ZW50cyQpXG4gICAgICApO1xuICAgfVxuXG4gICBwcml2YXRlIHBydW5lc1RvU2VsZigpOiBPYnNlcnZhYmxlPFBydW5lRXZlbnQ8VXNlcmxhbmRDb21wb25lbnQ+PiB7XG4gICAgICByZXR1cm4gdGhpcy5ldmVudHMoKS5waXBlKFxuICAgICAgICAgZmlsdGVyKFxuICAgICAgICAgICAgKGV2ZW50KTogZXZlbnQgaXMgUHJ1bmVFdmVudDxVc2VybGFuZENvbXBvbmVudD4gPT5cbiAgICAgICAgICAgICAgIGV2ZW50IGluc3RhbmNlb2YgUHJ1bmVFdmVudFxuICAgICAgICAgKSxcbiAgICAgICAgIGZpbHRlcigoZXZlbnQpID0+IGV2ZW50LnBhcmVudCgpLmV2ZW50cygpID09PSB0aGlzLmV2ZW50cyQpXG4gICAgICApO1xuICAgfVxuXG4gICBwcml2YXRlIHJlZ2lzdGVyQ2hpbGRSZWxhdGlvbnNoaXAoXG4gICAgICBjaGlsZDogVHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4sXG4gICAgICBpbmRleDogbnVtYmVyXG4gICApOiB2b2lkIHtcbiAgICAgIGNvbnN0IGJyYW5jaGVzID0gdGhpcy5icmFuY2hlcygpO1xuICAgICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+IGJyYW5jaGVzLmxlbmd0aCkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcbiAgICAgICAgICAgIGBDYW4ndCByZWdpc3RlciBjaGlsZCBhdCBpbmRleCAke2luZGV4fS4gT3V0IG9mIHJhbmdlLmBcbiAgICAgICAgICk7XG4gICAgICB9XG4gICAgICB0aGlzLl9icmFuY2hlcy5zcGxpY2UoaW5kZXgsIDAsIGNoaWxkKTtcbiAgIH1cbn1cbiJdfQ==