@limble/limble-tree 1.0.0-alpha.2 → 1.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +4 -0
  2. package/esm2020/lib/components/branch/branch.component.mjs +1 -1
  3. package/esm2020/lib/components/dropzone/dropzone.component.mjs +2 -2
  4. package/esm2020/lib/core/configuration/configuration.mjs +1 -1
  5. package/esm2020/lib/core/configuration/tree-options.interface.mjs +1 -1
  6. package/esm2020/lib/core/index.mjs +1 -2
  7. package/esm2020/lib/core/tree-branch/tree-branch.mjs +210 -9
  8. package/esm2020/lib/core/tree-node-base.mjs +13 -1
  9. package/esm2020/lib/core/tree-root/tree-root.mjs +111 -3
  10. package/esm2020/lib/core/tree-service/tree.service.mjs +7 -1
  11. package/esm2020/lib/events/drag/drag-end-event.mjs +9 -7
  12. package/esm2020/lib/events/drag/drag-start-event.mjs +2 -4
  13. package/esm2020/lib/events/drag/drop-event.mjs +2 -4
  14. package/esm2020/lib/events/general/destruction-event.mjs +2 -4
  15. package/esm2020/lib/events/relational/graft-event.mjs +2 -4
  16. package/esm2020/lib/events/relational/prune-event.mjs +2 -4
  17. package/esm2020/lib/events/relational/relational-tree-event.interface.mjs +1 -1
  18. package/esm2020/lib/extras/collapse/collapse.module.mjs +2 -1
  19. package/esm2020/lib/extras/collapse/collapse.service.mjs +26 -1
  20. package/esm2020/lib/extras/drag-and-drop/drag-and-drop.module.mjs +5 -1
  21. package/esm2020/lib/extras/drag-and-drop/drag-and-drop.service.mjs +21 -5
  22. package/esm2020/lib/extras/drag-and-drop/draggable.directive.mjs +7 -7
  23. package/esm2020/lib/extras/drag-and-drop/dragover-no-change-detect.mjs +10 -11
  24. package/esm2020/lib/legacy/legacy-component-obj.interface.mjs +1 -1
  25. package/esm2020/lib/legacy/legacy-tree-data.interface.mjs +1 -1
  26. package/esm2020/lib/legacy/legacy-tree-options.interface.mjs +1 -1
  27. package/esm2020/lib/legacy/legacy-tree.mjs +3 -2
  28. package/esm2020/lib/legacy/limble-tree-root/limble-tree-root.component.mjs +1 -1
  29. package/esm2020/lib/limble-tree.module.mjs +6 -2
  30. package/esm2020/lib/structure/component-container.interface.mjs +1 -1
  31. package/esm2020/lib/structure/index.mjs +1 -2
  32. package/esm2020/lib/structure/tree-branch-node.interface.mjs +1 -1
  33. package/esm2020/lib/structure/tree-event.interface.mjs +1 -1
  34. package/esm2020/lib/structure/tree-node.interface.mjs +1 -1
  35. package/esm2020/lib/structure/tree-relationship.interface.mjs +1 -1
  36. package/esm2020/shared/has-property.mjs +4 -0
  37. package/fesm2015/limble-limble-tree.mjs +569 -195
  38. package/fesm2015/limble-limble-tree.mjs.map +1 -1
  39. package/fesm2020/limble-limble-tree.mjs +568 -194
  40. package/fesm2020/limble-limble-tree.mjs.map +1 -1
  41. package/lib/core/configuration/configuration.d.ts +2 -2
  42. package/lib/core/configuration/tree-options.interface.d.ts +38 -16
  43. package/lib/core/index.d.ts +0 -1
  44. package/lib/core/tree-branch/tree-branch.d.ts +185 -8
  45. package/lib/core/tree-node-base.d.ts +1 -0
  46. package/lib/core/tree-root/tree-root.d.ts +101 -7
  47. package/lib/core/tree-service/tree.service.d.ts +8 -2
  48. package/lib/events/drag/drag-end-event.d.ts +11 -8
  49. package/lib/events/drag/drag-start-event.d.ts +6 -5
  50. package/lib/events/drag/drop-event.d.ts +6 -6
  51. package/lib/events/general/destruction-event.d.ts +5 -5
  52. package/lib/events/relational/graft-event.d.ts +5 -6
  53. package/lib/events/relational/prune-event.d.ts +5 -6
  54. package/lib/events/relational/relational-tree-event.interface.d.ts +5 -1
  55. package/lib/extras/collapse/collapse.module.d.ts +1 -0
  56. package/lib/extras/collapse/collapse.service.d.ts +25 -0
  57. package/lib/extras/drag-and-drop/drag-and-drop.module.d.ts +4 -0
  58. package/lib/extras/drag-and-drop/drag-and-drop.service.d.ts +22 -3
  59. package/lib/extras/drag-and-drop/draggable.directive.d.ts +3 -4
  60. package/lib/extras/drag-and-drop/dragover-no-change-detect.d.ts +7 -3
  61. package/lib/legacy/legacy-component-obj.interface.d.ts +1 -1
  62. package/lib/legacy/legacy-tree-data.interface.d.ts +1 -1
  63. package/lib/legacy/legacy-tree-options.interface.d.ts +2 -2
  64. package/lib/legacy/legacy-tree.d.ts +4 -4
  65. package/lib/legacy/limble-tree-root/limble-tree-root.component.d.ts +4 -4
  66. package/lib/limble-tree.module.d.ts +4 -0
  67. package/lib/structure/component-container.interface.d.ts +1 -1
  68. package/lib/structure/index.d.ts +0 -1
  69. package/lib/structure/tree-branch-node.interface.d.ts +2 -2
  70. package/lib/structure/tree-event.interface.d.ts +3 -3
  71. package/lib/structure/tree-node.interface.d.ts +12 -8
  72. package/lib/structure/tree-relationship.interface.d.ts +2 -2
  73. package/package.json +1 -1
  74. package/shared/has-property.d.ts +3 -0
  75. package/esm2020/lib/structure/event-conduit.interface.mjs +0 -2
  76. package/lib/structure/event-conduit.interface.d.ts +0 -6
package/README.md CHANGED
@@ -331,6 +331,10 @@ Drag and drop functionality is easy to use. Simply add the `[limbleTreeDraggable
331
331
 
332
332
  As the user drags the branch over other branches of the tree, dropzones will appear to indicate where the dragged branch may be placed. Dropping into a dropzone will graft the dragged branch at that location.
333
333
 
334
+ ### Dragging Into Empty Trees
335
+
336
+ Dropzones appear automatically as a branch is dragged over other branches. But what if the target tree has no other branches? In this case, a dropzone will not appear automatically. You will have to manually tell the tree when to render its dropzone using the `TreeDragAndDropService`.
337
+
334
338
  ### Configurable Restrictions For Drag-And-Drop
335
339
 
336
340
  A tree can be configured to disallow certain branches from...
@@ -54,7 +54,7 @@ export class BranchComponent {
54
54
  }
55
55
  }
56
56
  BranchComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BranchComponent, deps: [{ token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Component });
57
- BranchComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BranchComponent, isStandalone: true, selector: "branch", inputs: { contentToHost: "contentToHost" }, outputs: { contentCreated: "contentCreated", showDropzones: "showDropzones", dropped: "dropped" }, viewQueries: [{ propertyName: "branchesContainer", first: true, predicate: ["branchesContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "dropzones", predicate: DropzoneComponent, descendants: true }], ngImport: i0, template: "<div class=\"content\" (dragoverNoChangeDetect)=\"dragoverHandler($event)\">\n <div #contentContainer></div>\n</div>\n<div class=\"branches-container\">\n <dropzone placement=\"inner\" [hidden]=\"!showInnerDropzone\"></dropzone>\n <div #branchesContainer></div>\n</div>\n<dropzone placement=\"lateral\" [hidden]=\"!showLateralDropzone\"></dropzone>\n", styles: [".branches-container{margin-left:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DropzoneComponent, selector: "dropzone", inputs: ["placement"], outputs: ["dropped"] }, { kind: "directive", type: DragoverNoChangeDetectDirective, selector: "[dragoverNoChangeDetect]", inputs: ["dragoverEventThrottle"], outputs: ["dragoverNoChangeDetect"] }] });
57
+ BranchComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BranchComponent, isStandalone: true, selector: "branch", inputs: { contentToHost: "contentToHost" }, outputs: { contentCreated: "contentCreated", showDropzones: "showDropzones", dropped: "dropped" }, viewQueries: [{ propertyName: "branchesContainer", first: true, predicate: ["branchesContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "contentContainer", first: true, predicate: ["contentContainer"], descendants: true, read: ViewContainerRef }, { propertyName: "dropzones", predicate: DropzoneComponent, descendants: true }], ngImport: i0, template: "<div class=\"content\" (dragoverNoChangeDetect)=\"dragoverHandler($event)\">\n <div #contentContainer></div>\n</div>\n<div class=\"branches-container\">\n <dropzone placement=\"inner\" [hidden]=\"!showInnerDropzone\"></dropzone>\n <div #branchesContainer></div>\n</div>\n<dropzone placement=\"lateral\" [hidden]=\"!showLateralDropzone\"></dropzone>\n", styles: [".branches-container{margin-left:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DropzoneComponent, selector: "dropzone", inputs: ["placement"], outputs: ["dropped"] }, { kind: "directive", type: DragoverNoChangeDetectDirective, selector: "[dragoverNoChangeDetect]", outputs: ["dragoverNoChangeDetect"] }] });
58
58
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BranchComponent, decorators: [{
59
59
  type: Component,
60
60
  args: [{ standalone: true, selector: "branch", imports: [CommonModule, DropzoneComponent, DragoverNoChangeDetectDirective], template: "<div class=\"content\" (dragoverNoChangeDetect)=\"dragoverHandler($event)\">\n <div #contentContainer></div>\n</div>\n<div class=\"branches-container\">\n <dropzone placement=\"inner\" [hidden]=\"!showInnerDropzone\"></dropzone>\n <div #branchesContainer></div>\n</div>\n<dropzone placement=\"lateral\" [hidden]=\"!showLateralDropzone\"></dropzone>\n", styles: [".branches-container{margin-left:16px}\n"] }]
@@ -23,10 +23,10 @@ export class DropzoneComponent {
23
23
  }
24
24
  }
25
25
  DropzoneComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DropzoneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
26
- DropzoneComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: DropzoneComponent, isStandalone: true, selector: "dropzone", inputs: { placement: "placement" }, outputs: { dropped: "dropped" }, ngImport: i0, template: "<div\n class=\"dropzone\"\n [ngClass]=\"{ active: active }\"\n (dragenter)=\"dragenterHandler()\"\n (dragleave)=\"dragleaveHandler()\"\n (dragoverNoChangeDetect)=\"dragoverHandler($event)\"\n (drop)=\"dropHandler($event)\"\n></div>\n", styles: [".dropzone{border-radius:8px;border:1px dashed #727374;background-color:#ededed;height:20px;margin:8px 0;transition:height .2s ease-out;animation:animation .2s ease-out}.dropzone.active{border-color:#289e49;border-width:2px;background-color:#d0e8d6;height:48px}@keyframes animation{0%{height:0px;opacity:0}to{height:20px;opacity:1}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: DragoverNoChangeDetectDirective, selector: "[dragoverNoChangeDetect]", inputs: ["dragoverEventThrottle"], outputs: ["dragoverNoChangeDetect"] }] });
26
+ DropzoneComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: DropzoneComponent, isStandalone: true, selector: "dropzone", inputs: { placement: "placement" }, outputs: { dropped: "dropped" }, ngImport: i0, template: "<div\n class=\"dropzone\"\n [ngClass]=\"{ active: active }\"\n (dragenter)=\"dragenterHandler()\"\n (dragleave)=\"dragleaveHandler()\"\n (dragoverNoChangeDetect)=\"dragoverHandler($event)\"\n (drop)=\"dropHandler($event)\"\n></div>\n", styles: [".dropzone{border-radius:8px;border:1px dashed #727374;background-color:#ededed;height:36px;margin:8px 0;transition:height .3s ease-out;animation:animation .3s ease-out}.dropzone.active{border-color:#289e49;border-width:2px;background-color:#d0e8d6;height:72px}@keyframes animation{0%{height:0px;opacity:0}to{height:36px;opacity:1}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: DragoverNoChangeDetectDirective, selector: "[dragoverNoChangeDetect]", outputs: ["dragoverNoChangeDetect"] }] });
27
27
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: DropzoneComponent, decorators: [{
28
28
  type: Component,
29
- args: [{ standalone: true, selector: "dropzone", imports: [CommonModule, DragoverNoChangeDetectDirective], template: "<div\n class=\"dropzone\"\n [ngClass]=\"{ active: active }\"\n (dragenter)=\"dragenterHandler()\"\n (dragleave)=\"dragleaveHandler()\"\n (dragoverNoChangeDetect)=\"dragoverHandler($event)\"\n (drop)=\"dropHandler($event)\"\n></div>\n", styles: [".dropzone{border-radius:8px;border:1px dashed #727374;background-color:#ededed;height:20px;margin:8px 0;transition:height .2s ease-out;animation:animation .2s ease-out}.dropzone.active{border-color:#289e49;border-width:2px;background-color:#d0e8d6;height:48px}@keyframes animation{0%{height:0px;opacity:0}to{height:20px;opacity:1}}\n"] }]
29
+ args: [{ standalone: true, selector: "dropzone", imports: [CommonModule, DragoverNoChangeDetectDirective], template: "<div\n class=\"dropzone\"\n [ngClass]=\"{ active: active }\"\n (dragenter)=\"dragenterHandler()\"\n (dragleave)=\"dragleaveHandler()\"\n (dragoverNoChangeDetect)=\"dragoverHandler($event)\"\n (drop)=\"dropHandler($event)\"\n></div>\n", styles: [".dropzone{border-radius:8px;border:1px dashed #727374;background-color:#ededed;height:36px;margin:8px 0;transition:height .3s ease-out;animation:animation .3s ease-out}.dropzone.active{border-color:#289e49;border-width:2px;background-color:#d0e8d6;height:72px}@keyframes animation{0%{height:0px;opacity:0}to{height:36px;opacity:1}}\n"] }]
30
30
  }], propDecorators: { placement: [{
31
31
  type: Input
32
32
  }], dropped: [{
@@ -14,4 +14,4 @@ class Configuration {
14
14
  }
15
15
  }
16
16
  export const config = new Configuration();
17
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlndXJhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2xpbWJsZS10cmVlL3NyYy9saWIvY29yZS9jb25maWd1cmF0aW9uL2NvbmZpZ3VyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsTUFBTSxhQUFhO0lBR2hCO1FBRmlCLGtCQUFhLEdBQUcsSUFBSSxHQUFHLEVBQThCLENBQUM7UUFHcEUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFTSxTQUFTLENBQUksSUFBaUIsRUFBRSxPQUFvQjtRQUN4RCxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVNLFNBQVMsQ0FBQyxJQUFTO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVNLE1BQU0sQ0FBQyxJQUFTO1FBQ3BCLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25DLENBQUM7Q0FDSDtBQUVELE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBRyxJQUFJLGFBQWEsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVHJlZVJvb3QgfSBmcm9tIFwiLi4vdHJlZS1yb290L3RyZWUtcm9vdFwiO1xuaW1wb3J0IHsgVHJlZU9wdGlvbnMgfSBmcm9tIFwiLi90cmVlLW9wdGlvbnMuaW50ZXJmYWNlXCI7XG5cbmNsYXNzIENvbmZpZ3VyYXRpb24ge1xuICAgcHJpdmF0ZSByZWFkb25seSBjb25maWdTdG9yYWdlID0gbmV3IE1hcDxUcmVlUm9vdDxhbnk+LCBUcmVlT3B0aW9ucz4oKTtcblxuICAgcHVibGljIGNvbnN0cnVjdG9yKCkge1xuICAgICAgdGhpcy5jb25maWdTdG9yYWdlID0gbmV3IE1hcCgpO1xuICAgfVxuXG4gICBwdWJsaWMgc2V0Q29uZmlnPFQ+KHJvb3Q6IFRyZWVSb290PFQ+LCBvcHRpb25zOiBUcmVlT3B0aW9ucyk6IHZvaWQge1xuICAgICAgdGhpcy5jb25maWdTdG9yYWdlLnNldChyb290LCBvcHRpb25zKTtcbiAgIH1cblxuICAgcHVibGljIGdldENvbmZpZyhyb290OiBhbnkpOiBUcmVlT3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gICAgICByZXR1cm4gdGhpcy5jb25maWdTdG9yYWdlLmdldChyb290KTtcbiAgIH1cblxuICAgcHVibGljIGRlbGV0ZShyb290OiBhbnkpOiB2b2lkIHtcbiAgICAgIHRoaXMuY29uZmlnU3RvcmFnZS5kZWxldGUocm9vdCk7XG4gICB9XG59XG5cbmV4cG9ydCBjb25zdCBjb25maWcgPSBuZXcgQ29uZmlndXJhdGlvbigpO1xuIl19
17
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlndXJhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2xpbWJsZS10cmVlL3NyYy9saWIvY29yZS9jb25maWd1cmF0aW9uL2NvbmZpZ3VyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsTUFBTSxhQUFhO0lBR2hCO1FBRmlCLGtCQUFhLEdBQUcsSUFBSSxHQUFHLEVBQThCLENBQUM7UUFHcEUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFTSxTQUFTLENBQUksSUFBaUIsRUFBRSxPQUFvQjtRQUN4RCxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVNLFNBQVMsQ0FBQyxJQUFTO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVNLE1BQU0sQ0FBQyxJQUFTO1FBQ3BCLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25DLENBQUM7Q0FDSDtBQUVELE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBRyxJQUFJLGFBQWEsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBUcmVlUm9vdCB9IGZyb20gXCIuLi90cmVlLXJvb3QvdHJlZS1yb290XCI7XG5pbXBvcnQgdHlwZSB7IFRyZWVPcHRpb25zIH0gZnJvbSBcIi4vdHJlZS1vcHRpb25zLmludGVyZmFjZVwiO1xuXG5jbGFzcyBDb25maWd1cmF0aW9uIHtcbiAgIHByaXZhdGUgcmVhZG9ubHkgY29uZmlnU3RvcmFnZSA9IG5ldyBNYXA8VHJlZVJvb3Q8YW55PiwgVHJlZU9wdGlvbnM+KCk7XG5cbiAgIHB1YmxpYyBjb25zdHJ1Y3RvcigpIHtcbiAgICAgIHRoaXMuY29uZmlnU3RvcmFnZSA9IG5ldyBNYXAoKTtcbiAgIH1cblxuICAgcHVibGljIHNldENvbmZpZzxUPihyb290OiBUcmVlUm9vdDxUPiwgb3B0aW9uczogVHJlZU9wdGlvbnMpOiB2b2lkIHtcbiAgICAgIHRoaXMuY29uZmlnU3RvcmFnZS5zZXQocm9vdCwgb3B0aW9ucyk7XG4gICB9XG5cbiAgIHB1YmxpYyBnZXRDb25maWcocm9vdDogYW55KTogVHJlZU9wdGlvbnMgfCB1bmRlZmluZWQge1xuICAgICAgcmV0dXJuIHRoaXMuY29uZmlnU3RvcmFnZS5nZXQocm9vdCk7XG4gICB9XG5cbiAgIHB1YmxpYyBkZWxldGUocm9vdDogYW55KTogdm9pZCB7XG4gICAgICB0aGlzLmNvbmZpZ1N0b3JhZ2UuZGVsZXRlKHJvb3QpO1xuICAgfVxufVxuXG5leHBvcnQgY29uc3QgY29uZmlnID0gbmV3IENvbmZpZ3VyYXRpb24oKTtcbiJdfQ==
@@ -1,2 +1,2 @@
1
1
  export {};
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1vcHRpb25zLmludGVyZmFjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2xpbWJsZS10cmVlL3NyYy9saWIvY29yZS9jb25maWd1cmF0aW9uL3RyZWUtb3B0aW9ucy5pbnRlcmZhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRyZWVCcmFuY2ggfSBmcm9tIFwiLi4vdHJlZS1icmFuY2gvdHJlZS1icmFuY2hcIjtcbmltcG9ydCB7IFRyZWVSb290IH0gZnJvbSBcIi4uL3RyZWUtcm9vdC90cmVlLXJvb3RcIjtcblxuZXhwb3J0IGludGVyZmFjZSBUcmVlT3B0aW9ucyB7XG4gICBkcmFnQW5kRHJvcD86IHtcbiAgICAgIC8qKlxuICAgICAgICogQSBmdW5jdGlvbiB0byBpbmRpY2F0ZSB3aGV0aGVyIHRvIGFsbG93IGEgbm9kZSB0byBiZSBkcmFnZ2VkLiBUaGUgbm9kZSBpblxuICAgICAgICogcXVlc3Rpb24gaXMgcGFzc2VkIGluLiBEZWZhdWx0cyB0byBhIGZ1bmN0aW9uIHRoYXQgYWx3YXlzIHJldHVybnMgdHJ1ZS4gVGhpc1xuICAgICAgICogZnVuY3Rpb24gcnVucyB3aGVuIERyYWdBbmREcm9wU2VydmljZS5kcmFnU3RhcnQgcnVucywgYW5kIGJlZm9yZSB0aGUgYnJhbmNoXG4gICAgICAgKiBpcyBwcnVuZWQgZnJvbSB0aGUgdHJlZS5cbiAgICAgICAqL1xuICAgICAgYWxsb3dEcmFnZ2luZz86IDxUPih0cmVlQnJhbmNoOiBUcmVlQnJhbmNoPFQ+KSA9PiBib29sZWFuO1xuXG4gICAgICAvKipcbiAgICAgICAqIEEgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIHdoZXRoZXIgYSBzb3VyY2VOb2RlIGNhbiBiZSBkcm9wcGVkIGF0IGEgcGFydGljdWxhciBsb2NhdGlvbi5cbiAgICAgICAqIFRoZSBzb3VyY2VOb2RlLCB0aGUgbmV3IHByb3Bvc2VkUGFyZW50IGZvciB0aGUgc291cmNlTm9kZSwgYW5kIHRoZSBuZXcgcHJvcG9zZWRJbmRleFxuICAgICAgICogZm9yIHRoZSBzb3VyY2Ugbm9kZSBhcmUgcGFzc2VkIGluLiBUaGlzIGZ1bmN0aW9uIHJ1bnMganVzdCBiZWZvcmUgZGlzcGxheWluZyBhXG4gICAgICAgKiBmYW1pbHkgb2YgZHJvcHpvbmVzLlxuICAgICAgICovXG4gICAgICBhbGxvd0Ryb3A/OiA8VD4oXG4gICAgICAgICBzb3VyY2VOb2RlOiBUcmVlQnJhbmNoPFQ+LFxuICAgICAgICAgcHJvcG9zZWRQYXJlbnQ6IFRyZWVCcmFuY2g8VD4gfCBUcmVlUm9vdDxUPixcbiAgICAgICAgIHByb3Bvc2VkSW5kZXg6IG51bWJlclxuICAgICAgKSA9PiBib29sZWFuO1xuXG4gICAgICAvKipcbiAgICAgICAqIEEgZnVuY3Rpb24gdG8gaW5kaWNhdGUgd2hldGhlciB0byBhbGxvdyBcIm5lc3RpbmdcIiAocGxhY2luZyBhIGJyYW5jaCBvbmUgbGV2ZWxcbiAgICAgICAqIGRlZXBlciB0aGFuIGl0cyBwYXJlbnQpLiBUaGUgbm9kZSBpbiBxdWVzdGlvbiBpcyBwYXNzZWQgaW4uIERlZmF1bHRzIHRvIGEgZnVuY3Rpb25cbiAgICAgICAqIHRoYXQgYWx3YXlzIHJldHVybnMgdHJ1ZS4gVGhpcyBmdW5jdGlvbiBydW5zIGp1c3QgYmVmb3JlIGRpc3BsYXlpbmcgYSBmYW1pbHkgb2ZcbiAgICAgICAqIGRyb3B6b25lcy5cbiAgICAgICAqL1xuICAgICAgYWxsb3dOZXN0aW5nPzogPFQ+KHRyZWVCcmFuY2g6IFRyZWVCcmFuY2g8VD4pID0+IGJvb2xlYW47XG4gICB9O1xuXG4gICAvKipcbiAgICAqIFRoZSBudW1iZXIgb2YgcGl4ZWxzIGVhY2ggbGV2ZWwgb2YgdGhlIHRyZWUgd2lsbCBiZSBpbmRlbnRlZCByZWxhdGl2ZSB0b1xuICAgICogaXRzIHBhcmVudC4gRGVmYXVsdHMgdG8gMTYuXG4gICAgKi9cbiAgIGluZGVudGF0aW9uPzogbnVtYmVyO1xufVxuIl19
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1vcHRpb25zLmludGVyZmFjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2xpbWJsZS10cmVlL3NyYy9saWIvY29yZS9jb25maWd1cmF0aW9uL3RyZWUtb3B0aW9ucy5pbnRlcmZhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgVHJlZUJyYW5jaCB9IGZyb20gXCIuLi90cmVlLWJyYW5jaC90cmVlLWJyYW5jaFwiO1xuaW1wb3J0IHR5cGUgeyBUcmVlUm9vdCB9IGZyb20gXCIuLi90cmVlLXJvb3QvdHJlZS1yb290XCI7XG5cbi8qKiBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBhIHRyZWUsIGFzIGlkZW50aWZpZWQgYnkgYSBUcmVlUm9vdCAqL1xuZXhwb3J0IGludGVyZmFjZSBUcmVlT3B0aW9ucyB7XG4gICBkcmFnQW5kRHJvcD86IHtcbiAgICAgIC8qKlxuICAgICAgICogQSBmdW5jdGlvbiB0aGF0IGRldGVybWluZXMgd2hldGhlciB0byBhbGxvdyBhIG5vZGUgdG8gYmUgZHJhZ2dlZC5cbiAgICAgICAqXG4gICAgICAgKiBAcmVtYXJrc1xuICAgICAgICogUnVucyB3aGVuIGEgZHJhZyBiZWdpbnMsIGJ1dCBiZWZvcmUgdGhlIGJyYW5jaCBpcyBwcnVuZWQgZnJvbSB0aGUgdHJlZS5cbiAgICAgICAqXG4gICAgICAgKiBAcGFyYW0gdHJlZUJyYW5jaCAtIFRoZSBub2RlIG9mIHRoZSB0cmVlIHRoYXQgaXMgYWJvdXQgdG8gYmUgZHJhZ2dlZC5cbiAgICAgICAqXG4gICAgICAgKiBAZGVmYXVsdFZhbHVlIEEgZnVuY3Rpb24gdGhhdCBhbHdheXMgcmV0dXJucyB0cnVlLlxuICAgICAgICpcbiAgICAgICAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbm9kZSBjYW4gYmUgZHJhZ2dlZDsgYGZhbHNlYCBpZiBpdCBjYW5ub3QuXG4gICAgICAgKi9cbiAgICAgIGFsbG93RHJhZ2dpbmc/OiA8VD4odHJlZUJyYW5jaDogVHJlZUJyYW5jaDxUPikgPT4gYm9vbGVhbjtcblxuICAgICAgLyoqXG4gICAgICAgKiBBIGZ1bmN0aW9uIHRvIGRldGVybWluZSB3aGV0aGVyIGEgc291cmNlTm9kZSBjYW4gYmUgZHJvcHBlZCBhdCBhXG4gICAgICAgKiBwYXJ0aWN1bGFyIGxvY2F0aW9uLlxuICAgICAgICpcbiAgICAgICAqIEByZW1hcmtzXG4gICAgICAgKiBUaGlzIGZ1bmN0aW9uIHJ1bnMganVzdCBiZWZvcmUgZGlzcGxheWluZyBhIGZhbWlseSBvZiBkcm9wem9uZXMuXG4gICAgICAgKlxuICAgICAgICogQHBhcmFtIHNvdXJjZUJyYW5jaCAtIFRoZSBicmFuY2ggdGhhdCBpcyBiZWluZyBkcmFnZ2VkLlxuICAgICAgICogQHBhcmFtIHByb3Bvc2VkUGFyZW50IC0gVGhlIHByb3Bvc2VkIG5ldyBwYXJlbnQgb2YgdGhlIHNvdXJjZUJyYW5jaC5cbiAgICAgICAqIEBwYXJhbSBwcm9wb3NlZEluZGV4IC0gVGhlIHByb3Bvc2VkIG5ldyBpbmRleCBvZiB0aGUgc291cmNlQnJhbmNoLlxuICAgICAgICpcbiAgICAgICAqIEBkZWZhdWx0VmFsdWUgQSBmdW5jdGlvbiB0aGF0IGFsd2F5cyByZXR1cm5zIHRydWUuXG4gICAgICAgKi9cbiAgICAgIGFsbG93RHJvcD86IDxUPihcbiAgICAgICAgIHNvdXJjZUJyYW5jaDogVHJlZUJyYW5jaDxUPixcbiAgICAgICAgIHByb3Bvc2VkUGFyZW50OiBUcmVlQnJhbmNoPFQ+IHwgVHJlZVJvb3Q8VD4sXG4gICAgICAgICBwcm9wb3NlZEluZGV4OiBudW1iZXJcbiAgICAgICkgPT4gYm9vbGVhbjtcblxuICAgICAgLyoqXG4gICAgICAgKiBBIGZ1bmN0aW9uIHRvIGluZGljYXRlIHdoZXRoZXIgdG8gYWxsb3cgXCJuZXN0aW5nXCIgKHBsYWNpbmcgYSBicmFuY2ggYXNcbiAgICAgICAqIGEgY2hpbGQpIG9mIGEgcGFydGljdWxhciBicmFuY2guXG4gICAgICAgKlxuICAgICAgICogQHJlbWFya3NcbiAgICAgICAqIFRoaXMgZnVuY3Rpb24gcnVucyBqdXN0IGJlZm9yZSBkaXNwbGF5aW5nIGEgZmFtaWx5IG9mIGRyb3B6b25lcy5cbiAgICAgICAqXG4gICAgICAgKiBAcGFyYW0gdHJlZUJyYW5jaCAtIFRoZSBub2RlIG9mIHRoZSB0cmVlIHdob3NlIG5lc3RpbmcgY2FwYWJpbGl0eSBpcyBiZWluZ1xuICAgICAgICogY2hlY2tlZC5cbiAgICAgICAqXG4gICAgICAgKiBAZGVmYXVsdFZhbHVlIEEgZnVuY3Rpb24gdGhhdCBhbHdheXMgcmV0dXJucyB0cnVlLlxuICAgICAgICovXG4gICAgICBhbGxvd05lc3Rpbmc/OiA8VD4odHJlZUJyYW5jaDogVHJlZUJyYW5jaDxUPikgPT4gYm9vbGVhbjtcbiAgIH07XG5cbiAgIC8qKlxuICAgICogVGhlIG51bWJlciBvZiBwaXhlbHMgZWFjaCBsZXZlbCBvZiB0aGUgdHJlZSB3aWxsIGJlIGluZGVudGVkIHJlbGF0aXZlIHRvXG4gICAgKiBpdHMgcGFyZW50LlxuICAgICpcbiAgICAqIEBkZWZhdWx0VmFsdWUgMTZcbiAgICAqL1xuICAgaW5kZW50YXRpb24/OiBudW1iZXI7XG59XG4iXX0=
@@ -2,5 +2,4 @@ export * from "./tree-service/tree.service";
2
2
  export * from "./tree-root/tree-root";
3
3
  export * from "./tree-branch/tree-branch";
4
4
  export * from "./configuration/tree-options.interface";
5
- export * from "./configuration/configuration";
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2NvcmUvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyw2QkFBNkIsQ0FBQztBQUM1QyxjQUFjLHVCQUF1QixDQUFDO0FBQ3RDLGNBQWMsMkJBQTJCLENBQUM7QUFDMUMsY0FBYyx3Q0FBd0MsQ0FBQztBQUN2RCxjQUFjLCtCQUErQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSBcIi4vdHJlZS1zZXJ2aWNlL3RyZWUuc2VydmljZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHJlZS1yb290L3RyZWUtcm9vdFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHJlZS1icmFuY2gvdHJlZS1icmFuY2hcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbmZpZ3VyYXRpb24vdHJlZS1vcHRpb25zLmludGVyZmFjZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29uZmlndXJhdGlvbi9jb25maWd1cmF0aW9uXCI7XG4iXX0=
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2NvcmUvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyw2QkFBNkIsQ0FBQztBQUM1QyxjQUFjLHVCQUF1QixDQUFDO0FBQ3RDLGNBQWMsMkJBQTJCLENBQUM7QUFDMUMsY0FBYyx3Q0FBd0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gXCIuL3RyZWUtc2VydmljZS90cmVlLnNlcnZpY2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3RyZWUtcm9vdC90cmVlLXJvb3RcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3RyZWUtYnJhbmNoL3RyZWUtYnJhbmNoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb25maWd1cmF0aW9uL3RyZWUtb3B0aW9ucy5pbnRlcmZhY2VcIjtcbiJdfQ==
@@ -1,14 +1,21 @@
1
1
  import { assert } from "../../../shared/assert";
2
- import { GraftEvent } from "../../events/relational/graft-event";
3
- import { PruneEvent } from "../../events/relational/prune-event";
4
2
  import { TreeNodeBase } from "../tree-node-base";
5
- import { TreeError } from "../../errors/tree-error";
3
+ import { TreeError } from "../../errors";
6
4
  import { dropzoneRenderer } from "../../extras/drag-and-drop/dropzone-renderer";
7
5
  import { config } from "../configuration/configuration";
8
6
  import { TreeRoot } from "..";
9
7
  import { treeCollapser } from "../../extras/collapse/collapse";
10
- import { DestructionEvent } from "../../events/general";
8
+ import { DestructionEvent, GraftEvent, PruneEvent } from "../../events";
11
9
  import { BranchController } from "./branch-controller";
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
+ */
12
19
  export class TreeBranch {
13
20
  constructor(parent, branchOptions) {
14
21
  this.branchOptions = branchOptions;
@@ -17,26 +24,36 @@ export class TreeBranch {
17
24
  const parentBranchesContainer = parent.getBranchesContainer();
18
25
  assert(parentBranchesContainer !== undefined);
19
26
  this.branchController = new BranchController(this, parentBranchesContainer);
27
+ const hostView = this.branchController.getHostView();
20
28
  this.setIndentation(parent);
21
29
  if (parent instanceof TreeBranch &&
22
30
  parent.branchOptions.defaultCollapsed === true) {
23
31
  treeCollapser.storePrecollapsedNode(parent, this);
24
- this.detachedView = this.branchController.getHostView();
32
+ this.detachedView = hostView;
25
33
  }
26
34
  else {
27
- parentBranchesContainer.insert(this.branchController.getHostView());
28
- this.detectChanges();
35
+ parentBranchesContainer.insert(hostView);
29
36
  this._parent = parent;
30
37
  this.dispatch(new GraftEvent(this, {
31
38
  parent: this._parent,
32
39
  child: this,
33
40
  index: this._parent.branches().length
34
41
  }));
42
+ this.detectChanges();
35
43
  }
36
44
  }
45
+ /** @returns All child branches as an array of TreeBranch instances, in order. */
37
46
  branches() {
38
47
  return this.treeNodeBase.branches();
39
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
+ */
40
57
  destroy() {
41
58
  if (this.isDestroyed()) {
42
59
  throw new TreeError("Cannot destroy a destroyed tree branch");
@@ -49,49 +66,101 @@ export class TreeBranch {
49
66
  this.branchController.destroy();
50
67
  this.dispatch(new DestructionEvent(this));
51
68
  }
69
+ /** Run Angular change detection on this branch */
52
70
  detectChanges() {
53
71
  this.branchController.detectChanges();
54
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
+ */
55
86
  dispatch(event) {
56
87
  this.treeNodeBase.dispatch(event);
57
88
  this._parent?.dispatch(event);
58
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
+ */
59
95
  events() {
60
96
  return this.treeNodeBase.events();
61
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
+ */
62
105
  getBranch(index) {
63
106
  return this.treeNodeBase.getBranch(index);
64
107
  }
108
+ /** @returns The ViewContainerRef in which child branches are rendered */
65
109
  getBranchesContainer() {
66
110
  if (this.isDestroyed()) {
67
111
  throw new TreeError("Cannot get branches container from a destroyed tree branch");
68
112
  }
69
113
  return this.branchController.getBranchesContainer();
70
114
  }
115
+ /** @returns The instance of BranchComponent that is rendered by this class. */
71
116
  getComponentInstance() {
72
117
  if (this.isDestroyed()) {
73
118
  throw new TreeError("Cannot get component instance from a destroyed tree branch");
74
119
  }
75
120
  return this.branchController.getComponentInstance();
76
121
  }
122
+ /** @returns The Host View in which the BranchComponent is rendered */
77
123
  getHostView() {
78
124
  if (this.isDestroyed()) {
79
125
  throw new TreeError("Cannot get component host view from a destroyed tree branch");
80
126
  }
81
127
  return this.branchController.getHostView();
82
128
  }
129
+ /** @returns The BranchComponent as a native HTML Element */
83
130
  getNativeElement() {
84
131
  if (this.isDestroyed()) {
85
132
  throw new TreeError("Cannot get native element from a destroyed tree branch");
86
133
  }
87
134
  return this.branchController.getNativeElement();
88
135
  }
136
+ /**
137
+ * @returns
138
+ * A ComponentRef containing the instance of the user-provided
139
+ * component which is rendered by this branch.
140
+ */
89
141
  getUserlandComponentRef() {
90
142
  if (this.isDestroyed()) {
91
143
  throw new TreeError("Cannot get userland component from a destroyed tree branch");
92
144
  }
93
145
  return this.branchController.getUserlandComponentRef();
94
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
+ */
95
164
  graftTo(newParent, index) {
96
165
  this.checkGraftLocationValidity(newParent, index);
97
166
  const ownIndex = this.index();
@@ -108,12 +177,40 @@ export class TreeBranch {
108
177
  }));
109
178
  return newIndex;
110
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
+ */
111
190
  grow(component, options) {
112
191
  if (this.isDestroyed()) {
113
192
  throw new TreeError("Cannot grow a branch on a destroyed tree branch");
114
193
  }
115
- return new TreeBranch(this, { component, ...options });
194
+ try {
195
+ return new TreeBranch(this, { component, ...options });
196
+ }
197
+ catch (error) {
198
+ this.handleUserlandError(error);
199
+ }
116
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
+ */
117
214
  index() {
118
215
  if (!this._parent) {
119
216
  return undefined;
@@ -124,18 +221,76 @@ export class TreeBranch {
124
221
  assert(index >= 0);
125
222
  return index;
126
223
  }
224
+ /** @returns `true` if the branch is destroyed, `false` otherwise */
127
225
  isDestroyed() {
128
226
  return this.treeNodeBase.isDestroyed();
129
227
  }
228
+ /**
229
+ * @returns
230
+ * The data that was passed into the `branchOptions`' `meta` property
231
+ * at construction.
232
+ */
130
233
  meta() {
131
234
  return this.branchOptions.meta ?? {};
132
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
+ */
133
242
  parent() {
134
243
  return this._parent;
135
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
+ */
136
273
  plot() {
137
274
  return this.treeNodeBase.plot();
138
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
+ */
139
294
  position() {
140
295
  const index = this.index();
141
296
  if (index === undefined) {
@@ -147,6 +302,19 @@ export class TreeBranch {
147
302
  }
148
303
  return [index];
149
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
+ */
150
318
  prune() {
151
319
  if (this.isDestroyed()) {
152
320
  throw new TreeError("Cannot prune a destroyed tree branch");
@@ -168,6 +336,14 @@ export class TreeBranch {
168
336
  this._parent = undefined;
169
337
  return this;
170
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
+ */
171
347
  root() {
172
348
  const parent = this.parent();
173
349
  if (parent instanceof TreeBranch) {
@@ -176,6 +352,12 @@ export class TreeBranch {
176
352
  assert(parent instanceof TreeRoot || parent === undefined);
177
353
  return parent;
178
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
+ */
179
361
  traverse(callback) {
180
362
  callback(this);
181
363
  this.treeNodeBase.traverse(callback);
@@ -197,9 +379,28 @@ export class TreeBranch {
197
379
  }
198
380
  });
199
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
+ }
200
390
  indexIsOutOfRange(parent, index) {
201
391
  return index < 0 || index > parent.branches().length;
202
392
  }
393
+ furthestAncestor() {
394
+ // eslint-disable-next-line @typescript-eslint/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
+ }
203
404
  reattachView(index) {
204
405
  assert(this._parent !== undefined);
205
406
  assert(this.detachedView !== null);
@@ -221,4 +422,4 @@ export class TreeBranch {
221
422
  branchesContainerEl.style.marginLeft = `${options?.indentation ?? 16}px`;
222
423
  }
223
424
  }
224
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1icmFuY2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2NvcmUvdHJlZS1icmFuY2gvdHJlZS1icmFuY2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR2hELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFNakUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVwRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUNoRixPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDeEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLElBQUksQ0FBQztBQUM5QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDL0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFeEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFdkQsTUFBTSxPQUFPLFVBQVU7SUFlcEIsWUFDRyxNQUE4RCxFQUM5QyxhQUFtRDtRQUFuRCxrQkFBYSxHQUFiLGFBQWEsQ0FBc0M7UUFSOUQsaUJBQVksR0FBbUIsSUFBSSxDQUFDO1FBVXpDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUN2QyxNQUFNLHVCQUF1QixHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzlELE1BQU0sQ0FBQyx1QkFBdUIsS0FBSyxTQUFTLENBQUMsQ0FBQztRQUM5QyxJQUFJ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ZXJ0XCI7XG5pbXBvcnQgeyBUcmVlUGxvdCB9IGZyb20gXCIuLi8uLi9zdHJ1Y3R1cmUvdHJlZS1wbG90XCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IEdyYWZ0RXZlbnQgfSBmcm9tIFwiLi4vLi4vZXZlbnRzL3JlbGF0aW9uYWwvZ3JhZnQtZXZlbnRcIjtcbmltcG9ydCB7IFBydW5lRXZlbnQgfSBmcm9tIFwiLi4vLi4vZXZlbnRzL3JlbGF0aW9uYWwvcHJ1bmUtZXZlbnRcIjtcbmltcG9ydCB7IFRyZWVFdmVudCB9IGZyb20gXCIuLi8uLi9zdHJ1Y3R1cmUvdHJlZS1ldmVudC5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRyZWVCcmFuY2hOb2RlIH0gZnJvbSBcIi4uLy4uL3N0cnVjdHVyZS90cmVlLWJyYW5jaC1ub2RlLmludGVyZmFjZVwiO1xuaW1wb3J0IHsgQ29tcG9uZW50UmVmLCBUeXBlLCBWaWV3Q29udGFpbmVyUmVmLCBWaWV3UmVmIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEJyYW5jaENvbXBvbmVudCB9IGZyb20gXCIuLi8uLi9jb21wb25lbnRzL2JyYW5jaC9icmFuY2guY29tcG9uZW50XCI7XG5pbXBvcnQgeyBOb2RlQ29tcG9uZW50IH0gZnJvbSBcIi4uLy4uL2NvbXBvbmVudHMvbm9kZS1jb21wb25lbnQuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUcmVlTm9kZUJhc2UgfSBmcm9tIFwiLi4vdHJlZS1ub2RlLWJhc2VcIjtcbmltcG9ydCB7IFRyZWVFcnJvciB9IGZyb20gXCIuLi8uLi9lcnJvcnMvdHJlZS1lcnJvclwiO1xuaW1wb3J0IHsgQnJhbmNoT3B0aW9ucywgRnVsbEJyYW5jaE9wdGlvbnMgfSBmcm9tIFwiLi4vYnJhbmNoLW9wdGlvbnMuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBkcm9wem9uZVJlbmRlcmVyIH0gZnJvbSBcIi4uLy4uL2V4dHJhcy9kcmFnLWFuZC1kcm9wL2Ryb3B6b25lLXJlbmRlcmVyXCI7XG5pbXBvcnQgeyBjb25maWcgfSBmcm9tIFwiLi4vY29uZmlndXJhdGlvbi9jb25maWd1cmF0aW9uXCI7XG5pbXBvcnQgeyBUcmVlUm9vdCB9IGZyb20gXCIuLlwiO1xuaW1wb3J0IHsgdHJlZUNvbGxhcHNlciB9IGZyb20gXCIuLi8uLi9leHRyYXMvY29sbGFwc2UvY29sbGFwc2VcIjtcbmltcG9ydCB7IERlc3RydWN0aW9uRXZlbnQgfSBmcm9tIFwiLi4vLi4vZXZlbnRzL2dlbmVyYWxcIjtcbmltcG9ydCB7IFRyZWVOb2RlIH0gZnJvbSBcIi4uLy4uL3N0cnVjdHVyZVwiO1xuaW1wb3J0IHsgQnJhbmNoQ29udHJvbGxlciB9IGZyb20gXCIuL2JyYW5jaC1jb250cm9sbGVyXCI7XG5cbmV4cG9ydCBjbGFzcyBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PlxuICAgaW1wbGVtZW50c1xuICAgICAgVHJlZUJyYW5jaE5vZGU8XG4gICAgICAgICBCcmFuY2hDb21wb25lbnQ8VXNlcmxhbmRDb21wb25lbnQ+LFxuICAgICAgICAgVHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4sXG4gICAgICAgICBOb2RlQ29tcG9uZW50XG4gICAgICA+XG57XG4gICBwcml2YXRlIHJlYWRvbmx5IGJyYW5jaENvbnRyb2xsZXI6IEJyYW5jaENvbnRyb2xsZXI8VXNlcmxhbmRDb21wb25lbnQ+O1xuICAgcHJpdmF0ZSBkZXRhY2hlZFZpZXc6IFZpZXdSZWYgfCBudWxsID0gbnVsbDtcbiAgIHByaXZhdGUgX3BhcmVudDpcbiAgICAgIHwgVHJlZU5vZGU8VHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4sIE5vZGVDb21wb25lbnQ+XG4gICAgICB8IHVuZGVmaW5lZDtcbiAgIHByaXZhdGUgcmVhZG9ubHkgdHJlZU5vZGVCYXNlOiBUcmVlTm9kZUJhc2U8VXNlcmxhbmRDb21wb25lbnQ+O1xuXG4gICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgICBwYXJlbnQ6IFRyZWVOb2RlPFRyZWVCcmFuY2g8VXNlcmxhbmRDb21wb25lbnQ+LCBOb2RlQ29tcG9uZW50PixcbiAgICAgIHB1YmxpYyByZWFkb25seSBicmFuY2hPcHRpb25zOiBGdWxsQnJhbmNoT3B0aW9uczxVc2VybGFuZENvbXBvbmVudD5cbiAgICkge1xuICAgICAgdGhpcy50cmVlTm9kZUJhc2UgPSBuZXcgVHJlZU5vZGVCYXNlKCk7XG4gICAgICBjb25zdCBwYXJlbnRCcmFuY2hlc0NvbnRhaW5lciA9IHBhcmVudC5nZXRCcmFuY2hlc0NvbnRhaW5lcigpO1xuICAgICAgYXNzZXJ0KHBhcmVudEJyYW5jaGVzQ29udGFpbmVyICE9PSB1bmRlZmluZWQpO1xuICAgICAgdGhpcy5icmFuY2hDb250cm9sbGVyID0gbmV3IEJyYW5jaENvbnRyb2xsZXIoXG4gICAgICAgICB0aGlzLFxuICAgICAgICAgcGFyZW50QnJhbmNoZXNDb250YWluZXJcbiAgICAgICk7XG4gICAgICB0aGlzLnNldEluZGVudGF0aW9uKHBhcmVudCk7XG4gICAgICBpZiAoXG4gICAgICAgICBwYXJlbnQgaW5zdGFuY2VvZiBUcmVlQnJhbmNoICYmXG4gICAgICAgICBwYXJlbnQuYnJhbmNoT3B0aW9ucy5kZWZhdWx0Q29sbGFwc2VkID09PSB0cnVlXG4gICAgICApIHtcbiAgICAgICAgIHRyZWVDb2xsYXBzZXIuc3RvcmVQcmVjb2xsYXBzZWROb2RlKHBhcmVudCwgdGhpcyk7XG4gICAgICAgICB0aGlzLmRldGFjaGVkVmlldyA9IHRoaXMuYnJhbmNoQ29udHJvbGxlci5nZXRIb3N0VmlldygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgIHBhcmVudEJyYW5jaGVzQ29udGFpbmVyLmluc2VydCh0aGlzLmJyYW5jaENvbnRyb2xsZXIuZ2V0SG9zdFZpZXcoKSk7XG4gICAgICAgICB0aGlzLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgIHRoaXMuX3BhcmVudCA9IHBhcmVudDtcbiAgICAgICAgIHRoaXMuZGlzcGF0Y2goXG4gICAgICAgICAgICBuZXcgR3JhZnRFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICAgICBwYXJlbnQ6IHRoaXMuX3BhcmVudCxcbiAgICAgICAgICAgICAgIGNoaWxkOiB0aGlzLFxuICAgICAgICAgICAgICAgaW5kZXg6IHRoaXMuX3BhcmVudC5icmFuY2hlcygpLmxlbmd0aFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICk7XG4gICAgICB9XG4gICB9XG5cbiAgIHB1YmxpYyBicmFuY2hlcygpOiBBcnJheTxUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50Pj4ge1xuICAgICAgcmV0dXJuIHRoaXMudHJlZU5vZGVCYXNlLmJyYW5jaGVzKCk7XG4gICB9XG5cbiAgIHB1YmxpYyBkZXN0cm95KCk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBkZXN0cm95IGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5wcnVuZSgpO1xuICAgICAgdHJlZUNvbGxhcHNlci5leHBhbmQodGhpcyk7XG4gICAgICBkcm9wem9uZVJlbmRlcmVyLmNsZWFyVHJlZUZyb21SZWdpc3RyeSh0aGlzKTtcbiAgICAgIHRoaXMuYnJhbmNoQ29udHJvbGxlci5nZXRIb3N0VmlldygpLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMudHJlZU5vZGVCYXNlLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMuYnJhbmNoQ29udHJvbGxlci5kZXN0cm95KCk7XG4gICAgICB0aGlzLmRpc3BhdGNoKG5ldyBEZXN0cnVjdGlvbkV2ZW50KHRoaXMpKTtcbiAgIH1cblxuICAgcHVibGljIGRldGVjdENoYW5nZXMoKTogdm9pZCB7XG4gICAgICB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgfVxuXG4gICBwdWJsaWMgZGlzcGF0Y2goZXZlbnQ6IFRyZWVFdmVudCk6IHZvaWQge1xuICAgICAgdGhpcy50cmVlTm9kZUJhc2UuZGlzcGF0Y2goZXZlbnQpO1xuICAgICAgdGhpcy5fcGFyZW50Py5kaXNwYXRjaChldmVudCk7XG4gICB9XG5cbiAgIHB1YmxpYyBldmVudHMoKTogT2JzZXJ2YWJsZTxUcmVlRXZlbnQ+IHtcbiAgICAgIHJldHVybiB0aGlzLnRyZWVOb2RlQmFzZS5ldmVudHMoKTtcbiAgIH1cblxuICAgcHVibGljIGdldEJyYW5jaChpbmRleDogbnVtYmVyKTogVHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4gfCB1bmRlZmluZWQge1xuICAgICAgcmV0dXJuIHRoaXMudHJlZU5vZGVCYXNlLmdldEJyYW5jaChpbmRleCk7XG4gICB9XG5cbiAgIHB1YmxpYyBnZXRCcmFuY2hlc0NvbnRhaW5lcigpOiBWaWV3Q29udGFpbmVyUmVmIHwgdW5kZWZpbmVkIHtcbiAgICAgIGlmICh0aGlzLmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICBcIkNhbm5vdCBnZXQgYnJhbmNoZXMgY29udGFpbmVyIGZyb20gYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIlxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZ2V0QnJhbmNoZXNDb250YWluZXIoKTtcbiAgIH1cblxuICAgcHVibGljIGdldENvbXBvbmVudEluc3RhbmNlKCk6IEJyYW5jaENvbXBvbmVudDxVc2VybGFuZENvbXBvbmVudD4ge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcbiAgICAgICAgICAgIFwiQ2Fubm90IGdldCBjb21wb25lbnQgaW5zdGFuY2UgZnJvbSBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiXG4gICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYnJhbmNoQ29udHJvbGxlci5nZXRDb21wb25lbnRJbnN0YW5jZSgpO1xuICAgfVxuXG4gICBwdWJsaWMgZ2V0SG9zdFZpZXcoKTogVmlld1JlZiB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgXCJDYW5ub3QgZ2V0IGNvbXBvbmVudCBob3N0IHZpZXcgZnJvbSBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiXG4gICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYnJhbmNoQ29udHJvbGxlci5nZXRIb3N0VmlldygpO1xuICAgfVxuXG4gICBwdWJsaWMgZ2V0TmF0aXZlRWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgXCJDYW5ub3QgZ2V0IG5hdGl2ZSBlbGVtZW50IGZyb20gYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIlxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZ2V0TmF0aXZlRWxlbWVudCgpO1xuICAgfVxuXG4gICBwdWJsaWMgZ2V0VXNlcmxhbmRDb21wb25lbnRSZWYoKTpcbiAgICAgIHwgQ29tcG9uZW50UmVmPFVzZXJsYW5kQ29tcG9uZW50PlxuICAgICAgfCB1bmRlZmluZWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcbiAgICAgICAgICAgIFwiQ2Fubm90IGdldCB1c2VybGFuZCBjb21wb25lbnQgZnJvbSBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiXG4gICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYnJhbmNoQ29udHJvbGxlci5nZXRVc2VybGFuZENvbXBvbmVudFJlZigpO1xuICAgfVxuXG4gICBwdWJsaWMgZ3JhZnRUbyhcbiAgICAgIG5ld1BhcmVudDogVHJlZU5vZGU8VHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4sIE5vZGVDb21wb25lbnQ+LFxuICAgICAgaW5kZXg/OiBudW1iZXJcbiAgICk6IG51bWJlciB7XG4gICAgICB0aGlzLmNoZWNrR3JhZnRMb2NhdGlvblZhbGlkaXR5KG5ld1BhcmVudCwgaW5kZXgpO1xuICAgICAgY29uc3Qgb3duSW5kZXggPSB0aGlzLmluZGV4KCk7XG4gICAgICBpZiAob3duSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgdGhpcy5wcnVuZSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5fcGFyZW50ID0gbmV3UGFyZW50O1xuICAgICAgY29uc3QgbmV3SW5kZXggPSBpbmRleCA/PyBuZXdQYXJlbnQuYnJhbmNoZXMoKS5sZW5ndGg7XG4gICAgICB0aGlzLnJlYXR0YWNoVmlldyhuZXdJbmRleCk7XG4gICAgICB0aGlzLmRpc3BhdGNoKFxuICAgICAgICAgbmV3IEdyYWZ0RXZlbnQodGhpcywge1xuICAgICAgICAgICAgcGFyZW50OiBuZXdQYXJlbnQsXG4gICAgICAgICAgICBjaGlsZDogdGhpcyxcbiAgICAgICAgICAgIGluZGV4OiBuZXdJbmRleFxuICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICByZXR1cm4gbmV3SW5kZXg7XG4gICB9XG5cbiAgIHB1YmxpYyBncm93KFxuICAgICAgY29tcG9uZW50OiBUeXBlPFVzZXJsYW5kQ29tcG9uZW50PixcbiAgICAgIG9wdGlvbnM/OiBCcmFuY2hPcHRpb25zPFVzZXJsYW5kQ29tcG9uZW50PlxuICAgKTogVHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4ge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBncm93IGEgYnJhbmNoIG9uIGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBUcmVlQnJhbmNoKHRoaXMsIHsgY29tcG9uZW50LCAuLi5vcHRpb25zIH0pO1xuICAgfVxuXG4gICBwdWJsaWMgaW5kZXgoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICAgIGlmICghdGhpcy5fcGFyZW50KSB7XG4gICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9wYXJlbnRcbiAgICAgICAgIC5icmFuY2hlcygpXG4gICAgICAgICAuZmluZEluZGV4KChicmFuY2gpID0+IGJyYW5jaCA9PT0gdGhpcyk7XG4gICAgICBhc3NlcnQoaW5kZXggPj0gMCk7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICB9XG5cbiAgIHB1YmxpYyBpc0Rlc3Ryb3llZCgpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnRyZWVOb2RlQmFzZS5pc0Rlc3Ryb3llZCgpO1xuICAgfVxuXG4gICBwdWJsaWMgbWV0YSgpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICAgIHJldHVybiB0aGlzLmJyYW5jaE9wdGlvbnMubWV0YSA/PyB7fTtcbiAgIH1cblxuICAgcHVibGljIHBhcmVudCgpOlxuICAgICAgfCBUcmVlTm9kZTxUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PiwgTm9kZUNvbXBvbmVudD5cbiAgICAgIHwgdW5kZWZpbmVkIHtcbiAgICAgIHJldHVybiB0aGlzLl9wYXJlbnQ7XG4gICB9XG5cbiAgIHB1YmxpYyBwbG90KCk6IFRyZWVQbG90IHtcbiAgICAgIHJldHVybiB0aGlzLnRyZWVOb2RlQmFzZS5wbG90KCk7XG4gICB9XG5cbiAgIHB1YmxpYyBwb3NpdGlvbigpOiBBcnJheTxudW1iZXI+IHtcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5pbmRleCgpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICBcImJyYW5jaCBoYXMgbm8gcGFyZW50LiBQb3NpdGlvbiBjYW5ub3QgYmUgZGV0ZXJtaW5lZC5cIlxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9wYXJlbnQgaW5zdGFuY2VvZiBUcmVlQnJhbmNoKSB7XG4gICAgICAgICBjb25zdCBwYXJlbnRQb3NpdGlvbiA9IHRoaXMuX3BhcmVudC5wb3NpdGlvbigpO1xuICAgICAgICAgcmV0dXJuIFsuLi5wYXJlbnRQb3NpdGlvbiwgaW5kZXhdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtpbmRleF07XG4gICB9XG5cbiAgIHB1YmxpYyBwcnVuZSgpOiB0aGlzIHwgdW5kZWZpbmVkIHtcbiAgICAgIGlmICh0aGlzLmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXCJDYW5ub3QgcHJ1bmUgYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIik7XG4gICAgICB9XG4gICAgICBjb25zdCBwYXJlbnQgPSB0aGlzLl9wYXJlbnQ7XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMuaW5kZXgoKTtcbiAgICAgIGlmIChpbmRleCA9PT0gdW5kZWZpbmVkIHx8IHBhcmVudCA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgICBjb25zdCBjb250YWluZXIgPSBwYXJlbnQuZ2V0QnJhbmNoZXNDb250YWluZXIoKTtcbiAgICAgIGFzc2VydChjb250YWluZXIgIT09IHVuZGVmaW5lZCk7XG4gICAgICB0aGlzLmRldGFjaGVkVmlldyA9IGNvbnRhaW5lci5kZXRhY2goaW5kZXgpO1xuICAgICAgYXNzZXJ0KHRoaXMuZGV0YWNoZWRWaWV3ICE9PSBudWxsKTtcbiAgICAgIHRoaXMuZGV0YWNoZWRWaWV3LmRldGFjaCgpO1xuICAgICAgdGhpcy5kaXNwYXRjaChcbiAgICAgICAgIG5ldyBQcnVuZUV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgIHBhcmVudDogcGFyZW50LFxuICAgICAgICAgICAgY2hpbGQ6IHRoaXMsXG4gICAgICAgICAgICBpbmRleDogaW5kZXhcbiAgICAgICAgIH0pXG4gICAgICApO1xuICAgICAgdGhpcy5fcGFyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICB9XG5cbiAgIHB1YmxpYyByb290KCk6IFRyZWVSb290PFVzZXJsYW5kQ29tcG9uZW50PiB8IHVuZGVmaW5lZCB7XG4gICAgICBjb25zdCBwYXJlbnQgPSB0aGlzLnBhcmVudCgpO1xuICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIFRyZWVCcmFuY2gpIHtcbiAgICAgICAgIHJldHVybiBwYXJlbnQucm9vdCgpO1xuICAgICAgfVxuICAgICAgYXNzZXJ0KHBhcmVudCBpbnN0YW5jZW9mIFRyZWVSb290IHx8IHBhcmVudCA9PT0gdW5kZWZpbmVkKTtcbiAgICAgIHJldHVybiBwYXJlbnQ7XG4gICB9XG5cbiAgIHB1YmxpYyB0cmF2ZXJzZShcbiAgICAgIGNhbGxiYWNrOiAoXG4gICAgICAgICBub2RlOiBUcmVlTm9kZTxUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PiwgTm9kZUNvbXBvbmVudD5cbiAgICAgICkgPT4gdm9pZFxuICAgKTogdm9pZCB7XG4gICAgICBjYWxsYmFjayh0aGlzKTtcbiAgICAgIHRoaXMudHJlZU5vZGVCYXNlLnRyYXZlcnNlKGNhbGxiYWNrKTtcbiAgIH1cblxuICAgcHJpdmF0ZSBjaGVja0dyYWZ0TG9jYXRpb25WYWxpZGl0eShcbiAgICAgIG5ld1BhcmVudDogVHJlZU5vZGU8VHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4sIE5vZGVDb21wb25lbnQ+LFxuICAgICAgaW5kZXg/OiBudW1iZXJcbiAgICk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBncmFmdCBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChuZXdQYXJlbnQuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBncmFmdCB0byBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgIHR5cGVvZiBpbmRleCA9PT0gXCJudW1iZXJcIiAmJlxuICAgICAgICAgdGhpcy5pbmRleElzT3V0T2ZSYW5nZShuZXdQYXJlbnQsIGluZGV4KVxuICAgICAgKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgYENhbm5vdCBncmFmdCBicmFuY2ggYXQgaW5kZXggJHtpbmRleH0gb2YgdGhlIHBhcmVudC4gT3V0IG9mIHJhbmdlLmBcbiAgICAgICAgICk7XG4gICAgICB9XG4gICAgICB0aGlzLnRyYXZlcnNlKChub2RlKSA9PiB7XG4gICAgICAgICBpZiAobm9kZSA9PT0gbmV3UGFyZW50KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgICAgXCJDYW5ub3QgZ3JhZnQgYSBicmFuY2ggdG8gaXRzZWxmIG9yIGFueSBvZiBpdHMgb3duIGRlc2NlbmRhbnRzXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICB9XG4gICAgICB9KTtcbiAgIH1cblxuICAgcHJpdmF0ZSBpbmRleElzT3V0T2ZSYW5nZShcbiAgICAgIHBhcmVudDogVHJlZU5vZGU8VHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4sIE5vZGVDb21wb25lbnQ+LFxuICAgICAgaW5kZXg6IG51bWJlclxuICAgKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gaW5kZXggPCAwIHx8IGluZGV4ID4gcGFyZW50LmJyYW5jaGVzKCkubGVuZ3RoO1xuICAgfVxuXG4gICBwcml2YXRlIHJlYXR0YWNoVmlldyhpbmRleD86IG51bWJlcik6IHZvaWQge1xuICAgICAgYXNzZXJ0KHRoaXMuX3BhcmVudCAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIGFzc2VydCh0aGlzLmRldGFjaGVkVmlldyAhPT0gbnVsbCk7XG4gICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLl9wYXJlbnQuZ2V0QnJhbmNoZXNDb250YWluZXIoKTtcbiAgICAgIGFzc2VydChjb250YWluZXIgIT09IHVuZGVmaW5lZCk7XG4gICAgICB0aGlzLmRldGFjaGVkVmlldy5yZWF0dGFjaCgpO1xuICAgICAgY29udGFpbmVyLmluc2VydCh0aGlzLmRldGFjaGVkVmlldywgaW5kZXgpO1xuICAgICAgdGhpcy5kZXRhY2hlZFZpZXcgPSBudWxsO1xuICAgfVxuXG4gICBwcml2YXRlIHNldEluZGVudGF0aW9uKFxuICAgICAgcGFyZW50OiBUcmVlTm9kZTxUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PiwgTm9kZUNvbXBvbmVudD5cbiAgICk6IHZvaWQge1xuICAgICAgY29uc3Qgcm9vdCA9IHBhcmVudC5yb290KCk7XG4gICAgICBhc3NlcnQocm9vdCAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSBjb25maWcuZ2V0Q29uZmlnKHJvb3QpO1xuICAgICAgY29uc3QgYnJhbmNoZXNDb250YWluZXJFbCA9IHRoaXMuYnJhbmNoQ29udHJvbGxlclxuICAgICAgICAgLmdldE5hdGl2ZUVsZW1lbnQoKVxuICAgICAgICAgLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJicmFuY2hlcy1jb250YWluZXJcIilcbiAgICAgICAgIC5pdGVtKDApO1xuICAgICAgYXNzZXJ0KGJyYW5jaGVzQ29udGFpbmVyRWwgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCk7XG4gICAgICBicmFuY2hlc0NvbnRhaW5lckVsLnN0eWxlLm1hcmdpbkxlZnQgPSBgJHtvcHRpb25zPy5pbmRlbnRhdGlvbiA/PyAxNn1weGA7XG4gICB9XG59XG4iXX0=
425
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1icmFuY2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saW1ibGUtdHJlZS9zcmMvbGliL2NvcmUvdHJlZS1icmFuY2gvdHJlZS1icmFuY2gudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBVWhELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBS3pDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN4RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQzlCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMvRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQU94RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV2RDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sT0FBTyxVQUFVO0lBZXBCLFlBQ0csTUFBOEQsRUFDOUMsYUFBbUQ7UUFBbkQsa0JBQWEsR0FBYixhQUFhLENBQXNDO1FBUjlELGlCQUFZLEdBQW1CLElBQUksQ0FBQztRQVV6QyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDdkMsTUFBTSx1QkFBdUIsR0FBRyxNQUFNLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUM5RCxNQUFNLENBQUMsdUJBQXVCLEtBQUssU0FBUyxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksZ0JBQWdCLENBQ3pDLElBQUksRUFDSix1QkFBdUIsQ0FDekIsQ0FBQztRQUNGLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNyRCxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVCLElBQ0csTUFBTSxZQUFZLFVBQVU7WUFDNUIsTUFBTSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsS0FBSyxJQUFJLEVBQy9DO1lBQ0MsYUFBYSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNsRCxJQUFJLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQztTQUMvQjthQUFNO1lBQ0osdUJBQXVCLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3pDLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxRQUFRLENBQ1YsSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFO2dCQUNsQixNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU87Z0JBQ3BCLEtBQUssRUFBRSxJQUFJO2dCQUNYLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU07YUFDdkMsQ0FBQyxDQUNKLENBQUM7WUFDRixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDdkI7SUFDSixDQUFDO0lBRUQsaUZBQWlGO0lBQzFFLFFBQVE7UUFDWixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxPQUFPO1FBQ1gsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDckIsTUFBTSxJQUFJLFNBQVMsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1NBQ2hFO1FBQ0QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2IsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMzQixnQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDOUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDaEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVELGtEQUFrRDtJQUMzQyxhQUFhO1FBQ2pCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ksUUFBUSxDQUFDLEtBQWdCO1FBQzdCLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksTUFBTTtRQUNWLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksU0FBUyxDQUFDLEtBQWE7UUFDM0IsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQseUVBQXlFO0lBQ2xFLG9CQUFvQjtRQUN4QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUNyQixNQUFNLElBQUksU0FBUyxDQUNoQiw0REFBNEQsQ0FDOUQsQ0FBQztTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJQUN2RCxDQUFDO0lBRUQsK0VBQStFO0lBQ3hFLG9CQUFvQjtRQUN4QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUNyQixNQUFNLElBQUksU0FBUyxDQUNoQiw0REFBNEQsQ0FDOUQsQ0FBQztTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztJQUN2RCxDQUFDO0lBRUQsc0VBQXNFO0lBQy9ELFdBQVc7UUFDZixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUNyQixNQUFNLElBQUksU0FBUyxDQUNoQiw2REFBNkQsQ0FDL0QsQ0FBQztTQUNKO1FBQ0QsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDOUMsQ0FBQztJQUVELDREQUE0RDtJQUNyRCxnQkFBZ0I7UUFDcEIsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDckIsTUFBTSxJQUFJLFNBQVMsQ0FDaEIsd0RBQXdELENBQzFELENBQUM7U0FDSjtRQUNELE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDbkQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSx1QkFBdUI7UUFHM0IsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDckIsTUFBTSxJQUFJLFNBQVMsQ0FDaEIsNERBQTRELENBQzlELENBQUM7U0FDSjtRQUNELE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLHVCQUF1QixFQUFFLENBQUM7SUFDMUQsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7O09BZ0JHO0lBQ0ksT0FBTyxDQUNYLFNBQWlFLEVBQ2pFLEtBQWM7UUFFZCxJQUFJLENBQUMsMEJBQTBCLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2xELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM5QixJQUFJLFFBQVEsS0FBSyxTQUFTLEVBQUU7WUFDekIsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ2Y7UUFDRCxJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQztRQUN6QixNQUFNLFFBQVEsR0FBRyxLQUFLLElBQUksU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQztRQUN0RCxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzVCLElBQUksQ0FBQyxRQUFRLENBQ1YsSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFO1lBQ2xCLE1BQU0sRUFBRSxTQUFTO1lBQ2pCLEtBQUssRUFBRSxJQUFJO1lBQ1gsS0FBSyxFQUFFLFFBQVE7U0FDakIsQ0FBQyxDQUNKLENBQUM7UUFDRixPQUFPLFFBQVEsQ0FBQztJQUNuQixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksSUFBSSxDQUNSLFNBQWtDLEVBQ2xDLE9BQTBDO1FBRTFDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFO1lBQ3JCLE1BQU0sSUFBSSxTQUFTLENBQUMsaURBQWlELENBQUMsQ0FBQztTQUN6RTtRQUNELElBQUk7WUFDRCxPQUFPLElBQUksVUFBVSxDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDLENBQUM7U0FDekQ7UUFBQyxPQUFPLEtBQWMsRUFBRTtZQUN0QixJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDbEM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ksS0FBSztRQUNULElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2hCLE9BQU8sU0FBUyxDQUFDO1NBQ25CO1FBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU87YUFDdEIsUUFBUSxFQUFFO2FBQ1YsU0FBUyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLENBQUM7UUFDM0MsTUFBTSxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNuQixPQUFPLEtBQUssQ0FBQztJQUNoQixDQUFDO0lBRUQsb0VBQW9FO0lBQzdELFdBQVc7UUFDZixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxJQUFJO1FBQ1IsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksTUFBTTtRQUdWLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN2QixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQTJCRztJQUNJLElBQUk7UUFDUixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztPQWlCRztJQUNJLFFBQVE7UUFDWixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDM0IsSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFO1lBQ3RCLE1BQU0sSUFBSSxTQUFTLENBQ2hCLHNEQUFzRCxDQUN4RCxDQUFDO1NBQ0o7UUFDRCxJQUFJLElBQUksQ0FBQyxPQUFPLFlBQVksVUFBVSxFQUFFO1lBQ3JDLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDL0MsT0FBTyxDQUFDLEdBQUcsY0FBYyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ3BDO1FBQ0QsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2xCLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSSxLQUFLO1FBQ1QsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDckIsTUFBTSxJQUFJLFNBQVMsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1NBQzlEO1FBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM1QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDM0IsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLE1BQU0sS0FBSyxTQUFTO1lBQUUsT0FBTztRQUN4RCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUNoRCxNQUFNLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksS0FBSyxJQUFJLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxRQUFRLENBQ1YsSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFO1lBQ2xCLE1BQU0sRUFBRSxNQUFNO1lBQ2QsS0FBSyxFQUFFLElBQUk7WUFDWCxLQUFLLEVBQUUsS0FBSztTQUNkLENBQUMsQ0FDSixDQUFDO1FBQ0YsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUM7UUFDekIsT0FBTyxJQUFJLENBQUM7SUFDZixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLElBQUk7UUFDUixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDN0IsSUFBSSxNQUFNLFlBQVksVUFBVSxFQUFFO1lBQy9CLE9BQU8sTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1NBQ3ZCO1FBQ0QsTUFBTSxDQUFDLE1BQU0sWUFBWSxRQUFRLElBQUksTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBQzNELE9BQU8sTUFBTSxDQUFDO0lBQ2pCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLFFBQVEsQ0FDWixRQUVTO1FBRVQsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVPLDBCQUEwQixDQUMvQixTQUFpRSxFQUNqRSxLQUFjO1FBRWQsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDckIsTUFBTSxJQUFJLFNBQVMsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1NBQzlEO1FBQ0QsSUFBSSxTQUFTLENBQUMsV0FBVyxFQUFFLEVBQUU7WUFDMUIsTUFBTSxJQUFJLFNBQVMsQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO1NBQ2pFO1FBQ0QsSUFDRyxPQUFPLEtBQUssS0FBSyxRQUFRO1lBQ3pCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEVBQ3pDO1lBQ0MsTUFBTSxJQUFJLFNBQVMsQ0FDaEIsZ0NBQWdDLEtBQUssK0JBQStCLENBQ3RFLENBQUM7U0FDSjtRQUNELElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNwQixJQUFJLElBQUksS0FBSyxTQUFTLEVBQUU7Z0JBQ3JCLE1BQU0sSUFBSSxTQUFTLENBQ2hCLCtEQUErRCxDQUNqRSxDQUFDO2FBQ0o7UUFDSixDQUFDLENBQUMsQ0FBQztJQUNOLENBQUM7SUFFTyxtQkFBbUIsQ0FBQyxLQUFjO1FBQ3ZDLHdFQUF3RTtRQUN4RSx5RUFBeUU7UUFDekUscUVBQXFFO1FBQ3JFLHVDQUF1QztRQUN2QyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsWUFBWSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFTyxpQkFBaUIsQ0FDdEIsTUFBOEQsRUFDOUQsS0FBYTtRQUViLE9BQU8sS0FBSyxHQUFHLENBQUMsSUFBSSxLQUFLLEdBQUcsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQztJQUN4RCxDQUFDO0lBRU8sZ0JBQWdCO1FBSXJCLG9NQUFvTTtRQUNwTSxJQUFJLElBQUksR0FBMkQsSUFBSSxDQUFDO1FBQ3hFLE9BQU8sSUFBSSxZQUFZLFVBQVUsRUFBRTtZQUNoQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDN0IsSUFBSSxNQUFNLEtBQUssU0FBUztnQkFBRSxNQUFNO1lBQ2hDLElBQUksR0FBRyxNQUFNLENBQUM7U0FDaEI7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNmLENBQUM7SUFFTyxZQUFZLENBQUMsS0FBYztRQUNoQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sS0FBSyxTQUFTLENBQUMsQ0FBQztRQUNuQyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksS0FBSyxJQUFJLENBQUMsQ0FBQztRQUNuQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDdEQsTUFBTSxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzdCLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMzQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztJQUM1QixDQUFDO0lBRU8sY0FBYyxDQUNuQixNQUE4RDtRQUU5RCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDM0IsTUFBTSxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQztRQUMzQixNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLGdCQUFnQjthQUM3QyxnQkFBZ0IsRUFBRTthQUNsQixzQkFBc0IsQ0FBQyxvQkFBb0IsQ0FBQzthQUM1QyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDWixNQUFNLENBQUMsbUJBQW1CLFlBQVksV0FBVyxDQUFDLENBQUM7UUFDbkQsbUJBQW1CLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxHQUFHLE9BQU8sRUFBRSxXQUFXLElBQUksRUFBRSxJQUFJLENBQUM7SUFDNUUsQ0FBQztDQUNIIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uLy4uL3NoYXJlZC9hc3NlcnRcIjtcbmltcG9ydCB0eXBlIHsgT2JzZXJ2YWJsZSB9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQgdHlwZSB7XG4gICBDb21wb25lbnRSZWYsXG4gICBUeXBlLFxuICAgVmlld0NvbnRhaW5lclJlZixcbiAgIFZpZXdSZWZcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IEJyYW5jaENvbXBvbmVudCB9IGZyb20gXCIuLi8uLi9jb21wb25lbnRzL2JyYW5jaC9icmFuY2guY29tcG9uZW50XCI7XG5pbXBvcnQgdHlwZSB7IE5vZGVDb21wb25lbnQgfSBmcm9tIFwiLi4vLi4vY29tcG9uZW50cy9ub2RlLWNvbXBvbmVudC5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRyZWVOb2RlQmFzZSB9IGZyb20gXCIuLi90cmVlLW5vZGUtYmFzZVwiO1xuaW1wb3J0IHsgVHJlZUVycm9yIH0gZnJvbSBcIi4uLy4uL2Vycm9yc1wiO1xuaW1wb3J0IHR5cGUge1xuICAgQnJhbmNoT3B0aW9ucyxcbiAgIEZ1bGxCcmFuY2hPcHRpb25zXG59IGZyb20gXCIuLi9icmFuY2gtb3B0aW9ucy5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IGRyb3B6b25lUmVuZGVyZXIgfSBmcm9tIFwiLi4vLi4vZXh0cmFzL2RyYWctYW5kLWRyb3AvZHJvcHpvbmUtcmVuZGVyZXJcIjtcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gXCIuLi9jb25maWd1cmF0aW9uL2NvbmZpZ3VyYXRpb25cIjtcbmltcG9ydCB7IFRyZWVSb290IH0gZnJvbSBcIi4uXCI7XG5pbXBvcnQgeyB0cmVlQ29sbGFwc2VyIH0gZnJvbSBcIi4uLy4uL2V4dHJhcy9jb2xsYXBzZS9jb2xsYXBzZVwiO1xuaW1wb3J0IHsgRGVzdHJ1Y3Rpb25FdmVudCwgR3JhZnRFdmVudCwgUHJ1bmVFdmVudCB9IGZyb20gXCIuLi8uLi9ldmVudHNcIjtcbmltcG9ydCB0eXBlIHtcbiAgIFRyZWVOb2RlLFxuICAgVHJlZVBsb3QsXG4gICBUcmVlRXZlbnQsXG4gICBUcmVlQnJhbmNoTm9kZVxufSBmcm9tIFwiLi4vLi4vc3RydWN0dXJlXCI7XG5pbXBvcnQgeyBCcmFuY2hDb250cm9sbGVyIH0gZnJvbSBcIi4vYnJhbmNoLWNvbnRyb2xsZXJcIjtcblxuLyoqIFJlcHJlc2VudHMgYSBzdGFuZGFyZCBub2RlIGluIGEgdHJlZS4gUmVuZGVycyBhIEJyYW5jaENvbXBvbmVudC5cbiAqXG4gKiBAcmVtYXJrc1xuICogVGhpcyBjbGFzcyByZW5kZXJzIGEgYnJhbmNoIGNvbXBvbmVudCwgd2hpY2ggZG9lcyB0aGUgZm9sbG93aW5nOlxuICogMS4gUmVuZGVycyBhIGNvbXBvbmVudCBwcm92aWRlZCBieSB0aGUgdXNlclxuICogMi4gUHJvdmlkZXMgYSBjb250YWluZXIgaW4gd2hpY2ggY2hpbGQgYnJhbmNoZXMgbWF5IGJlIHJlbmRlcmVkXG4gKiAzLiBDb250YWlucyB0d28gRHJvcHpvbmVzOiBvbmUgZm9yIGRyb3BwaW5nIGJyYW5jaGVzIGJlbG93IHRoaXMgYnJhbmNoIChhcyBhXG4gKiBzaWJsaW5nKSwgYW5kIG9uZSBmb3IgZHJvcHBpbmcgYnJhbmNoZXMgYXMgYSBmaXJzdCBjaGlsZCBvZiB0aGlzIGJyYW5jaC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRyZWVCcmFuY2g8VXNlcmxhbmRDb21wb25lbnQ+XG4gICBpbXBsZW1lbnRzXG4gICAgICBUcmVlQnJhbmNoTm9kZTxcbiAgICAgICAgIEJyYW5jaENvbXBvbmVudDxVc2VybGFuZENvbXBvbmVudD4sXG4gICAgICAgICBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PixcbiAgICAgICAgIE5vZGVDb21wb25lbnRcbiAgICAgID5cbntcbiAgIHByaXZhdGUgcmVhZG9ubHkgYnJhbmNoQ29udHJvbGxlcjogQnJhbmNoQ29udHJvbGxlcjxVc2VybGFuZENvbXBvbmVudD47XG4gICBwcml2YXRlIGRldGFjaGVkVmlldzogVmlld1JlZiB8IG51bGwgPSBudWxsO1xuICAgcHJpdmF0ZSBfcGFyZW50OlxuICAgICAgfCBUcmVlTm9kZTxUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PiwgTm9kZUNvbXBvbmVudD5cbiAgICAgIHwgdW5kZWZpbmVkO1xuICAgcHJpdmF0ZSByZWFkb25seSB0cmVlTm9kZUJhc2U6IFRyZWVOb2RlQmFzZTxVc2VybGFuZENvbXBvbmVudD47XG5cbiAgIHB1YmxpYyBjb25zdHJ1Y3RvcihcbiAgICAgIHBhcmVudDogVHJlZU5vZGU8VHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4sIE5vZGVDb21wb25lbnQ+LFxuICAgICAgcHVibGljIHJlYWRvbmx5IGJyYW5jaE9wdGlvbnM6IEZ1bGxCcmFuY2hPcHRpb25zPFVzZXJsYW5kQ29tcG9uZW50PlxuICAgKSB7XG4gICAgICB0aGlzLnRyZWVOb2RlQmFzZSA9IG5ldyBUcmVlTm9kZUJhc2UoKTtcbiAgICAgIGNvbnN0IHBhcmVudEJyYW5jaGVzQ29udGFpbmVyID0gcGFyZW50LmdldEJyYW5jaGVzQ29udGFpbmVyKCk7XG4gICAgICBhc3NlcnQocGFyZW50QnJhbmNoZXNDb250YWluZXIgIT09IHVuZGVmaW5lZCk7XG4gICAgICB0aGlzLmJyYW5jaENvbnRyb2xsZXIgPSBuZXcgQnJhbmNoQ29udHJvbGxlcihcbiAgICAgICAgIHRoaXMsXG4gICAgICAgICBwYXJlbnRCcmFuY2hlc0NvbnRhaW5lclxuICAgICAgKTtcbiAgICAgIGNvbnN0IGhvc3RWaWV3ID0gdGhpcy5icmFuY2hDb250cm9sbGVyLmdldEhvc3RWaWV3KCk7XG4gICAgICB0aGlzLnNldEluZGVudGF0aW9uKHBhcmVudCk7XG4gICAgICBpZiAoXG4gICAgICAgICBwYXJlbnQgaW5zdGFuY2VvZiBUcmVlQnJhbmNoICYmXG4gICAgICAgICBwYXJlbnQuYnJhbmNoT3B0aW9ucy5kZWZhdWx0Q29sbGFwc2VkID09PSB0cnVlXG4gICAgICApIHtcbiAgICAgICAgIHRyZWVDb2xsYXBzZXIuc3RvcmVQcmVjb2xsYXBzZWROb2RlKHBhcmVudCwgdGhpcyk7XG4gICAgICAgICB0aGlzLmRldGFjaGVkVmlldyA9IGhvc3RWaWV3O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgIHBhcmVudEJyYW5jaGVzQ29udGFpbmVyLmluc2VydChob3N0Vmlldyk7XG4gICAgICAgICB0aGlzLl9wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICAgICB0aGlzLmRpc3BhdGNoKFxuICAgICAgICAgICAgbmV3IEdyYWZ0RXZlbnQodGhpcywge1xuICAgICAgICAgICAgICAgcGFyZW50OiB0aGlzLl9wYXJlbnQsXG4gICAgICAgICAgICAgICBjaGlsZDogdGhpcyxcbiAgICAgICAgICAgICAgIGluZGV4OiB0aGlzLl9wYXJlbnQuYnJhbmNoZXMoKS5sZW5ndGhcbiAgICAgICAgICAgIH0pXG4gICAgICAgICApO1xuICAgICAgICAgdGhpcy5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9XG4gICB9XG5cbiAgIC8qKiBAcmV0dXJucyBBbGwgY2hpbGQgYnJhbmNoZXMgYXMgYW4gYXJyYXkgb2YgVHJlZUJyYW5jaCBpbnN0YW5jZXMsIGluIG9yZGVyLiAqL1xuICAgcHVibGljIGJyYW5jaGVzKCk6IEFycmF5PFRyZWVCcmFuY2g8VXNlcmxhbmRDb21wb25lbnQ+PiB7XG4gICAgICByZXR1cm4gdGhpcy50cmVlTm9kZUJhc2UuYnJhbmNoZXMoKTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBSZWN1cnNpdmVseSBkZXN0cm95cyBhbGwgZGVzY2VuZGFudCBicmFuY2hlcywgYXMgd2VsbCBhcyBpdHNlbGYuIFRoaXNcbiAgICAqIHJlbGVhc2VzIGFsbCByZXNvdXJjZXMgaGVsZCBvciBjb25zdW1lZCBieSB0aGlzIGJyYW5jaCBhbmQgaXRzIGRlc2NlbmRhbnRzLlxuICAgICpcbiAgICAqIEByZW1hcmtzXG4gICAgKiBJdCBpcyBpbXBvcnRhbnQgdG8gY2FsbCB0aGlzIG1ldGhvZCB3aGVuIGEgYnJhbmNoIGlzIGRpc2NhcmRlZCwgb3RoZXJ3aXNlXG4gICAgKiB0aGUgYnJhbmNoIHdpbGwgcmVtYWluIGluIG1lbW9yeSBhbmQgY29udGludWUgdG8gY29uc3VtZSByZXNvdXJjZXMuXG4gICAgKi9cbiAgIHB1YmxpYyBkZXN0cm95KCk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBkZXN0cm95IGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5wcnVuZSgpO1xuICAgICAgdHJlZUNvbGxhcHNlci5leHBhbmQodGhpcyk7XG4gICAgICBkcm9wem9uZVJlbmRlcmVyLmNsZWFyVHJlZUZyb21SZWdpc3RyeSh0aGlzKTtcbiAgICAgIHRoaXMuYnJhbmNoQ29udHJvbGxlci5nZXRIb3N0VmlldygpLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMudHJlZU5vZGVCYXNlLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMuYnJhbmNoQ29udHJvbGxlci5kZXN0cm95KCk7XG4gICAgICB0aGlzLmRpc3BhdGNoKG5ldyBEZXN0cnVjdGlvbkV2ZW50KHRoaXMpKTtcbiAgIH1cblxuICAgLyoqIFJ1biBBbmd1bGFyIGNoYW5nZSBkZXRlY3Rpb24gb24gdGhpcyBicmFuY2ggKi9cbiAgIHB1YmxpYyBkZXRlY3RDaGFuZ2VzKCk6IHZvaWQge1xuICAgICAgdGhpcy5icmFuY2hDb250cm9sbGVyLmRldGVjdENoYW5nZXMoKTtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBFbWl0cyB0aGUgc3BlY2lmaWVkIFRyZWVFdmVudC5cbiAgICAqXG4gICAgKiBAcmVtYXJrc1xuICAgICogQ2F1dGlvbjogSXQgaXMgbm90IHJlY29tbWVuZGVkIHRvIG1hbnVhbGx5IGVtaXQgVHJlZUV2ZW50cyB0aGF0IGFyZSBhbHJlYWR5XG4gICAgKiBwcm92aWRlZCBieSB0aGUgbGlicmFyeS4gRm9yIGV4YW1wbGUsIGl0IGlzIG5vdCByZWNvbW1lbmRlZCB0byBlbWl0IGFcbiAgICAqIGBHcmFmdEV2ZW50YCwgYERlc3RydWN0aW9uRXZlbnRgLCBldGMuIFRoZXNlIGV2ZW50cyBtYXkgYmUgdXNlZCBieSB0aGUgdHJlZSxcbiAgICAqIGFuZCBlbWl0dGluZyB0aGVtIG1hbnVhbGx5IG1heSBjYXVzZSB1bmV4cGVjdGVkIGJlaGF2aW9yLiBJbnN0ZWFkLCB3ZVxuICAgICogcmVjb21tZW5kIGltcGxlbWVudGluZyB0aGUgVHJlZUV2ZW50IGludGVyZmFjZSB3aXRoIHlvdXIgb3duIGN1c3RvbSBldmVudHNcbiAgICAqIGFuZCBkaXNwYXRjaGluZyB0aG9zZS5cbiAgICAqXG4gICAgKiBAcGFyYW0gZXZlbnQgLSBUaGUgVHJlZUV2ZW50IHRoYXQgd2lsbCBiZSBlbWl0dGVkLlxuICAgICovXG4gICBwdWJsaWMgZGlzcGF0Y2goZXZlbnQ6IFRyZWVFdmVudCk6IHZvaWQge1xuICAgICAgdGhpcy50cmVlTm9kZUJhc2UuZGlzcGF0Y2goZXZlbnQpO1xuICAgICAgdGhpcy5fcGFyZW50Py5kaXNwYXRjaChldmVudCk7XG4gICB9XG5cbiAgIC8qKlxuICAgICogQHJldHVybnNcbiAgICAqIEFuIG9ic2VydmFibGUgdGhhdCBlbWl0cyBUcmVlRXZlbnRzIHdoZW5ldmVyIGFuIGV2ZW50IGlzIGRpc3BhdGNoZWRcbiAgICAqIGluIHRoaXMgYnJhbmNoIG9yIGFueSBvZiBpdHMgZGVzY2VuZGFudCBicmFuY2hlcy5cbiAgICAqL1xuICAgcHVibGljIGV2ZW50cygpOiBPYnNlcnZhYmxlPFRyZWVFdmVudD4ge1xuICAgICAgcmV0dXJuIHRoaXMudHJlZU5vZGVCYXNlLmV2ZW50cygpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIEBwYXJhbSBpbmRleCAtIFRoZSBpbmRleCBvZiB0aGUgY2hpbGQgYnJhbmNoIHRvIHJldHJpZXZlLlxuICAgICpcbiAgICAqIEByZXR1cm5zXG4gICAgKiBUaGUgY2hpbGQgYnJhbmNoIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXgsIG9yIHVuZGVmaW5lZCBpZiB0aGVyZSBpc1xuICAgICogbm8gY2hpbGQgYnJhbmNoIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguXG4gICAgKi9cbiAgIHB1YmxpYyBnZXRCcmFuY2goaW5kZXg6IG51bWJlcik6IFRyZWVCcmFuY2g8VXNlcmxhbmRDb21wb25lbnQ+IHwgdW5kZWZpbmVkIHtcbiAgICAgIHJldHVybiB0aGlzLnRyZWVOb2RlQmFzZS5nZXRCcmFuY2goaW5kZXgpO1xuICAgfVxuXG4gICAvKiogQHJldHVybnMgVGhlIFZpZXdDb250YWluZXJSZWYgaW4gd2hpY2ggY2hpbGQgYnJhbmNoZXMgYXJlIHJlbmRlcmVkICovXG4gICBwdWJsaWMgZ2V0QnJhbmNoZXNDb250YWluZXIoKTogVmlld0NvbnRhaW5lclJlZiB8IHVuZGVmaW5lZCB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgXCJDYW5ub3QgZ2V0IGJyYW5jaGVzIGNvbnRhaW5lciBmcm9tIGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCJcbiAgICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5icmFuY2hDb250cm9sbGVyLmdldEJyYW5jaGVzQ29udGFpbmVyKCk7XG4gICB9XG5cbiAgIC8qKiBAcmV0dXJucyBUaGUgaW5zdGFuY2Ugb2YgQnJhbmNoQ29tcG9uZW50IHRoYXQgaXMgcmVuZGVyZWQgYnkgdGhpcyBjbGFzcy4gKi9cbiAgIHB1YmxpYyBnZXRDb21wb25lbnRJbnN0YW5jZSgpOiBCcmFuY2hDb21wb25lbnQ8VXNlcmxhbmRDb21wb25lbnQ+IHtcbiAgICAgIGlmICh0aGlzLmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICBcIkNhbm5vdCBnZXQgY29tcG9uZW50IGluc3RhbmNlIGZyb20gYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIlxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZ2V0Q29tcG9uZW50SW5zdGFuY2UoKTtcbiAgIH1cblxuICAgLyoqIEByZXR1cm5zIFRoZSBIb3N0IFZpZXcgaW4gd2hpY2ggdGhlIEJyYW5jaENvbXBvbmVudCBpcyByZW5kZXJlZCAqL1xuICAgcHVibGljIGdldEhvc3RWaWV3KCk6IFZpZXdSZWYge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcbiAgICAgICAgICAgIFwiQ2Fubm90IGdldCBjb21wb25lbnQgaG9zdCB2aWV3IGZyb20gYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIlxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZ2V0SG9zdFZpZXcoKTtcbiAgIH1cblxuICAgLyoqIEByZXR1cm5zIFRoZSBCcmFuY2hDb21wb25lbnQgYXMgYSBuYXRpdmUgSFRNTCBFbGVtZW50ICovXG4gICBwdWJsaWMgZ2V0TmF0aXZlRWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFxuICAgICAgICAgICAgXCJDYW5ub3QgZ2V0IG5hdGl2ZSBlbGVtZW50IGZyb20gYSBkZXN0cm95ZWQgdHJlZSBicmFuY2hcIlxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmJyYW5jaENvbnRyb2xsZXIuZ2V0TmF0aXZlRWxlbWVudCgpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIEByZXR1cm5zXG4gICAgKiBBIENvbXBvbmVudFJlZiBjb250YWluaW5nIHRoZSBpbnN0YW5jZSBvZiB0aGUgdXNlci1wcm92aWRlZFxuICAgICogY29tcG9uZW50IHdoaWNoIGlzIHJlbmRlcmVkIGJ5IHRoaXMgYnJhbmNoLlxuICAgICovXG4gICBwdWJsaWMgZ2V0VXNlcmxhbmRDb21wb25lbnRSZWYoKTpcbiAgICAgIHwgQ29tcG9uZW50UmVmPFVzZXJsYW5kQ29tcG9uZW50PlxuICAgICAgfCB1bmRlZmluZWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcbiAgICAgICAgICAgIFwiQ2Fubm90IGdldCB1c2VybGFuZCBjb21wb25lbnQgZnJvbSBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiXG4gICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuYnJhbmNoQ29udHJvbGxlci5nZXRVc2VybGFuZENvbXBvbmVudFJlZigpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIEF0dGFjaGVzIGEgYnJhbmNoIHRvIGEgbmV3IHBhcmVudCBub2RlLlxuICAgICpcbiAgICAqIEByZW1hcmtzXG4gICAgKiBJZiBub3QgYWxyZWFkeSBwcnVuZWQsIHRoaXMgbWV0aG9kIHBydW5lcyAocmVtb3ZlcykgdGhpcyBicmFuY2ggZnJvbSBpdHNcbiAgICAqIGN1cnJlbnQgcG9zaXRpb24gaW4gdGhlIHRyZWU7IHRoZW4gZ3JhZnRzIChyZWF0dGFjaGVzKSBpdCBhcyBhIGNoaWxkIG9mIHRoZVxuICAgICogc3BlY2lmaWVkIHBhcmVudCBicmFuY2ggYXQgdGhlIHNwZWNpZmllZCBpbmRleC4gSWYgbm8gaW5kZXggaXMgc3BlY2lmaWVkLFxuICAgICogdGhlIGJyYW5jaCBpcyBhcHBlbmRlZCBhcyB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgcGFyZW50LiBUaGlzIGNhdXNlcyB0aGlzXG4gICAgKiBicmFuY2gncyBhc3NvY2lhdGVkIEJyYW5jaENvbXBvbmVudCB0byBiZSByZS1yZW5kZXJlZCBpbiB0aGUgRE9NIGF0IHRoZVxuICAgICogbmV3IGxvY2F0aW9uLlxuICAgICpcbiAgICAqIEBwYXJhbSBuZXdQYXJlbnQgLSBUaGUgbmV3IHBhcmVudCBicmFuY2ggdW50byB3aGljaCB0aGlzIGJyYW5jaCB3aWxsIGJlIGdyYWZ0ZWQuXG4gICAgKiBAcGFyYW0gaW5kZXggLSBUaGUgaW5kZXggYXQgd2hpY2ggdGhpcyBicmFuY2ggd2lsbCBiZSBncmFmdGVkLiBJZiBub3Qgc3BlY2lmaWVkLFxuICAgICogdGhpcyBicmFuY2ggd2lsbCBiZSBhcHBlbmRlZCBhcyB0aGUgbGFzdCBjaGlsZCBvZiB0aGUgbmV3IHBhcmVudC5cbiAgICAqXG4gICAgKiBAcmV0dXJucyBUaGUgaW5kZXggYXQgd2hpY2ggdGhpcyBicmFuY2ggd2FzIGdyYWZ0ZWQuXG4gICAgKi9cbiAgIHB1YmxpYyBncmFmdFRvKFxuICAgICAgbmV3UGFyZW50OiBUcmVlTm9kZTxUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PiwgTm9kZUNvbXBvbmVudD4sXG4gICAgICBpbmRleD86IG51bWJlclxuICAgKTogbnVtYmVyIHtcbiAgICAgIHRoaXMuY2hlY2tHcmFmdExvY2F0aW9uVmFsaWRpdHkobmV3UGFyZW50LCBpbmRleCk7XG4gICAgICBjb25zdCBvd25JbmRleCA9IHRoaXMuaW5kZXgoKTtcbiAgICAgIGlmIChvd25JbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICB0aGlzLnBydW5lKCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9wYXJlbnQgPSBuZXdQYXJlbnQ7XG4gICAgICBjb25zdCBuZXdJbmRleCA9IGluZGV4ID8/IG5ld1BhcmVudC5icmFuY2hlcygpLmxlbmd0aDtcbiAgICAgIHRoaXMucmVhdHRhY2hWaWV3KG5ld0luZGV4KTtcbiAgICAgIHRoaXMuZGlzcGF0Y2goXG4gICAgICAgICBuZXcgR3JhZnRFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICBwYXJlbnQ6IG5ld1BhcmVudCxcbiAgICAgICAgICAgIGNoaWxkOiB0aGlzLFxuICAgICAgICAgICAgaW5kZXg6IG5ld0luZGV4XG4gICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIHJldHVybiBuZXdJbmRleDtcbiAgIH1cblxuICAgLyoqXG4gICAgKiBBcHBlbmRzIGEgbmV3IGNoaWxkIGJyYW5jaCB0byB0aGlzIGJyYW5jaC4gVGhlIGNoaWxkIGJyYW5jaCB3aWxsIHJlbmRlclxuICAgICogdGhlIHNwZWNpZmllZCBjb21wb25lbnQgYWNjb3JkaW5nIHRvIHRoZSAob3B0aW9uYWwpIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVyLlxuICAgICpcbiAgICAqIEBwYXJhbSBjb21wb25lbnQgLSBUaGUgY29tcG9uZW50IHRvIHJlbmRlciBpbiB0aGUgbmV3IGNoaWxkIGJyYW5jaC5cbiAgICAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgbmV3IGNoaWxkIGJyYW5jaC5cbiAgICAqXG4gICAgKiBAcmV0dXJuc1xuICAgICogVGhlIG5ld2x5LWNyZWF0ZWQgY2hpbGQgYnJhbmNoLlxuICAgICovXG4gICBwdWJsaWMgZ3JvdyhcbiAgICAgIGNvbXBvbmVudDogVHlwZTxVc2VybGFuZENvbXBvbmVudD4sXG4gICAgICBvcHRpb25zPzogQnJhbmNoT3B0aW9uczxVc2VybGFuZENvbXBvbmVudD5cbiAgICk6IFRyZWVCcmFuY2g8VXNlcmxhbmRDb21wb25lbnQ+IHtcbiAgICAgIGlmICh0aGlzLmlzRGVzdHJveWVkKCkpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXCJDYW5ub3QgZ3JvdyBhIGJyYW5jaCBvbiBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiKTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgICByZXR1cm4gbmV3IFRyZWVCcmFuY2godGhpcywgeyBjb21wb25lbnQsIC4uLm9wdGlvbnMgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgdGhpcy5oYW5kbGVVc2VybGFuZEVycm9yKGVycm9yKTtcbiAgICAgIH1cbiAgIH1cblxuICAgLyoqXG4gICAgKiBEZXRlcm1pbmVzIHRoaXMgYnJhbmNoJ3MgaW5kZXggaW4gcmVsYXRpb24gdG8gaXRzIHNpYmxpbmcgYnJhbmNoZXMuXG4gICAgKlxuICAgICogQHJlbWFya3NcbiAgICAqIEZvciBleGFtcGxlLCBpZiBpdCBpcyB0aGUgZmlyc3QgY2hpbGQgb2YgaXRzIHBhcmVudCwgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm5cbiAgICAqIDAuIElmIGl0IGlzIHRoZSBzZWNvbmQgY2hpbGQgb2YgaXRzIHBhcmVudCwgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gMS5cbiAgICAqXG4gICAgKiBJZiB0aGlzIGJyYW5jaCBoYXMgbm8gcGFyZW50LCAoZWcsIGlmIHRoaXMgYnJhbmNoIGhhcyBiZWVuIHBydW5lZCkgdGhpc1xuICAgICogbWV0aG9kIHdpbGwgcmV0dXJuIHVuZGVmaW5lZC5cbiAgICAqXG4gICAgKiBAcmV0dXJuc1xuICAgICogVGhlIGluZGV4IG9mIHRoaXMgYnJhbmNoIGluIHJlbGF0aW9uIHRvIGl0cyBzaWJsaW5nIGJyYW5jaGVzLCBvciB1bmRlZmluZWQuXG4gICAgKi9cbiAgIHB1YmxpYyBpbmRleCgpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgICAgaWYgKCF0aGlzLl9wYXJlbnQpIHtcbiAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3BhcmVudFxuICAgICAgICAgLmJyYW5jaGVzKClcbiAgICAgICAgIC5maW5kSW5kZXgoKGJyYW5jaCkgPT4gYnJhbmNoID09PSB0aGlzKTtcbiAgICAgIGFzc2VydChpbmRleCA+PSAwKTtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgIH1cblxuICAgLyoqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgYnJhbmNoIGlzIGRlc3Ryb3llZCwgYGZhbHNlYCBvdGhlcndpc2UgKi9cbiAgIHB1YmxpYyBpc0Rlc3Ryb3llZCgpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnRyZWVOb2RlQmFzZS5pc0Rlc3Ryb3llZCgpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIEByZXR1cm5zXG4gICAgKiBUaGUgZGF0YSB0aGF0IHdhcyBwYXNzZWQgaW50byB0aGUgYGJyYW5jaE9wdGlvbnNgJyBgbWV0YWAgcHJvcGVydHlcbiAgICAqIGF0IGNvbnN0cnVjdGlvbi5cbiAgICAqL1xuICAgcHVibGljIG1ldGEoKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgICByZXR1cm4gdGhpcy5icmFuY2hPcHRpb25zLm1ldGEgPz8ge307XG4gICB9XG5cbiAgIC8qKlxuICAgICogQHJldHVybnNcbiAgICAqIFRoaXMgYnJhbmNoJ3MgcGFyZW50IG5vZGUgKHdoaWNoIG1heSBiZSBhIFRyZWVCcmFuY2ggb3IgVHJlZVJvb3QpLlxuICAgICogSWYgdGhpcyBicmFuY2ggaGFzIG5vIHBhcmVudCwgKGVnLCBpZiB0aGlzIGJyYW5jaCBoYXMgYmVlbiBwcnVuZWQpIHRoaXNcbiAgICAqIG1ldGhvZCB3aWxsIHJldHVybiB1bmRlZmluZWQuXG4gICAgKi9cbiAgIHB1YmxpYyBwYXJlbnQoKTpcbiAgICAgIHwgVHJlZU5vZGU8VHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4sIE5vZGVDb21wb25lbnQ+XG4gICAgICB8IHVuZGVmaW5lZCB7XG4gICAgICByZXR1cm4gdGhpcy5fcGFyZW50O1xuICAgfVxuXG4gICAvKipcbiAgICAqIFByb3ZpZGVzIGEgbW9kZWwgZGVzY3JpYmluZyB0aGlzIGJyYW5jaCdzIGRlc2NlbmRhbnRzLlxuICAgICpcbiAgICAqIEByZXR1cm5zXG4gICAgKiBBIG11bHRpLWRpbWVuc2lvbmFsIE1hcCB3aGljaCBkZXNjcmliZXMgdGhlIHNoYXBlIG9mIHRoaXMgYnJhbmNoJ3NcbiAgICAqIGRlc2NlbmRhbnRzLlxuICAgICpcbiAgICAqIEBleGFtcGxlXG4gICAgKiBBIGJyYW5jaCB3aXRoIG5vIGNoaWxkcmVuIHdpbGwgcmV0dXJuIGFuIGVtcHR5IE1hcC4gQSBicmFuY2ggd2l0aFxuICAgICogYSBzaW5nbGUgY2hpbGQgd2lsbCByZXR1cm4gYSBNYXAgd2l0aCBhIHNpbmdsZSBlbnRyeSwgd2hlcmUgdGhlIGtleSBpcyB0aGUgaW5kZXhcbiAgICAqIG9mIHRoZSBicmFuY2ggKHplcm8pIGFuZCB0aGUgdmFsdWUgaXMgYW4gZW1wdHkgTWFwLiBBIFRyZWUgbGlrZSB0aGlzOlxuICAgICpcbiAgICAqIGBgYFxuICAgICogICAgICAgICAtLS1CcmFuY2gtLS0tLS0tQnJhbmNoXG4gICAgKiAgICAgICAgL1xuICAgICogQnJhbmNoLS0tLS0tLUJyYW5jaFxuICAgICogICAgICAgIFxcXG4gICAgKiAgICAgICAgIC0tLUJyYW5jaFxuICAgICogYGBgXG4gICAgKiBXaWxsIHJldHVybiBhIE1hcCBvZiBtYXRjaGluZyBzaGFwZTpcbiAgICAqIGBgYFxuICAgICogTWFwIHtcbiAgICAqICAgIDA6IE1hcCB7IDA6IE1hcCB7fX0sXG4gICAgKiAgICAxOiBNYXAge30sXG4gICAgKiAgICAyOiBNYXAge31cbiAgICAqIH1cbiAgICAqIGBgYFxuICAgICovXG4gICBwdWJsaWMgcGxvdCgpOiBUcmVlUGxvdCB7XG4gICAgICByZXR1cm4gdGhpcy50cmVlTm9kZUJhc2UucGxvdCgpO1xuICAgfVxuXG4gICAvKipcbiAgICAqIENhbGN1bGF0ZXMgdGhlIGJyYW5jaCdzIHBvc2l0aW9uIGluIHRoZSB0cmVlIHJlbGF0aXZlIHRvIHRoZSBSb290LlxuICAgICpcbiAgICAqIEByZW1hcmtzXG4gICAgKiBUaGUgcG9zaXRpb24gaXMgZGVzY3JpYmVkIGFzIGFuIGFycmF5IG9mIG51bWJlcnMsIHdoZXJlIGVhY2ggbnVtYmVyXG4gICAgKiByZXByZXNlbnRzIHRoZSBpbmRleCBvZiB0aGUgYnJhbmNoIGF0IHRoYXQgbGV2ZWwgb2YgdGhlIHRyZWUuXG4gICAgKlxuICAgICogRm9yIGV4YW1wbGUsIGlmIHRoaXMgYnJhbmNoIGlzIHRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgUm9vdCwgdGhpcyBtZXRob2RcbiAgICAqIHdpbGwgcmV0dXJuIFswXS4gSWYgdGhpcyBicmFuY2ggaXMgdGhlIHNlY29uZCBjaGlsZCBvZiB0aGUgZmlyc3QgY2hpbGRcbiAgICAqIG9mIHRoZSBSb290LCB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiBbMCwgMV0uXG4gICAgKlxuICAgICogSWYgdGhlIGJyYW5jaCBpcyBub3QgcmVsYXRlZCB0byBhIFRyZWVSb290LCAoc3VjaCBhcyB3aGVuIGl0IGhhcyBiZWVuXG4gICAgKiBwcnVuZWQsKSB0aGlzIG1ldGhvZCB3aWxsIHRocm93IGFuIGVycm9yLlxuICAgICpcbiAgICAqIEByZXR1cm5zXG4gICAgKiBBbiBhcnJheSBvZiBudW1iZXJzIHdoaWNoIGRlc2NyaWJlIHRoZSBicmFuY2gncyBwb3NpdGlvbiBpbiB0aGUgdHJlZVxuICAgICogcmVsYXRpdmUgdG8gdGhlIFJvb3QuXG4gICAgKi9cbiAgIHB1YmxpYyBwb3NpdGlvbigpOiBBcnJheTxudW1iZXI+IHtcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5pbmRleCgpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICBcImJyYW5jaCBoYXMgbm8gcGFyZW50LiBQb3NpdGlvbiBjYW5ub3QgYmUgZGV0ZXJtaW5lZC5cIlxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9wYXJlbnQgaW5zdGFuY2VvZiBUcmVlQnJhbmNoKSB7XG4gICAgICAgICBjb25zdCBwYXJlbnRQb3NpdGlvbiA9IHRoaXMuX3BhcmVudC5wb3NpdGlvbigpO1xuICAgICAgICAgcmV0dXJuIFsuLi5wYXJlbnRQb3NpdGlvbiwgaW5kZXhdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtpbmRleF07XG4gICB9XG5cbiAgIC8qKlxuICAgICogUmVtb3ZlcyBhIGJyYW5jaCBmcm9tIGl0cyB0cmVlIHdpdGhvdXQgZGVzdHJveWluZyBpdC5cbiAgICAqXG4gICAgKiBAcmVtYXJrc1xuICAgICogUmVtb3ZlcyB0aGlzIGJyYW5jaCBmcm9tIGl0cyBwYXJlbnQgYW5kIGRldGFjaGVzIGl0cyBhc3NvY2lhdGVkXG4gICAgKiBCcmFuY2hDb21wb25lbnQgZnJvbSB0aGUgRE9NLiBUaGlzIHB1dHMgdGhlIGJyYW5jaCBpbiBhIFwicHJ1bmVkXCIgc3RhdGUsXG4gICAgKiB3aGljaCBtYXkgYWZmZWN0IHRoZSBiZWhhdmlvciBvZiBvdGhlciBtZXRob2RzLlxuICAgICpcbiAgICAqIEEgcHJ1bmVkIGJyYW5jaCBjYW4gYmUgcmVhdHRhY2hlZCB0byBhbnkgb3RoZXIgbm9kZSB1c2luZyB0aGUgYGdyYWZ0VG9gIG1ldGhvZC5cbiAgICAqXG4gICAgKiBAcmV0dXJuc1xuICAgICogSXRzZWxmLCBvciB1bmRlZmluZWQgaWYgaXQgaXMgYWxyZWFkeSBpbiBhIHBydW5lZCBzdGF0ZS5cbiAgICAqL1xuICAgcHVibGljIHBydW5lKCk6IHRoaXMgfCB1bmRlZmluZWQge1xuICAgICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQoKSkge1xuICAgICAgICAgdGhyb3cgbmV3IFRyZWVFcnJvcihcIkNhbm5vdCBwcnVuZSBhIGRlc3Ryb3llZCB0cmVlIGJyYW5jaFwiKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBhcmVudCA9IHRoaXMuX3BhcmVudDtcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5pbmRleCgpO1xuICAgICAgaWYgKGluZGV4ID09PSB1bmRlZmluZWQgfHwgcGFyZW50ID09PSB1bmRlZmluZWQpIHJldHVybjtcbiAgICAgIGNvbnN0IGNvbnRhaW5lciA9IHBhcmVudC5nZXRCcmFuY2hlc0NvbnRhaW5lcigpO1xuICAgICAgYXNzZXJ0KGNvbnRhaW5lciAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIHRoaXMuZGV0YWNoZWRWaWV3ID0gY29udGFpbmVyLmRldGFjaChpbmRleCk7XG4gICAgICBhc3NlcnQodGhpcy5kZXRhY2hlZFZpZXcgIT09IG51bGwpO1xuICAgICAgdGhpcy5kZXRhY2hlZFZpZXcuZGV0YWNoKCk7XG4gICAgICB0aGlzLmRpc3BhdGNoKFxuICAgICAgICAgbmV3IFBydW5lRXZlbnQodGhpcywge1xuICAgICAgICAgICAgcGFyZW50OiBwYXJlbnQsXG4gICAgICAgICAgICBjaGlsZDogdGhpcyxcbiAgICAgICAgICAgIGluZGV4OiBpbmRleFxuICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICB0aGlzLl9wYXJlbnQgPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gdGhpcztcbiAgIH1cblxuICAgLyoqXG4gICAgKiBHZXQgdGhlIHJvb3Qgb2YgdGhlIHRyZWUgdG8gd2hpY2ggdGhpcyBCcmFuY2ggaXMgYXR0YWNoZWQuXG4gICAgKlxuICAgICogQHJldHVybnNcbiAgICAqIFRoZSBUcmVlUm9vdCBvZiB0aGUgdHJlZSB0aGlzIGJyYW5jaCBpcyBpbi4gSWYgdGhpcyBicmFuY2ggaXNcbiAgICAqIGRvZXMgbm90IGhhdmUgYSByb290IChzdWNoIGFzIHdoZW4gaXQgaGFzIGJlZW4gcHJ1bmVkKSB0aGlzIG1ldGhvZCB3aWxsXG4gICAgKiByZXR1cm4gdW5kZWZpbmVkLlxuICAgICovXG4gICBwdWJsaWMgcm9vdCgpOiBUcmVlUm9vdDxVc2VybGFuZENvbXBvbmVudD4gfCB1bmRlZmluZWQge1xuICAgICAgY29uc3QgcGFyZW50ID0gdGhpcy5wYXJlbnQoKTtcbiAgICAgIGlmIChwYXJlbnQgaW5zdGFuY2VvZiBUcmVlQnJhbmNoKSB7XG4gICAgICAgICByZXR1cm4gcGFyZW50LnJvb3QoKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydChwYXJlbnQgaW5zdGFuY2VvZiBUcmVlUm9vdCB8fCBwYXJlbnQgPT09IHVuZGVmaW5lZCk7XG4gICAgICByZXR1cm4gcGFyZW50O1xuICAgfVxuXG4gICAvKipcbiAgICAqIFRyYXZlcnNlcyB0aGlzIGJyYW5jaCdzIGRlc2NlbmRhbnRzIGluIGRlcHRoLWZpcnN0IHByZS1vcmRlciwgZXhlY3V0aW5nXG4gICAgKiB0aGUgcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24gb24gZWFjaCBub2RlLiBUcmF2ZXJzYWwgaW5jbHVkZXMgdGhpcyBicmFuY2guXG4gICAgKlxuICAgICogQHBhcmFtIGNhbGxiYWNrIC0gQSBmdW5jdGlvbiB0byBleGVjdXRlIG9uIGVhY2ggbm9kZS5cbiAgICAqL1xuICAgcHVibGljIHRyYXZlcnNlKFxuICAgICAgY2FsbGJhY2s6IChcbiAgICAgICAgIG5vZGU6IFRyZWVOb2RlPFRyZWVCcmFuY2g8VXNlcmxhbmRDb21wb25lbnQ+LCBOb2RlQ29tcG9uZW50PlxuICAgICAgKSA9PiB2b2lkXG4gICApOiB2b2lkIHtcbiAgICAgIGNhbGxiYWNrKHRoaXMpO1xuICAgICAgdGhpcy50cmVlTm9kZUJhc2UudHJhdmVyc2UoY2FsbGJhY2spO1xuICAgfVxuXG4gICBwcml2YXRlIGNoZWNrR3JhZnRMb2NhdGlvblZhbGlkaXR5KFxuICAgICAgbmV3UGFyZW50OiBUcmVlTm9kZTxUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PiwgTm9kZUNvbXBvbmVudD4sXG4gICAgICBpbmRleD86IG51bWJlclxuICAgKTogdm9pZCB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFwiQ2Fubm90IGdyYWZ0IGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCIpO1xuICAgICAgfVxuICAgICAgaWYgKG5ld1BhcmVudC5pc0Rlc3Ryb3llZCgpKSB7XG4gICAgICAgICB0aHJvdyBuZXcgVHJlZUVycm9yKFwiQ2Fubm90IGdyYWZ0IHRvIGEgZGVzdHJveWVkIHRyZWUgYnJhbmNoXCIpO1xuICAgICAgfVxuICAgICAgaWYgKFxuICAgICAgICAgdHlwZW9mIGluZGV4ID09PSBcIm51bWJlclwiICYmXG4gICAgICAgICB0aGlzLmluZGV4SXNPdXRPZlJhbmdlKG5ld1BhcmVudCwgaW5kZXgpXG4gICAgICApIHtcbiAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICBgQ2Fubm90IGdyYWZ0IGJyYW5jaCBhdCBpbmRleCAke2luZGV4fSBvZiB0aGUgcGFyZW50LiBPdXQgb2YgcmFuZ2UuYFxuICAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudHJhdmVyc2UoKG5vZGUpID0+IHtcbiAgICAgICAgIGlmIChub2RlID09PSBuZXdQYXJlbnQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUcmVlRXJyb3IoXG4gICAgICAgICAgICAgICBcIkNhbm5vdCBncmFmdCBhIGJyYW5jaCB0byBpdHNlbGYgb3IgYW55IG9mIGl0cyBvd24gZGVzY2VuZGFudHNcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgIH1cbiAgICAgIH0pO1xuICAgfVxuXG4gICBwcml2YXRlIGhhbmRsZVVzZXJsYW5kRXJyb3IoZXJyb3I6IHVua25vd24pOiBuZXZlciB7XG4gICAgICAvLyBXaGVuIGFuIGVycm9yIG9jY3VycyBpbiBhIHVzZXJsYW5kIGNvbXBvbmVudCBkdXJpbmcgYSB0cmVlIG9wZXJhdGlvbixcbiAgICAgIC8vIGl0IGNhbiBjYXVzZSB1bmRlZmluZWQsIGJpemFycmUgYmVoYXZpb3IgaW4gdGhlIHRyZWUuIFRvIHByZXZlbnQgdGhpcyxcbiAgICAgIC8vIHdlIGRlc3Ryb3kgdGhlIHRyZWUgYW5kIHRocm93IGFuIGVycm9yIGluc3RlYWQuIFRoaXMgaGVscHMgcHJvdGVjdFxuICAgICAgLy8gdGhlIGVuZC11c2VyJ3MgZGF0YSBmcm9tIGNvcnJ1cHRpb24uXG4gICAgICB0aGlzLmZ1cnRoZXN0QW5jZXN0b3IoKS5kZXN0cm95KCk7XG4gICAgICB0aGlzLnRyZWVOb2RlQmFzZS5oYW5kbGVVc2VybGFuZEVycm9yKGVycm9yKTtcbiAgIH1cblxuICAgcHJpdmF0ZSBpbmRleElzT3V0T2ZSYW5nZShcbiAgICAgIHBhcmVudDogVHJlZU5vZGU8VHJlZUJyYW5jaDxVc2VybGFuZENvbXBvbmVudD4sIE5vZGVDb21wb25lbnQ+LFxuICAgICAgaW5kZXg6IG51bWJlclxuICAgKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gaW5kZXggPCAwIHx8IGluZGV4ID4gcGFyZW50LmJyYW5jaGVzKCkubGVuZ3RoO1xuICAgfVxuXG4gICBwcml2YXRlIGZ1cnRoZXN0QW5jZXN0b3IoKTogVHJlZU5vZGU8XG4gICAgICBUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PixcbiAgICAgIE5vZGVDb21wb25lbnRcbiAgID4ge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzIC0tIFRoaXMgY29kZSBpcyBmb3IgYW4gaXRlcmF0aW9uLCBub3QgdG8gbWFrZSBgdGhpc2AgYXZhaWxhYmxlIGluIG90aGVyIHNjb3BlcyAod2hpY2ggaXMgd2hhdCB0aGUgcnVsZSBpcyBpbnRlbmRlZCB0byBwcm90ZWN0IGFnYWluc3QpLlxuICAgICAgbGV0IG5vZGU6IFRyZWVOb2RlPFRyZWVCcmFuY2g8VXNlcmxhbmRDb21wb25lbnQ+LCBOb2RlQ29tcG9uZW50PiA9IHRoaXM7XG4gICAgICB3aGlsZSAobm9kZSBpbnN0YW5jZW9mIFRyZWVCcmFuY2gpIHtcbiAgICAgICAgIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50KCk7XG4gICAgICAgICBpZiAocGFyZW50ID09PSB1bmRlZmluZWQpIGJyZWFrO1xuICAgICAgICAgbm9kZSA9IHBhcmVudDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBub2RlO1xuICAgfVxuXG4gICBwcml2YXRlIHJlYXR0YWNoVmlldyhpbmRleD86IG51bWJlcik6IHZvaWQge1xuICAgICAgYXNzZXJ0KHRoaXMuX3BhcmVudCAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIGFzc2VydCh0aGlzLmRldGFjaGVkVmlldyAhPT0gbnVsbCk7XG4gICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLl9wYXJlbnQuZ2V0QnJhbmNoZXNDb250YWluZXIoKTtcbiAgICAgIGFzc2VydChjb250YWluZXIgIT09IHVuZGVmaW5lZCk7XG4gICAgICB0aGlzLmRldGFjaGVkVmlldy5yZWF0dGFjaCgpO1xuICAgICAgY29udGFpbmVyLmluc2VydCh0aGlzLmRldGFjaGVkVmlldywgaW5kZXgpO1xuICAgICAgdGhpcy5kZXRhY2hlZFZpZXcgPSBudWxsO1xuICAgfVxuXG4gICBwcml2YXRlIHNldEluZGVudGF0aW9uKFxuICAgICAgcGFyZW50OiBUcmVlTm9kZTxUcmVlQnJhbmNoPFVzZXJsYW5kQ29tcG9uZW50PiwgTm9kZUNvbXBvbmVudD5cbiAgICk6IHZvaWQge1xuICAgICAgY29uc3Qgcm9vdCA9IHBhcmVudC5yb290KCk7XG4gICAgICBhc3NlcnQocm9vdCAhPT0gdW5kZWZpbmVkKTtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSBjb25maWcuZ2V0Q29uZmlnKHJvb3QpO1xuICAgICAgY29uc3QgYnJhbmNoZXNDb250YWluZXJFbCA9IHRoaXMuYnJhbmNoQ29udHJvbGxlclxuICAgICAgICAgLmdldE5hdGl2ZUVsZW1lbnQoKVxuICAgICAgICAgLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoXCJicmFuY2hlcy1jb250YWluZXJcIilcbiAgICAgICAgIC5pdGVtKDApO1xuICAgICAgYXNzZXJ0KGJyYW5jaGVzQ29udGFpbmVyRWwgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCk7XG4gICAgICBicmFuY2hlc0NvbnRhaW5lckVsLnN0eWxlLm1hcmdpbkxlZnQgPSBgJHtvcHRpb25zPy5pbmRlbnRhdGlvbiA/PyAxNn1weGA7XG4gICB9XG59XG4iXX0=