@flogeez/angular-tiptap-editor 3.1.3 → 3.1.4

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 (113) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +2 -2
  3. package/esm2022/flogeez-angular-tiptap-editor.mjs +5 -0
  4. package/esm2022/lib/ate-editor.provider.mjs +38 -0
  5. package/esm2022/lib/components/bubble-menus/base/ate-base-bubble-menu.mjs +207 -0
  6. package/esm2022/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.mjs +137 -0
  7. package/esm2022/lib/components/bubble-menus/color/ate-color-bubble-menu.component.mjs +365 -0
  8. package/esm2022/lib/components/bubble-menus/image/ate-image-bubble-menu.component.mjs +309 -0
  9. package/esm2022/lib/components/bubble-menus/link/ate-link-bubble-menu.component.mjs +247 -0
  10. package/esm2022/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.mjs +126 -0
  11. package/esm2022/lib/components/bubble-menus/table/ate-table-bubble-menu.component.mjs +271 -0
  12. package/esm2022/lib/components/bubble-menus/text/ate-bubble-menu.component.mjs +272 -0
  13. package/esm2022/lib/components/color-picker/ate-color-picker.component.mjs +123 -0
  14. package/esm2022/lib/components/edit-toggle/ate-edit-toggle.component.mjs +42 -0
  15. package/esm2022/lib/components/editor/angular-tiptap-editor.component.mjs +1031 -0
  16. package/esm2022/lib/components/editor/ate-block-controls.component.mjs +256 -0
  17. package/esm2022/lib/components/slash-commands/ate-slash-commands.component.mjs +328 -0
  18. package/esm2022/lib/components/toolbar/ate-toolbar.component.mjs +531 -0
  19. package/esm2022/lib/components/ui/ate-button.component.mjs +91 -0
  20. package/esm2022/lib/components/ui/ate-separator.component.mjs +11 -0
  21. package/esm2022/lib/config/ate-editor.config.mjs +133 -0
  22. package/esm2022/lib/config/ate-global-config.token.mjs +6 -0
  23. package/esm2022/lib/config/ate-slash-commands.config.mjs +130 -0
  24. package/esm2022/lib/directives/ate-noop-value-accessor.directive.mjs +40 -0
  25. package/esm2022/lib/directives/ate-tooltip.directive.mjs +138 -0
  26. package/esm2022/lib/extensions/ate-block-controls.extension.mjs +156 -0
  27. package/esm2022/lib/extensions/ate-link-click-behavior.extension.mjs +32 -0
  28. package/esm2022/lib/extensions/ate-resizable-image.extension.mjs +277 -0
  29. package/esm2022/lib/extensions/ate-table.extension.mjs +27 -0
  30. package/esm2022/lib/extensions/ate-tiptap-state.extension.mjs +85 -0
  31. package/esm2022/lib/extensions/ate-upload-progress.extension.mjs +195 -0
  32. package/esm2022/lib/extensions/calculators/ate-discovery.calculator.mjs +62 -0
  33. package/esm2022/lib/extensions/calculators/ate-image.calculator.mjs +8 -0
  34. package/esm2022/lib/extensions/calculators/ate-marks.calculator.mjs +75 -0
  35. package/esm2022/lib/extensions/calculators/ate-selection.calculator.mjs +35 -0
  36. package/esm2022/lib/extensions/calculators/ate-structure.calculator.mjs +34 -0
  37. package/esm2022/lib/extensions/calculators/ate-table.calculator.mjs +38 -0
  38. package/esm2022/lib/models/ate-bubble-menu.model.mjs +53 -0
  39. package/esm2022/lib/models/ate-editor-config.model.mjs +2 -0
  40. package/esm2022/lib/models/ate-editor-state.model.mjs +90 -0
  41. package/esm2022/lib/models/ate-image.model.mjs +2 -0
  42. package/esm2022/lib/models/ate-slash-command.model.mjs +2 -0
  43. package/esm2022/lib/models/ate-toolbar.model.mjs +35 -0
  44. package/esm2022/lib/node-view/ate-angular-node-view.mjs +97 -0
  45. package/esm2022/lib/node-view/ate-injector.registry.mjs +16 -0
  46. package/esm2022/lib/node-view/ate-node-view.factory.mjs +125 -0
  47. package/esm2022/lib/node-view/ate-node-view.models.mjs +2 -0
  48. package/esm2022/lib/node-view/ate-node-view.renderer.mjs +154 -0
  49. package/esm2022/lib/node-view/ate-register-angular-component.mjs +49 -0
  50. package/esm2022/lib/services/ate-color-picker.service.mjs +194 -0
  51. package/esm2022/lib/services/ate-editor-commands.service.mjs +474 -0
  52. package/esm2022/lib/services/ate-i18n.service.mjs +422 -0
  53. package/esm2022/lib/services/ate-image.service.mjs +459 -0
  54. package/esm2022/lib/services/ate-link.service.mjs +99 -0
  55. package/esm2022/lib/utils/ate-color.utils.mjs +60 -0
  56. package/esm2022/public-api.mjs +40 -0
  57. package/fesm2022/flogeez-angular-tiptap-editor.mjs +319 -352
  58. package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
  59. package/index.d.ts +3 -1734
  60. package/lib/ate-editor.provider.d.ts +21 -0
  61. package/lib/components/bubble-menus/base/ate-base-bubble-menu.d.ts +71 -0
  62. package/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.d.ts +60 -0
  63. package/lib/components/bubble-menus/color/ate-color-bubble-menu.component.d.ts +77 -0
  64. package/lib/components/bubble-menus/image/ate-image-bubble-menu.component.d.ts +49 -0
  65. package/lib/components/bubble-menus/link/ate-link-bubble-menu.component.d.ts +55 -0
  66. package/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.d.ts +16 -0
  67. package/lib/components/bubble-menus/table/ate-table-bubble-menu.component.d.ts +25 -0
  68. package/lib/components/bubble-menus/text/ate-bubble-menu.component.d.ts +53 -0
  69. package/lib/components/color-picker/ate-color-picker.component.d.ts +54 -0
  70. package/lib/components/edit-toggle/ate-edit-toggle.component.d.ts +13 -0
  71. package/lib/components/editor/angular-tiptap-editor.component.d.ts +242 -0
  72. package/lib/components/editor/ate-block-controls.component.d.ts +44 -0
  73. package/lib/components/slash-commands/ate-slash-commands.component.d.ts +34 -0
  74. package/lib/components/toolbar/ate-toolbar.component.d.ts +47 -0
  75. package/lib/components/ui/ate-button.component.d.ts +25 -0
  76. package/lib/components/ui/ate-separator.component.d.ts +5 -0
  77. package/lib/config/ate-editor.config.d.ts +19 -0
  78. package/lib/config/ate-global-config.token.d.ts +6 -0
  79. package/lib/config/ate-slash-commands.config.d.ts +41 -0
  80. package/lib/directives/ate-noop-value-accessor.directive.d.ts +13 -0
  81. package/lib/directives/ate-tooltip.directive.d.ts +30 -0
  82. package/lib/extensions/ate-block-controls.extension.d.ts +10 -0
  83. package/lib/extensions/ate-link-click-behavior.extension.d.ts +2 -0
  84. package/lib/extensions/ate-resizable-image.extension.d.ts +27 -0
  85. package/lib/extensions/ate-table.extension.d.ts +2 -0
  86. package/lib/extensions/ate-tiptap-state.extension.d.ts +7 -0
  87. package/lib/extensions/ate-upload-progress.extension.d.ts +7 -0
  88. package/lib/extensions/calculators/ate-discovery.calculator.d.ts +7 -0
  89. package/lib/extensions/calculators/ate-image.calculator.d.ts +2 -0
  90. package/lib/extensions/calculators/ate-marks.calculator.d.ts +2 -0
  91. package/lib/extensions/calculators/ate-selection.calculator.d.ts +2 -0
  92. package/lib/extensions/calculators/ate-structure.calculator.d.ts +2 -0
  93. package/lib/extensions/calculators/ate-table.calculator.d.ts +2 -0
  94. package/lib/models/ate-bubble-menu.model.d.ts +33 -0
  95. package/lib/models/ate-editor-config.model.d.ts +113 -0
  96. package/lib/models/ate-editor-state.model.d.ts +109 -0
  97. package/lib/models/ate-image.model.d.ts +104 -0
  98. package/lib/models/ate-slash-command.model.d.ts +17 -0
  99. package/lib/models/ate-toolbar.model.d.ts +18 -0
  100. package/lib/node-view/ate-angular-node-view.d.ts +115 -0
  101. package/lib/node-view/ate-injector.registry.d.ts +3 -0
  102. package/lib/node-view/ate-node-view.factory.d.ts +10 -0
  103. package/lib/node-view/ate-node-view.models.d.ts +138 -0
  104. package/lib/node-view/ate-node-view.renderer.d.ts +23 -0
  105. package/lib/node-view/ate-register-angular-component.d.ts +35 -0
  106. package/lib/services/ate-color-picker.service.d.ts +65 -0
  107. package/lib/services/ate-editor-commands.service.d.ts +75 -0
  108. package/lib/services/ate-i18n.service.d.ts +406 -0
  109. package/lib/services/ate-image.service.d.ts +82 -0
  110. package/lib/services/ate-link.service.d.ts +42 -0
  111. package/lib/utils/ate-color.utils.d.ts +12 -0
  112. package/package.json +3 -1
  113. package/public-api.d.ts +31 -0
@@ -0,0 +1,126 @@
1
+ import { Component, input, ChangeDetectionStrategy, computed } from "@angular/core";
2
+ import { CommonModule } from "@angular/common";
3
+ import { AteButtonComponent } from "../../ui/ate-button.component";
4
+ import { AteBaseBubbleMenu } from "../base/ate-base-bubble-menu";
5
+ import { ATE_DEFAULT_CELL_MENU_CONFIG } from "../../../config/ate-editor.config";
6
+ import * as i0 from "@angular/core";
7
+ export class AteCellBubbleMenuComponent extends AteBaseBubbleMenu {
8
+ constructor() {
9
+ super(...arguments);
10
+ // Inputs
11
+ this.config = input(ATE_DEFAULT_CELL_MENU_CONFIG);
12
+ this.cellBubbleMenuConfig = computed(() => ({
13
+ mergeCells: this.config().mergeCells ?? true,
14
+ splitCell: this.config().splitCell ?? true,
15
+ }));
16
+ // Signals
17
+ this.i18n = () => this.i18nService;
18
+ }
19
+ shouldShow() {
20
+ const { selection, nodes, isEditable, isFocused } = this.state();
21
+ if (this.editorCommands.linkEditMode() || this.editorCommands.colorEditMode()) {
22
+ return false;
23
+ }
24
+ // Only show cell bubble menu for CellSelection
25
+ return selection.type === "cell" && nodes.isTableCell && isEditable && isFocused;
26
+ }
27
+ getSelectionRect() {
28
+ const ed = this.editor();
29
+ if (!ed) {
30
+ return new DOMRect(0, 0, 0, 0);
31
+ }
32
+ // CellSelection
33
+ const selection = ed.state.selection;
34
+ // 1. Multiple cells selected
35
+ if (selection.$anchorCell && selection.$headCell) {
36
+ const cells = [];
37
+ // Try to find all selected cell nodes
38
+ ed.view.dom.querySelectorAll(".selectedCell").forEach(el => {
39
+ if (el instanceof HTMLElement) {
40
+ cells.push(el);
41
+ }
42
+ });
43
+ if (cells.length > 0) {
44
+ let top = Infinity, bottom = -Infinity, left = Infinity, right = -Infinity;
45
+ cells.forEach(cell => {
46
+ const r = cell.getBoundingClientRect();
47
+ top = Math.min(top, r.top);
48
+ bottom = Math.max(bottom, r.bottom);
49
+ left = Math.min(left, r.left);
50
+ right = Math.max(right, r.right);
51
+ });
52
+ return new DOMRect(left, top, right - left, bottom - top);
53
+ }
54
+ // Fallback to anchor/head if no .selectedCell (rare)
55
+ const anchor = ed.view.nodeDOM(selection.$anchorCell.pos);
56
+ const head = ed.view.nodeDOM(selection.$headCell.pos);
57
+ if (anchor && head) {
58
+ const anchorRect = anchor.getBoundingClientRect();
59
+ const headRect = head.getBoundingClientRect();
60
+ const top = Math.min(anchorRect.top, headRect.top);
61
+ const bottom = Math.max(anchorRect.bottom, headRect.bottom);
62
+ const left = Math.min(anchorRect.left, headRect.left);
63
+ const right = Math.max(anchorRect.right, headRect.right);
64
+ return new DOMRect(left, top, right - left, bottom - top);
65
+ }
66
+ }
67
+ // 2. Ultimate fallback via ProseMirror class
68
+ const singleCell = ed.view.dom.querySelector(".selectedCell");
69
+ if (singleCell) {
70
+ return singleCell.getBoundingClientRect();
71
+ }
72
+ return new DOMRect(-9999, -9999, 0, 0);
73
+ }
74
+ executeCommand(editor, command, ...args) {
75
+ this.editorCommands.execute(editor, command, ...args);
76
+ }
77
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteCellBubbleMenuComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
78
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AteCellBubbleMenuComponent, isStandalone: true, selector: "ate-cell-bubble-menu", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
79
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
80
+ <!-- Cell specific actions -->
81
+ @if (cellBubbleMenuConfig().mergeCells !== false && !state().selection.isSingleCell) {
82
+ <ate-button
83
+ icon="cell_merge"
84
+ [title]="i18n().table().mergeCells"
85
+ [disabled]="!state().can.mergeCells"
86
+ (buttonClick)="onCommand('mergeCells', $event)"></ate-button>
87
+ }
88
+ @if (cellBubbleMenuConfig().splitCell !== false && state().selection.isSingleCell) {
89
+ <ate-button
90
+ icon="split_scene"
91
+ [title]="i18n().table().splitCell"
92
+ [disabled]="!state().can.splitCell"
93
+ (buttonClick)="onCommand('splitCell', $event)"></ate-button>
94
+ }
95
+ </div>
96
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AteButtonComponent, selector: "ate-button", inputs: ["icon", "title", "active", "disabled", "color", "backgroundColor", "variant", "size", "iconSize"], outputs: ["buttonClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
97
+ }
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteCellBubbleMenuComponent, decorators: [{
99
+ type: Component,
100
+ args: [{
101
+ selector: "ate-cell-bubble-menu",
102
+ standalone: true,
103
+ changeDetection: ChangeDetectionStrategy.OnPush,
104
+ imports: [CommonModule, AteButtonComponent],
105
+ template: `
106
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
107
+ <!-- Cell specific actions -->
108
+ @if (cellBubbleMenuConfig().mergeCells !== false && !state().selection.isSingleCell) {
109
+ <ate-button
110
+ icon="cell_merge"
111
+ [title]="i18n().table().mergeCells"
112
+ [disabled]="!state().can.mergeCells"
113
+ (buttonClick)="onCommand('mergeCells', $event)"></ate-button>
114
+ }
115
+ @if (cellBubbleMenuConfig().splitCell !== false && state().selection.isSingleCell) {
116
+ <ate-button
117
+ icon="split_scene"
118
+ [title]="i18n().table().splitCell"
119
+ [disabled]="!state().can.splitCell"
120
+ (buttonClick)="onCommand('splitCell', $event)"></ate-button>
121
+ }
122
+ </div>
123
+ `,
124
+ }]
125
+ }] });
126
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLWNlbGwtYnViYmxlLW1lbnUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci10aXB0YXAtZWRpdG9yL3NyYy9saWIvY29tcG9uZW50cy9idWJibGUtbWVudXMvdGFibGUvYXRlLWNlbGwtYnViYmxlLW1lbnUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLHVCQUF1QixFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNwRixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFL0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDbkUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFHakUsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sbUNBQW1DLENBQUM7O0FBMkJqRixNQUFNLE9BQU8sMEJBQTJCLFNBQVEsaUJBQWlCO0lBekJqRTs7UUEwQkUsU0FBUztRQUNULFdBQU0sR0FBRyxLQUFLLENBQTBCLDRCQUE0QixDQUFDLENBQUM7UUFFdEUseUJBQW9CLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDckMsVUFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLElBQUksSUFBSTtZQUM1QyxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLFNBQVMsSUFBSSxJQUFJO1NBQzNDLENBQUMsQ0FBQyxDQUFDO1FBRUosVUFBVTtRQUNELFNBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO0tBa0Z4QztJQWhGVSxVQUFVO1FBQ2pCLE1BQU0sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsR0FB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QXFCL0IsMEJBQTBCO2tCQXpCdEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsc0JBQXNCO29CQUNoQyxVQUFVLEVBQUUsSUFBSTtvQkFDaEIsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07b0JBQy9DLE9BQU8sRUFBRSxDQUFDLFlBQVksRUFBRSxrQkFBa0IsQ0FBQztvQkFDM0MsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQlQ7aUJBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGlucHV0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgY29tcHV0ZWQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHsgdHlwZSBFZGl0b3IgfSBmcm9tIFwiQHRpcHRhcC9jb3JlXCI7XG5pbXBvcnQgeyBBdGVCdXR0b25Db21wb25lbnQgfSBmcm9tIFwiLi4vLi4vdWkvYXRlLWJ1dHRvbi5jb21wb25lbnRcIjtcbmltcG9ydCB7IEF0ZUJhc2VCdWJibGVNZW51IH0gZnJvbSBcIi4uL2Jhc2UvYXRlLWJhc2UtYnViYmxlLW1lbnVcIjtcblxuaW1wb3J0IHsgQXRlQ2VsbEJ1YmJsZU1lbnVDb25maWcgfSBmcm9tIFwiLi4vLi4vLi4vbW9kZWxzL2F0ZS1idWJibGUtbWVudS5tb2RlbFwiO1xuaW1wb3J0IHsgQVRFX0RFRkFVTFRfQ0VMTF9NRU5VX0NPTkZJRyB9IGZyb20gXCIuLi8uLi8uLi9jb25maWcvYXRlLWVkaXRvci5jb25maWdcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcImF0ZS1jZWxsLWJ1YmJsZS1tZW51XCIsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBBdGVCdXR0b25Db21wb25lbnRdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgI21lbnVSZWYgY2xhc3M9XCJidWJibGUtbWVudVwiIChtb3VzZWRvd24pPVwiJGV2ZW50LnByZXZlbnREZWZhdWx0KClcIj5cbiAgICAgIDwhLS0gQ2VsbCBzcGVjaWZpYyBhY3Rpb25zIC0tPlxuICAgICAgQGlmIChjZWxsQnViYmxlTWVudUNvbmZpZygpLm1lcmdlQ2VsbHMgIT09IGZhbHNlICYmICFzdGF0ZSgpLnNlbGVjdGlvbi5pc1NpbmdsZUNlbGwpIHtcbiAgICAgICAgPGF0ZS1idXR0b25cbiAgICAgICAgICBpY29uPVwiY2VsbF9tZXJnZVwiXG4gICAgICAgICAgW3RpdGxlXT1cImkxOG4oKS50YWJsZSgpLm1lcmdlQ2VsbHNcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCIhc3RhdGUoKS5jYW4ubWVyZ2VDZWxsc1wiXG4gICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQ29tbWFuZCgnbWVyZ2VDZWxscycsICRldmVudClcIj48L2F0ZS1idXR0b24+XG4gICAgICB9XG4gICAgICBAaWYgKGNlbGxCdWJibGVNZW51Q29uZmlnKCkuc3BsaXRDZWxsICE9PSBmYWxzZSAmJiBzdGF0ZSgpLnNlbGVjdGlvbi5pc1NpbmdsZUNlbGwpIHtcbiAgICAgICAgPGF0ZS1idXR0b25cbiAgICAgICAgICBpY29uPVwic3BsaXRfc2NlbmVcIlxuICAgICAgICAgIFt0aXRsZV09XCJpMThuKCkudGFibGUoKS5zcGxpdENlbGxcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCIhc3RhdGUoKS5jYW4uc3BsaXRDZWxsXCJcbiAgICAgICAgICAoYnV0dG9uQ2xpY2spPVwib25Db21tYW5kKCdzcGxpdENlbGwnLCAkZXZlbnQpXCI+PC9hdGUtYnV0dG9uPlxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBBdGVDZWxsQnViYmxlTWVudUNvbXBvbmVudCBleHRlbmRzIEF0ZUJhc2VCdWJibGVNZW51IHtcbiAgLy8gSW5wdXRzXG4gIGNvbmZpZyA9IGlucHV0PEF0ZUNlbGxCdWJibGVNZW51Q29uZmlnPihBVEVfREVGQVVMVF9DRUxMX01FTlVfQ09ORklHKTtcblxuICBjZWxsQnViYmxlTWVudUNvbmZpZyA9IGNvbXB1dGVkKCgpID0+ICh7XG4gICAgbWVyZ2VDZWxsczogdGhpcy5jb25maWcoKS5tZXJnZUNlbGxzID8/IHRydWUsXG4gICAgc3BsaXRDZWxsOiB0aGlzLmNvbmZpZygpLnNwbGl0Q2VsbCA/PyB0cnVlLFxuICB9KSk7XG5cbiAgLy8gU2lnbmFsc1xuICByZWFkb25seSBpMThuID0gKCkgPT4gdGhpcy5pMThuU2VydmljZTtcblxuICBvdmVycmlkZSBzaG91bGRTaG93KCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHsgc2VsZWN0aW9uLCBub2RlcywgaXNFZGl0YWJsZSwgaXNGb2N1c2VkIH0gPSB0aGlzLnN0YXRlKCk7XG5cbiAgICBpZiAodGhpcy5lZGl0b3JDb21tYW5kcy5saW5rRWRpdE1vZGUoKSB8fCB0aGlzLmVkaXRvckNvbW1hbmRzLmNvbG9yRWRpdE1vZGUoKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIE9ubHkgc2hvdyBjZWxsIGJ1YmJsZSBtZW51IGZvciBDZWxsU2VsZWN0aW9uXG4gICAgcmV0dXJuIHNlbGVjdGlvbi50eXBlID09PSBcImNlbGxcIiAmJiBub2Rlcy5pc1RhYmxlQ2VsbCAmJiBpc0VkaXRhYmxlICYmIGlzRm9jdXNlZDtcbiAgfVxuXG4gIG92ZXJyaWRlIGdldFNlbGVjdGlvblJlY3QoKTogRE9NUmVjdCB7XG4gICAgY29uc3QgZWQgPSB0aGlzLmVkaXRvcigpO1xuICAgIGlmICghZWQpIHtcbiAgICAgIHJldHVybiBuZXcgRE9NUmVjdCgwLCAwLCAwLCAwKTtcbiAgICB9XG5cbiAgICAvLyBDZWxsU2VsZWN0aW9uXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gZWQuc3RhdGUuc2VsZWN0aW9uIGFzIHVua25vd24gYXMge1xuICAgICAgJGFuY2hvckNlbGw/OiB7IHBvczogbnVtYmVyIH07XG4gICAgICAkaGVhZENlbGw/OiB7IHBvczogbnVtYmVyIH07XG4gICAgfTtcblxuICAgIC8vIDEuIE11bHRpcGxlIGNlbGxzIHNlbGVjdGVkXG4gICAgaWYgKHNlbGVjdGlvbi4kYW5jaG9yQ2VsbCAmJiBzZWxlY3Rpb24uJGhlYWRDZWxsKSB7XG4gICAgICBjb25zdCBjZWxsczogSFRNTEVsZW1lbnRbXSA9IFtdO1xuXG4gICAgICAvLyBUcnkgdG8gZmluZCBhbGwgc2VsZWN0ZWQgY2VsbCBub2Rlc1xuICAgICAgZWQudmlldy5kb20ucXVlcnlTZWxlY3RvckFsbChcIi5zZWxlY3RlZENlbGxcIikuZm9yRWFjaChlbCA9PiB7XG4gICAgICAgIGlmIChlbCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgICAgY2VsbHMucHVzaChlbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAoY2VsbHMubGVuZ3RoID4gMCkge1xuICAgICAgICBsZXQgdG9wID0gSW5maW5pdHksXG4gICAgICAgICAgYm90dG9tID0gLUluZmluaXR5LFxuICAgICAgICAgIGxlZnQgPSBJbmZpbml0eSxcbiAgICAgICAgICByaWdodCA9IC1JbmZpbml0eTtcblxuICAgICAgICBjZWxscy5mb3JFYWNoKGNlbGwgPT4ge1xuICAgICAgICAgIGNvbnN0IHIgPSBjZWxsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgIHRvcCA9IE1hdGgubWluKHRvcCwgci50b3ApO1xuICAgICAgICAgIGJvdHRvbSA9IE1hdGgubWF4KGJvdHRvbSwgci5ib3R0b20pO1xuICAgICAgICAgIGxlZnQgPSBNYXRoLm1pbihsZWZ0LCByLmxlZnQpO1xuICAgICAgICAgIHJpZ2h0ID0gTWF0aC5tYXgocmlnaHQsIHIucmlnaHQpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbmV3IERPTVJlY3QobGVmdCwgdG9wLCByaWdodCAtIGxlZnQsIGJvdHRvbSAtIHRvcCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEZhbGxiYWNrIHRvIGFuY2hvci9oZWFkIGlmIG5vIC5zZWxlY3RlZENlbGwgKHJhcmUpXG4gICAgICBjb25zdCBhbmNob3IgPSBlZC52aWV3Lm5vZGVET00oc2VsZWN0aW9uLiRhbmNob3JDZWxsLnBvcykgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICBjb25zdCBoZWFkID0gZWQudmlldy5ub2RlRE9NKHNlbGVjdGlvbi4kaGVhZENlbGwucG9zKSBhcyBIVE1MRWxlbWVudDtcblxuICAgICAgaWYgKGFuY2hvciAmJiBoZWFkKSB7XG4gICAgICAgIGNvbnN0IGFuY2hvclJlY3QgPSBhbmNob3IuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGNvbnN0IGhlYWRSZWN0ID0gaGVhZC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgICBjb25zdCB0b3AgPSBNYXRoLm1pbihhbmNob3JSZWN0LnRvcCwgaGVhZFJlY3QudG9wKTtcbiAgICAgICAgY29uc3QgYm90dG9tID0gTWF0aC5tYXgoYW5jaG9yUmVjdC5ib3R0b20sIGhlYWRSZWN0LmJvdHRvbSk7XG4gICAgICAgIGNvbnN0IGxlZnQgPSBNYXRoLm1pbihhbmNob3JSZWN0LmxlZnQsIGhlYWRSZWN0LmxlZnQpO1xuICAgICAgICBjb25zdCByaWdodCA9IE1hdGgubWF4KGFuY2hvclJlY3QucmlnaHQsIGhlYWRSZWN0LnJpZ2h0KTtcblxuICAgICAgICByZXR1cm4gbmV3IERPTVJlY3QobGVmdCwgdG9wLCByaWdodCAtIGxlZnQsIGJvdHRvbSAtIHRvcCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gMi4gVWx0aW1hdGUgZmFsbGJhY2sgdmlhIFByb3NlTWlycm9yIGNsYXNzXG4gICAgY29uc3Qgc2luZ2xlQ2VsbCA9IGVkLnZpZXcuZG9tLnF1ZXJ5U2VsZWN0b3IoXCIuc2VsZWN0ZWRDZWxsXCIpO1xuICAgIGlmIChzaW5nbGVDZWxsKSB7XG4gICAgICByZXR1cm4gc2luZ2xlQ2VsbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IERPTVJlY3QoLTk5OTksIC05OTk5LCAwLCAwKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBleGVjdXRlQ29tbWFuZChlZGl0b3I6IEVkaXRvciwgY29tbWFuZDogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRvckNvbW1hbmRzLmV4ZWN1dGUoZWRpdG9yLCBjb21tYW5kLCAuLi5hcmdzKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,271 @@
1
+ import { Component, input, ChangeDetectionStrategy, computed } from "@angular/core";
2
+ import { CommonModule } from "@angular/common";
3
+ import { AteButtonComponent } from "../../ui/ate-button.component";
4
+ import { AteSeparatorComponent } from "../../ui/ate-separator.component";
5
+ import { AteBaseBubbleMenu } from "../base/ate-base-bubble-menu";
6
+ import { ATE_TABLE_BUBBLE_MENU_KEYS, } from "../../../models/ate-bubble-menu.model";
7
+ import { ATE_DEFAULT_TABLE_MENU_CONFIG } from "../../../config/ate-editor.config";
8
+ import * as i0 from "@angular/core";
9
+ export class AteTableBubbleMenuComponent extends AteBaseBubbleMenu {
10
+ constructor() {
11
+ super(...arguments);
12
+ // Alias for template
13
+ this.t = this.i18nService.table;
14
+ this.config = input(ATE_DEFAULT_TABLE_MENU_CONFIG);
15
+ this.tableBubbleMenuConfig = computed(() => {
16
+ const c = this.config();
17
+ const result = {};
18
+ ATE_TABLE_BUBBLE_MENU_KEYS.forEach(key => {
19
+ result[key] = c[key] ?? true;
20
+ });
21
+ return result;
22
+ });
23
+ }
24
+ shouldShow() {
25
+ const { selection, nodes, isEditable, isFocused } = this.state();
26
+ if (this.editorCommands.linkEditMode() || this.editorCommands.colorEditMode()) {
27
+ return false;
28
+ }
29
+ // Only show table bubble menu if:
30
+ // 1. We are inside a table (nodes.isTable)
31
+ // 2. Editor is editable and focused
32
+ // 3. Selection is EMPTY (cursor) OR the Table node itself is selected
33
+ // 4. It's NOT a CellSelection (cell bubble menu takes priority)
34
+ return (nodes.isTable &&
35
+ isEditable &&
36
+ isFocused &&
37
+ (selection.empty || nodes.isTableNodeSelected) &&
38
+ selection.type !== "cell");
39
+ }
40
+ getSelectionRect() {
41
+ const ed = this.editor();
42
+ if (!ed) {
43
+ return new DOMRect(0, 0, 0, 0);
44
+ }
45
+ const { from } = ed.state.selection;
46
+ try {
47
+ // 1. Direct ProseMirror approach: get DOM node at position
48
+ const dom = ed.view.domAtPos(from).node;
49
+ // Find closest table element
50
+ const tableElement = dom instanceof HTMLElement
51
+ ? dom.closest("table")
52
+ : dom.parentElement?.closest("table");
53
+ if (tableElement) {
54
+ return tableElement.getBoundingClientRect();
55
+ }
56
+ }
57
+ catch (_e) {
58
+ // Fallback
59
+ }
60
+ // 2. Fallback via coordinates
61
+ const coords = ed.view.coordsAtPos(from);
62
+ if (coords) {
63
+ // Search for table element at these coordinates
64
+ const element = document.elementFromPoint(coords.left, coords.top);
65
+ const table = element?.closest("table");
66
+ if (table) {
67
+ return table.getBoundingClientRect();
68
+ }
69
+ }
70
+ // 3. Ultimate fallback if selection is ambiguous
71
+ const activeTable = ed.view.dom.querySelector("table.selected, table:has(.selected), table:has(.selected-cell), table:has(.selected-node)");
72
+ if (activeTable) {
73
+ return activeTable.getBoundingClientRect();
74
+ }
75
+ return new DOMRect(-9999, -9999, 0, 0);
76
+ }
77
+ executeCommand(editor, command, ...args) {
78
+ this.editorCommands.execute(editor, command, ...args);
79
+ }
80
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteTableBubbleMenuComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
81
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AteTableBubbleMenuComponent, isStandalone: true, selector: "ate-table-bubble-menu", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
82
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
83
+ <!-- Row actions -->
84
+ @if (tableBubbleMenuConfig().addRowBefore !== false) {
85
+ <ate-button
86
+ icon="add_row_above"
87
+ [title]="t().addRowBefore"
88
+ [disabled]="!state().can.addRowBefore"
89
+ (buttonClick)="onCommand('addRowBefore', $event)"></ate-button>
90
+ }
91
+ @if (tableBubbleMenuConfig().addRowAfter !== false) {
92
+ <ate-button
93
+ icon="add_row_below"
94
+ [title]="t().addRowAfter"
95
+ [disabled]="!state().can.addRowAfter"
96
+ (buttonClick)="onCommand('addRowAfter', $event)"></ate-button>
97
+ }
98
+ @if (tableBubbleMenuConfig().deleteRow !== false) {
99
+ <ate-button
100
+ icon="delete"
101
+ [title]="t().deleteRow"
102
+ variant="danger"
103
+ [disabled]="!state().can.deleteRow"
104
+ (buttonClick)="onCommand('deleteRow', $event)"></ate-button>
105
+ }
106
+ @if (tableBubbleMenuConfig().separator !== false) {
107
+ <ate-separator />
108
+ }
109
+
110
+ <!-- Column actions -->
111
+ @if (tableBubbleMenuConfig().addColumnBefore !== false) {
112
+ <ate-button
113
+ icon="add_column_left"
114
+ [title]="t().addColumnBefore"
115
+ [disabled]="!state().can.addColumnBefore"
116
+ (buttonClick)="onCommand('addColumnBefore', $event)"></ate-button>
117
+ }
118
+ @if (tableBubbleMenuConfig().addColumnAfter !== false) {
119
+ <ate-button
120
+ icon="add_column_right"
121
+ [title]="t().addColumnAfter"
122
+ [disabled]="!state().can.addColumnAfter"
123
+ (buttonClick)="onCommand('addColumnAfter', $event)"></ate-button>
124
+ }
125
+ @if (tableBubbleMenuConfig().deleteColumn !== false) {
126
+ <ate-button
127
+ icon="delete"
128
+ [title]="t().deleteColumn"
129
+ variant="danger"
130
+ [disabled]="!state().can.deleteColumn"
131
+ (buttonClick)="onCommand('deleteColumn', $event)"></ate-button>
132
+ }
133
+ @if (tableBubbleMenuConfig().separator !== false) {
134
+ <ate-separator />
135
+ }
136
+
137
+ <!-- Cell actions -->
138
+ @if (tableBubbleMenuConfig().toggleHeaderRow !== false) {
139
+ <ate-button
140
+ icon="toolbar"
141
+ [title]="t().toggleHeaderRow"
142
+ [active]="state().nodes.isTableHeaderRow"
143
+ [disabled]="!state().can.toggleHeaderRow"
144
+ (buttonClick)="onCommand('toggleHeaderRow', $event)"></ate-button>
145
+ }
146
+ @if (tableBubbleMenuConfig().toggleHeaderColumn !== false) {
147
+ <ate-button
148
+ icon="dock_to_right"
149
+ [title]="t().toggleHeaderColumn"
150
+ [active]="state().nodes.isTableHeaderColumn"
151
+ [disabled]="!state().can.toggleHeaderColumn"
152
+ (buttonClick)="onCommand('toggleHeaderColumn', $event)"></ate-button>
153
+ }
154
+ @if (
155
+ tableBubbleMenuConfig().separator !== false && tableBubbleMenuConfig().deleteTable !== false
156
+ ) {
157
+ <ate-separator />
158
+ }
159
+
160
+ <!-- Table actions -->
161
+ @if (tableBubbleMenuConfig().deleteTable !== false) {
162
+ <ate-button
163
+ icon="delete_forever"
164
+ [title]="t().deleteTable"
165
+ variant="danger"
166
+ [disabled]="!state().can.deleteTable"
167
+ (buttonClick)="onCommand('deleteTable', $event)"></ate-button>
168
+ }
169
+ </div>
170
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AteButtonComponent, selector: "ate-button", inputs: ["icon", "title", "active", "disabled", "color", "backgroundColor", "variant", "size", "iconSize"], outputs: ["buttonClick"] }, { kind: "component", type: AteSeparatorComponent, selector: "ate-separator" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
171
+ }
172
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteTableBubbleMenuComponent, decorators: [{
173
+ type: Component,
174
+ args: [{
175
+ selector: "ate-table-bubble-menu",
176
+ standalone: true,
177
+ changeDetection: ChangeDetectionStrategy.OnPush,
178
+ imports: [CommonModule, AteButtonComponent, AteSeparatorComponent],
179
+ template: `
180
+ <div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
181
+ <!-- Row actions -->
182
+ @if (tableBubbleMenuConfig().addRowBefore !== false) {
183
+ <ate-button
184
+ icon="add_row_above"
185
+ [title]="t().addRowBefore"
186
+ [disabled]="!state().can.addRowBefore"
187
+ (buttonClick)="onCommand('addRowBefore', $event)"></ate-button>
188
+ }
189
+ @if (tableBubbleMenuConfig().addRowAfter !== false) {
190
+ <ate-button
191
+ icon="add_row_below"
192
+ [title]="t().addRowAfter"
193
+ [disabled]="!state().can.addRowAfter"
194
+ (buttonClick)="onCommand('addRowAfter', $event)"></ate-button>
195
+ }
196
+ @if (tableBubbleMenuConfig().deleteRow !== false) {
197
+ <ate-button
198
+ icon="delete"
199
+ [title]="t().deleteRow"
200
+ variant="danger"
201
+ [disabled]="!state().can.deleteRow"
202
+ (buttonClick)="onCommand('deleteRow', $event)"></ate-button>
203
+ }
204
+ @if (tableBubbleMenuConfig().separator !== false) {
205
+ <ate-separator />
206
+ }
207
+
208
+ <!-- Column actions -->
209
+ @if (tableBubbleMenuConfig().addColumnBefore !== false) {
210
+ <ate-button
211
+ icon="add_column_left"
212
+ [title]="t().addColumnBefore"
213
+ [disabled]="!state().can.addColumnBefore"
214
+ (buttonClick)="onCommand('addColumnBefore', $event)"></ate-button>
215
+ }
216
+ @if (tableBubbleMenuConfig().addColumnAfter !== false) {
217
+ <ate-button
218
+ icon="add_column_right"
219
+ [title]="t().addColumnAfter"
220
+ [disabled]="!state().can.addColumnAfter"
221
+ (buttonClick)="onCommand('addColumnAfter', $event)"></ate-button>
222
+ }
223
+ @if (tableBubbleMenuConfig().deleteColumn !== false) {
224
+ <ate-button
225
+ icon="delete"
226
+ [title]="t().deleteColumn"
227
+ variant="danger"
228
+ [disabled]="!state().can.deleteColumn"
229
+ (buttonClick)="onCommand('deleteColumn', $event)"></ate-button>
230
+ }
231
+ @if (tableBubbleMenuConfig().separator !== false) {
232
+ <ate-separator />
233
+ }
234
+
235
+ <!-- Cell actions -->
236
+ @if (tableBubbleMenuConfig().toggleHeaderRow !== false) {
237
+ <ate-button
238
+ icon="toolbar"
239
+ [title]="t().toggleHeaderRow"
240
+ [active]="state().nodes.isTableHeaderRow"
241
+ [disabled]="!state().can.toggleHeaderRow"
242
+ (buttonClick)="onCommand('toggleHeaderRow', $event)"></ate-button>
243
+ }
244
+ @if (tableBubbleMenuConfig().toggleHeaderColumn !== false) {
245
+ <ate-button
246
+ icon="dock_to_right"
247
+ [title]="t().toggleHeaderColumn"
248
+ [active]="state().nodes.isTableHeaderColumn"
249
+ [disabled]="!state().can.toggleHeaderColumn"
250
+ (buttonClick)="onCommand('toggleHeaderColumn', $event)"></ate-button>
251
+ }
252
+ @if (
253
+ tableBubbleMenuConfig().separator !== false && tableBubbleMenuConfig().deleteTable !== false
254
+ ) {
255
+ <ate-separator />
256
+ }
257
+
258
+ <!-- Table actions -->
259
+ @if (tableBubbleMenuConfig().deleteTable !== false) {
260
+ <ate-button
261
+ icon="delete_forever"
262
+ [title]="t().deleteTable"
263
+ variant="danger"
264
+ [disabled]="!state().can.deleteTable"
265
+ (buttonClick)="onCommand('deleteTable', $event)"></ate-button>
266
+ }
267
+ </div>
268
+ `,
269
+ }]
270
+ }] });
271
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLXRhYmxlLWJ1YmJsZS1tZW51LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdGlwdGFwLWVkaXRvci9zcmMvbGliL2NvbXBvbmVudHMvYnViYmxlLW1lbnVzL3RhYmxlL2F0ZS10YWJsZS1idWJibGUtbWVudS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsdUJBQXVCLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUvQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNuRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUN6RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUVqRSxPQUFPLEVBRUwsMEJBQTBCLEdBQzNCLE1BQU0sdUNBQXVDLENBQUM7QUFDL0MsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sbUNBQW1DLENBQUM7O0FBa0dsRixNQUFNLE9BQU8sMkJBQTRCLFNBQVEsaUJBQWlCO0lBaEdsRTs7UUFpR0UscUJBQXFCO1FBQ1osTUFBQyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDO1FBRXBDLFdBQU0sR0FBRyxLQUFLLENBQTJCLDZCQUE2QixDQUFDLENBQUM7UUFFeEUsMEJBQXFCLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUNwQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDeEIsTUFBTSxNQUFNLEdBQTRCLEVBQUUsQ0FBQztZQUMzQywwQkFBMEIsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7Z0JBQ3ZDLE1BQU0sQ0FBQyxH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RUFBRSxPQUFlLEVBQUUsR0FBRyxJQUFlO1FBQ25GLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztJQUN4RCxDQUFDOytHQXJGVSwyQkFBMkI7bUdBQTNCLDJCQUEyQiwrT0EzRjVCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlGVCwyREExRlMsWUFBWSwrQkFBRSxrQkFBa0IsNkxBQUUscUJBQXFCOzs0RkE0RnRELDJCQUEyQjtrQkFoR3ZDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLHVCQUF1QjtvQkFDakMsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO29CQUMvQyxPQUFPLEVBQUUsQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLEVBQUUscUJBQXFCLENBQUM7b0JBQ2xFLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F5RlQ7aUJBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGlucHV0LCBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgY29tcHV0ZWQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHsgdHlwZSBFZGl0b3IgfSBmcm9tIFwiQHRpcHRhcC9jb3JlXCI7XG5pbXBvcnQgeyBBdGVCdXR0b25Db21wb25lbnQgfSBmcm9tIFwiLi4vLi4vdWkvYXRlLWJ1dHRvbi5jb21wb25lbnRcIjtcbmltcG9ydCB7IEF0ZVNlcGFyYXRvckNvbXBvbmVudCB9IGZyb20gXCIuLi8uLi91aS9hdGUtc2VwYXJhdG9yLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgQXRlQmFzZUJ1YmJsZU1lbnUgfSBmcm9tIFwiLi4vYmFzZS9hdGUtYmFzZS1idWJibGUtbWVudVwiO1xuXG5pbXBvcnQge1xuICBBdGVUYWJsZUJ1YmJsZU1lbnVDb25maWcsXG4gIEFURV9UQUJMRV9CVUJCTEVfTUVOVV9LRVlTLFxufSBmcm9tIFwiLi4vLi4vLi4vbW9kZWxzL2F0ZS1idWJibGUtbWVudS5tb2RlbFwiO1xuaW1wb3J0IHsgQVRFX0RFRkFVTFRfVEFCTEVfTUVOVV9DT05GSUcgfSBmcm9tIFwiLi4vLi4vLi4vY29uZmlnL2F0ZS1lZGl0b3IuY29uZmlnXCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogXCJhdGUtdGFibGUtYnViYmxlLW1lbnVcIixcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEF0ZUJ1dHRvbkNvbXBvbmVudCwgQXRlU2VwYXJhdG9yQ29tcG9uZW50XSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2ICNtZW51UmVmIGNsYXNzPVwiYnViYmxlLW1lbnVcIiAobW91c2Vkb3duKT1cIiRldmVudC5wcmV2ZW50RGVmYXVsdCgpXCI+XG4gICAgICA8IS0tIFJvdyBhY3Rpb25zIC0tPlxuICAgICAgQGlmICh0YWJsZUJ1YmJsZU1lbnVDb25maWcoKS5hZGRSb3dCZWZvcmUgIT09IGZhbHNlKSB7XG4gICAgICAgIDxhdGUtYnV0dG9uXG4gICAgICAgICAgaWNvbj1cImFkZF9yb3dfYWJvdmVcIlxuICAgICAgICAgIFt0aXRsZV09XCJ0KCkuYWRkUm93QmVmb3JlXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiIXN0YXRlKCkuY2FuLmFkZFJvd0JlZm9yZVwiXG4gICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQ29tbWFuZCgnYWRkUm93QmVmb3JlJywgJGV2ZW50KVwiPjwvYXRlLWJ1dHRvbj5cbiAgICAgIH1cbiAgICAgIEBpZiAodGFibGVCdWJibGVNZW51Q29uZmlnKCkuYWRkUm93QWZ0ZXIgIT09IGZhbHNlKSB7XG4gICAgICAgIDxhdGUtYnV0dG9uXG4gICAgICAgICAgaWNvbj1cImFkZF9yb3dfYmVsb3dcIlxuICAgICAgICAgIFt0aXRsZV09XCJ0KCkuYWRkUm93QWZ0ZXJcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCIhc3RhdGUoKS5jYW4uYWRkUm93QWZ0ZXJcIlxuICAgICAgICAgIChidXR0b25DbGljayk9XCJvbkNvbW1hbmQoJ2FkZFJvd0FmdGVyJywgJGV2ZW50KVwiPjwvYXRlLWJ1dHRvbj5cbiAgICAgIH1cbiAgICAgIEBpZiAodGFibGVCdWJibGVNZW51Q29uZmlnKCkuZGVsZXRlUm93ICE9PSBmYWxzZSkge1xuICAgICAgICA8YXRlLWJ1dHRvblxuICAgICAgICAgIGljb249XCJkZWxldGVcIlxuICAgICAgICAgIFt0aXRsZV09XCJ0KCkuZGVsZXRlUm93XCJcbiAgICAgICAgICB2YXJpYW50PVwiZGFuZ2VyXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiIXN0YXRlKCkuY2FuLmRlbGV0ZVJvd1wiXG4gICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQ29tbWFuZCgnZGVsZXRlUm93JywgJGV2ZW50KVwiPjwvYXRlLWJ1dHRvbj5cbiAgICAgIH1cbiAgICAgIEBpZiAodGFibGVCdWJibGVNZW51Q29uZmlnKCkuc2VwYXJhdG9yICE9PSBmYWxzZSkge1xuICAgICAgICA8YXRlLXNlcGFyYXRvciAvPlxuICAgICAgfVxuXG4gICAgICA8IS0tIENvbHVtbiBhY3Rpb25zIC0tPlxuICAgICAgQGlmICh0YWJsZUJ1YmJsZU1lbnVDb25maWcoKS5hZGRDb2x1bW5CZWZvcmUgIT09IGZhbHNlKSB7XG4gICAgICAgIDxhdGUtYnV0dG9uXG4gICAgICAgICAgaWNvbj1cImFkZF9jb2x1bW5fbGVmdFwiXG4gICAgICAgICAgW3RpdGxlXT1cInQoKS5hZGRDb2x1bW5CZWZvcmVcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCIhc3RhdGUoKS5jYW4uYWRkQ29sdW1uQmVmb3JlXCJcbiAgICAgICAgICAoYnV0dG9uQ2xpY2spPVwib25Db21tYW5kKCdhZGRDb2x1bW5CZWZvcmUnLCAkZXZlbnQpXCI+PC9hdGUtYnV0dG9uPlxuICAgICAgfVxuICAgICAgQGlmICh0YWJsZUJ1YmJsZU1lbnVDb25maWcoKS5hZGRDb2x1bW5BZnRlciAhPT0gZmFsc2UpIHtcbiAgICAgICAgPGF0ZS1idXR0b25cbiAgICAgICAgICBpY29uPVwiYWRkX2NvbHVtbl9yaWdodFwiXG4gICAgICAgICAgW3RpdGxlXT1cInQoKS5hZGRDb2x1bW5BZnRlclwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIiFzdGF0ZSgpLmNhbi5hZGRDb2x1bW5BZnRlclwiXG4gICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQ29tbWFuZCgnYWRkQ29sdW1uQWZ0ZXInLCAkZXZlbnQpXCI+PC9hdGUtYnV0dG9uPlxuICAgICAgfVxuICAgICAgQGlmICh0YWJsZUJ1YmJsZU1lbnVDb25maWcoKS5kZWxldGVDb2x1bW4gIT09IGZhbHNlKSB7XG4gICAgICAgIDxhdGUtYnV0dG9uXG4gICAgICAgICAgaWNvbj1cImRlbGV0ZVwiXG4gICAgICAgICAgW3RpdGxlXT1cInQoKS5kZWxldGVDb2x1bW5cIlxuICAgICAgICAgIHZhcmlhbnQ9XCJkYW5nZXJcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCIhc3RhdGUoKS5jYW4uZGVsZXRlQ29sdW1uXCJcbiAgICAgICAgICAoYnV0dG9uQ2xpY2spPVwib25Db21tYW5kKCdkZWxldGVDb2x1bW4nLCAkZXZlbnQpXCI+PC9hdGUtYnV0dG9uPlxuICAgICAgfVxuICAgICAgQGlmICh0YWJsZUJ1YmJsZU1lbnVDb25maWcoKS5zZXBhcmF0b3IgIT09IGZhbHNlKSB7XG4gICAgICAgIDxhdGUtc2VwYXJhdG9yIC8+XG4gICAgICB9XG5cbiAgICAgIDwhLS0gQ2VsbCBhY3Rpb25zIC0tPlxuICAgICAgQGlmICh0YWJsZUJ1YmJsZU1lbnVDb25maWcoKS50b2dnbGVIZWFkZXJSb3cgIT09IGZhbHNlKSB7XG4gICAgICAgIDxhdGUtYnV0dG9uXG4gICAgICAgICAgaWNvbj1cInRvb2xiYXJcIlxuICAgICAgICAgIFt0aXRsZV09XCJ0KCkudG9nZ2xlSGVhZGVyUm93XCJcbiAgICAgICAgICBbYWN0aXZlXT1cInN0YXRlKCkubm9kZXMuaXNUYWJsZUhlYWRlclJvd1wiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIiFzdGF0ZSgpLmNhbi50b2dnbGVIZWFkZXJSb3dcIlxuICAgICAgICAgIChidXR0b25DbGljayk9XCJvbkNvbW1hbmQoJ3RvZ2dsZUhlYWRlclJvdycsICRldmVudClcIj48L2F0ZS1idXR0b24+XG4gICAgICB9XG4gICAgICBAaWYgKHRhYmxlQnViYmxlTWVudUNvbmZpZygpLnRvZ2dsZUhlYWRlckNvbHVtbiAhPT0gZmFsc2UpIHtcbiAgICAgICAgPGF0ZS1idXR0b25cbiAgICAgICAgICBpY29uPVwiZG9ja190b19yaWdodFwiXG4gICAgICAgICAgW3RpdGxlXT1cInQoKS50b2dnbGVIZWFkZXJDb2x1bW5cIlxuICAgICAgICAgIFthY3RpdmVdPVwic3RhdGUoKS5ub2Rlcy5pc1RhYmxlSGVhZGVyQ29sdW1uXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiIXN0YXRlKCkuY2FuLnRvZ2dsZUhlYWRlckNvbHVtblwiXG4gICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQ29tbWFuZCgndG9nZ2xlSGVhZGVyQ29sdW1uJywgJGV2ZW50KVwiPjwvYXRlLWJ1dHRvbj5cbiAgICAgIH1cbiAgICAgIEBpZiAoXG4gICAgICAgIHRhYmxlQnViYmxlTWVudUNvbmZpZygpLnNlcGFyYXRvciAhPT0gZmFsc2UgJiYgdGFibGVCdWJibGVNZW51Q29uZmlnKCkuZGVsZXRlVGFibGUgIT09IGZhbHNlXG4gICAgICApIHtcbiAgICAgICAgPGF0ZS1zZXBhcmF0b3IgLz5cbiAgICAgIH1cblxuICAgICAgPCEtLSBUYWJsZSBhY3Rpb25zIC0tPlxuICAgICAgQGlmICh0YWJsZUJ1YmJsZU1lbnVDb25maWcoKS5kZWxldGVUYWJsZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgPGF0ZS1idXR0b25cbiAgICAgICAgICBpY29uPVwiZGVsZXRlX2ZvcmV2ZXJcIlxuICAgICAgICAgIFt0aXRsZV09XCJ0KCkuZGVsZXRlVGFibGVcIlxuICAgICAgICAgIHZhcmlhbnQ9XCJkYW5nZXJcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCIhc3RhdGUoKS5jYW4uZGVsZXRlVGFibGVcIlxuICAgICAgICAgIChidXR0b25DbGljayk9XCJvbkNvbW1hbmQoJ2RlbGV0ZVRhYmxlJywgJGV2ZW50KVwiPjwvYXRlLWJ1dHRvbj5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgQXRlVGFibGVCdWJibGVNZW51Q29tcG9uZW50IGV4dGVuZHMgQXRlQmFzZUJ1YmJsZU1lbnUge1xuICAvLyBBbGlhcyBmb3IgdGVtcGxhdGVcbiAgcmVhZG9ubHkgdCA9IHRoaXMuaTE4blNlcnZpY2UudGFibGU7XG5cbiAgY29uZmlnID0gaW5wdXQ8QXRlVGFibGVCdWJibGVNZW51Q29uZmlnPihBVEVfREVGQVVMVF9UQUJMRV9NRU5VX0NPTkZJRyk7XG5cbiAgdGFibGVCdWJibGVNZW51Q29uZmlnID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGMgPSB0aGlzLmNvbmZpZygpO1xuICAgIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgYm9vbGVhbj4gPSB7fTtcbiAgICBBVEVfVEFCTEVfQlVCQkxFX01FTlVfS0VZUy5mb3JFYWNoKGtleSA9PiB7XG4gICAgICByZXN1bHRba2V5XSA9IGNba2V5XSA/PyB0cnVlO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQgYXMgUmVxdWlyZWQ8QXRlVGFibGVCdWJibGVNZW51Q29uZmlnPjtcbiAgfSk7XG5cbiAgb3ZlcnJpZGUgc2hvdWxkU2hvdygpOiBib29sZWFuIHtcbiAgICBjb25zdCB7IHNlbGVjdGlvbiwgbm9kZXMsIGlzRWRpdGFibGUsIGlzRm9jdXNlZCB9ID0gdGhpcy5zdGF0ZSgpO1xuXG4gICAgaWYgKHRoaXMuZWRpdG9yQ29tbWFuZHMubGlua0VkaXRNb2RlKCkgfHwgdGhpcy5lZGl0b3JDb21tYW5kcy5jb2xvckVkaXRNb2RlKCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBPbmx5IHNob3cgdGFibGUgYnViYmxlIG1lbnUgaWY6XG4gICAgLy8gMS4gV2UgYXJlIGluc2lkZSBhIHRhYmxlIChub2Rlcy5pc1RhYmxlKVxuICAgIC8vIDIuIEVkaXRvciBpcyBlZGl0YWJsZSBhbmQgZm9jdXNlZFxuICAgIC8vIDMuIFNlbGVjdGlvbiBpcyBFTVBUWSAoY3Vyc29yKSBPUiB0aGUgVGFibGUgbm9kZSBpdHNlbGYgaXMgc2VsZWN0ZWRcbiAgICAvLyA0LiBJdCdzIE5PVCBhIENlbGxTZWxlY3Rpb24gKGNlbGwgYnViYmxlIG1lbnUgdGFrZXMgcHJpb3JpdHkpXG4gICAgcmV0dXJuIChcbiAgICAgIG5vZGVzLmlzVGFibGUgJiZcbiAgICAgIGlzRWRpdGFibGUgJiZcbiAgICAgIGlzRm9jdXNlZCAmJlxuICAgICAgKHNlbGVjdGlvbi5lbXB0eSB8fCBub2Rlcy5pc1RhYmxlTm9kZVNlbGVjdGVkKSAmJlxuICAgICAgc2VsZWN0aW9uLnR5cGUgIT09IFwiY2VsbFwiXG4gICAgKTtcbiAgfVxuXG4gIG92ZXJyaWRlIGdldFNlbGVjdGlvblJlY3QoKTogRE9NUmVjdCB7XG4gICAgY29uc3QgZWQgPSB0aGlzLmVkaXRvcigpO1xuICAgIGlmICghZWQpIHtcbiAgICAgIHJldHVybiBuZXcgRE9NUmVjdCgwLCAwLCAwLCAwKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGZyb20gfSA9IGVkLnN0YXRlLnNlbGVjdGlvbjtcblxuICAgIHRyeSB7XG4gICAgICAvLyAxLiBEaXJlY3QgUHJvc2VNaXJyb3IgYXBwcm9hY2g6IGdldCBET00gbm9kZSBhdCBwb3NpdGlvblxuICAgICAgY29uc3QgZG9tID0gZWQudmlldy5kb21BdFBvcyhmcm9tKS5ub2RlO1xuXG4gICAgICAvLyBGaW5kIGNsb3Nlc3QgdGFibGUgZWxlbWVudFxuICAgICAgY29uc3QgdGFibGVFbGVtZW50ID1cbiAgICAgICAgZG9tIGluc3RhbmNlb2YgSFRNTEVsZW1lbnRcbiAgICAgICAgICA/IGRvbS5jbG9zZXN0KFwidGFibGVcIilcbiAgICAgICAgICA6IChkb20ucGFyZW50RWxlbWVudCBhcyBIVE1MRWxlbWVudCk/LmNsb3Nlc3QoXCJ0YWJsZVwiKTtcblxuICAgICAgaWYgKHRhYmxlRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gdGFibGVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKF9lKSB7XG4gICAgICAvLyBGYWxsYmFja1xuICAgIH1cblxuICAgIC8vIDIuIEZhbGxiYWNrIHZpYSBjb29yZGluYXRlc1xuICAgIGNvbnN0IGNvb3JkcyA9IGVkLnZpZXcuY29vcmRzQXRQb3MoZnJvbSk7XG4gICAgaWYgKGNvb3Jkcykge1xuICAgICAgLy8gU2VhcmNoIGZvciB0YWJsZSBlbGVtZW50IGF0IHRoZXNlIGNvb3JkaW5hdGVzXG4gICAgICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChjb29yZHMubGVmdCwgY29vcmRzLnRvcCk7XG4gICAgICBjb25zdCB0YWJsZSA9IChlbGVtZW50IGFzIEVsZW1lbnQpPy5jbG9zZXN0KFwidGFibGVcIik7XG4gICAgICBpZiAodGFibGUpIHtcbiAgICAgICAgcmV0dXJuIHRhYmxlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIDMuIFVsdGltYXRlIGZhbGxiYWNrIGlmIHNlbGVjdGlvbiBpcyBhbWJpZ3VvdXNcbiAgICBjb25zdCBhY3RpdmVUYWJsZSA9IGVkLnZpZXcuZG9tLnF1ZXJ5U2VsZWN0b3IoXG4gICAgICBcInRhYmxlLnNlbGVjdGVkLCB0YWJsZTpoYXMoLnNlbGVjdGVkKSwgdGFibGU6aGFzKC5zZWxlY3RlZC1jZWxsKSwgdGFibGU6aGFzKC5zZWxlY3RlZC1ub2RlKVwiXG4gICAgKTtcbiAgICBpZiAoYWN0aXZlVGFibGUpIHtcbiAgICAgIHJldHVybiBhY3RpdmVUYWJsZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IERPTVJlY3QoLTk5OTksIC05OTk5LCAwLCAwKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBleGVjdXRlQ29tbWFuZChlZGl0b3I6IEVkaXRvciwgY29tbWFuZDogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRvckNvbW1hbmRzLmV4ZWN1dGUoZWRpdG9yLCBjb21tYW5kLCAuLi5hcmdzKTtcbiAgfVxufVxuIl19