@supernovaio/prototyping-tooling 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +193 -0
  2. package/dist/build/index.d.ts +3 -0
  3. package/dist/build/index.d.ts.map +1 -0
  4. package/dist/build/index.js +96 -0
  5. package/dist/build/vite-plugin-forge-ids.d.ts +7 -0
  6. package/dist/build/vite-plugin-forge-ids.d.ts.map +1 -0
  7. package/dist/client/annotation/AnnotationOverlay.d.ts +86 -0
  8. package/dist/client/annotation/AnnotationOverlay.d.ts.map +1 -0
  9. package/dist/client/design-mode/DesignModeController.d.ts +35 -0
  10. package/dist/client/design-mode/DesignModeController.d.ts.map +1 -0
  11. package/dist/client/general/ComponentRegistry.d.ts +15 -0
  12. package/dist/client/general/ComponentRegistry.d.ts.map +1 -0
  13. package/dist/client/general/ForgeClient.d.ts +36 -0
  14. package/dist/client/general/ForgeClient.d.ts.map +1 -0
  15. package/dist/client/general/SourceCodeUpdater.d.ts +15 -0
  16. package/dist/client/general/SourceCodeUpdater.d.ts.map +1 -0
  17. package/dist/client/general/element-utils.d.ts +20 -0
  18. package/dist/client/general/element-utils.d.ts.map +1 -0
  19. package/dist/client/general/overlay.d.ts +9 -0
  20. package/dist/client/general/overlay.d.ts.map +1 -0
  21. package/dist/client/general/react-detection.d.ts +49 -0
  22. package/dist/client/general/react-detection.d.ts.map +1 -0
  23. package/dist/client/general/types.d.ts +26 -0
  24. package/dist/client/general/types.d.ts.map +1 -0
  25. package/dist/client/general/xpath.d.ts +3 -0
  26. package/dist/client/general/xpath.d.ts.map +1 -0
  27. package/dist/client/index.d.ts +6 -0
  28. package/dist/client/index.d.ts.map +1 -0
  29. package/dist/client/select-mode/SelectModeController.d.ts +31 -0
  30. package/dist/client/select-mode/SelectModeController.d.ts.map +1 -0
  31. package/dist/client.js +836 -0
  32. package/dist/constants-BXKWBfHg.js +55 -0
  33. package/dist/debug-CLzmqn3R.js +11 -0
  34. package/dist/host/ForgeHost.d.ts +57 -0
  35. package/dist/host/ForgeHost.d.ts.map +1 -0
  36. package/dist/host/index.d.ts +3 -0
  37. package/dist/host/index.d.ts.map +1 -0
  38. package/dist/host/types.d.ts +32 -0
  39. package/dist/host/types.d.ts.map +1 -0
  40. package/dist/host.js +142 -0
  41. package/dist/index.d.ts +12 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +14 -0
  44. package/dist/react/index.d.ts +5 -0
  45. package/dist/react/index.d.ts.map +1 -0
  46. package/dist/react/useDesignMode.d.ts +12 -0
  47. package/dist/react/useDesignMode.d.ts.map +1 -0
  48. package/dist/react/useElementSelector.d.ts +12 -0
  49. package/dist/react/useElementSelector.d.ts.map +1 -0
  50. package/dist/react.js +5 -0
  51. package/dist/shared/constants.d.ts +27 -0
  52. package/dist/shared/constants.d.ts.map +1 -0
  53. package/dist/shared/debug.d.ts +4 -0
  54. package/dist/shared/debug.d.ts.map +1 -0
  55. package/dist/shared/events.d.ts +157 -0
  56. package/dist/shared/events.d.ts.map +1 -0
  57. package/dist/shared/messaging.d.ts +19 -0
  58. package/dist/shared/messaging.d.ts.map +1 -0
  59. package/dist/useDesignMode-VIipNUSj.js +68 -0
  60. package/package.json +69 -0
package/dist/client.js ADDED
@@ -0,0 +1,836 @@
1
+ import { b as F, c as $, R as X, d as Y, Z as S, C as f, B as L, e as G, M as C, P as B, i as W, a as V, T as j } from "./constants-BXKWBfHg.js";
2
+ import { d as c } from "./debug-CLzmqn3R.js";
3
+ import { parse as U } from "@babel/parser";
4
+ import x from "@babel/traverse";
5
+ import _ from "@babel/generator";
6
+ class z {
7
+ registry = /* @__PURE__ */ new Map();
8
+ register(e, t) {
9
+ this.registry.set(e, t);
10
+ }
11
+ registerAll(e) {
12
+ for (const [t, n] of Object.entries(e))
13
+ this.registry.set(t, n);
14
+ }
15
+ getEditableProps(e) {
16
+ let t = this.registry.get(e);
17
+ if (!t) {
18
+ const o = e.toLowerCase();
19
+ for (const [i, s] of this.registry.entries())
20
+ if (i.toLowerCase() === o) {
21
+ t = s;
22
+ break;
23
+ }
24
+ }
25
+ const n = { p: "p", h1: "h1", h2: "h2", h3: "h3" };
26
+ return !t && n[e] && (t = this.registry.get(n[e])), t ? Object.entries(t.props).filter(([o, i]) => i.editable).map(([o, i]) => ({ name: o, type: i.type, options: i.options, default: i.default, editable: i.editable, label: i.label })) : [];
27
+ }
28
+ }
29
+ function w(a) {
30
+ if (a.id)
31
+ return `//*[@id="${a.id}"]`;
32
+ const e = [];
33
+ let t = a;
34
+ for (; t && t.nodeType === Node.ELEMENT_NODE; ) {
35
+ let n = t.nodeName.toLowerCase();
36
+ if (t.parentNode) {
37
+ const o = Array.from(t.parentNode.children), i = o.indexOf(t) + 1;
38
+ o.length > 1 && (n += `[${i}]`);
39
+ }
40
+ e.unshift(n), t = t.parentElement;
41
+ }
42
+ return "/" + e.join("/");
43
+ }
44
+ const d = { FunctionComponent: 0, ClassComponent: 1, IndeterminateComponent: 2, HostRoot: 3, HostPortal: 4, HostComponent: 5, HostText: 6, Fragment: 7, Mode: 8, ContextConsumer: 9, ContextProvider: 10, ForwardRef: 11, Profiler: 12, SuspenseComponent: 13, MemoComponent: 14, SimpleMemoComponent: 15, LazyComponent: 16, IncompleteClassComponent: 17, DehydratedFragment: 18, SuspenseListComponent: 19, ScopeComponent: 21, OffscreenComponent: 22, LegacyHiddenComponent: 23, CacheComponent: 24, TracingMarkerComponent: 25, HostHoistable: 26, HostSingleton: 27, IncompleteFunctionComponent: 28, Throw: 29, ViewTransitionComponent: 30, ActivityComponent: 31 }, K = /* @__PURE__ */ new Set(["Component", "PureComponent", "Fragment", "Suspense", "Profiler", "StrictMode", "Routes", "Route", "Outlet", "Root", "ErrorBoundaryHandler", "HotReload", "Hot"]), J = [/Boundary$/, /BoundaryHandler$/, /Provider$/, /Consumer$/, /^(Inner|Outer)/, /Router$/, /^Client(Page|Segment|Root)/, /^Server(Root|Component|Render)/, /^RSC/, /Context$/, /^Hot(Reload)?$/, /^(Dev|React)(Overlay|Tools|Root)/, /Overlay$/, /Handler$/, /^With[A-Z]/, /Wrapper$/, /^Root$/];
45
+ let O = null;
46
+ function D(a) {
47
+ const e = (t) => t.some((n) => n.startsWith("__reactFiber$") || n.startsWith("__reactInternalInstance$") || n.startsWith("__reactProps$"));
48
+ return e(Object.keys(a)) || e(Object.getOwnPropertyNames(a));
49
+ }
50
+ function q() {
51
+ if (O !== null) return O;
52
+ if (typeof document > "u") return !1;
53
+ if (document.body && D(document.body))
54
+ return c("client", "Detected React on document.body"), O = !0, !0;
55
+ for (const e of X) {
56
+ const t = document.querySelector(e);
57
+ if (t) {
58
+ if (D(t))
59
+ return c("client", "Detected React on", e), O = !0, !0;
60
+ for (const n of t.children)
61
+ if (D(n))
62
+ return c("client", "Detected React on child of", e), O = !0, !0;
63
+ }
64
+ }
65
+ if (document.body) {
66
+ for (const e of document.body.children)
67
+ if (D(e))
68
+ return c("client", "Detected React on body child:", e.tagName), O = !0, !0;
69
+ }
70
+ const a = document.querySelectorAll("*");
71
+ for (const e of a) {
72
+ if (D(e))
73
+ return c("client", "Detected React on deep scan:", e.tagName), O = !0, !0;
74
+ if (a.length > Y) break;
75
+ }
76
+ return c("client", "React NOT detected on page"), O = !1, !1;
77
+ }
78
+ function Z(a) {
79
+ const e = Object.keys(a);
80
+ let t = e.find((s) => s.startsWith("__reactFiber$"));
81
+ if (t) return a[t] || null;
82
+ let n = e.find((s) => s.startsWith("__reactInternalInstance$"));
83
+ if (n) return a[n] || null;
84
+ const o = Object.getOwnPropertyNames(a);
85
+ if (t = o.find((s) => s.startsWith("__reactFiber$")), t) return a[t] || null;
86
+ if (n = o.find((s) => s.startsWith("__reactInternalInstance$")), n) return a[n] || null;
87
+ const i = o.find((s) => {
88
+ if (!s.startsWith("__react")) return !1;
89
+ const r = a[s];
90
+ return r && typeof r == "object" && ("return" in r || "tag" in r);
91
+ });
92
+ return i && a[i] || null;
93
+ }
94
+ function T(a) {
95
+ return a ? a.displayName ? a.displayName : a.name ? a.name : null : null;
96
+ }
97
+ function Q(a) {
98
+ const { tag: e, type: t, elementType: n } = a;
99
+ if ((/* @__PURE__ */ new Set([d.HostComponent, d.HostText, d.HostHoistable, d.HostSingleton, d.Fragment, d.Mode, d.Profiler, d.DehydratedFragment, d.HostRoot, d.HostPortal, d.ScopeComponent, d.OffscreenComponent, d.LegacyHiddenComponent, d.CacheComponent, d.TracingMarkerComponent, d.Throw, d.ViewTransitionComponent, d.ActivityComponent, d.SuspenseComponent, d.SuspenseListComponent])).has(e)) return null;
100
+ if (e === d.ForwardRef) {
101
+ const i = n;
102
+ if (i?.render) {
103
+ const s = T(i.render);
104
+ if (s) return s;
105
+ }
106
+ return i?.displayName ? i.displayName : T(t);
107
+ }
108
+ if (e === d.MemoComponent || e === d.SimpleMemoComponent) {
109
+ const i = n;
110
+ if (i?.type) {
111
+ const s = T(i.type);
112
+ if (s) return s;
113
+ }
114
+ return i?.displayName ? i.displayName : T(t);
115
+ }
116
+ if (e === d.ContextProvider) {
117
+ const i = t;
118
+ return i?._context?.displayName ? `${i._context.displayName}.Provider` : null;
119
+ }
120
+ if (e === d.ContextConsumer) {
121
+ const i = t;
122
+ return i?.displayName ? `${i.displayName}.Consumer` : null;
123
+ }
124
+ if (e === d.LazyComponent) {
125
+ const i = n;
126
+ return i?._status === 1 && i._result ? T(i._result) : null;
127
+ }
128
+ return e === d.IncompleteClassComponent || e === d.IncompleteFunctionComponent || e === d.FunctionComponent || e === d.ClassComponent || e === d.IndeterminateComponent ? T(t) : null;
129
+ }
130
+ function ee(a) {
131
+ return a.length <= 2 || a.length <= 3 && a === a.toLowerCase();
132
+ }
133
+ function te(a) {
134
+ return !(K.has(a) || J.some((e) => e.test(a)));
135
+ }
136
+ function ne(a, e = F, t = $) {
137
+ if (!q())
138
+ return c("client", "isReactPage() = false"), { path: null, components: [] };
139
+ const n = [];
140
+ try {
141
+ let i = Z(a), s = 0;
142
+ for (; i && s < t && n.length < e; ) {
143
+ const r = Q(i);
144
+ r && !ee(r) && te(r) && n.push(r), i = i.return, s++;
145
+ }
146
+ } catch (i) {
147
+ return c("client", "Error walking fiber tree:", i), { path: null, components: [] };
148
+ }
149
+ return n.length === 0 ? { path: null, components: [] } : { path: n.slice().reverse().map((i) => `<${i}>`).join(" "), components: n };
150
+ }
151
+ let I = null, E = null;
152
+ function N(a, e, t, n = "solid") {
153
+ const o = document.createElement("div");
154
+ return Object.assign(o.style, { position: "fixed", left: `${a.left}px`, top: `${a.top}px`, width: `${a.width}px`, height: `${a.height}px`, border: `1px ${n} ${e}`, backgroundColor: t, pointerEvents: "none", zIndex: S.HOVER_OVERLAY, borderRadius: "2px" }), o;
155
+ }
156
+ function oe(a) {
157
+ M();
158
+ const e = a.getBoundingClientRect();
159
+ I = N(e, f.SELECT_OVERLAY_BORDER, f.SELECT_OVERLAY_BG), I.className = "forge-overlay", document.body.appendChild(I);
160
+ }
161
+ function M() {
162
+ I && (I.remove(), I = null);
163
+ }
164
+ function ie() {
165
+ return E || (E = document.createElement("div"), Object.assign(E.style, { position: "fixed", top: "0", left: "0", width: "100%", height: "100%", backgroundColor: "transparent", pointerEvents: "auto", zIndex: S.HIT_TEST_OVERLAY, cursor: "crosshair" }), E.className = "forge-hit-test-overlay", document.body.appendChild(E), E);
166
+ }
167
+ function se() {
168
+ E && (E.remove(), E = null);
169
+ }
170
+ let re = 0;
171
+ function ae() {
172
+ return `ann-${Date.now()}-${++re}`;
173
+ }
174
+ class R {
175
+ active = !1;
176
+ messenger;
177
+ hoverOverlay = null;
178
+ componentTooltip = null;
179
+ hitTestOverlay = null;
180
+ dragRect = null;
181
+ dragHighlights = [];
182
+ annotationHighlights = [];
183
+ dots = /* @__PURE__ */ new Map();
184
+ isDragging = !1;
185
+ dragStartX = 0;
186
+ dragStartY = 0;
187
+ dragScopeParent = null;
188
+ hoverSuppressed = !1;
189
+ activeHighlightDotId = null;
190
+ constructor(e) {
191
+ this.messenger = e, window.__forgeAnnotations = this, window.addEventListener("scroll", this.repositionAll, { capture: !0, passive: !0 }), window.addEventListener("resize", this.repositionAll, { passive: !0 });
192
+ }
193
+ activate() {
194
+ this.active || (this.active = !0, c("annotation", "Annotation mode activated"), this.createHitTestOverlay(), this.addListeners(), this.setMarkersVisible(!0), document.body.style.cursor = "crosshair");
195
+ }
196
+ deactivate() {
197
+ this.active && (this.active = !1, c("annotation", "Annotation mode deactivated"), this.removeHoverOverlay(), this.clearAnnotationHighlights(), this.removeHitTestOverlay(), this.removeDragRect(), this.removeListeners(), this.setMarkersVisible(!1), document.body.style.cursor = "");
198
+ }
199
+ removeDot(e) {
200
+ const t = this.dots.get(e);
201
+ t && (t.element.remove(), this.dots.delete(e)), this.hoverSuppressed = !1;
202
+ }
203
+ removeAllDots() {
204
+ this.dots.forEach((e) => e.element.remove()), this.dots.clear();
205
+ }
206
+ restoreDots(e) {
207
+ this.removeAllDots();
208
+ for (const t of e) {
209
+ const n = t.elements.map((i) => ({ xpath: i.xpath, forgeId: i.forgeId, forgeIdIndex: i.forgeIdIndex })), o = this.getAnchorRect(n);
210
+ if (o && t.anchorOffset && o.width > 0 && o.height > 0) {
211
+ const i = { rx: t.anchorOffset.x, ry: t.anchorOffset.y }, s = o.left + i.rx * o.width, r = o.top + i.ry * o.height;
212
+ this.createDotAtPosition(s, r, t.mode, t.id, t.order, n, i);
213
+ } else
214
+ this.createDot(t.dotX, t.dotY, t.mode, t.id, t.order, n);
215
+ }
216
+ c("annotation", `Restored ${e.length} annotation dots`);
217
+ }
218
+ markersVisible = !1;
219
+ toggleMarkers() {
220
+ this.setMarkersVisible(!this.markersVisible);
221
+ }
222
+ setMarkersVisible(e) {
223
+ this.markersVisible = e;
224
+ const t = e ? "flex" : "none";
225
+ this.dots.forEach((n) => {
226
+ n.element.style.display = t;
227
+ });
228
+ }
229
+ repositionAll = () => {
230
+ if (this.dots.forEach((e) => {
231
+ if (e.locators.length === 0) return;
232
+ const t = this.getAnchorRect(e.locators);
233
+ t && (e.element.style.left = `${t.left + e.anchorRatio.rx * t.width}px`, e.element.style.top = `${t.top + e.anchorRatio.ry * t.height}px`);
234
+ }), this.activeHighlightDotId) {
235
+ const e = this.dots.get(this.activeHighlightDotId);
236
+ e && this.highlightAnnotationElements(e);
237
+ }
238
+ };
239
+ createHitTestOverlay() {
240
+ this.hitTestOverlay || (this.hitTestOverlay = document.createElement("div"), Object.assign(this.hitTestOverlay.style, { position: "fixed", top: "0", left: "0", width: "100%", height: "100%", backgroundColor: "transparent", pointerEvents: "auto", zIndex: S.HIT_TEST_OVERLAY, cursor: "crosshair" }), this.hitTestOverlay.className = "forge-annotation-hit-test", document.body.appendChild(this.hitTestOverlay));
241
+ }
242
+ removeHitTestOverlay() {
243
+ this.hitTestOverlay && (this.hitTestOverlay.remove(), this.hitTestOverlay = null);
244
+ }
245
+ showHoverOverlay(e, t, n) {
246
+ this.hoverOverlay && (this.hoverOverlay.remove(), this.hoverOverlay = null);
247
+ const o = e.getBoundingClientRect(), i = t === f.ANNOTATION_MULTI ? f.ANNOTATION_MULTI_BG : f.ANNOTATION_SINGLE_BG;
248
+ this.hoverOverlay = N(o, t, i, "solid"), this.hoverOverlay.style.transition = "all 0.05s ease", this.hoverOverlay.className = "forge-annotation-hover", document.body.appendChild(this.hoverOverlay), this.showComponentTooltip(n || e, o);
249
+ }
250
+ removeHoverOverlay() {
251
+ this.hoverOverlay && (this.hoverOverlay.remove(), this.hoverOverlay = null), this.removeComponentTooltip();
252
+ }
253
+ highlightAnnotationElements(e) {
254
+ this.clearAnnotationHighlights(), this.activeHighlightDotId = e.id, this.applySelectedStyle(e), this.highlightLocators(e.locators, e.mode === "multi");
255
+ }
256
+ applySelectedStyle(e) {
257
+ e.element.style.backgroundColor = "#0038AE", e.element.style.borderColor = "#0038AE", e.element.style.color = "#FFFFFF";
258
+ }
259
+ applyDefaultStyle(e) {
260
+ e.element.style.backgroundColor = "#FFFFFF", e.element.style.borderColor = "#1A58D0", e.element.style.color = "#1A58D0";
261
+ }
262
+ resolveLocator(e) {
263
+ if (e.forgeId) {
264
+ const t = document.querySelectorAll(`[data-forge-id="${e.forgeId}"]`);
265
+ if (t.length === 1) return t[0];
266
+ if (t.length > 1 && e.forgeIdIndex != null && e.forgeIdIndex < t.length)
267
+ return t[e.forgeIdIndex];
268
+ t.length > 1 && c("annotation", `Multiple elements with forge-id "${e.forgeId}", falling back to xpath`), t.length === 0 && c("annotation", `No element with forge-id "${e.forgeId}", falling back to xpath`);
269
+ }
270
+ try {
271
+ return document.evaluate(e.xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
272
+ } catch {
273
+ return null;
274
+ }
275
+ }
276
+ highlightLocators(e, t) {
277
+ const n = [];
278
+ for (const o of e) {
279
+ const i = this.resolveLocator(o);
280
+ if (i) {
281
+ const s = i.getBoundingClientRect();
282
+ n.push(s);
283
+ const r = N(s, f.ANNOTATION_SINGLE, f.ANNOTATION_SINGLE_BG, "solid");
284
+ r.className = "forge-annotation-highlight", document.body.appendChild(r), this.annotationHighlights.push(r);
285
+ }
286
+ }
287
+ if (t && n.length > 1) {
288
+ const o = Math.min(...n.map((h) => h.left)), i = Math.min(...n.map((h) => h.top)), s = Math.max(...n.map((h) => h.right)), r = Math.max(...n.map((h) => h.bottom)), l = new DOMRect(o, i, s - o, r - i), u = N(l, f.ANNOTATION_SINGLE, "transparent", "dashed");
289
+ u.className = "forge-annotation-bounding-rect", document.body.appendChild(u), this.annotationHighlights.push(u);
290
+ }
291
+ }
292
+ clearAnnotationHighlights() {
293
+ if (this.activeHighlightDotId) {
294
+ const e = this.dots.get(this.activeHighlightDotId);
295
+ e && this.applyDefaultStyle(e);
296
+ }
297
+ for (const e of this.annotationHighlights) e.remove();
298
+ this.annotationHighlights = [], this.activeHighlightDotId = null;
299
+ }
300
+ getAnchorRect(e) {
301
+ let t = 1 / 0, n = 1 / 0, o = -1 / 0, i = -1 / 0, s = !1;
302
+ for (const r of e) {
303
+ const l = this.resolveLocator(r);
304
+ if (l) {
305
+ const u = l.getBoundingClientRect();
306
+ t = Math.min(t, u.left), n = Math.min(n, u.top), o = Math.max(o, u.right), i = Math.max(i, u.bottom), s = !0;
307
+ }
308
+ }
309
+ return s ? new DOMRect(t, n, o - t, i - n) : null;
310
+ }
311
+ getComponentPath(e) {
312
+ const t = [], n = /* @__PURE__ */ new Set();
313
+ let o = e;
314
+ for (; o; ) {
315
+ const r = o.getAttribute("data-component");
316
+ r && !n.has(r) && (n.add(r), t.push(r)), o = o.parentElement;
317
+ }
318
+ const i = ne(e), s = [...t];
319
+ if (i.components.length > 0)
320
+ for (const r of i.components)
321
+ n.has(r) || (n.add(r), s.push(r));
322
+ return s.length === 0 ? null : s.reverse().map((r) => `<${r}>`).join(" ");
323
+ }
324
+ showComponentTooltip(e, t) {
325
+ this.removeComponentTooltip();
326
+ const n = this.getComponentPath(e);
327
+ if (!n) return;
328
+ const o = document.createElement("div");
329
+ Object.assign(o.style, { position: "fixed", zIndex: S.TOOLTIP, backgroundColor: "rgba(30, 30, 30, 0.92)", color: "#e4e4e7", padding: "4px 10px", borderRadius: "6px", fontSize: "11px", fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", fontWeight: "500", letterSpacing: "0.3px", whiteSpace: "nowrap", pointerEvents: "none", backdropFilter: "blur(8px)", boxShadow: "0 2px 8px rgba(0,0,0,0.3)", transition: "opacity 0.1s ease" }), o.textContent = n, o.className = "forge-annotation-component-tooltip", document.body.appendChild(o);
330
+ const i = o.getBoundingClientRect();
331
+ let s = t.left + t.width / 2 - i.width / 2, r = t.top - i.height - 6;
332
+ s < 4 && (s = 4), s + i.width > window.innerWidth - 4 && (s = window.innerWidth - i.width - 4), r < 4 && (r = t.bottom + 6), o.style.left = `${s}px`, o.style.top = `${r}px`, this.componentTooltip = o;
333
+ }
334
+ removeComponentTooltip() {
335
+ this.componentTooltip && (this.componentTooltip.remove(), this.componentTooltip = null);
336
+ }
337
+ showDragRect(e, t, n, o) {
338
+ this.dragRect || (this.dragRect = document.createElement("div"), Object.assign(this.dragRect.style, { position: "fixed", border: `1px dashed ${f.ANNOTATION_MULTI}`, backgroundColor: f.DRAG_RECT_BG, pointerEvents: "none", zIndex: S.HOVER_OVERLAY, borderRadius: "4px" }), this.dragRect.className = "forge-annotation-drag-rect", document.body.appendChild(this.dragRect)), Object.assign(this.dragRect.style, { left: `${Math.min(e, n)}px`, top: `${Math.min(t, o)}px`, width: `${Math.abs(n - e)}px`, height: `${Math.abs(o - t)}px` });
339
+ }
340
+ removeDragRect() {
341
+ this.dragRect && (this.dragRect.remove(), this.dragRect = null), this.clearDragHighlights();
342
+ }
343
+ showDragHighlights(e) {
344
+ this.clearDragHighlights();
345
+ for (const t of e) {
346
+ const n = t.getBoundingClientRect(), o = N(n, f.ANNOTATION_MULTI, f.ANNOTATION_MULTI_BG, "solid");
347
+ o.className = "forge-annotation-drag-highlight", document.body.appendChild(o), this.dragHighlights.push(o);
348
+ }
349
+ }
350
+ clearDragHighlights() {
351
+ for (const e of this.dragHighlights) e.remove();
352
+ this.dragHighlights = [];
353
+ }
354
+ createDot(e, t, n, o, i, s = []) {
355
+ const r = this.getAnchorRect(s), l = e - 2, u = t - L - 2, h = r && r.width > 0 && r.height > 0 ? { rx: (l - r.left) / r.width, ry: (u - r.top) / r.height } : { rx: 0, ry: 0 };
356
+ this.createDotAtPosition(l, u, n, o, i, s, h);
357
+ }
358
+ createDotAtPosition(e, t, n, o, i, s, r) {
359
+ const l = document.createElement("div");
360
+ Object.assign(l.style, { position: "fixed", left: `${e}px`, top: `${t}px`, minWidth: `${G}px`, height: `${L}px`, borderRadius: "50% 50% 50% 0", backgroundColor: "#FFFFFF", border: "1px solid #1A58D0", cursor: "pointer", zIndex: S.ANNOTATION_DOT, transition: "transform 0.15s ease", display: this.markersVisible ? "flex" : "none", alignItems: "center", justifyContent: "center", padding: "0 4px", fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif", fontSize: "11px", fontWeight: "700", color: "#1A58D0", lineHeight: "1", userSelect: "none" }), l.textContent = String(i), l.className = "forge-annotation-dot", l.dataset.annotationId = o, l.addEventListener("mouseenter", () => {
361
+ l.style.transform = "scale(1.05)", this.removeHoverOverlay(), this.hoverSuppressed = !0;
362
+ }), l.addEventListener("mouseleave", () => {
363
+ l.style.transform = "scale(1)";
364
+ }), l.addEventListener("click", (u) => {
365
+ u.stopPropagation(), u.preventDefault(), this.hoverSuppressed = !0, this.removeHoverOverlay();
366
+ const h = this.dots.get(o);
367
+ h && this.highlightAnnotationElements(h);
368
+ const m = l.getBoundingClientRect();
369
+ this.messenger.send({ type: "ANNOTATION_DOT_CLICKED", annotationId: o, dotX: m.left, dotY: m.bottom, origin: C });
370
+ }), document.body.appendChild(l), this.dots.set(o, { id: o, element: l, mode: n, order: i, locators: s, anchorRatio: r });
371
+ }
372
+ updateOrders(e) {
373
+ for (const [t, n] of Object.entries(e)) {
374
+ const o = this.dots.get(t);
375
+ o && (o.order = n, o.element.textContent = String(n));
376
+ }
377
+ }
378
+ elementAtPoint(e, t) {
379
+ this.hitTestOverlay && (this.hitTestOverlay.style.pointerEvents = "none"), this.hoverOverlay && (this.hoverOverlay.style.pointerEvents = "none"), this.dots.forEach((o) => o.element.style.pointerEvents = "none");
380
+ const n = document.elementFromPoint(e, t);
381
+ return this.hitTestOverlay && (this.hitTestOverlay.style.pointerEvents = "auto"), this.hoverOverlay && (this.hoverOverlay.style.pointerEvents = "none"), this.dots.forEach((o) => o.element.style.pointerEvents = "auto"), !n || n === document.body || n === document.documentElement ? null : this.escapeToSvgRoot(n);
382
+ }
383
+ escapeToSvgRoot(e) {
384
+ if (!(e instanceof SVGElement)) return e;
385
+ let t = e;
386
+ for (; t.parentElement; ) {
387
+ if (t.tagName.toLowerCase() === "svg" && !(t.parentElement instanceof SVGElement))
388
+ return t;
389
+ t = t.parentElement;
390
+ }
391
+ return t || e;
392
+ }
393
+ findTopmostWithSameForgeId(e) {
394
+ const t = e.getAttribute("data-forge-id");
395
+ if (!t) return e;
396
+ let n = e, o = e;
397
+ for (; n.parentElement; ) {
398
+ const i = n.parentElement;
399
+ if (i.getAttribute("data-forge-id") !== t) break;
400
+ o = i, n = i;
401
+ }
402
+ return o;
403
+ }
404
+ findForgeIdParent(e) {
405
+ let t = e.parentElement;
406
+ for (; t; ) {
407
+ if (t.getAttribute("data-forge-id")) return t;
408
+ t = t.parentElement;
409
+ }
410
+ return null;
411
+ }
412
+ elementsInRect(e, t, n, o) {
413
+ const i = Math.min(e, n), s = Math.min(t, o), r = Math.max(e, n), l = Math.max(t, o), u = document.querySelectorAll("[data-forge-id]"), h = [], m = /* @__PURE__ */ new Set();
414
+ if (u.forEach((p) => {
415
+ const y = p, g = y.getAttribute("data-forge-id");
416
+ if (!g || m.has(g) || y instanceof SVGElement && y.tagName.toLowerCase() !== "svg" || y.closest?.("svg") && y.tagName.toLowerCase() !== "svg") return;
417
+ const v = this.findTopmostWithSameForgeId(y);
418
+ if (m.has(v.getAttribute("data-forge-id") || "")) return;
419
+ const b = v.getBoundingClientRect();
420
+ b.right >= i && b.left <= r && b.bottom >= s && b.top <= l && (m.add(g), h.push(v));
421
+ }), this.dragScopeParent) {
422
+ const p = this.findForgeIdParent(this.dragScopeParent);
423
+ if (p)
424
+ return h.filter((g) => {
425
+ const v = this.findForgeIdParent(g);
426
+ return v ? this.findForgeIdParent(v) === p : !1;
427
+ });
428
+ const y = this.dragScopeParent;
429
+ return h.filter((g) => this.findForgeIdParent(g) === y);
430
+ }
431
+ return h;
432
+ }
433
+ handleMouseMove = (e) => {
434
+ if (this.hoverSuppressed) {
435
+ this.removeHoverOverlay();
436
+ return;
437
+ }
438
+ if (this.isDragging) {
439
+ this.showDragRect(this.dragStartX, this.dragStartY, e.clientX, e.clientY);
440
+ const n = this.elementsInRect(this.dragStartX, this.dragStartY, e.clientX, e.clientY);
441
+ this.showDragHighlights(n), this.removeHoverOverlay();
442
+ return;
443
+ }
444
+ if (e.buttons === 1) {
445
+ const n = e.clientX - this.dragStartX, o = e.clientY - this.dragStartY;
446
+ if (Math.abs(n) > R.DRAG_THRESHOLD || Math.abs(o) > R.DRAG_THRESHOLD) {
447
+ this.isDragging = !0;
448
+ return;
449
+ }
450
+ }
451
+ const t = this.elementAtPoint(e.clientX, e.clientY);
452
+ if (t) {
453
+ const n = this.findTopmostWithSameForgeId(t);
454
+ this.showHoverOverlay(n, f.ANNOTATION_SINGLE, t);
455
+ } else
456
+ this.removeHoverOverlay();
457
+ };
458
+ static DRAG_THRESHOLD = 5;
459
+ handleMouseDown = (e) => {
460
+ this.dragStartX = e.clientX, this.dragStartY = e.clientY, this.isDragging = !1;
461
+ const t = this.elementAtPoint(e.clientX, e.clientY);
462
+ if (t) {
463
+ const n = this.findTopmostWithSameForgeId(t);
464
+ this.dragScopeParent = this.findForgeIdParent(n);
465
+ } else
466
+ this.dragScopeParent = null;
467
+ e.preventDefault();
468
+ };
469
+ handleMouseUp = (e) => {
470
+ if (this.isDragging) {
471
+ this.isDragging = !1;
472
+ const o = this.elementsInRect(this.dragStartX, this.dragStartY, e.clientX, e.clientY);
473
+ this.dragScopeParent = null, this.removeDragRect(), o.length > 0 && this.createAnnotationFromElements(o, "multi", e.clientX, e.clientY);
474
+ return;
475
+ }
476
+ const t = this.elementAtPoint(e.clientX, e.clientY);
477
+ if (!t) return;
478
+ const n = this.findTopmostWithSameForgeId(t);
479
+ this.createAnnotationFromElements([n], "single", e.clientX, e.clientY);
480
+ };
481
+ handleClick = (e) => {
482
+ e.preventDefault(), e.stopPropagation();
483
+ };
484
+ handleKeyDown = (e) => {
485
+ e.key === "Escape" && (this.removeHoverOverlay(), this.removeDragRect(), this.isDragging = !1, this.dragScopeParent = null);
486
+ };
487
+ handleKeyUp = (e) => {
488
+ };
489
+ pendingAnnotations = /* @__PURE__ */ new Map();
490
+ confirmDot(e, t) {
491
+ const n = this.pendingAnnotations.get(e);
492
+ n && (this.createDot(n.dotX, n.dotY, n.mode, e, t, n.locators), this.pendingAnnotations.delete(e)), this.clearAnnotationHighlights(), this.hoverSuppressed = !1;
493
+ }
494
+ cancelPending(e) {
495
+ this.pendingAnnotations.delete(e), this.clearAnnotationHighlights(), this.hoverSuppressed = !1;
496
+ }
497
+ createAnnotationFromElements(e, t, n, o) {
498
+ const i = ae();
499
+ this.hoverSuppressed = !0, this.removeHoverOverlay();
500
+ const s = e.map((g) => {
501
+ const v = g.getAttribute("data-forge-id") || void 0;
502
+ let b;
503
+ if (v) {
504
+ const P = document.querySelectorAll(`[data-forge-id="${v}"]`);
505
+ P.length > 1 && (b = Array.from(P).indexOf(g));
506
+ }
507
+ return { elementTag: g.tagName.toLowerCase(), xpath: w(g), componentName: g.getAttribute("data-component") || void 0, componentPath: this.getComponentPath(g) || void 0, forgeId: v, forgeIdIndex: b, sourcePos: g.getAttribute("data-source-pos") || void 0 };
508
+ }), r = s.map((g) => ({ xpath: g.xpath, forgeId: g.forgeId, forgeIdIndex: g.forgeIdIndex })), l = this.getAnchorRect(r), u = n - 2, h = o - L - 2, m = l && l.width > 0 && l.height > 0 ? { x: (u - l.left) / l.width, y: (h - l.top) / l.height } : { x: 0, y: 0 };
509
+ this.pendingAnnotations.set(i, { dotX: n, dotY: o, mode: t, locators: r }), this.clearDragHighlights(), this.highlightLocators(r, t === "multi");
510
+ const p = s[0], y = { id: i, dotX: n, dotY: o, anchorOffset: m, mode: t, elements: s, xpaths: s.map((g) => g.xpath), elementTag: p.elementTag, componentName: p.componentName, componentPath: p.componentPath, forgeId: p.forgeId, sourcePos: p.sourcePos };
511
+ c("annotation", "Annotation created (pending):", y), this.messenger.send({ type: "ANNOTATION_CREATED", annotation: y, origin: C });
512
+ }
513
+ handleDocumentLeave = () => {
514
+ this.removeHoverOverlay();
515
+ };
516
+ addListeners() {
517
+ this.hitTestOverlay && (this.hitTestOverlay.addEventListener("mousemove", this.handleMouseMove), this.hitTestOverlay.addEventListener("mousedown", this.handleMouseDown), this.hitTestOverlay.addEventListener("mouseup", this.handleMouseUp), this.hitTestOverlay.addEventListener("click", this.handleClick), document.addEventListener("keydown", this.handleKeyDown), document.addEventListener("keyup", this.handleKeyUp), document.addEventListener("mouseleave", this.handleDocumentLeave));
518
+ }
519
+ removeListeners() {
520
+ this.hitTestOverlay && (this.hitTestOverlay.removeEventListener("mousemove", this.handleMouseMove), this.hitTestOverlay.removeEventListener("mousedown", this.handleMouseDown), this.hitTestOverlay.removeEventListener("mouseup", this.handleMouseUp), this.hitTestOverlay.removeEventListener("click", this.handleClick)), document.removeEventListener("keydown", this.handleKeyDown), document.removeEventListener("keyup", this.handleKeyUp), document.removeEventListener("mouseleave", this.handleDocumentLeave);
521
+ }
522
+ }
523
+ class le {
524
+ messenger;
525
+ callbacks;
526
+ hitTestOverlay = null;
527
+ hoveredElement = null;
528
+ constructor(e, t) {
529
+ this.messenger = e, this.callbacks = t;
530
+ }
531
+ enableListeners() {
532
+ this.hitTestOverlay = ie(), this.hitTestOverlay.addEventListener("mousemove", this.handleMouseOver), this.hitTestOverlay.addEventListener("mouseout", this.handleMouseOut), this.hitTestOverlay.addEventListener("click", this.handleClick), document.addEventListener("scroll", this.handleScroll, !0);
533
+ }
534
+ disableListeners() {
535
+ this.hitTestOverlay && (this.hitTestOverlay.removeEventListener("mousemove", this.handleMouseOver), this.hitTestOverlay.removeEventListener("mouseout", this.handleMouseOut), this.hitTestOverlay.removeEventListener("click", this.handleClick)), document.removeEventListener("scroll", this.handleScroll, !0), se(), this.hitTestOverlay = null;
536
+ }
537
+ clearHover() {
538
+ this.hoveredElement = null, M();
539
+ }
540
+ findTopmostElementWithSameId(e) {
541
+ const t = e.getAttribute("data-forge-id");
542
+ if (!t) return e;
543
+ let n = e, o = e;
544
+ for (; n.parentElement; ) {
545
+ const i = n.parentElement;
546
+ if (i.getAttribute("data-forge-id") !== t) break;
547
+ o = i, n = i;
548
+ }
549
+ return o;
550
+ }
551
+ handleSelectModeClick(e) {
552
+ const t = w(e);
553
+ c("client", "Element clicked, XPath:", t), this.messenger.send({ type: "XPATH_REPORT", xpath: t, origin: C }), this.messenger.send({ type: "SELECT_MODE_DISABLED", origin: C });
554
+ }
555
+ handleMouseOver = (e) => {
556
+ if (!this.callbacks.getSelectMode() && !this.callbacks.getDesignMode() || this.callbacks.getHoverDisabled()) return;
557
+ this.hitTestOverlay && (this.hitTestOverlay.style.pointerEvents = "none");
558
+ const t = document.elementFromPoint(e.clientX, e.clientY);
559
+ if (this.hitTestOverlay && (this.hitTestOverlay.style.pointerEvents = "auto"), t && t !== document.body && t !== document.documentElement) {
560
+ const o = t.getAttribute("data-forge-id") ? this.findTopmostElementWithSameId(t) : t;
561
+ if (this.callbacks.getDesignMode() && o === this.callbacks.getSelectedDesignElement())
562
+ return;
563
+ this.hoveredElement = o, oe(o);
564
+ }
565
+ };
566
+ handleMouseOut = (e) => {
567
+ if (!this.callbacks.getSelectMode() && !this.callbacks.getDesignMode()) return;
568
+ e.target === this.hoveredElement && (this.hoveredElement = null, M());
569
+ };
570
+ handleClick = (e) => {
571
+ if (!this.callbacks.getSelectMode() && !this.callbacks.getDesignMode()) return;
572
+ e.preventDefault(), e.stopPropagation(), this.hitTestOverlay && (this.hitTestOverlay.style.pointerEvents = "none");
573
+ const t = document.elementFromPoint(e.clientX, e.clientY);
574
+ this.hitTestOverlay && (this.hitTestOverlay.style.pointerEvents = "auto"), t && t !== document.body && t !== document.documentElement && (this.callbacks.getSelectMode() && this.callbacks.onSelectClick(t), this.callbacks.getDesignMode() && (M(), this.hoveredElement = null, this.callbacks.onDesignClick(t)));
575
+ };
576
+ handleScroll = () => {
577
+ (this.callbacks.getSelectMode() || this.callbacks.getDesignMode()) && (this.hoveredElement = null, M());
578
+ };
579
+ }
580
+ const ce = typeof x == "function" ? x : x.default, he = typeof _ == "function" ? _ : _.default;
581
+ function H(a) {
582
+ return typeof a == "boolean" ? { type: "JSXExpressionContainer", expression: { type: "BooleanLiteral", value: a, loc: null }, loc: null } : typeof a == "number" ? { type: "JSXExpressionContainer", expression: { type: "NumericLiteral", value: a, loc: null }, loc: null } : { type: "StringLiteral", value: String(a), loc: null };
583
+ }
584
+ function k(a, e, t) {
585
+ const n = a.node.attributes.find((o) => o.type === "JSXAttribute" && o.name.type === "JSXIdentifier" && o.name.name === e);
586
+ return n && n.type === "JSXAttribute" ? (n.value = H(t), !0) : (a.node.attributes.push({ type: "JSXAttribute", name: { type: "JSXIdentifier", name: e }, value: H(t), loc: null }), !0);
587
+ }
588
+ function de(a, e, t, n, o) {
589
+ try {
590
+ const i = U(a, { sourceType: "module", plugins: ["jsx", "typescript"] });
591
+ let s = !1;
592
+ const r = /* @__PURE__ */ new Map();
593
+ if (ce(i, { JSXOpeningElement(l) {
594
+ if (l.node.name.type !== "JSXIdentifier") return;
595
+ const u = l.node.loc;
596
+ if (!u) return;
597
+ const h = `${u.start.line}:${u.start.column}`;
598
+ r.set(h, l);
599
+ const m = l.node.attributes.find((p) => p.type === "JSXAttribute" && p.name.type === "JSXIdentifier" && p.name.name === "data-forge-id" && p.value?.type === "StringLiteral");
600
+ m && m.type === "JSXAttribute" && m.value.value === e && (s = k(l, t, n));
601
+ } }), !s && o) {
602
+ const l = o.split(":");
603
+ if (l.length >= 5) {
604
+ const u = `${l[l.length - 4]}:${l[l.length - 3]}`, h = r.get(u);
605
+ h && (s = k(h, t, n));
606
+ }
607
+ }
608
+ if (s)
609
+ return he(i, {}, a).code;
610
+ } catch (i) {
611
+ c("client", "Failed to parse/update AST:", i);
612
+ }
613
+ return a;
614
+ }
615
+ async function ue(a) {
616
+ try {
617
+ const e = await fetch(`/__forge-read-source?path=${a}`);
618
+ if (e.ok)
619
+ return await e.text();
620
+ c("client", `Failed to fetch source for ${a}: ${e.status}`);
621
+ } catch (e) {
622
+ c("client", "Failed to fetch source:", e);
623
+ }
624
+ return null;
625
+ }
626
+ async function ge(a, e) {
627
+ try {
628
+ return await fetch("/__forge-update-source", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ filePath: a, source: e }) }), !0;
629
+ } catch (t) {
630
+ return c("client", "Failed to write source:", t), !1;
631
+ }
632
+ }
633
+ class me {
634
+ messenger;
635
+ componentRegistry;
636
+ selectController;
637
+ selectedElement = null;
638
+ sourceCache = /* @__PURE__ */ new Map();
639
+ constructor(e, t, n) {
640
+ this.messenger = e, this.componentRegistry = t, this.selectController = n;
641
+ }
642
+ getSelectedElement() {
643
+ return this.selectedElement;
644
+ }
645
+ clearSelection() {
646
+ this.selectedElement && (this.removeHighlight(this.selectedElement), this.selectedElement = null);
647
+ }
648
+ handleClick(e) {
649
+ const t = e.getAttribute("data-forge-id");
650
+ if (!t) {
651
+ c("client", "Clicked element has no data-forge-id");
652
+ return;
653
+ }
654
+ const n = this.selectController.findTopmostElementWithSameId(e), o = n.getAttribute("data-component"), i = n.getAttribute("data-source-pos"), s = o || n.tagName.toLowerCase();
655
+ this.clearSelection(), this.selectedElement = n, this.applyHighlight(n);
656
+ const r = n.textContent?.trim() || "", l = n.tagName.toLowerCase(), u = w(n), h = this.componentRegistry.getEditableProps(s), m = this.extractPropValues(n, h);
657
+ c("client", "Element selected in design mode:", { forgeId: t, sourcePos: i, text: r, type: l, componentName: s, editableProps: h, propValues: m }), this.messenger.send({ type: "ELEMENT_SELECTED", forgeId: t, sourcePos: i || void 0, text: r, elementType: l, xpath: u, componentName: s, editableProps: h, propValues: m, origin: C });
658
+ }
659
+ updateText(e, t) {
660
+ this.updateProperty(e, "children", t);
661
+ }
662
+ async updateProperty(e, t, n) {
663
+ const o = document.querySelector(`[data-forge-id="${e}"]`);
664
+ if (!o) {
665
+ c("client", `Element with forge ID ${e} not found`);
666
+ return;
667
+ }
668
+ const i = o.getAttribute("data-source-pos");
669
+ if (!i) {
670
+ c("client", `Element ${e} missing data-source-pos attribute`);
671
+ return;
672
+ }
673
+ const s = i.split(":");
674
+ if (s.length < 5) {
675
+ c("client", `Invalid data-source-pos format: ${i}`);
676
+ return;
677
+ }
678
+ const r = s.slice(0, -4).join(":");
679
+ c("client", `Updating property ${t} = ${n} for ${e} in ${r}`), this.sourceCache.delete(r);
680
+ const l = await ue(r);
681
+ if (!l) return;
682
+ this.sourceCache.set(r, l);
683
+ const u = this.selectedElement?.getAttribute("data-source-pos") ?? null, h = de(l, e, t, n, u);
684
+ h !== l ? (this.sourceCache.set(r, h), c("client", `Updated source for ${r}`), await ge(r, h) && (c("client", `Source written to disk and HMR triggered for ${r}`), this.messenger.send({ type: "SOURCE_UPDATED", forgeId: e, source: h, filePath: r, origin: C }))) : c("client", `No source changes detected for ${r}`);
685
+ }
686
+ applyHighlight(e) {
687
+ e.style.outline = `3px solid ${f.DESIGN_SELECTION_OUTLINE}`, e.style.outlineOffset = "2px";
688
+ }
689
+ removeHighlight(e) {
690
+ e.style.outline = "", e.style.outlineOffset = "";
691
+ }
692
+ extractPropValues(e, t) {
693
+ const n = this.getFiberFromElement(e);
694
+ if (!n) return {};
695
+ let o = n;
696
+ for (; o; ) {
697
+ if (o.memoizedProps && o.type && typeof o.type != "string") {
698
+ const i = o.memoizedProps, s = {};
699
+ for (const r of t) {
700
+ const l = r.name;
701
+ l === "children" ? s[l] = i.children || e.textContent?.trim() || "" : l in i && (s[l] = i[l]);
702
+ }
703
+ return c("client", "Extracted prop values:", s), s;
704
+ }
705
+ o = o.return;
706
+ }
707
+ return {};
708
+ }
709
+ getFiberFromElement(e) {
710
+ const t = Object.keys(e).find((n) => n.startsWith("__reactFiber") || n.startsWith("__reactInternalInstance"));
711
+ return t ? e[t] : null;
712
+ }
713
+ }
714
+ class A {
715
+ static instance = null;
716
+ messenger;
717
+ selectMode = !1;
718
+ designMode = !1;
719
+ hoverDisabled = !1;
720
+ componentRegistry;
721
+ annotationOverlay = null;
722
+ selectController;
723
+ designController;
724
+ onError;
725
+ constructor(e) {
726
+ this.onError = e?.onError, c("client", "ForgeClient initialized"), this.messenger = new B(), this.componentRegistry = new z(), this.selectController = new le(this.messenger, { getSelectMode: () => this.selectMode, getDesignMode: () => this.designMode, getHoverDisabled: () => this.hoverDisabled, getSelectedDesignElement: () => this.designController.getSelectedElement(), onSelectClick: (t) => this.handleSelectClick(t), onDesignClick: (t) => this.handleDesignClick(t) }), this.designController = new me(this.messenger, this.componentRegistry, this.selectController), this.setupMessageListener(), this.sendReady(), this.setupForgeIdPropagation(), window.__forgeClient = this;
727
+ }
728
+ static getInstance(e) {
729
+ return A.instance || (A.instance = new A(e)), A.instance;
730
+ }
731
+ enableAnnotationMode(e) {
732
+ this.setAnnotationMode(e);
733
+ }
734
+ setupMessageListener() {
735
+ c("client", "Setting up message listener..."), this.messenger.onMessage((e) => {
736
+ if (W(e.data) || !e.data || typeof e.data != "object" || !("origin" in e.data)) return;
737
+ const t = e.data;
738
+ if (t.origin === V) {
739
+ c("client", "Received message from host:", t);
740
+ try {
741
+ switch (t.type) {
742
+ case "ENABLE_SELECT_MODE":
743
+ this.setSelectMode(t.enabled);
744
+ break;
745
+ case "ENABLE_DESIGN_MODE":
746
+ this.setDesignMode(t.enabled);
747
+ break;
748
+ case "UPDATE_TEXT":
749
+ this.designController.updateText(t.forgeId, t.text);
750
+ break;
751
+ case "UPDATE_PROPERTY":
752
+ this.designController.updateProperty(t.forgeId, t.propName, t.value);
753
+ break;
754
+ case "ENABLE_ANNOTATION_MODE":
755
+ this.setAnnotationMode(t.enabled);
756
+ break;
757
+ case "ANNOTATION_DELETED":
758
+ this.annotationOverlay?.cancelPending(t.annotationId), this.annotationOverlay?.removeDot(t.annotationId);
759
+ break;
760
+ case "ANNOTATION_KEEP":
761
+ this.annotationOverlay?.confirmDot(t.annotationId, t.order);
762
+ break;
763
+ case "ANNOTATION_UPDATE_ORDERS":
764
+ this.annotationOverlay?.updateOrders(t.orders);
765
+ break;
766
+ case "DESELECT_ELEMENT":
767
+ this.designController.clearSelection();
768
+ break;
769
+ case "TOGGLE_MARKERS":
770
+ this.annotationOverlay?.toggleMarkers();
771
+ break;
772
+ case "RESTORE_ANNOTATIONS":
773
+ this.annotationOverlay || (this.annotationOverlay = new R(this.messenger)), this.annotationOverlay.restoreDots(t.annotations);
774
+ break;
775
+ case "PING":
776
+ c("client", "Received PING");
777
+ break;
778
+ }
779
+ } catch (n) {
780
+ c("client", "Error handling message:", t.type, n), this.onError?.(n instanceof Error ? n : new Error(String(n)));
781
+ }
782
+ }
783
+ });
784
+ }
785
+ setSelectMode(e) {
786
+ this.selectMode !== e && (c("client", `Setting select mode to: ${e}`), this.selectMode = e, e ? (this.selectController.enableListeners(), document.body.style.cursor = "crosshair") : (this.selectController.disableListeners(), document.body.style.cursor = "", this.selectController.clearHover()));
787
+ }
788
+ setDesignMode(e) {
789
+ this.designMode !== e && (c("client", `Setting design mode to: ${e}`), this.designMode = e, e ? (this.selectController.enableListeners(), this.hoverDisabled = !1, document.body.style.cursor = "crosshair") : (this.selectController.disableListeners(), this.hoverDisabled = !1, document.body.style.cursor = "", this.selectController.clearHover()));
790
+ }
791
+ setAnnotationMode(e) {
792
+ e ? (this.annotationOverlay || (this.annotationOverlay = new R(this.messenger)), this.setSelectMode(!1), this.setDesignMode(!1), this.annotationOverlay.activate()) : this.annotationOverlay?.deactivate();
793
+ }
794
+ handleSelectClick(e) {
795
+ this.selectController.handleSelectModeClick(e), this.setSelectMode(!1);
796
+ }
797
+ handleDesignClick(e) {
798
+ this.designController.handleClick(e), this.setDesignMode(!1);
799
+ }
800
+ sendReady() {
801
+ c("client", "Scheduling CHILD_READY message..."), setTimeout(() => {
802
+ c("client", "Sending CHILD_READY message to parent"), this.messenger.send({ type: "CHILD_READY", origin: C });
803
+ }, j.CHILD_READY_DELAY);
804
+ }
805
+ setupForgeIdPropagation() {
806
+ const e = () => {
807
+ document.querySelectorAll("*").forEach((n) => {
808
+ const o = this.getFiberFromElement(n);
809
+ o && this.propagateForgeIdFromFiber(o, n);
810
+ });
811
+ };
812
+ document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", e) : e(), new MutationObserver(() => e()).observe(document.body, { childList: !0, subtree: !0 });
813
+ }
814
+ getFiberFromElement(e) {
815
+ const t = Object.keys(e).find((n) => n.startsWith("__reactFiber") || n.startsWith("__reactInternalInstance"));
816
+ return t ? e[t] : null;
817
+ }
818
+ propagateForgeIdFromFiber(e, t) {
819
+ let n = e;
820
+ for (; n; ) {
821
+ if (n.memoizedProps) {
822
+ const o = n.memoizedProps["data-forge-id"], i = n.memoizedProps["data-component"], s = n.memoizedProps["data-source-pos"];
823
+ if (o && !t.getAttribute("data-forge-id")) {
824
+ t.setAttribute("data-forge-id", o), i && t.setAttribute("data-component", i), s && t.setAttribute("data-source-pos", s);
825
+ break;
826
+ }
827
+ }
828
+ n = n.return;
829
+ }
830
+ }
831
+ }
832
+ A.getInstance();
833
+ export {
834
+ A as ForgeClient,
835
+ B as ParentMessenger
836
+ };