@flogeez/angular-tiptap-editor 3.1.3 → 3.1.5
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.
- package/CHANGELOG.md +24 -0
- package/README.md +2 -2
- package/esm2022/flogeez-angular-tiptap-editor.mjs +5 -0
- package/esm2022/lib/ate-editor.provider.mjs +38 -0
- package/esm2022/lib/components/bubble-menus/base/ate-base-bubble-menu.mjs +207 -0
- package/esm2022/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.mjs +137 -0
- package/esm2022/lib/components/bubble-menus/color/ate-color-bubble-menu.component.mjs +365 -0
- package/esm2022/lib/components/bubble-menus/image/ate-image-bubble-menu.component.mjs +309 -0
- package/esm2022/lib/components/bubble-menus/link/ate-link-bubble-menu.component.mjs +247 -0
- package/esm2022/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.mjs +126 -0
- package/esm2022/lib/components/bubble-menus/table/ate-table-bubble-menu.component.mjs +271 -0
- package/esm2022/lib/components/bubble-menus/text/ate-bubble-menu.component.mjs +272 -0
- package/esm2022/lib/components/color-picker/ate-color-picker.component.mjs +123 -0
- package/esm2022/lib/components/edit-toggle/ate-edit-toggle.component.mjs +42 -0
- package/esm2022/lib/components/editor/angular-tiptap-editor.component.mjs +1032 -0
- package/esm2022/lib/components/editor/ate-block-controls.component.mjs +256 -0
- package/esm2022/lib/components/slash-commands/ate-slash-commands.component.mjs +328 -0
- package/esm2022/lib/components/toolbar/ate-toolbar.component.mjs +531 -0
- package/esm2022/lib/components/ui/ate-button.component.mjs +91 -0
- package/esm2022/lib/components/ui/ate-separator.component.mjs +11 -0
- package/esm2022/lib/config/ate-editor.config.mjs +133 -0
- package/esm2022/lib/config/ate-global-config.token.mjs +6 -0
- package/esm2022/lib/config/ate-slash-commands.config.mjs +130 -0
- package/esm2022/lib/directives/ate-noop-value-accessor.directive.mjs +40 -0
- package/esm2022/lib/directives/ate-tooltip.directive.mjs +138 -0
- package/esm2022/lib/extensions/ate-block-controls.extension.mjs +156 -0
- package/esm2022/lib/extensions/ate-link-click-behavior.extension.mjs +32 -0
- package/esm2022/lib/extensions/ate-resizable-image.extension.mjs +277 -0
- package/esm2022/lib/extensions/ate-table.extension.mjs +27 -0
- package/esm2022/lib/extensions/ate-tiptap-state.extension.mjs +85 -0
- package/esm2022/lib/extensions/ate-upload-progress.extension.mjs +195 -0
- package/esm2022/lib/extensions/calculators/ate-discovery.calculator.mjs +62 -0
- package/esm2022/lib/extensions/calculators/ate-image.calculator.mjs +8 -0
- package/esm2022/lib/extensions/calculators/ate-marks.calculator.mjs +75 -0
- package/esm2022/lib/extensions/calculators/ate-selection.calculator.mjs +35 -0
- package/esm2022/lib/extensions/calculators/ate-structure.calculator.mjs +34 -0
- package/esm2022/lib/extensions/calculators/ate-table.calculator.mjs +38 -0
- package/esm2022/lib/models/ate-bubble-menu.model.mjs +53 -0
- package/esm2022/lib/models/ate-editor-config.model.mjs +2 -0
- package/esm2022/lib/models/ate-editor-state.model.mjs +90 -0
- package/esm2022/lib/models/ate-image.model.mjs +2 -0
- package/esm2022/lib/models/ate-slash-command.model.mjs +2 -0
- package/esm2022/lib/models/ate-toolbar.model.mjs +35 -0
- package/esm2022/lib/node-view/ate-angular-node-view.mjs +97 -0
- package/esm2022/lib/node-view/ate-injector.registry.mjs +16 -0
- package/esm2022/lib/node-view/ate-node-view.factory.mjs +125 -0
- package/esm2022/lib/node-view/ate-node-view.models.mjs +2 -0
- package/esm2022/lib/node-view/ate-node-view.renderer.mjs +154 -0
- package/esm2022/lib/node-view/ate-register-angular-component.mjs +49 -0
- package/esm2022/lib/services/ate-color-picker.service.mjs +194 -0
- package/esm2022/lib/services/ate-editor-commands.service.mjs +507 -0
- package/esm2022/lib/services/ate-export.service.mjs +71 -0
- package/esm2022/lib/services/ate-i18n.service.mjs +449 -0
- package/esm2022/lib/services/ate-image.service.mjs +459 -0
- package/esm2022/lib/services/ate-link.service.mjs +99 -0
- package/esm2022/lib/utils/ate-color.utils.mjs +60 -0
- package/esm2022/lib/utils/ate-markdown.utils.mjs +179 -0
- package/esm2022/public-api.mjs +41 -0
- package/fesm2022/flogeez-angular-tiptap-editor.mjs +627 -354
- package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
- package/index.d.ts +3 -1734
- package/lib/ate-editor.provider.d.ts +21 -0
- package/lib/components/bubble-menus/base/ate-base-bubble-menu.d.ts +71 -0
- package/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.d.ts +60 -0
- package/lib/components/bubble-menus/color/ate-color-bubble-menu.component.d.ts +77 -0
- package/lib/components/bubble-menus/image/ate-image-bubble-menu.component.d.ts +49 -0
- package/lib/components/bubble-menus/link/ate-link-bubble-menu.component.d.ts +55 -0
- package/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.d.ts +16 -0
- package/lib/components/bubble-menus/table/ate-table-bubble-menu.component.d.ts +25 -0
- package/lib/components/bubble-menus/text/ate-bubble-menu.component.d.ts +53 -0
- package/lib/components/color-picker/ate-color-picker.component.d.ts +54 -0
- package/lib/components/edit-toggle/ate-edit-toggle.component.d.ts +13 -0
- package/lib/components/editor/angular-tiptap-editor.component.d.ts +242 -0
- package/lib/components/editor/ate-block-controls.component.d.ts +44 -0
- package/lib/components/slash-commands/ate-slash-commands.component.d.ts +34 -0
- package/lib/components/toolbar/ate-toolbar.component.d.ts +47 -0
- package/lib/components/ui/ate-button.component.d.ts +25 -0
- package/lib/components/ui/ate-separator.component.d.ts +5 -0
- package/lib/config/ate-editor.config.d.ts +19 -0
- package/lib/config/ate-global-config.token.d.ts +6 -0
- package/lib/config/ate-slash-commands.config.d.ts +41 -0
- package/lib/directives/ate-noop-value-accessor.directive.d.ts +13 -0
- package/lib/directives/ate-tooltip.directive.d.ts +30 -0
- package/lib/extensions/ate-block-controls.extension.d.ts +10 -0
- package/lib/extensions/ate-link-click-behavior.extension.d.ts +2 -0
- package/lib/extensions/ate-resizable-image.extension.d.ts +27 -0
- package/lib/extensions/ate-table.extension.d.ts +2 -0
- package/lib/extensions/ate-tiptap-state.extension.d.ts +7 -0
- package/lib/extensions/ate-upload-progress.extension.d.ts +7 -0
- package/lib/extensions/calculators/ate-discovery.calculator.d.ts +7 -0
- package/lib/extensions/calculators/ate-image.calculator.d.ts +2 -0
- package/lib/extensions/calculators/ate-marks.calculator.d.ts +2 -0
- package/lib/extensions/calculators/ate-selection.calculator.d.ts +2 -0
- package/lib/extensions/calculators/ate-structure.calculator.d.ts +2 -0
- package/lib/extensions/calculators/ate-table.calculator.d.ts +2 -0
- package/lib/models/ate-bubble-menu.model.d.ts +33 -0
- package/lib/models/ate-editor-config.model.d.ts +113 -0
- package/lib/models/ate-editor-state.model.d.ts +109 -0
- package/lib/models/ate-image.model.d.ts +104 -0
- package/lib/models/ate-slash-command.model.d.ts +17 -0
- package/lib/models/ate-toolbar.model.d.ts +18 -0
- package/lib/node-view/ate-angular-node-view.d.ts +115 -0
- package/lib/node-view/ate-injector.registry.d.ts +3 -0
- package/lib/node-view/ate-node-view.factory.d.ts +10 -0
- package/lib/node-view/ate-node-view.models.d.ts +138 -0
- package/lib/node-view/ate-node-view.renderer.d.ts +23 -0
- package/lib/node-view/ate-register-angular-component.d.ts +35 -0
- package/lib/services/ate-color-picker.service.d.ts +65 -0
- package/lib/services/ate-editor-commands.service.d.ts +89 -0
- package/lib/services/ate-export.service.d.ts +27 -0
- package/lib/services/ate-i18n.service.d.ts +432 -0
- package/lib/services/ate-image.service.d.ts +82 -0
- package/lib/services/ate-link.service.d.ts +42 -0
- package/lib/utils/ate-color.utils.d.ts +12 -0
- package/lib/utils/ate-markdown.utils.d.ts +4 -0
- package/package.json +3 -1
- package/public-api.d.ts +32 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { Component, input, ChangeDetectionStrategy, computed, inject } from "@angular/core";
|
|
2
|
+
import { AteButtonComponent } from "../../ui/ate-button.component";
|
|
3
|
+
import { AteSeparatorComponent } from "../../ui/ate-separator.component";
|
|
4
|
+
import { AteImageService } from "../../../services/ate-image.service";
|
|
5
|
+
import { ATE_IMAGE_BUBBLE_MENU_KEYS, } from "../../../models/ate-bubble-menu.model";
|
|
6
|
+
import { ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG } from "../../../config/ate-editor.config";
|
|
7
|
+
import { AteBaseBubbleMenu } from "../base/ate-base-bubble-menu";
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
export class AteImageBubbleMenuComponent extends AteBaseBubbleMenu {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(...arguments);
|
|
12
|
+
this.t = this.i18nService.imageUpload;
|
|
13
|
+
this.imageService = inject(AteImageService);
|
|
14
|
+
this.config = input(ATE_DEFAULT_IMAGE_BUBBLE_MENU_CONFIG);
|
|
15
|
+
this.imageUpload = input({});
|
|
16
|
+
this.imageBubbleMenuConfig = computed(() => {
|
|
17
|
+
const c = this.config();
|
|
18
|
+
const result = {};
|
|
19
|
+
ATE_IMAGE_BUBBLE_MENU_KEYS.forEach(key => {
|
|
20
|
+
result[key] = c[key] ?? true;
|
|
21
|
+
});
|
|
22
|
+
return result;
|
|
23
|
+
});
|
|
24
|
+
this.hasAlignmentButtons = computed(() => this.imageBubbleMenuConfig().alignLeft ||
|
|
25
|
+
this.imageBubbleMenuConfig().alignCenter ||
|
|
26
|
+
this.imageBubbleMenuConfig().alignRight);
|
|
27
|
+
this.hasResizeButtons = computed(() => {
|
|
28
|
+
const c = this.imageBubbleMenuConfig();
|
|
29
|
+
return c.resizeSmall || c.resizeMedium || c.resizeLarge || c.resizeOriginal;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
shouldShow() {
|
|
33
|
+
const { nodes, isEditable, isFocused, selection } = this.state();
|
|
34
|
+
if (this.editorCommands.linkEditMode() || this.editorCommands.colorEditMode()) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
// In read-only mode, focus reporting can be unreliable,
|
|
38
|
+
// so we show the menu as long as an image is selected.
|
|
39
|
+
if (!isEditable) {
|
|
40
|
+
return nodes.isImage && selection.type === "node";
|
|
41
|
+
}
|
|
42
|
+
return nodes.isImage && isFocused;
|
|
43
|
+
}
|
|
44
|
+
getSelectionRect() {
|
|
45
|
+
const ed = this.editor();
|
|
46
|
+
if (!ed) {
|
|
47
|
+
return new DOMRect(0, 0, 0, 0);
|
|
48
|
+
}
|
|
49
|
+
const { from } = ed.state.selection;
|
|
50
|
+
try {
|
|
51
|
+
// 1. Direct ProseMirror approach: get DOM node at position
|
|
52
|
+
const dom = ed.view.nodeDOM(from);
|
|
53
|
+
if (dom instanceof HTMLElement) {
|
|
54
|
+
// If it's a resizable container, look for the image inside
|
|
55
|
+
if (dom.classList.contains("resizable-image-container")) {
|
|
56
|
+
const img = dom.querySelector("img");
|
|
57
|
+
if (img) {
|
|
58
|
+
return img.getBoundingClientRect();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return dom.getBoundingClientRect();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (_e) {
|
|
65
|
+
// Fallback if nodeDOM fails
|
|
66
|
+
}
|
|
67
|
+
// 2. Ultimate fallback: find selected image in DOM
|
|
68
|
+
const selectedImg = ed.view.dom.querySelector("img.selected, .resizable-image-container.selected img");
|
|
69
|
+
if (selectedImg) {
|
|
70
|
+
return selectedImg.getBoundingClientRect();
|
|
71
|
+
}
|
|
72
|
+
// If nothing found at all
|
|
73
|
+
return new DOMRect(-9999, -9999, 0, 0);
|
|
74
|
+
}
|
|
75
|
+
executeCommand(editor, command, ..._args) {
|
|
76
|
+
switch (command) {
|
|
77
|
+
case "changeImage":
|
|
78
|
+
this.changeImage();
|
|
79
|
+
break;
|
|
80
|
+
case "downloadImage":
|
|
81
|
+
this.editorCommands.downloadImage(editor);
|
|
82
|
+
break;
|
|
83
|
+
case "resizeSmall":
|
|
84
|
+
this.imageService.resizeImageToSmall(editor);
|
|
85
|
+
break;
|
|
86
|
+
case "resizeMedium":
|
|
87
|
+
this.imageService.resizeImageToMedium(editor);
|
|
88
|
+
break;
|
|
89
|
+
case "resizeLarge":
|
|
90
|
+
this.imageService.resizeImageToLarge(editor);
|
|
91
|
+
break;
|
|
92
|
+
case "resizeOriginal":
|
|
93
|
+
this.imageService.resizeImageToOriginal(editor);
|
|
94
|
+
break;
|
|
95
|
+
case "deleteImage":
|
|
96
|
+
this.deleteImage();
|
|
97
|
+
break;
|
|
98
|
+
case "alignLeft":
|
|
99
|
+
editor.chain().focus().setTextAlign("left").run();
|
|
100
|
+
break;
|
|
101
|
+
case "alignCenter":
|
|
102
|
+
editor.chain().focus().setTextAlign("center").run();
|
|
103
|
+
break;
|
|
104
|
+
case "alignRight":
|
|
105
|
+
editor.chain().focus().setTextAlign("right").run();
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async changeImage() {
|
|
110
|
+
const ed = this.editor();
|
|
111
|
+
if (!ed) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
// Use dedicated method to replace an existing image
|
|
116
|
+
await this.imageService.selectAndReplaceImage(ed, this.imageUpload());
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
console.error(this.i18nService.imageUpload().uploadError, error);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
deleteImage() {
|
|
123
|
+
const ed = this.editor();
|
|
124
|
+
if (ed) {
|
|
125
|
+
ed.chain().focus().deleteSelection().run();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteImageBubbleMenuComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
129
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AteImageBubbleMenuComponent, isStandalone: true, selector: "ate-image-bubble-menu", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, imageUpload: { classPropertyName: "imageUpload", publicName: "imageUpload", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
|
|
130
|
+
<div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
|
|
131
|
+
@if (imageBubbleMenuConfig().changeImage && editor().isEditable) {
|
|
132
|
+
<ate-button
|
|
133
|
+
icon="drive_file_rename_outline"
|
|
134
|
+
[title]="t().changeImage"
|
|
135
|
+
(buttonClick)="onCommand('changeImage', $event)"></ate-button>
|
|
136
|
+
}
|
|
137
|
+
@if (imageBubbleMenuConfig().downloadImage) {
|
|
138
|
+
<ate-button
|
|
139
|
+
icon="download"
|
|
140
|
+
[title]="t().downloadImage"
|
|
141
|
+
(buttonClick)="onCommand('downloadImage', $event)"></ate-button>
|
|
142
|
+
}
|
|
143
|
+
@if (imageBubbleMenuConfig().separator && hasResizeButtons() && editor().isEditable) {
|
|
144
|
+
<ate-separator />
|
|
145
|
+
}
|
|
146
|
+
@if (imageBubbleMenuConfig().resizeSmall && editor().isEditable) {
|
|
147
|
+
<ate-button
|
|
148
|
+
icon="crop_square"
|
|
149
|
+
iconSize="small"
|
|
150
|
+
[title]="t().resizeSmall"
|
|
151
|
+
(buttonClick)="onCommand('resizeSmall', $event)"></ate-button>
|
|
152
|
+
}
|
|
153
|
+
@if (imageBubbleMenuConfig().resizeMedium && editor().isEditable) {
|
|
154
|
+
<ate-button
|
|
155
|
+
icon="crop_square"
|
|
156
|
+
iconSize="medium"
|
|
157
|
+
[title]="t().resizeMedium"
|
|
158
|
+
(buttonClick)="onCommand('resizeMedium', $event)"></ate-button>
|
|
159
|
+
}
|
|
160
|
+
@if (imageBubbleMenuConfig().resizeLarge && editor().isEditable) {
|
|
161
|
+
<ate-button
|
|
162
|
+
icon="crop_square"
|
|
163
|
+
iconSize="large"
|
|
164
|
+
[title]="t().resizeLarge"
|
|
165
|
+
(buttonClick)="onCommand('resizeLarge', $event)"></ate-button>
|
|
166
|
+
}
|
|
167
|
+
@if (imageBubbleMenuConfig().resizeOriginal && editor().isEditable) {
|
|
168
|
+
<ate-button
|
|
169
|
+
icon="photo_size_select_actual"
|
|
170
|
+
[title]="t().resizeOriginal"
|
|
171
|
+
(buttonClick)="onCommand('resizeOriginal', $event)"></ate-button>
|
|
172
|
+
}
|
|
173
|
+
@if (imageBubbleMenuConfig().separator && hasAlignmentButtons() && editor().isEditable) {
|
|
174
|
+
<ate-separator />
|
|
175
|
+
}
|
|
176
|
+
@if (imageBubbleMenuConfig().alignLeft && editor().isEditable) {
|
|
177
|
+
<ate-button
|
|
178
|
+
icon="format_align_left"
|
|
179
|
+
[title]="t().alignLeft"
|
|
180
|
+
[active]="editor().isActive({ textAlign: 'left' })"
|
|
181
|
+
(buttonClick)="onCommand('alignLeft', $event)"></ate-button>
|
|
182
|
+
}
|
|
183
|
+
@if (imageBubbleMenuConfig().alignCenter && editor().isEditable) {
|
|
184
|
+
<ate-button
|
|
185
|
+
icon="format_align_center"
|
|
186
|
+
[title]="t().alignCenter"
|
|
187
|
+
[active]="editor().isActive({ textAlign: 'center' })"
|
|
188
|
+
(buttonClick)="onCommand('alignCenter', $event)"></ate-button>
|
|
189
|
+
}
|
|
190
|
+
@if (imageBubbleMenuConfig().alignRight && editor().isEditable) {
|
|
191
|
+
<ate-button
|
|
192
|
+
icon="format_align_right"
|
|
193
|
+
[title]="t().alignRight"
|
|
194
|
+
[active]="editor().isActive({ textAlign: 'right' })"
|
|
195
|
+
(buttonClick)="onCommand('alignRight', $event)"></ate-button>
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
@if (
|
|
199
|
+
imageBubbleMenuConfig().separator &&
|
|
200
|
+
imageBubbleMenuConfig().deleteImage &&
|
|
201
|
+
editor().isEditable
|
|
202
|
+
) {
|
|
203
|
+
<ate-separator />
|
|
204
|
+
}
|
|
205
|
+
@if (imageBubbleMenuConfig().deleteImage && editor().isEditable) {
|
|
206
|
+
<ate-button
|
|
207
|
+
icon="delete"
|
|
208
|
+
[title]="t().deleteImage"
|
|
209
|
+
variant="danger"
|
|
210
|
+
(buttonClick)="onCommand('deleteImage', $event)"></ate-button>
|
|
211
|
+
}
|
|
212
|
+
</div>
|
|
213
|
+
`, isInline: true, dependencies: [{ 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 }); }
|
|
214
|
+
}
|
|
215
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteImageBubbleMenuComponent, decorators: [{
|
|
216
|
+
type: Component,
|
|
217
|
+
args: [{
|
|
218
|
+
selector: "ate-image-bubble-menu",
|
|
219
|
+
standalone: true,
|
|
220
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
221
|
+
imports: [AteButtonComponent, AteSeparatorComponent],
|
|
222
|
+
template: `
|
|
223
|
+
<div #menuRef class="bubble-menu" (mousedown)="$event.preventDefault()">
|
|
224
|
+
@if (imageBubbleMenuConfig().changeImage && editor().isEditable) {
|
|
225
|
+
<ate-button
|
|
226
|
+
icon="drive_file_rename_outline"
|
|
227
|
+
[title]="t().changeImage"
|
|
228
|
+
(buttonClick)="onCommand('changeImage', $event)"></ate-button>
|
|
229
|
+
}
|
|
230
|
+
@if (imageBubbleMenuConfig().downloadImage) {
|
|
231
|
+
<ate-button
|
|
232
|
+
icon="download"
|
|
233
|
+
[title]="t().downloadImage"
|
|
234
|
+
(buttonClick)="onCommand('downloadImage', $event)"></ate-button>
|
|
235
|
+
}
|
|
236
|
+
@if (imageBubbleMenuConfig().separator && hasResizeButtons() && editor().isEditable) {
|
|
237
|
+
<ate-separator />
|
|
238
|
+
}
|
|
239
|
+
@if (imageBubbleMenuConfig().resizeSmall && editor().isEditable) {
|
|
240
|
+
<ate-button
|
|
241
|
+
icon="crop_square"
|
|
242
|
+
iconSize="small"
|
|
243
|
+
[title]="t().resizeSmall"
|
|
244
|
+
(buttonClick)="onCommand('resizeSmall', $event)"></ate-button>
|
|
245
|
+
}
|
|
246
|
+
@if (imageBubbleMenuConfig().resizeMedium && editor().isEditable) {
|
|
247
|
+
<ate-button
|
|
248
|
+
icon="crop_square"
|
|
249
|
+
iconSize="medium"
|
|
250
|
+
[title]="t().resizeMedium"
|
|
251
|
+
(buttonClick)="onCommand('resizeMedium', $event)"></ate-button>
|
|
252
|
+
}
|
|
253
|
+
@if (imageBubbleMenuConfig().resizeLarge && editor().isEditable) {
|
|
254
|
+
<ate-button
|
|
255
|
+
icon="crop_square"
|
|
256
|
+
iconSize="large"
|
|
257
|
+
[title]="t().resizeLarge"
|
|
258
|
+
(buttonClick)="onCommand('resizeLarge', $event)"></ate-button>
|
|
259
|
+
}
|
|
260
|
+
@if (imageBubbleMenuConfig().resizeOriginal && editor().isEditable) {
|
|
261
|
+
<ate-button
|
|
262
|
+
icon="photo_size_select_actual"
|
|
263
|
+
[title]="t().resizeOriginal"
|
|
264
|
+
(buttonClick)="onCommand('resizeOriginal', $event)"></ate-button>
|
|
265
|
+
}
|
|
266
|
+
@if (imageBubbleMenuConfig().separator && hasAlignmentButtons() && editor().isEditable) {
|
|
267
|
+
<ate-separator />
|
|
268
|
+
}
|
|
269
|
+
@if (imageBubbleMenuConfig().alignLeft && editor().isEditable) {
|
|
270
|
+
<ate-button
|
|
271
|
+
icon="format_align_left"
|
|
272
|
+
[title]="t().alignLeft"
|
|
273
|
+
[active]="editor().isActive({ textAlign: 'left' })"
|
|
274
|
+
(buttonClick)="onCommand('alignLeft', $event)"></ate-button>
|
|
275
|
+
}
|
|
276
|
+
@if (imageBubbleMenuConfig().alignCenter && editor().isEditable) {
|
|
277
|
+
<ate-button
|
|
278
|
+
icon="format_align_center"
|
|
279
|
+
[title]="t().alignCenter"
|
|
280
|
+
[active]="editor().isActive({ textAlign: 'center' })"
|
|
281
|
+
(buttonClick)="onCommand('alignCenter', $event)"></ate-button>
|
|
282
|
+
}
|
|
283
|
+
@if (imageBubbleMenuConfig().alignRight && editor().isEditable) {
|
|
284
|
+
<ate-button
|
|
285
|
+
icon="format_align_right"
|
|
286
|
+
[title]="t().alignRight"
|
|
287
|
+
[active]="editor().isActive({ textAlign: 'right' })"
|
|
288
|
+
(buttonClick)="onCommand('alignRight', $event)"></ate-button>
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
@if (
|
|
292
|
+
imageBubbleMenuConfig().separator &&
|
|
293
|
+
imageBubbleMenuConfig().deleteImage &&
|
|
294
|
+
editor().isEditable
|
|
295
|
+
) {
|
|
296
|
+
<ate-separator />
|
|
297
|
+
}
|
|
298
|
+
@if (imageBubbleMenuConfig().deleteImage && editor().isEditable) {
|
|
299
|
+
<ate-button
|
|
300
|
+
icon="delete"
|
|
301
|
+
[title]="t().deleteImage"
|
|
302
|
+
variant="danger"
|
|
303
|
+
(buttonClick)="onCommand('deleteImage', $event)"></ate-button>
|
|
304
|
+
}
|
|
305
|
+
</div>
|
|
306
|
+
`,
|
|
307
|
+
}]
|
|
308
|
+
}] });
|
|
309
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLWltYWdlLWJ1YmJsZS1tZW51LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdGlwdGFwLWVkaXRvci9zcmMvbGliL2NvbXBvbmVudHMvYnViYmxlLW1lbnVzL2ltYWdlL2F0ZS1pbWFnZS1idWJibGUtbWVudS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsdUJBQXVCLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU1RixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNuRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUN6RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDdEUsT0FBTyxFQUVMLDBCQUEwQixHQUMzQixNQUFNLHVDQUF1QyxDQUFDO0FBQy9DLE9BQU8sRUFBRSxvQ0FBb0MsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDOztBQThGakUsTUFBTSxPQUFPLDJCQUE0QixTQUFRLGlCQUFpQjtJQTNGbEU7O1FBNEZXLE1BQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQztRQUN6QixpQkFBWSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUV4RCxXQUFNLEdBQUcsS0FBSyxDQUEyQixvQ0FBb0MsQ0FBQyxDQUFDO1FBRS9FLGdCQUFXLEdBQUcsS0FBSyxDQUF3QixFQUFFLENBQUMsQ0FBQztRQUUvQywwQkFBcUIsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ3BDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN4QixNQUFN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QUFDO29CQUNULFFBQVEsRUFBRSx1QkFBdUI7b0JBQ2pDLFVBQVUsRUFBRSxJQUFJO29CQUNoQixlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtvQkFDL0MsT0FBTyxFQUFFLENBQUMsa0JBQWtCLEVBQUUscUJBQXFCLENBQUM7b0JBQ3BELFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0ZUO2lCQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBpbnB1dCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIGNvbXB1dGVkLCBpbmplY3QgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgdHlwZSBFZGl0b3IgfSBmcm9tIFwiQHRpcHRhcC9jb3JlXCI7XG5pbXBvcnQgeyBBdGVCdXR0b25Db21wb25lbnQgfSBmcm9tIFwiLi4vLi4vdWkvYXRlLWJ1dHRvbi5jb21wb25lbnRcIjtcbmltcG9ydCB7IEF0ZVNlcGFyYXRvckNvbXBvbmVudCB9IGZyb20gXCIuLi8uLi91aS9hdGUtc2VwYXJhdG9yLmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgQXRlSW1hZ2VTZXJ2aWNlIH0gZnJvbSBcIi4uLy4uLy4uL3NlcnZpY2VzL2F0ZS1pbWFnZS5zZXJ2aWNlXCI7XG5pbXBvcnQge1xuICBBdGVJbWFnZUJ1YmJsZU1lbnVDb25maWcsXG4gIEFURV9JTUFHRV9CVUJCTEVfTUVOVV9LRVlTLFxufSBmcm9tIFwiLi4vLi4vLi4vbW9kZWxzL2F0ZS1idWJibGUtbWVudS5tb2RlbFwiO1xuaW1wb3J0IHsgQVRFX0RFRkFVTFRfSU1BR0VfQlVCQkxFX01FTlVfQ09ORklHIH0gZnJvbSBcIi4uLy4uLy4uL2NvbmZpZy9hdGUtZWRpdG9yLmNvbmZpZ1wiO1xuaW1wb3J0IHsgQXRlQmFzZUJ1YmJsZU1lbnUgfSBmcm9tIFwiLi4vYmFzZS9hdGUtYmFzZS1idWJibGUtbWVudVwiO1xuaW1wb3J0IHsgQXRlSW1hZ2VVcGxvYWRPcHRpb25zIH0gZnJvbSBcIi4uLy4uLy4uL21vZGVscy9hdGUtaW1hZ2UubW9kZWxcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcImF0ZS1pbWFnZS1idWJibGUtbWVudVwiLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaW1wb3J0czogW0F0ZUJ1dHRvbkNvbXBvbmVudCwgQXRlU2VwYXJhdG9yQ29tcG9uZW50XSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2ICNtZW51UmVmIGNsYXNzPVwiYnViYmxlLW1lbnVcIiAobW91c2Vkb3duKT1cIiRldmVudC5wcmV2ZW50RGVmYXVsdCgpXCI+XG4gICAgICBAaWYgKGltYWdlQnViYmxlTWVudUNvbmZpZygpLmNoYW5nZUltYWdlICYmIGVkaXRvcigpLmlzRWRpdGFibGUpIHtcbiAgICAgICAgPGF0ZS1idXR0b25cbiAgICAgICAgICBpY29uPVwiZHJpdmVfZmlsZV9yZW5hbWVfb3V0bGluZVwiXG4gICAgICAgICAgW3RpdGxlXT1cInQoKS5jaGFuZ2VJbWFnZVwiXG4gICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQ29tbWFuZCgnY2hhbmdlSW1hZ2UnLCAkZXZlbnQpXCI+PC9hdGUtYnV0dG9uPlxuICAgICAgfVxuICAgICAgQGlmIChpbWFnZUJ1YmJsZU1lbnVDb25maWcoKS5kb3dubG9hZEltYWdlKSB7XG4gICAgICAgIDxhdGUtYnV0dG9uXG4gICAgICAgICAgaWNvbj1cImRvd25sb2FkXCJcbiAgICAgICAgICBbdGl0bGVdPVwidCgpLmRvd25sb2FkSW1hZ2VcIlxuICAgICAgICAgIChidXR0b25DbGljayk9XCJvbkNvbW1hbmQoJ2Rvd25sb2FkSW1hZ2UnLCAkZXZlbnQpXCI+PC9hdGUtYnV0dG9uPlxuICAgICAgfVxuICAgICAgQGlmIChpbWFnZUJ1YmJsZU1lbnVDb25maWcoKS5zZXBhcmF0b3IgJiYgaGFzUmVzaXplQnV0dG9ucygpICYmIGVkaXRvcigpLmlzRWRpdGFibGUpIHtcbiAgICAgICAgPGF0ZS1zZXBhcmF0b3IgLz5cbiAgICAgIH1cbiAgICAgIEBpZiAoaW1hZ2VCdWJibGVNZW51Q29uZmlnKCkucmVzaXplU21hbGwgJiYgZWRpdG9yKCkuaXNFZGl0YWJsZSkge1xuICAgICAgICA8YXRlLWJ1dHRvblxuICAgICAgICAgIGljb249XCJjcm9wX3NxdWFyZVwiXG4gICAgICAgICAgaWNvblNpemU9XCJzbWFsbFwiXG4gICAgICAgICAgW3RpdGxlXT1cInQoKS5yZXNpemVTbWFsbFwiXG4gICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQ29tbWFuZCgncmVzaXplU21hbGwnLCAkZXZlbnQpXCI+PC9hdGUtYnV0dG9uPlxuICAgICAgfVxuICAgICAgQGlmIChpbWFnZUJ1YmJsZU1lbnVDb25maWcoKS5yZXNpemVNZWRpdW0gJiYgZWRpdG9yKCkuaXNFZGl0YWJsZSkge1xuICAgICAgICA8YXRlLWJ1dHRvblxuICAgICAgICAgIGljb249XCJjcm9wX3NxdWFyZVwiXG4gICAgICAgICAgaWNvblNpemU9XCJtZWRpdW1cIlxuICAgICAgICAgIFt0aXRsZV09XCJ0KCkucmVzaXplTWVkaXVtXCJcbiAgICAgICAgICAoYnV0dG9uQ2xpY2spPVwib25Db21tYW5kKCdyZXNpemVNZWRpdW0nLCAkZXZlbnQpXCI+PC9hdGUtYnV0dG9uPlxuICAgICAgfVxuICAgICAgQGlmIChpbWFnZUJ1YmJsZU1lbnVDb25maWcoKS5yZXNpemVMYXJnZSAmJiBlZGl0b3IoKS5pc0VkaXRhYmxlKSB7XG4gICAgICAgIDxhdGUtYnV0dG9uXG4gICAgICAgICAgaWNvbj1cImNyb3Bfc3F1YXJlXCJcbiAgICAgICAgICBpY29uU2l6ZT1cImxhcmdlXCJcbiAgICAgICAgICBbdGl0bGVdPVwidCgpLnJlc2l6ZUxhcmdlXCJcbiAgICAgICAgICAoYnV0dG9uQ2xpY2spPVwib25Db21tYW5kKCdyZXNpemVMYXJnZScsICRldmVudClcIj48L2F0ZS1idXR0b24+XG4gICAgICB9XG4gICAgICBAaWYgKGltYWdlQnViYmxlTWVudUNvbmZpZygpLnJlc2l6ZU9yaWdpbmFsICYmIGVkaXRvcigpLmlzRWRpdGFibGUpIHtcbiAgICAgICAgPGF0ZS1idXR0b25cbiAgICAgICAgICBpY29uPVwicGhvdG9fc2l6ZV9zZWxlY3RfYWN0dWFsXCJcbiAgICAgICAgICBbdGl0bGVdPVwidCgpLnJlc2l6ZU9yaWdpbmFsXCJcbiAgICAgICAgICAoYnV0dG9uQ2xpY2spPVwib25Db21tYW5kKCdyZXNpemVPcmlnaW5hbCcsICRldmVudClcIj48L2F0ZS1idXR0b24+XG4gICAgICB9XG4gICAgICBAaWYgKGltYWdlQnViYmxlTWVudUNvbmZpZygpLnNlcGFyYXRvciAmJiBoYXNBbGlnbm1lbnRCdXR0b25zKCkgJiYgZWRpdG9yKCkuaXNFZGl0YWJsZSkge1xuICAgICAgICA8YXRlLXNlcGFyYXRvciAvPlxuICAgICAgfVxuICAgICAgQGlmIChpbWFnZUJ1YmJsZU1lbnVDb25maWcoKS5hbGlnbkxlZnQgJiYgZWRpdG9yKCkuaXNFZGl0YWJsZSkge1xuICAgICAgICA8YXRlLWJ1dHRvblxuICAgICAgICAgIGljb249XCJmb3JtYXRfYWxpZ25fbGVmdFwiXG4gICAgICAgICAgW3RpdGxlXT1cInQoKS5hbGlnbkxlZnRcIlxuICAgICAgICAgIFthY3RpdmVdPVwiZWRpdG9yKCkuaXNBY3RpdmUoeyB0ZXh0QWxpZ246ICdsZWZ0JyB9KVwiXG4gICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQ29tbWFuZCgnYWxpZ25MZWZ0JywgJGV2ZW50KVwiPjwvYXRlLWJ1dHRvbj5cbiAgICAgIH1cbiAgICAgIEBpZiAoaW1hZ2VCdWJibGVNZW51Q29uZmlnKCkuYWxpZ25DZW50ZXIgJiYgZWRpdG9yKCkuaXNFZGl0YWJsZSkge1xuICAgICAgICA8YXRlLWJ1dHRvblxuICAgICAgICAgIGljb249XCJmb3JtYXRfYWxpZ25fY2VudGVyXCJcbiAgICAgICAgICBbdGl0bGVdPVwidCgpLmFsaWduQ2VudGVyXCJcbiAgICAgICAgICBbYWN0aXZlXT1cImVkaXRvcigpLmlzQWN0aXZlKHsgdGV4dEFsaWduOiAnY2VudGVyJyB9KVwiXG4gICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQ29tbWFuZCgnYWxpZ25DZW50ZXInLCAkZXZlbnQpXCI+PC9hdGUtYnV0dG9uPlxuICAgICAgfVxuICAgICAgQGlmIChpbWFnZUJ1YmJsZU1lbnVDb25maWcoKS5hbGlnblJpZ2h0ICYmIGVkaXRvcigpLmlzRWRpdGFibGUpIHtcbiAgICAgICAgPGF0ZS1idXR0b25cbiAgICAgICAgICBpY29uPVwiZm9ybWF0X2FsaWduX3JpZ2h0XCJcbiAgICAgICAgICBbdGl0bGVdPVwidCgpLmFsaWduUmlnaHRcIlxuICAgICAgICAgIFthY3RpdmVdPVwiZWRpdG9yKCkuaXNBY3RpdmUoeyB0ZXh0QWxpZ246ICdyaWdodCcgfSlcIlxuICAgICAgICAgIChidXR0b25DbGljayk9XCJvbkNvbW1hbmQoJ2FsaWduUmlnaHQnLCAkZXZlbnQpXCI+PC9hdGUtYnV0dG9uPlxuICAgICAgfVxuXG4gICAgICBAaWYgKFxuICAgICAgICBpbWFnZUJ1YmJsZU1lbnVDb25maWcoKS5zZXBhcmF0b3IgJiZcbiAgICAgICAgaW1hZ2VCdWJibGVNZW51Q29uZmlnKCkuZGVsZXRlSW1hZ2UgJiZcbiAgICAgICAgZWRpdG9yKCkuaXNFZGl0YWJsZVxuICAgICAgKSB7XG4gICAgICAgIDxhdGUtc2VwYXJhdG9yIC8+XG4gICAgICB9XG4gICAgICBAaWYgKGltYWdlQnViYmxlTWVudUNvbmZpZygpLmRlbGV0ZUltYWdlICYmIGVkaXRvcigpLmlzRWRpdGFibGUpIHtcbiAgICAgICAgPGF0ZS1idXR0b25cbiAgICAgICAgICBpY29uPVwiZGVsZXRlXCJcbiAgICAgICAgICBbdGl0bGVdPVwidCgpLmRlbGV0ZUltYWdlXCJcbiAgICAgICAgICB2YXJpYW50PVwiZGFuZ2VyXCJcbiAgICAgICAgICAoYnV0dG9uQ2xpY2spPVwib25Db21tYW5kKCdkZWxldGVJbWFnZScsICRldmVudClcIj48L2F0ZS1idXR0b24+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gIGAsXG59KVxuZXhwb3J0IGNsYXNzIEF0ZUltYWdlQnViYmxlTWVudUNvbXBvbmVudCBleHRlbmRzIEF0ZUJhc2VCdWJibGVNZW51IHtcbiAgcmVhZG9ubHkgdCA9IHRoaXMuaTE4blNlcnZpY2UuaW1hZ2VVcGxvYWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgaW1hZ2VTZXJ2aWNlID0gaW5qZWN0KEF0ZUltYWdlU2VydmljZSk7XG5cbiAgY29uZmlnID0gaW5wdXQ8QXRlSW1hZ2VCdWJibGVNZW51Q29uZmlnPihBVEVfREVGQVVMVF9JTUFHRV9CVUJCTEVfTUVOVV9DT05GSUcpO1xuXG4gIGltYWdlVXBsb2FkID0gaW5wdXQ8QXRlSW1hZ2VVcGxvYWRPcHRpb25zPih7fSk7XG5cbiAgaW1hZ2VCdWJibGVNZW51Q29uZmlnID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGMgPSB0aGlzLmNvbmZpZygpO1xuICAgIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgYm9vbGVhbj4gPSB7fTtcbiAgICBBVEVfSU1BR0VfQlVCQkxFX01FTlVfS0VZUy5mb3JFYWNoKGtleSA9PiB7XG4gICAgICByZXN1bHRba2V5XSA9IGNba2V5XSA/PyB0cnVlO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQgYXMgUmVxdWlyZWQ8QXRlSW1hZ2VCdWJibGVNZW51Q29uZmlnPjtcbiAgfSk7XG5cbiAgaGFzQWxpZ25tZW50QnV0dG9ucyA9IGNvbXB1dGVkKFxuICAgICgpID0+XG4gICAgICB0aGlzLmltYWdlQnViYmxlTWVudUNvbmZpZygpLmFsaWduTGVmdCB8fFxuICAgICAgdGhpcy5pbWFnZUJ1YmJsZU1lbnVDb25maWcoKS5hbGlnbkNlbnRlciB8fFxuICAgICAgdGhpcy5pbWFnZUJ1YmJsZU1lbnVDb25maWcoKS5hbGlnblJpZ2h0XG4gICk7XG5cbiAgaGFzUmVzaXplQnV0dG9ucyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBjID0gdGhpcy5pbWFnZUJ1YmJsZU1lbnVDb25maWcoKTtcbiAgICByZXR1cm4gYy5yZXNpemVTbWFsbCB8fCBjLnJlc2l6ZU1lZGl1bSB8fCBjLnJlc2l6ZUxhcmdlIHx8IGMucmVzaXplT3JpZ2luYWw7XG4gIH0pO1xuXG4gIG92ZXJyaWRlIHNob3VsZFNob3coKTogYm9vbGVhbiB7XG4gICAgY29uc3QgeyBub2RlcywgaXNFZGl0YWJsZSwgaXNGb2N1c2VkLCBzZWxlY3Rpb24gfSA9IHRoaXMuc3RhdGUoKTtcblxuICAgIGlmICh0aGlzLmVkaXRvckNvbW1hbmRzLmxpbmtFZGl0TW9kZSgpIHx8IHRoaXMuZWRpdG9yQ29tbWFuZHMuY29sb3JFZGl0TW9kZSgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gSW4gcmVhZC1vbmx5IG1vZGUsIGZvY3VzIHJlcG9ydGluZyBjYW4gYmUgdW5yZWxpYWJsZSxcbiAgICAvLyBzbyB3ZSBzaG93IHRoZSBtZW51IGFzIGxvbmcgYXMgYW4gaW1hZ2UgaXMgc2VsZWN0ZWQuXG4gICAgaWYgKCFpc0VkaXRhYmxlKSB7XG4gICAgICByZXR1cm4gbm9kZXMuaXNJbWFnZSAmJiBzZWxlY3Rpb24udHlwZSA9PT0gXCJub2RlXCI7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGVzLmlzSW1hZ2UgJiYgaXNGb2N1c2VkO1xuICB9XG5cbiAgb3ZlcnJpZGUgZ2V0U2VsZWN0aW9uUmVjdCgpOiBET01SZWN0IHtcbiAgICBjb25zdCBlZCA9IHRoaXMuZWRpdG9yKCk7XG4gICAgaWYgKCFlZCkge1xuICAgICAgcmV0dXJuIG5ldyBET01SZWN0KDAsIDAsIDAsIDApO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZnJvbSB9ID0gZWQuc3RhdGUuc2VsZWN0aW9uO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIDEuIERpcmVjdCBQcm9zZU1pcnJvciBhcHByb2FjaDogZ2V0IERPTSBub2RlIGF0IHBvc2l0aW9uXG4gICAgICBjb25zdCBkb20gPSBlZC52aWV3Lm5vZGVET00oZnJvbSk7XG4gICAgICBpZiAoZG9tIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgLy8gSWYgaXQncyBhIHJlc2l6YWJsZSBjb250YWluZXIsIGxvb2sgZm9yIHRoZSBpbWFnZSBpbnNpZGVcbiAgICAgICAgaWYgKGRvbS5jbGFzc0xpc3QuY29udGFpbnMoXCJyZXNpemFibGUtaW1hZ2UtY29udGFpbmVyXCIpKSB7XG4gICAgICAgICAgY29uc3QgaW1nID0gZG9tLnF1ZXJ5U2VsZWN0b3IoXCJpbWdcIik7XG4gICAgICAgICAgaWYgKGltZykge1xuICAgICAgICAgICAgcmV0dXJuIGltZy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRvbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChfZSkge1xuICAgICAgLy8gRmFsbGJhY2sgaWYgbm9kZURPTSBmYWlsc1xuICAgIH1cblxuICAgIC8vIDIuIFVsdGltYXRlIGZhbGxiYWNrOiBmaW5kIHNlbGVjdGVkIGltYWdlIGluIERPTVxuICAgIGNvbnN0IHNlbGVjdGVkSW1nID0gZWQudmlldy5kb20ucXVlcnlTZWxlY3RvcihcbiAgICAgIFwiaW1nLnNlbGVjdGVkLCAucmVzaXphYmxlLWltYWdlLWNvbnRhaW5lci5zZWxlY3RlZCBpbWdcIlxuICAgICk7XG4gICAgaWYgKHNlbGVjdGVkSW1nKSB7XG4gICAgICByZXR1cm4gc2VsZWN0ZWRJbWcuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxuXG4gICAgLy8gSWYgbm90aGluZyBmb3VuZCBhdCBhbGxcbiAgICByZXR1cm4gbmV3IERPTVJlY3QoLTk5OTksIC05OTk5LCAwLCAwKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBleGVjdXRlQ29tbWFuZChlZGl0b3I6IEVkaXRvciwgY29tbWFuZDogc3RyaW5nLCAuLi5fYXJnczogdW5rbm93bltdKTogdm9pZCB7XG4gICAgc3dpdGNoIChjb21tYW5kKSB7XG4gICAgICBjYXNlIFwiY2hhbmdlSW1hZ2VcIjpcbiAgICAgICAgdGhpcy5jaGFuZ2VJbWFnZSgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJkb3dubG9hZEltYWdlXCI6XG4gICAgICAgIHRoaXMuZWRpdG9yQ29tbWFuZHMuZG93bmxvYWRJbWFnZShlZGl0b3IpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJyZXNpemVTbWFsbFwiOlxuICAgICAgICB0aGlzLmltYWdlU2VydmljZS5yZXNpemVJbWFnZVRvU21hbGwoZWRpdG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwicmVzaXplTWVkaXVtXCI6XG4gICAgICAgIHRoaXMuaW1hZ2VTZXJ2aWNlLnJlc2l6ZUltYWdlVG9NZWRpdW0oZWRpdG9yKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFwicmVzaXplTGFyZ2VcIjpcbiAgICAgICAgdGhpcy5pbWFnZVNlcnZpY2UucmVzaXplSW1hZ2VUb0xhcmdlKGVkaXRvcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcInJlc2l6ZU9yaWdpbmFsXCI6XG4gICAgICAgIHRoaXMuaW1hZ2VTZXJ2aWNlLnJlc2l6ZUltYWdlVG9PcmlnaW5hbChlZGl0b3IpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJkZWxldGVJbWFnZVwiOlxuICAgICAgICB0aGlzLmRlbGV0ZUltYWdlKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImFsaWduTGVmdFwiOlxuICAgICAgICBlZGl0b3IuY2hhaW4oKS5mb2N1cygpLnNldFRleHRBbGlnbihcImxlZnRcIikucnVuKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImFsaWduQ2VudGVyXCI6XG4gICAgICAgIGVkaXRvci5jaGFpbigpLmZvY3VzKCkuc2V0VGV4dEFsaWduKFwiY2VudGVyXCIpLnJ1bigpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJhbGlnblJpZ2h0XCI6XG4gICAgICAgIGVkaXRvci5jaGFpbigpLmZvY3VzKCkuc2V0VGV4dEFsaWduKFwicmlnaHRcIikucnVuKCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2hhbmdlSW1hZ2UoKSB7XG4gICAgY29uc3QgZWQgPSB0aGlzLmVkaXRvcigpO1xuICAgIGlmICghZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgLy8gVXNlIGRlZGljYXRlZCBtZXRob2QgdG8gcmVwbGFjZSBhbiBleGlzdGluZyBpbWFnZVxuICAgICAgYXdhaXQgdGhpcy5pbWFnZVNlcnZpY2Uuc2VsZWN0QW5kUmVwbGFjZUltYWdlKGVkLCB0aGlzLmltYWdlVXBsb2FkKCkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKHRoaXMuaTE4blNlcnZpY2UuaW1hZ2VVcGxvYWQoKS51cGxvYWRFcnJvciwgZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGVsZXRlSW1hZ2UoKSB7XG4gICAgY29uc3QgZWQgPSB0aGlzLmVkaXRvcigpO1xuICAgIGlmIChlZCkge1xuICAgICAgZWQuY2hhaW4oKS5mb2N1cygpLmRlbGV0ZVNlbGVjdGlvbigpLnJ1bigpO1xuICAgIH1cbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { Component, ChangeDetectionStrategy, viewChild, signal, effect, inject, } from "@angular/core";
|
|
2
|
+
import { FormsModule } from "@angular/forms";
|
|
3
|
+
import { AteButtonComponent } from "../../ui/ate-button.component";
|
|
4
|
+
import { AteLinkService } from "../../../services/ate-link.service";
|
|
5
|
+
import { AteSeparatorComponent } from "../../ui/ate-separator.component";
|
|
6
|
+
import { AteBaseSubBubbleMenu } from "../base/ate-base-sub-bubble-menu";
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "@angular/forms";
|
|
9
|
+
export class AteLinkBubbleMenuComponent extends AteBaseSubBubbleMenu {
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
this.linkSvc = inject(AteLinkService);
|
|
13
|
+
this.t = this.i18nService.bubbleMenu;
|
|
14
|
+
this.common = this.i18nService.common;
|
|
15
|
+
this.linkInput = viewChild("linkInput");
|
|
16
|
+
this.editUrl = signal("");
|
|
17
|
+
// Reactive effect for URL sync
|
|
18
|
+
effect(() => {
|
|
19
|
+
const state = this.state();
|
|
20
|
+
const isInteracting = this.linkSvc.isInteracting();
|
|
21
|
+
const currentLinkHref = state.marks.linkHref || "";
|
|
22
|
+
// SYNC LOGIC:
|
|
23
|
+
// If we are NOT currently typing (interacting),
|
|
24
|
+
// always keep the input in sync with the current editor selection.
|
|
25
|
+
if (!isInteracting) {
|
|
26
|
+
this.editUrl.set(currentLinkHref);
|
|
27
|
+
}
|
|
28
|
+
}, { allowSignalWrites: true });
|
|
29
|
+
}
|
|
30
|
+
onStateChange() {
|
|
31
|
+
this.linkSvc.editMode();
|
|
32
|
+
this.linkSvc.menuTrigger();
|
|
33
|
+
this.linkSvc.isInteracting();
|
|
34
|
+
}
|
|
35
|
+
shouldShow() {
|
|
36
|
+
const { selection, marks, isEditable, isFocused } = this.state();
|
|
37
|
+
if (!isEditable) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
// Show if explicitly in edit mode (from toolbar/bubble menu) or interacting with input
|
|
41
|
+
if (this.linkSvc.editMode() || this.linkSvc.isInteracting()) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
// Show if cursor is on an existing link (read/preview mode)
|
|
45
|
+
return isFocused && marks.link && selection.empty;
|
|
46
|
+
}
|
|
47
|
+
getSelectionRect() {
|
|
48
|
+
const trigger = this.linkSvc.menuTrigger();
|
|
49
|
+
const ed = this.editor();
|
|
50
|
+
if (!ed) {
|
|
51
|
+
return new DOMRect(0, 0, 0, 0);
|
|
52
|
+
}
|
|
53
|
+
// 1. If we have a stable trigger from service (toolbar or parent menu), anchor to it
|
|
54
|
+
if (trigger) {
|
|
55
|
+
const rect = trigger.getBoundingClientRect();
|
|
56
|
+
// Only use if it's still visible/in DOM (width > 0)
|
|
57
|
+
if (rect.width > 0) {
|
|
58
|
+
return rect;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// 2. Otherwise (bubble menu / relay), anchor to text selection
|
|
62
|
+
const { from } = ed.state.selection;
|
|
63
|
+
try {
|
|
64
|
+
const { node } = ed.view.domAtPos(from);
|
|
65
|
+
const element = node instanceof Element ? node : node.parentElement;
|
|
66
|
+
const linkElement = element?.closest("a");
|
|
67
|
+
if (linkElement) {
|
|
68
|
+
return linkElement.getBoundingClientRect();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (_e) {
|
|
72
|
+
/* ignore */
|
|
73
|
+
}
|
|
74
|
+
// Use native selection for multi-line accuracy
|
|
75
|
+
const selection = window.getSelection();
|
|
76
|
+
if (selection && selection.rangeCount > 0) {
|
|
77
|
+
const range = selection.getRangeAt(0);
|
|
78
|
+
const rect = range.getBoundingClientRect();
|
|
79
|
+
if (rect.width > 0 && rect.height > 0) {
|
|
80
|
+
return rect;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Final fallback to coordinates at cursor
|
|
84
|
+
const { top, bottom, left, right } = ed.view.coordsAtPos(from);
|
|
85
|
+
return new DOMRect(left, top, right - left, bottom - top);
|
|
86
|
+
}
|
|
87
|
+
onTippyHide() {
|
|
88
|
+
// Clear trigger only AFTER the menu is hidden to maintain anchor stability during animation
|
|
89
|
+
this.linkSvc.done();
|
|
90
|
+
this.linkSvc.close();
|
|
91
|
+
}
|
|
92
|
+
currentUrl() {
|
|
93
|
+
return this.state().marks.linkHref || "";
|
|
94
|
+
}
|
|
95
|
+
onMouseDown(event) {
|
|
96
|
+
event.stopPropagation();
|
|
97
|
+
const target = event.target;
|
|
98
|
+
if (target.tagName !== "INPUT") {
|
|
99
|
+
event.preventDefault();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
onFocus() {
|
|
103
|
+
this.linkSvc.setInteracting(true);
|
|
104
|
+
}
|
|
105
|
+
onBlur() {
|
|
106
|
+
setTimeout(() => {
|
|
107
|
+
this.linkSvc.setInteracting(false);
|
|
108
|
+
this.updateMenu();
|
|
109
|
+
}, 150);
|
|
110
|
+
}
|
|
111
|
+
onOpenLink(event) {
|
|
112
|
+
event.preventDefault();
|
|
113
|
+
event.stopPropagation();
|
|
114
|
+
const url = this.currentUrl();
|
|
115
|
+
if (url) {
|
|
116
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
onRemove(event) {
|
|
120
|
+
event.preventDefault();
|
|
121
|
+
event.stopPropagation();
|
|
122
|
+
this.linkSvc.unsetLink(this.editor());
|
|
123
|
+
}
|
|
124
|
+
onApply(event) {
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
event.stopPropagation();
|
|
127
|
+
const url = this.editUrl().trim();
|
|
128
|
+
if (url) {
|
|
129
|
+
this.linkSvc.setLink(this.editor(), url);
|
|
130
|
+
this.editUrl.set("");
|
|
131
|
+
this.linkSvc.setInteracting(false);
|
|
132
|
+
this.hideTippy();
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
this.onRemove(event);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
onCancel(event) {
|
|
139
|
+
event.preventDefault();
|
|
140
|
+
event.stopPropagation();
|
|
141
|
+
this.linkSvc.close();
|
|
142
|
+
this.hideTippy();
|
|
143
|
+
}
|
|
144
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteLinkBubbleMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
145
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "18.2.14", type: AteLinkBubbleMenuComponent, isStandalone: true, selector: "ate-link-bubble-menu", viewQueries: [{ propertyName: "linkInput", first: true, predicate: ["linkInput"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
|
|
146
|
+
<div
|
|
147
|
+
#menuRef
|
|
148
|
+
class="bubble-menu"
|
|
149
|
+
(mousedown)="onMouseDown($event)"
|
|
150
|
+
(click)="$event.stopPropagation()"
|
|
151
|
+
(keydown)="$event.stopPropagation()"
|
|
152
|
+
(keydown.escape)="onCancel($event)"
|
|
153
|
+
tabindex="-1"
|
|
154
|
+
role="dialog">
|
|
155
|
+
<div class="link-input-row">
|
|
156
|
+
<div class="url-input-container">
|
|
157
|
+
<span class="material-symbols-outlined icon-link">link</span>
|
|
158
|
+
<input
|
|
159
|
+
#linkInput
|
|
160
|
+
type="text"
|
|
161
|
+
class="url-field"
|
|
162
|
+
[placeholder]="t().linkUrl"
|
|
163
|
+
[ngModel]="editUrl()"
|
|
164
|
+
(ngModelChange)="editUrl.set($event)"
|
|
165
|
+
(focus)="onFocus()"
|
|
166
|
+
(blur)="onBlur()"
|
|
167
|
+
(keydown.enter)="onApply($event)"
|
|
168
|
+
(keydown.escape)="onCancel($event)" />
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<div class="action-buttons">
|
|
172
|
+
<ate-button
|
|
173
|
+
icon="check"
|
|
174
|
+
[title]="common().apply"
|
|
175
|
+
color="var(--ate-primary)"
|
|
176
|
+
[disabled]="!editUrl().trim()"
|
|
177
|
+
(buttonClick)="onApply($event)"></ate-button>
|
|
178
|
+
<ate-button
|
|
179
|
+
icon="open_in_new"
|
|
180
|
+
[title]="t().openLink"
|
|
181
|
+
[disabled]="!currentUrl()"
|
|
182
|
+
(buttonClick)="onOpenLink($event)"></ate-button>
|
|
183
|
+
<ate-separator />
|
|
184
|
+
<ate-button
|
|
185
|
+
icon="link_off"
|
|
186
|
+
[title]="t().removeLink"
|
|
187
|
+
variant="danger"
|
|
188
|
+
[disabled]="!currentUrl()"
|
|
189
|
+
(buttonClick)="onRemove($event)"></ate-button>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
</div>
|
|
193
|
+
`, isInline: true, styles: [".link-input-row{display:flex;align-items:center;gap:6px}.url-input-container{flex:1;display:flex;align-items:center;background:var(--ate-surface-secondary, #f8fafc);border:1px solid var(--ate-border, #e2e8f0);border-radius:8px;padding:0 10px;height:32px;transition:all .15s ease}.url-input-container:focus-within{border-color:var(--ate-primary, #3b82f6);background:var(--ate-surface, #ffffff);box-shadow:0 0 0 2px var(--ate-primary-light, rgba(59, 130, 246, .1))}.icon-link{font-size:16px;color:var(--ate-text-muted, #94a3b8);margin-right:6px}.url-field{background:transparent;border:none;outline:none;color:var(--ate-text, #1e293b);font-size:13px;width:100%;font-family:inherit}.action-buttons{display:flex;align-items:center;gap:2px}\n"], dependencies: [{ 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" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
194
|
+
}
|
|
195
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteLinkBubbleMenuComponent, decorators: [{
|
|
196
|
+
type: Component,
|
|
197
|
+
args: [{ selector: "ate-link-bubble-menu", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AteButtonComponent, AteSeparatorComponent, FormsModule], template: `
|
|
198
|
+
<div
|
|
199
|
+
#menuRef
|
|
200
|
+
class="bubble-menu"
|
|
201
|
+
(mousedown)="onMouseDown($event)"
|
|
202
|
+
(click)="$event.stopPropagation()"
|
|
203
|
+
(keydown)="$event.stopPropagation()"
|
|
204
|
+
(keydown.escape)="onCancel($event)"
|
|
205
|
+
tabindex="-1"
|
|
206
|
+
role="dialog">
|
|
207
|
+
<div class="link-input-row">
|
|
208
|
+
<div class="url-input-container">
|
|
209
|
+
<span class="material-symbols-outlined icon-link">link</span>
|
|
210
|
+
<input
|
|
211
|
+
#linkInput
|
|
212
|
+
type="text"
|
|
213
|
+
class="url-field"
|
|
214
|
+
[placeholder]="t().linkUrl"
|
|
215
|
+
[ngModel]="editUrl()"
|
|
216
|
+
(ngModelChange)="editUrl.set($event)"
|
|
217
|
+
(focus)="onFocus()"
|
|
218
|
+
(blur)="onBlur()"
|
|
219
|
+
(keydown.enter)="onApply($event)"
|
|
220
|
+
(keydown.escape)="onCancel($event)" />
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
<div class="action-buttons">
|
|
224
|
+
<ate-button
|
|
225
|
+
icon="check"
|
|
226
|
+
[title]="common().apply"
|
|
227
|
+
color="var(--ate-primary)"
|
|
228
|
+
[disabled]="!editUrl().trim()"
|
|
229
|
+
(buttonClick)="onApply($event)"></ate-button>
|
|
230
|
+
<ate-button
|
|
231
|
+
icon="open_in_new"
|
|
232
|
+
[title]="t().openLink"
|
|
233
|
+
[disabled]="!currentUrl()"
|
|
234
|
+
(buttonClick)="onOpenLink($event)"></ate-button>
|
|
235
|
+
<ate-separator />
|
|
236
|
+
<ate-button
|
|
237
|
+
icon="link_off"
|
|
238
|
+
[title]="t().removeLink"
|
|
239
|
+
variant="danger"
|
|
240
|
+
[disabled]="!currentUrl()"
|
|
241
|
+
(buttonClick)="onRemove($event)"></ate-button>
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
</div>
|
|
245
|
+
`, styles: [".link-input-row{display:flex;align-items:center;gap:6px}.url-input-container{flex:1;display:flex;align-items:center;background:var(--ate-surface-secondary, #f8fafc);border:1px solid var(--ate-border, #e2e8f0);border-radius:8px;padding:0 10px;height:32px;transition:all .15s ease}.url-input-container:focus-within{border-color:var(--ate-primary, #3b82f6);background:var(--ate-surface, #ffffff);box-shadow:0 0 0 2px var(--ate-primary-light, rgba(59, 130, 246, .1))}.icon-link{font-size:16px;color:var(--ate-text-muted, #94a3b8);margin-right:6px}.url-field{background:transparent;border:none;outline:none;color:var(--ate-text, #1e293b);font-size:13px;width:100%;font-family:inherit}.action-buttons{display:flex;align-items:center;gap:2px}\n"] }]
|
|
246
|
+
}], ctorParameters: () => [] });
|
|
247
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLWxpbmstYnViYmxlLW1lbnUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci10aXB0YXAtZWRpdG9yL3NyYy9saWIvY29tcG9uZW50cy9idWJibGUtbWVudXMvbGluay9hdGUtbGluay1idWJibGUtbWVudS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCx1QkFBdUIsRUFDdkIsU0FBUyxFQUVULE1BQU0sRUFDTixNQUFNLEVBQ04sTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNuRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDcEUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDekUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7OztBQTBHeEUsTUFBTSxPQUFPLDBCQUEyQixTQUFRLG9CQUFvQjtJQVVsRTtRQUNFLEtBQUssRUFBRSxDQUFDO1FBVk8sWUFBTyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUV6QyxNQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUM7UUFDaEMsV0FBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDO1FBRTFDLGNBQVMsR0FBRyxTQUFTLENBQStCLFdBQVcsQ0FBQyxDQUFDO1FBRWpFLFlBQU8sR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFLbkIsK0JBQStCO1FBQy9CLE1BQU0sQ0FBQyxHQUFHLEVBQUU7WUFDVixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxF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LENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDbkIsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7SUFDSCxDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQVk7UUFDbkIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUNuQixDQUFDOytHQTdKVSwwQkFBMEI7bUdBQTFCLDBCQUEwQiwrTkFuRzNCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnRFQsMnlCQWpEUyxrQkFBa0IsNkxBQUUscUJBQXFCLHlEQUFFLFdBQVc7OzRGQW9HckQsMEJBQTBCO2tCQXhHdEMsU0FBUzsrQkFDRSxzQkFBc0IsY0FDcEIsSUFBSSxtQkFDQyx1QkFBdUIsQ0FBQyxNQUFNLFdBQ3RDLENBQUMsa0JBQWtCLEVBQUUscUJBQXFCLEVBQUUsV0FBVyxDQUFDLFlBQ3ZEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnRFQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICB2aWV3Q2hpbGQsXG4gIEVsZW1lbnRSZWYsXG4gIHNpZ25hbCxcbiAgZWZmZWN0LFxuICBpbmplY3QsXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IHsgQXRlQnV0dG9uQ29tcG9uZW50IH0gZnJvbSBcIi4uLy4uL3VpL2F0ZS1idXR0b24uY29tcG9uZW50XCI7XG5pbXBvcnQgeyBBdGVMaW5rU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi9zZXJ2aWNlcy9hdGUtbGluay5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBBdGVTZXBhcmF0b3JDb21wb25lbnQgfSBmcm9tIFwiLi4vLi4vdWkvYXRlLXNlcGFyYXRvci5jb21wb25lbnRcIjtcbmltcG9ydCB7IEF0ZUJhc2VTdWJCdWJibGVNZW51IH0gZnJvbSBcIi4uL2Jhc2UvYXRlLWJhc2Utc3ViLWJ1YmJsZS1tZW51XCI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogXCJhdGUtbGluay1idWJibGUtbWVudVwiLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgaW1wb3J0czogW0F0ZUJ1dHRvbkNvbXBvbmVudCwgQXRlU2VwYXJhdG9yQ29tcG9uZW50LCBGb3Jtc01vZHVsZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdlxuICAgICAgI21lbnVSZWZcbiAgICAgIGNsYXNzPVwiYnViYmxlLW1lbnVcIlxuICAgICAgKG1vdXNlZG93bik9XCJvbk1vdXNlRG93bigkZXZlbnQpXCJcbiAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgKGtleWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgIChrZXlkb3duLmVzY2FwZSk9XCJvbkNhbmNlbCgkZXZlbnQpXCJcbiAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgICAgcm9sZT1cImRpYWxvZ1wiPlxuICAgICAgPGRpdiBjbGFzcz1cImxpbmstaW5wdXQtcm93XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ1cmwtaW5wdXQtY29udGFpbmVyXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJtYXRlcmlhbC1zeW1ib2xzLW91dGxpbmVkIGljb24tbGlua1wiPmxpbms8L3NwYW4+XG4gICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAjbGlua0lucHV0XG4gICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICBjbGFzcz1cInVybC1maWVsZFwiXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwidCgpLmxpbmtVcmxcIlxuICAgICAgICAgICAgW25nTW9kZWxdPVwiZWRpdFVybCgpXCJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImVkaXRVcmwuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgKGZvY3VzKT1cIm9uRm9jdXMoKVwiXG4gICAgICAgICAgICAoYmx1cik9XCJvbkJsdXIoKVwiXG4gICAgICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJvbkFwcGx5KCRldmVudClcIlxuICAgICAgICAgICAgKGtleWRvd24uZXNjYXBlKT1cIm9uQ2FuY2VsKCRldmVudClcIiAvPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLWJ1dHRvbnNcIj5cbiAgICAgICAgICA8YXRlLWJ1dHRvblxuICAgICAgICAgICAgaWNvbj1cImNoZWNrXCJcbiAgICAgICAgICAgIFt0aXRsZV09XCJjb21tb24oKS5hcHBseVwiXG4gICAgICAgICAgICBjb2xvcj1cInZhcigtLWF0ZS1wcmltYXJ5KVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiIWVkaXRVcmwoKS50cmltKClcIlxuICAgICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQXBwbHkoJGV2ZW50KVwiPjwvYXRlLWJ1dHRvbj5cbiAgICAgICAgICA8YXRlLWJ1dHRvblxuICAgICAgICAgICAgaWNvbj1cIm9wZW5faW5fbmV3XCJcbiAgICAgICAgICAgIFt0aXRsZV09XCJ0KCkub3BlbkxpbmtcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFjdXJyZW50VXJsKClcIlxuICAgICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uT3BlbkxpbmsoJGV2ZW50KVwiPjwvYXRlLWJ1dHRvbj5cbiAgICAgICAgICA8YXRlLXNlcGFyYXRvciAvPlxuICAgICAgICAgIDxhdGUtYnV0dG9uXG4gICAgICAgICAgICBpY29uPVwibGlua19vZmZcIlxuICAgICAgICAgICAgW3RpdGxlXT1cInQoKS5yZW1vdmVMaW5rXCJcbiAgICAgICAgICAgIHZhcmlhbnQ9XCJkYW5nZXJcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFjdXJyZW50VXJsKClcIlxuICAgICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uUmVtb3ZlKCRldmVudClcIj48L2F0ZS1idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGAsXG4gIHN0eWxlczogW1xuICAgIGBcbiAgICAgIC5saW5rLWlucHV0LXJvdyB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIGdhcDogNnB4O1xuICAgICAgfVxuXG4gICAgICAudXJsLWlucHV0LWNvbnRhaW5lciB7XG4gICAgICAgIGZsZXg6IDE7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIGJhY2tncm91bmQ6IHZhcigtLWF0ZS1zdXJmYWNlLXNlY29uZGFyeSwgI2Y4ZmFmYyk7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWF0ZS1ib3JkZXIsICNlMmU4ZjApO1xuICAgICAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgICAgIHBhZGRpbmc6IDAgMTBweDtcbiAgICAgICAgaGVpZ2h0OiAzMnB4O1xuICAgICAgICB0cmFuc2l0aW9uOiBhbGwgMTUwbXMgZWFzZTtcbiAgICAgIH1cblxuICAgICAgLnVybC1pbnB1dC1jb250YWluZXI6Zm9jdXMtd2l0aGluIHtcbiAgICAgICAgYm9yZGVyLWNvbG9yOiB2YXIoLS1hdGUtcHJpbWFyeSwgIzNiODJmNik7XG4gICAgICAgIGJhY2tncm91bmQ6IHZhcigtLWF0ZS1zdXJmYWNlLCAjZmZmZmZmKTtcbiAgICAgICAgYm94LXNoYWRvdzogMCAwIDAgMnB4IHZhcigtLWF0ZS1wcmltYXJ5LWxpZ2h0LCByZ2JhKDU5LCAxMzAsIDI0NiwgMC4xKSk7XG4gICAgICB9XG5cbiAgICAgIC5pY29uLWxpbmsge1xuICAgICAgICBmb250LXNpemU6IDE2cHg7XG4gICAgICAgIGNvbG9yOiB2YXIoLS1hdGUtdGV4dC1tdXRlZCwgIzk0YTNiOCk7XG4gICAgICAgIG1hcmdpbi1yaWdodDogNnB4O1xuICAgICAgfVxuXG4gICAgICAudXJsLWZpZWxkIHtcbiAgICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgICAgb3V0bGluZTogbm9uZTtcbiAgICAgICAgY29sb3I6IHZhcigtLWF0ZS10ZXh0LCAjMWUyOTNiKTtcbiAgICAgICAgZm9udC1zaXplOiAxM3B4O1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgZm9udC1mYW1pbHk6IGluaGVyaXQ7XG4gICAgICB9XG5cbiAgICAgIC5hY3Rpb24tYnV0dG9ucyB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIGdhcDogMnB4O1xuICAgICAgfVxuICAgIGAsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIEF0ZUxpbmtCdWJibGVNZW51Q29tcG9uZW50IGV4dGVuZHMgQXRlQmFzZVN1YkJ1YmJsZU1lbnUge1xuICBwcml2YXRlIHJlYWRvbmx5IGxpbmtTdmMgPSBpbmplY3QoQXRlTGlua1NlcnZpY2UpO1xuXG4gIHJlYWRvbmx5IHQgPSB0aGlzLmkxOG5TZXJ2aWNlLmJ1YmJsZU1lbnU7XG4gIHJlYWRvbmx5IGNvbW1vbiA9IHRoaXMuaTE4blNlcnZpY2UuY29tbW9uO1xuXG4gIGxpbmtJbnB1dCA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+PihcImxpbmtJbnB1dFwiKTtcblxuICBlZGl0VXJsID0gc2lnbmFsKFwiXCIpO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICAvLyBSZWFjdGl2ZSBlZmZlY3QgZm9yIFVSTCBzeW5jXG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRlID0gdGhpcy5zdGF0ZSgpO1xuICAgICAgY29uc3QgaXNJbnRlcmFjdGluZyA9IHRoaXMubGlua1N2Yy5pc0ludGVyYWN0aW5nKCk7XG4gICAgICBjb25zdCBjdXJyZW50TGlua0hyZWYgPSBzdGF0ZS5tYXJrcy5saW5rSHJlZiB8fCBcIlwiO1xuXG4gICAgICAvLyBTWU5DIExPR0lDOlxuICAgICAgLy8gSWYgd2UgYXJlIE5PVCBjdXJyZW50bHkgdHlwaW5nIChpbnRlcmFjdGluZyksXG4gICAgICAvLyBhbHdheXMga2VlcCB0aGUgaW5wdXQgaW4gc3luYyB3aXRoIHRoZSBjdXJyZW50IGVkaXRvciBzZWxlY3Rpb24uXG4gICAgICBpZiAoIWlzSW50ZXJhY3RpbmcpIHtcbiAgICAgICAgdGhpcy5lZGl0VXJsLnNldChjdXJyZW50TGlua0hyZWYpO1xuICAgICAgfVxuICAgIH0sIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgb25TdGF0ZUNoYW5nZSgpIHtcbiAgICB0aGlzLmxpbmtTdmMuZWRpdE1vZGUoKTtcbiAgICB0aGlzLmxpbmtTdmMubWVudVRyaWdnZXIoKTtcbiAgICB0aGlzLmxpbmtTdmMuaXNJbnRlcmFjdGluZygpO1xuICB9XG5cbiAgb3ZlcnJpZGUgc2hvdWxkU2hvdygpOiBib29sZWFuIHtcbiAgICBjb25zdCB7IHNlbGVjdGlvbiwgbWFya3MsIGlzRWRpdGFibGUsIGlzRm9jdXNlZCB9ID0gdGhpcy5zdGF0ZSgpO1xuICAgIGlmICghaXNFZGl0YWJsZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIFNob3cgaWYgZXhwbGljaXRseSBpbiBlZGl0IG1vZGUgKGZyb20gdG9vbGJhci9idWJibGUgbWVudSkgb3IgaW50ZXJhY3Rpbmcgd2l0aCBpbnB1dFxuICAgIGlmICh0aGlzLmxpbmtTdmMuZWRpdE1vZGUoKSB8fCB0aGlzLmxpbmtTdmMuaXNJbnRlcmFjdGluZygpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBTaG93IGlmIGN1cnNvciBpcyBvbiBhbiBleGlzdGluZyBsaW5rIChyZWFkL3ByZXZpZXcgbW9kZSlcbiAgICByZXR1cm4gaXNGb2N1c2VkICYmIG1hcmtzLmxpbmsgJiYgc2VsZWN0aW9uLmVtcHR5O1xuICB9XG5cbiAgb3ZlcnJpZGUgZ2V0U2VsZWN0aW9uUmVjdCgpOiBET01SZWN0IHtcbiAgICBjb25zdCB0cmlnZ2VyID0gdGhpcy5saW5rU3ZjLm1lbnVUcmlnZ2VyKCk7XG4gICAgY29uc3QgZWQgPSB0aGlzLmVkaXRvcigpO1xuICAgIGlmICghZWQpIHtcbiAgICAgIHJldHVybiBuZXcgRE9NUmVjdCgwLCAwLCAwLCAwKTtcbiAgICB9XG5cbiAgICAvLyAxLiBJZiB3ZSBoYXZlIGEgc3RhYmxlIHRyaWdnZXIgZnJvbSBzZXJ2aWNlICh0b29sYmFyIG9yIHBhcmVudCBtZW51KSwgYW5jaG9yIHRvIGl0XG4gICAgaWYgKHRyaWdnZXIpIHtcbiAgICAgIGNvbnN0IHJlY3QgPSB0cmlnZ2VyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgLy8gT25seSB1c2UgaWYgaXQncyBzdGlsbCB2aXNpYmxlL2luIERPTSAod2lkdGggPiAwKVxuICAgICAgaWYgKHJlY3Qud2lkdGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZWN0O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIDIuIE90aGVyd2lzZSAoYnViYmxlIG1lbnUgLyByZWxheSksIGFuY2hvciB0byB0ZXh0IHNlbGVjdGlvblxuICAgIGNvbnN0IHsgZnJvbSB9ID0gZWQuc3RhdGUuc2VsZWN0aW9uO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgbm9kZSB9ID0gZWQudmlldy5kb21BdFBvcyhmcm9tKTtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBub2RlIGluc3RhbmNlb2YgRWxlbWVudCA/IG5vZGUgOiBub2RlLnBhcmVudEVsZW1lbnQ7XG4gICAgICBjb25zdCBsaW5rRWxlbWVudCA9IChlbGVtZW50IGFzIEVsZW1lbnQpPy5jbG9zZXN0KFwiYVwiKTtcbiAgICAgIGlmIChsaW5rRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gbGlua0VsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoX2UpIHtcbiAgICAgIC8qIGlnbm9yZSAqL1xuICAgIH1cblxuICAgIC8vIFVzZSBuYXRpdmUgc2VsZWN0aW9uIGZvciBtdWx0aS1saW5lIGFjY3VyYWN5XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgIGlmIChzZWxlY3Rpb24gJiYgc2VsZWN0aW9uLnJhbmdlQ291bnQgPiAwKSB7XG4gICAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KDApO1xuICAgICAgY29uc3QgcmVjdCA9IHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgaWYgKHJlY3Qud2lkdGggPiAwICYmIHJlY3QuaGVpZ2h0ID4gMCkge1xuICAgICAgICByZXR1cm4gcmVjdDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBGaW5hbCBmYWxsYmFjayB0byBjb29yZGluYXRlcyBhdCBjdXJzb3JcbiAgICBjb25zdCB7IHRvcCwgYm90dG9tLCBsZWZ0LCByaWdodCB9ID0gZWQudmlldy5jb29yZHNBdFBvcyhmcm9tKTtcbiAgICByZXR1cm4gbmV3IERPTVJlY3QobGVmdCwgdG9wLCByaWdodCAtIGxlZnQsIGJvdHRvbSAtIHRvcCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgb25UaXBweUhpZGUoKSB7XG4gICAgLy8gQ2xlYXIgdHJpZ2dlciBvbmx5IEFGVEVSIHRoZSBtZW51IGlzIGhpZGRlbiB0byBtYWludGFpbiBhbmNob3Igc3RhYmlsaXR5IGR1cmluZyBhbmltYXRpb25cbiAgICB0aGlzLmxpbmtTdmMuZG9uZSgpO1xuICAgIHRoaXMubGlua1N2Yy5jbG9zZSgpO1xuICB9XG5cbiAgY3VycmVudFVybCgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZSgpLm1hcmtzLmxpbmtIcmVmIHx8IFwiXCI7XG4gIH1cblxuICBvbk1vdXNlRG93bihldmVudDogTW91c2VFdmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBpZiAodGFyZ2V0LnRhZ05hbWUgIT09IFwiSU5QVVRcIikge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH1cblxuICBvbkZvY3VzKCkge1xuICAgIHRoaXMubGlua1N2Yy5zZXRJbnRlcmFjdGluZyh0cnVlKTtcbiAgfVxuXG4gIG9uQmx1cigpIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMubGlua1N2Yy5zZXRJbnRlcmFjdGluZyhmYWxzZSk7XG4gICAgICB0aGlzLnVwZGF0ZU1lbnUoKTtcbiAgICB9LCAxNTApO1xuICB9XG5cbiAgb25PcGVuTGluayhldmVudDogRXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IHVybCA9IHRoaXMuY3VycmVudFVybCgpO1xuICAgIGlmICh1cmwpIHtcbiAgICAgIHdpbmRvdy5vcGVuKHVybCwgXCJfYmxhbmtcIiwgXCJub29wZW5lcixub3JlZmVycmVyXCIpO1xuICAgIH1cbiAgfVxuXG4gIG9uUmVtb3ZlKGV2ZW50OiBFdmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5saW5rU3ZjLnVuc2V0TGluayh0aGlzLmVkaXRvcigpKTtcbiAgfVxuXG4gIG9uQXBwbHkoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjb25zdCB1cmwgPSB0aGlzLmVkaXRVcmwoKS50cmltKCk7XG4gICAgaWYgKHVybCkge1xuICAgICAgdGhpcy5saW5rU3ZjLnNldExpbmsodGhpcy5lZGl0b3IoKSwgdXJsKTtcbiAgICAgIHRoaXMuZWRpdFVybC5zZXQoXCJcIik7XG4gICAgICB0aGlzLmxpbmtTdmMuc2V0SW50ZXJhY3RpbmcoZmFsc2UpO1xuICAgICAgdGhpcy5oaWRlVGlwcHkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vblJlbW92ZShldmVudCk7XG4gICAgfVxuICB9XG5cbiAgb25DYW5jZWwoZXZlbnQ6IEV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmxpbmtTdmMuY2xvc2UoKTtcbiAgICB0aGlzLmhpZGVUaXBweSgpO1xuICB9XG59XG4iXX0=
|