@levo-so/site-runtime 0.2.3 → 0.3.1

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/es-iCqKQf1c.js ADDED
@@ -0,0 +1,455 @@
1
+ //#region ../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/util.js
2
+ function e(e, t) {
3
+ if (e.match(/^[a-z]+:\/\//i)) return e;
4
+ if (e.match(/^\/\//)) return window.location.protocol + e;
5
+ if (e.match(/^[a-z]+:/i)) return e;
6
+ let n = document.implementation.createHTMLDocument(), r = n.createElement("base"), i = n.createElement("a");
7
+ return n.head.appendChild(r), n.body.appendChild(i), t && (r.href = t), i.href = e, i.href;
8
+ }
9
+ var t = (() => {
10
+ let e = 0, t = () => `0000${(Math.random() * 36 ** 4 << 0).toString(36)}`.slice(-4);
11
+ return () => (e += 1, `u${t()}${e}`);
12
+ })();
13
+ function n(e) {
14
+ let t = [];
15
+ for (let n = 0, r = e.length; n < r; n++) t.push(e[n]);
16
+ return t;
17
+ }
18
+ var r = null;
19
+ function i(e = {}) {
20
+ return r || (e.includeStyleProperties ? (r = e.includeStyleProperties, r) : (r = n(window.getComputedStyle(document.documentElement)), r));
21
+ }
22
+ function a(e, t) {
23
+ let n = (e.ownerDocument.defaultView || window).getComputedStyle(e).getPropertyValue(t);
24
+ return n ? parseFloat(n.replace("px", "")) : 0;
25
+ }
26
+ function o(e) {
27
+ let t = a(e, "border-left-width"), n = a(e, "border-right-width");
28
+ return e.clientWidth + t + n;
29
+ }
30
+ function s(e) {
31
+ let t = a(e, "border-top-width"), n = a(e, "border-bottom-width");
32
+ return e.clientHeight + t + n;
33
+ }
34
+ function c(e, t = {}) {
35
+ return {
36
+ width: t.width || o(e),
37
+ height: t.height || s(e)
38
+ };
39
+ }
40
+ function l() {
41
+ let e, t;
42
+ try {
43
+ t = process;
44
+ } catch {}
45
+ let n = t && t.env ? t.env.devicePixelRatio : null;
46
+ return n && (e = parseInt(n, 10), Number.isNaN(e) && (e = 1)), e || window.devicePixelRatio || 1;
47
+ }
48
+ var u = 16384;
49
+ function ee(e) {
50
+ (e.width > u || e.height > u) && (e.width > u && e.height > u ? e.width > e.height ? (e.height *= u / e.width, e.width = u) : (e.width *= u / e.height, e.height = u) : e.width > u ? (e.height *= u / e.width, e.width = u) : (e.width *= u / e.height, e.height = u));
51
+ }
52
+ function d(e) {
53
+ return new Promise((t, n) => {
54
+ let r = new Image();
55
+ r.onload = () => {
56
+ r.decode().then(() => {
57
+ requestAnimationFrame(() => t(r));
58
+ });
59
+ }, r.onerror = n, r.crossOrigin = "anonymous", r.decoding = "async", r.src = e;
60
+ });
61
+ }
62
+ async function f(e) {
63
+ return Promise.resolve().then(() => new XMLSerializer().serializeToString(e)).then(encodeURIComponent).then((e) => `data:image/svg+xml;charset=utf-8,${e}`);
64
+ }
65
+ async function te(e, t, n) {
66
+ let r = "http://www.w3.org/2000/svg", i = document.createElementNS(r, "svg"), a = document.createElementNS(r, "foreignObject");
67
+ return i.setAttribute("width", `${t}`), i.setAttribute("height", `${n}`), i.setAttribute("viewBox", `0 0 ${t} ${n}`), a.setAttribute("width", "100%"), a.setAttribute("height", "100%"), a.setAttribute("x", "0"), a.setAttribute("y", "0"), a.setAttribute("externalResourcesRequired", "true"), i.appendChild(a), a.appendChild(e), f(i);
68
+ }
69
+ var p = (e, t) => {
70
+ if (e instanceof t) return !0;
71
+ let n = Object.getPrototypeOf(e);
72
+ return n === null ? !1 : n.constructor.name === t.name || p(n, t);
73
+ };
74
+ //#endregion
75
+ //#region ../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/clone-pseudos.js
76
+ function m(e) {
77
+ let t = e.getPropertyValue("content");
78
+ return `${e.cssText} content: '${t.replace(/'|"/g, "")}';`;
79
+ }
80
+ function ne(e, t) {
81
+ return i(t).map((t) => `${t}: ${e.getPropertyValue(t)}${e.getPropertyPriority(t) ? " !important" : ""};`).join(" ");
82
+ }
83
+ function re(e, t, n, r) {
84
+ let i = `.${e}:${t}`, a = n.cssText ? m(n) : ne(n, r);
85
+ return document.createTextNode(`${i}{${a}}`);
86
+ }
87
+ function h(e, n, r, i) {
88
+ let a = window.getComputedStyle(e, r), o = a.getPropertyValue("content");
89
+ if (o === "" || o === "none") return;
90
+ let s = t();
91
+ try {
92
+ n.className = `${n.className} ${s}`;
93
+ } catch {
94
+ return;
95
+ }
96
+ let c = document.createElement("style");
97
+ c.appendChild(re(s, r, a, i)), n.appendChild(c);
98
+ }
99
+ function ie(e, t, n) {
100
+ h(e, t, ":before", n), h(e, t, ":after", n);
101
+ }
102
+ //#endregion
103
+ //#region ../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/mimes.js
104
+ var g = "application/font-woff", _ = "image/jpeg", v = {
105
+ woff: g,
106
+ woff2: g,
107
+ ttf: "application/font-truetype",
108
+ eot: "application/vnd.ms-fontobject",
109
+ png: "image/png",
110
+ jpg: _,
111
+ jpeg: _,
112
+ gif: "image/gif",
113
+ tiff: "image/tiff",
114
+ svg: "image/svg+xml",
115
+ webp: "image/webp"
116
+ };
117
+ function y(e) {
118
+ let t = /\.([^./]*?)$/g.exec(e);
119
+ return t ? t[1] : "";
120
+ }
121
+ function b(e) {
122
+ return v[y(e).toLowerCase()] || "";
123
+ }
124
+ //#endregion
125
+ //#region ../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/dataurl.js
126
+ function x(e) {
127
+ return e.split(/,/)[1];
128
+ }
129
+ function S(e) {
130
+ return e.search(/^(data:)/) !== -1;
131
+ }
132
+ function C(e, t) {
133
+ return `data:${t};base64,${e}`;
134
+ }
135
+ async function w(e, t, n) {
136
+ let r = await fetch(e, t);
137
+ if (r.status === 404) throw Error(`Resource "${r.url}" not found`);
138
+ let i = await r.blob();
139
+ return new Promise((e, t) => {
140
+ let a = new FileReader();
141
+ a.onerror = t, a.onloadend = () => {
142
+ try {
143
+ e(n({
144
+ res: r,
145
+ result: a.result
146
+ }));
147
+ } catch (e) {
148
+ t(e);
149
+ }
150
+ }, a.readAsDataURL(i);
151
+ });
152
+ }
153
+ var T = {};
154
+ function ae(e, t, n) {
155
+ let r = e.replace(/\?.*/, "");
156
+ return n && (r = e), /ttf|otf|eot|woff2?/i.test(r) && (r = r.replace(/.*\//, "")), t ? `[${t}]${r}` : r;
157
+ }
158
+ async function E(e, t, n) {
159
+ let r = ae(e, t, n.includeQueryParams);
160
+ if (T[r] != null) return T[r];
161
+ n.cacheBust && (e += (/\?/.test(e) ? "&" : "?") + (/* @__PURE__ */ new Date()).getTime());
162
+ let i;
163
+ try {
164
+ i = C(await w(e, n.fetchRequestInit, ({ res: e, result: n }) => (t ||= e.headers.get("Content-Type") || "", x(n))), t);
165
+ } catch (t) {
166
+ i = n.imagePlaceholder || "";
167
+ let r = `Failed to fetch resource: ${e}`;
168
+ t && (r = typeof t == "string" ? t : t.message), r && console.warn(r);
169
+ }
170
+ return T[r] = i, i;
171
+ }
172
+ //#endregion
173
+ //#region ../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/clone-node.js
174
+ async function oe(e) {
175
+ let t = e.toDataURL();
176
+ return t === "data:," ? e.cloneNode(!1) : d(t);
177
+ }
178
+ async function se(e, t) {
179
+ if (e.currentSrc) {
180
+ let t = document.createElement("canvas"), n = t.getContext("2d");
181
+ return t.width = e.clientWidth, t.height = e.clientHeight, n?.drawImage(e, 0, 0, t.width, t.height), d(t.toDataURL());
182
+ }
183
+ let n = e.poster;
184
+ return d(await E(n, b(n), t));
185
+ }
186
+ async function ce(e, t) {
187
+ try {
188
+ if (e?.contentDocument?.body) return await I(e.contentDocument.body, t, !0);
189
+ } catch {}
190
+ return e.cloneNode(!1);
191
+ }
192
+ async function D(e, t) {
193
+ return p(e, HTMLCanvasElement) ? oe(e) : p(e, HTMLVideoElement) ? se(e, t) : p(e, HTMLIFrameElement) ? ce(e, t) : e.cloneNode(k(e));
194
+ }
195
+ var O = (e) => e.tagName != null && e.tagName.toUpperCase() === "SLOT", k = (e) => e.tagName != null && e.tagName.toUpperCase() === "SVG";
196
+ async function A(e, t, r) {
197
+ if (k(t)) return t;
198
+ let i = [];
199
+ return i = O(e) && e.assignedNodes ? n(e.assignedNodes()) : p(e, HTMLIFrameElement) && e.contentDocument?.body ? n(e.contentDocument.body.childNodes) : n((e.shadowRoot ?? e).childNodes), i.length === 0 || p(e, HTMLVideoElement) || await i.reduce((e, n) => e.then(() => I(n, r)).then((e) => {
200
+ e && t.appendChild(e);
201
+ }), Promise.resolve()), t;
202
+ }
203
+ function j(e, t, n) {
204
+ let r = t.style;
205
+ if (!r) return;
206
+ let a = window.getComputedStyle(e);
207
+ a.cssText ? (r.cssText = a.cssText, r.transformOrigin = a.transformOrigin) : i(n).forEach((n) => {
208
+ let i = a.getPropertyValue(n);
209
+ n === "font-size" && i.endsWith("px") && (i = `${Math.floor(parseFloat(i.substring(0, i.length - 2))) - .1}px`), p(e, HTMLIFrameElement) && n === "display" && i === "inline" && (i = "block"), n === "d" && t.getAttribute("d") && (i = `path(${t.getAttribute("d")})`), r.setProperty(n, i, a.getPropertyPriority(n));
210
+ });
211
+ }
212
+ function M(e, t) {
213
+ p(e, HTMLTextAreaElement) && (t.innerHTML = e.value), p(e, HTMLInputElement) && t.setAttribute("value", e.value);
214
+ }
215
+ function N(e, t) {
216
+ if (p(e, HTMLSelectElement)) {
217
+ let n = t, r = Array.from(n.children).find((t) => e.value === t.getAttribute("value"));
218
+ r && r.setAttribute("selected", "");
219
+ }
220
+ }
221
+ function P(e, t, n) {
222
+ return p(t, Element) && (j(e, t, n), ie(e, t, n), M(e, t), N(e, t)), t;
223
+ }
224
+ async function F(e, t) {
225
+ let n = e.querySelectorAll ? e.querySelectorAll("use") : [];
226
+ if (n.length === 0) return e;
227
+ let r = {};
228
+ for (let i = 0; i < n.length; i++) {
229
+ let a = n[i].getAttribute("xlink:href");
230
+ if (a) {
231
+ let n = e.querySelector(a), i = document.querySelector(a);
232
+ !n && i && !r[a] && (r[a] = await I(i, t, !0));
233
+ }
234
+ }
235
+ let i = Object.values(r);
236
+ if (i.length) {
237
+ let t = "http://www.w3.org/1999/xhtml", n = document.createElementNS(t, "svg");
238
+ n.setAttribute("xmlns", t), n.style.position = "absolute", n.style.width = "0", n.style.height = "0", n.style.overflow = "hidden", n.style.display = "none";
239
+ let r = document.createElementNS(t, "defs");
240
+ n.appendChild(r);
241
+ for (let e = 0; e < i.length; e++) r.appendChild(i[e]);
242
+ e.appendChild(n);
243
+ }
244
+ return e;
245
+ }
246
+ async function I(e, t, n) {
247
+ return !n && t.filter && !t.filter(e) ? null : Promise.resolve(e).then((e) => D(e, t)).then((n) => A(e, n, t)).then((n) => P(e, n, t)).then((e) => F(e, t));
248
+ }
249
+ //#endregion
250
+ //#region ../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/embed-resources.js
251
+ var L = /url\((['"]?)([^'"]+?)\1\)/g, R = /url\([^)]+\)\s*format\((["']?)([^"']+)\1\)/g, z = /src:\s*(?:url\([^)]+\)\s*format\([^)]+\)[,;]\s*)+/g;
252
+ function B(e) {
253
+ let t = e.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1");
254
+ return RegExp(`(url\\(['"]?)(${t})(['"]?\\))`, "g");
255
+ }
256
+ function V(e) {
257
+ let t = [];
258
+ return e.replace(L, (e, n, r) => (t.push(r), e)), t.filter((e) => !S(e));
259
+ }
260
+ async function H(t, n, r, i, a) {
261
+ try {
262
+ let o = r ? e(n, r) : n, s = b(n), c;
263
+ return c = a ? C(await a(o), s) : await E(o, s, i), t.replace(B(n), `$1${c}$3`);
264
+ } catch {}
265
+ return t;
266
+ }
267
+ function le(e, { preferredFontFormat: t }) {
268
+ return t ? e.replace(z, (e) => {
269
+ for (;;) {
270
+ let [n, , r] = R.exec(e) || [];
271
+ if (!r) return "";
272
+ if (r === t) return `src: ${n};`;
273
+ }
274
+ }) : e;
275
+ }
276
+ function U(e) {
277
+ return e.search(L) !== -1;
278
+ }
279
+ async function W(e, t, n) {
280
+ if (!U(e)) return e;
281
+ let r = le(e, n);
282
+ return V(r).reduce((e, r) => e.then((e) => H(e, r, t, n)), Promise.resolve(r));
283
+ }
284
+ //#endregion
285
+ //#region ../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/embed-images.js
286
+ async function G(e, t, n) {
287
+ let r = t.style?.getPropertyValue(e);
288
+ if (r) {
289
+ let i = await W(r, null, n);
290
+ return t.style.setProperty(e, i, t.style.getPropertyPriority(e)), !0;
291
+ }
292
+ return !1;
293
+ }
294
+ async function ue(e, t) {
295
+ await G("background", e, t) || await G("background-image", e, t), await G("mask", e, t) || await G("-webkit-mask", e, t) || await G("mask-image", e, t) || await G("-webkit-mask-image", e, t);
296
+ }
297
+ async function de(e, t) {
298
+ let n = p(e, HTMLImageElement);
299
+ if (!(n && !S(e.src)) && !(p(e, SVGImageElement) && !S(e.href.baseVal))) return;
300
+ let r = n ? e.src : e.href.baseVal, i = await E(r, b(r), t);
301
+ await new Promise((r, a) => {
302
+ e.onload = r, e.onerror = t.onImageErrorHandler ? (...e) => {
303
+ try {
304
+ r(t.onImageErrorHandler(...e));
305
+ } catch (e) {
306
+ a(e);
307
+ }
308
+ } : a;
309
+ let o = e;
310
+ o.decode &&= r, o.loading === "lazy" && (o.loading = "eager"), n ? (e.srcset = "", e.src = i) : e.href.baseVal = i;
311
+ });
312
+ }
313
+ async function fe(e, t) {
314
+ let r = n(e.childNodes).map((e) => K(e, t));
315
+ await Promise.all(r).then(() => e);
316
+ }
317
+ async function K(e, t) {
318
+ p(e, Element) && (await ue(e, t), await de(e, t), await fe(e, t));
319
+ }
320
+ //#endregion
321
+ //#region ../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/apply-style.js
322
+ function pe(e, t) {
323
+ let { style: n } = e;
324
+ t.backgroundColor && (n.backgroundColor = t.backgroundColor), t.width && (n.width = `${t.width}px`), t.height && (n.height = `${t.height}px`);
325
+ let r = t.style;
326
+ return r != null && Object.keys(r).forEach((e) => {
327
+ n[e] = r[e];
328
+ }), e;
329
+ }
330
+ //#endregion
331
+ //#region ../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/embed-webfonts.js
332
+ var q = {};
333
+ async function J(e) {
334
+ let t = q[e];
335
+ return t ?? (t = {
336
+ url: e,
337
+ cssText: await (await fetch(e)).text()
338
+ }, q[e] = t, t);
339
+ }
340
+ async function Y(e, t) {
341
+ let n = e.cssText, r = /url\(["']?([^"')]+)["']?\)/g, i = (n.match(/url\([^)]+\)/g) || []).map(async (i) => {
342
+ let a = i.replace(r, "$1");
343
+ return a.startsWith("https://") || (a = new URL(a, e.url).href), w(a, t.fetchRequestInit, ({ result: e }) => (n = n.replace(i, `url(${e})`), [i, e]));
344
+ });
345
+ return Promise.all(i).then(() => n);
346
+ }
347
+ function X(e) {
348
+ if (e == null) return [];
349
+ let t = [], n = e.replace(/(\/\*[\s\S]*?\*\/)/gi, ""), r = /* @__PURE__ */ RegExp("((@.*?keyframes [\\s\\S]*?){([\\s\\S]*?}\\s*?)})", "gi");
350
+ for (;;) {
351
+ let e = r.exec(n);
352
+ if (e === null) break;
353
+ t.push(e[0]);
354
+ }
355
+ n = n.replace(r, "");
356
+ let i = /@import[\s\S]*?url\([^)]*\)[\s\S]*?;/gi, a = /* @__PURE__ */ RegExp("((\\s*?(?:\\/\\*[\\s\\S]*?\\*\\/)?\\s*?@media[\\s\\S]*?){([\\s\\S]*?)}\\s*?})|(([\\s\\S]*?){([\\s\\S]*?)})", "gi");
357
+ for (;;) {
358
+ let e = i.exec(n);
359
+ if (e === null) {
360
+ if (e = a.exec(n), e === null) break;
361
+ i.lastIndex = a.lastIndex;
362
+ } else a.lastIndex = i.lastIndex;
363
+ t.push(e[0]);
364
+ }
365
+ return t;
366
+ }
367
+ async function me(e, t) {
368
+ let r = [], i = [];
369
+ return e.forEach((r) => {
370
+ if ("cssRules" in r) try {
371
+ n(r.cssRules || []).forEach((e, n) => {
372
+ if (e.type === CSSRule.IMPORT_RULE) {
373
+ let a = n + 1, o = e.href, s = J(o).then((e) => Y(e, t)).then((e) => X(e).forEach((e) => {
374
+ try {
375
+ r.insertRule(e, e.startsWith("@import") ? a += 1 : r.cssRules.length);
376
+ } catch (t) {
377
+ console.error("Error inserting rule from remote css", {
378
+ rule: e,
379
+ error: t
380
+ });
381
+ }
382
+ })).catch((e) => {
383
+ console.error("Error loading remote css", e.toString());
384
+ });
385
+ i.push(s);
386
+ }
387
+ });
388
+ } catch (n) {
389
+ let a = e.find((e) => e.href == null) || document.styleSheets[0];
390
+ r.href != null && i.push(J(r.href).then((e) => Y(e, t)).then((e) => X(e).forEach((e) => {
391
+ a.insertRule(e, a.cssRules.length);
392
+ })).catch((e) => {
393
+ console.error("Error loading remote stylesheet", e);
394
+ })), console.error("Error inlining remote css file", n);
395
+ }
396
+ }), Promise.all(i).then(() => (e.forEach((e) => {
397
+ if ("cssRules" in e) try {
398
+ n(e.cssRules || []).forEach((e) => {
399
+ r.push(e);
400
+ });
401
+ } catch (t) {
402
+ console.error(`Error while reading CSS rules from ${e.href}`, t);
403
+ }
404
+ }), r));
405
+ }
406
+ function he(e) {
407
+ return e.filter((e) => e.type === CSSRule.FONT_FACE_RULE).filter((e) => U(e.style.getPropertyValue("src")));
408
+ }
409
+ async function ge(e, t) {
410
+ if (e.ownerDocument == null) throw Error("Provided element is not within a Document");
411
+ return he(await me(n(e.ownerDocument.styleSheets), t));
412
+ }
413
+ function Z(e) {
414
+ return e.trim().replace(/["']/g, "");
415
+ }
416
+ function _e(e) {
417
+ let t = /* @__PURE__ */ new Set();
418
+ function n(e) {
419
+ (e.style.fontFamily || getComputedStyle(e).fontFamily).split(",").forEach((e) => {
420
+ t.add(Z(e));
421
+ }), Array.from(e.children).forEach((e) => {
422
+ e instanceof HTMLElement && n(e);
423
+ });
424
+ }
425
+ return n(e), t;
426
+ }
427
+ async function Q(e, t) {
428
+ let n = await ge(e, t), r = _e(e);
429
+ return (await Promise.all(n.filter((e) => r.has(Z(e.style.fontFamily))).map((e) => {
430
+ let n = e.parentStyleSheet ? e.parentStyleSheet.href : null;
431
+ return W(e.cssText, n, t);
432
+ }))).join("\n");
433
+ }
434
+ async function ve(e, t) {
435
+ let n = t.fontEmbedCSS == null ? t.skipFonts ? null : await Q(e, t) : t.fontEmbedCSS;
436
+ if (n) {
437
+ let t = document.createElement("style"), r = document.createTextNode(n);
438
+ t.appendChild(r), e.firstChild ? e.insertBefore(t, e.firstChild) : e.appendChild(t);
439
+ }
440
+ }
441
+ //#endregion
442
+ //#region ../../node_modules/.pnpm/html-to-image@1.11.13/node_modules/html-to-image/es/index.js
443
+ async function ye(e, t = {}) {
444
+ let { width: n, height: r } = c(e, t), i = await I(e, t, !0);
445
+ return await ve(i, t), await K(i, t), pe(i, t), await te(i, n, r);
446
+ }
447
+ async function $(e, t = {}) {
448
+ let { width: n, height: r } = c(e, t), i = await d(await ye(e, t)), a = document.createElement("canvas"), o = a.getContext("2d"), s = t.pixelRatio || l(), u = t.canvasWidth || n, f = t.canvasHeight || r;
449
+ return a.width = u * s, a.height = f * s, t.skipAutoScale || ee(a), a.style.width = `${u}`, a.style.height = `${f}`, t.backgroundColor && (o.fillStyle = t.backgroundColor, o.fillRect(0, 0, a.width, a.height)), o.drawImage(i, 0, 0, a.width, a.height), a;
450
+ }
451
+ async function be(e, t = {}) {
452
+ return (await $(e, t)).toDataURL();
453
+ }
454
+ //#endregion
455
+ export { $ as toCanvas, be as toPng };
package/index.d.ts CHANGED
@@ -141,6 +141,16 @@ export declare type IEditorToPreview = {
141
141
  } | {
142
142
  type: "clear-staged";
143
143
  stageId?: string;
144
+ }
145
+ /**
146
+ * Rasterize the CURRENTLY selected element to a PNG data URL (reply:
147
+ * `capture-result`). Selection-state based — no locator round-trip — so it also
148
+ * works for unstamped elements and never suffers stale-locator misses. The editor
149
+ * attaches the result to the chat so the model can see what the user selected.
150
+ */
151
+ | {
152
+ type: "capture-selected";
153
+ requestId: string;
144
154
  };
145
155
 
146
156
  /** A nested element locator — `file:line:col` + occurrence index. Never top-level. */
@@ -287,6 +297,12 @@ export declare interface ILevoPopupsProps {
287
297
  * workspace-wide active popups are returned.
288
298
  */
289
299
  siteId?: string;
300
+ /**
301
+ * The current page's platform id, read from the head by `LevoSiteProvider` (see
302
+ * `../pageId`). Feeds page-bound targeting rules ("show on the pricing page", "show on
303
+ * all blog posts"). Absent → those rules never match; URL-path rules still do.
304
+ */
305
+ pageId?: string;
290
306
  }
291
307
 
292
308
  /** A single-record binding — one collection record / blog post / event by `slug` (a detail page). */
@@ -427,6 +443,13 @@ export declare interface IPatchedHistoryFn {
427
443
 
428
444
  /** The full `meta/<route>.json` shape: page identity (platform-owned) + the SEO object. */
429
445
  export declare interface IPlatformMetaFile {
446
+ /**
447
+ * The platform's page id. Stamped by the platform (never by the AI) and used for
448
+ * analytics `page_id` + popup page-bound targeting — see `./pageId`. Ships empty on
449
+ * sites provisioned before the platform started stamping it; empty = simply absent,
450
+ * every consumer degrades to URL-based behavior.
451
+ */
452
+ id?: string;
430
453
  title?: string;
431
454
  description?: string;
432
455
  meta?: IPlatformPageMeta;
@@ -495,6 +518,37 @@ export declare type IPreviewToEditor = {
495
518
  } | {
496
519
  type: "highlight-miss";
497
520
  element: IElementLocator;
521
+ }
522
+ /**
523
+ * Reply to `capture-selected`. `dataUrl` is a `data:image/png;base64,…` render of the
524
+ * selected element, or null with `error` set ("no-selection", "capture-failed") —
525
+ * always sent, so the editor's pending request settles instead of timing out.
526
+ */
527
+ | {
528
+ type: "capture-result";
529
+ requestId: string;
530
+ dataUrl: string | null;
531
+ error?: string;
532
+ }
533
+ /**
534
+ * A select-mode marquee drag finished. `rect` is the dragged area (viewport coords at
535
+ * capture time), `elements` the topmost source-stamped elements substantially inside
536
+ * it (capped — `truncated` set when over the cap), `dataUrl` a PNG render of exactly
537
+ * that area (null when rasterizing failed; the element list is still useful alone).
538
+ * Unlike `capture-selected` this is push-based: one drag = one deliberate intent, so
539
+ * the runtime captures immediately instead of waiting for an editor request.
540
+ */
541
+ | {
542
+ type: "region-selected";
543
+ rect: {
544
+ x: number;
545
+ y: number;
546
+ width: number;
547
+ height: number;
548
+ };
549
+ elements: IRegionElement[];
550
+ truncated: boolean;
551
+ dataUrl: string | null;
498
552
  };
499
553
 
500
554
  /**
@@ -510,6 +564,20 @@ export declare interface IQueryClientLike {
510
564
  }) => Promise<unknown>;
511
565
  }
512
566
 
567
+ /**
568
+ * One element inside a drag-selected region — the lean sibling of
569
+ * {@link ISelectedElement}: just enough for the AI to locate it (`source`/`index`)
570
+ * and for the editor to label it. Only source-stamped elements make the list.
571
+ */
572
+ export declare interface IRegionElement {
573
+ source: string;
574
+ index: number;
575
+ tag: string;
576
+ label: string;
577
+ /** Direct display text, truncated. Omitted for non-text containers. */
578
+ text?: string;
579
+ }
580
+
513
581
  /** The element-selected payload — see `selectedPayload`. */
514
582
  export declare interface ISelectedElement {
515
583
  tag: string;
@@ -686,9 +754,10 @@ export declare const LevoForm: React.FC<ILevoFormProps>;
686
754
  * everything else: it fetches active popups, evaluates page/referrer targeting against the
687
755
  * current URL, lazy-loads the renderer only when popups exist, and self-hides otherwise.
688
756
  *
689
- * No `pageId` is threaded: that is a studio DB page id with no equivalent in a code-routed
690
- * site, so page-bound rules don't apply here — site-wide and URL-path targeting (the
691
- * `is_all_pages` / `contains` / `begins_with` matchers) do.
757
+ * `pageId` comes from the matched route's `meta/<route>.json` (the provider reads it off the
758
+ * head — see `../pageId`), which is what makes page-bound rules work on a code-routed site.
759
+ * Sites whose meta files carry no id still get site-wide and URL-path targeting (the
760
+ * `is_all_pages` / `contains` / `begins_with` matchers).
692
761
  */
693
762
  export declare const LevoPopups: React.FC<ILevoPopupsProps>;
694
763
 
@@ -709,6 +778,9 @@ export declare const LevoSiteProvider: React.FC<{
709
778
  children: React.ReactNode;
710
779
  }>;
711
780
 
781
+ /** `name` of the head tag carrying the page id. Written by `levoHead`, read by `readPageId`. */
782
+ export declare const PAGE_ID_META = "levo:page-id";
783
+
712
784
  /**
713
785
  * Renders a page's metadata as document tags. Pages include it anywhere in their JSX —
714
786
  * React 19 hoists <title>/<meta>/<link> into <head> (SSR too); scripts render in place
@@ -763,6 +835,13 @@ export declare const prefetchLevoSources: ({ queryClient, config, sources, param
763
835
  params?: Record<string, string>;
764
836
  }) => Promise<Record<string, unknown>>;
765
837
 
838
+ /**
839
+ * The id the currently matched route stamped into the head, or null when the site's
840
+ * platform hasn't stamped ids into its meta files yet (the field ships empty). Client-only —
841
+ * returns null during SSR, so callers must read it in an effect.
842
+ */
843
+ export declare const readPageId: () => string | null;
844
+
766
845
  /** What `system` resolves to — the class actually on `<html>`. */
767
846
  export declare type ResolvedColorMode = "dark" | "light";
768
847