@popcraft/kit 0.52.0 → 0.53.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 (58) hide show
  1. package/dist/chunks/{agent-HRK56EXA.js → agent-VDTFMQFH.js} +1 -1
  2. package/dist/chunks/{builtin-3US63AOP.js → builtin-B425EDUG.js} +3 -3
  3. package/dist/chunks/{buy-credits-5C4ZIAPQ.js → buy-credits-YD6DBAQB.js} +2 -2
  4. package/dist/chunks/{check-template-SUCKEUAH.js → check-template-QIUI3LQM.js} +2 -2
  5. package/dist/chunks/{chunk-CKS6JHCU.js → chunk-5AMNMH7S.js} +9 -9
  6. package/dist/chunks/{chunk-YR6YKL6C.js → chunk-6Q7JYDNH.js} +3 -3
  7. package/dist/chunks/{chunk-3MLA5BUJ.js → chunk-7XLYPWQL.js} +4 -4
  8. package/dist/chunks/{chunk-EWLFJFDO.js → chunk-A3MCE2OL.js} +1 -1
  9. package/dist/chunks/{chunk-AKRFU5IC.js → chunk-AN2LMY4M.js} +4 -4
  10. package/dist/chunks/{chunk-6NVIZIQF.js → chunk-B4DDU5KM.js} +2 -2
  11. package/dist/chunks/{chunk-KWETGFIB.js → chunk-EISISJQ4.js} +14 -14
  12. package/dist/chunks/{chunk-OMD5UZER.js → chunk-EKKA4A5J.js} +5 -5
  13. package/dist/chunks/{chunk-KRUBAKYX.js → chunk-GPNEAC5E.js} +1 -1
  14. package/dist/chunks/{chunk-6OHSAJUQ.js → chunk-HGUHRTIM.js} +2 -2
  15. package/dist/chunks/{chunk-HJ7UVP3J.js → chunk-LHKOU6BP.js} +1 -1
  16. package/dist/chunks/{chunk-NGFWRQK3.js → chunk-MGWBSGMA.js} +2 -2
  17. package/dist/chunks/{chunk-IDWJKGNU.js → chunk-MY5CBA5H.js} +41 -41
  18. package/dist/chunks/{chunk-HKYBS2KY.js → chunk-PUFEIOUT.js} +1 -1
  19. package/dist/chunks/{chunk-DYSNP6UR.js → chunk-SD7QCT7C.js} +45 -3
  20. package/dist/chunks/{chunk-V66THETF.js → chunk-U5UFIM2E.js} +1 -1
  21. package/dist/chunks/{chunk-YOPG6IGL.js → chunk-V4SNTWZO.js} +4 -4
  22. package/dist/chunks/{chunk-AV6XTZEW.js → chunk-VLEZSLRZ.js} +2 -2
  23. package/dist/chunks/{chunk-KHUWNPIW.js → chunk-WXMIWRZM.js} +11 -11
  24. package/dist/chunks/{client-C5Y3Y5HH.js → client-4LUUUMO2.js} +2 -2
  25. package/dist/chunks/{client-DHB4LF4B.js → client-AMMTXTFS.js} +3 -3
  26. package/dist/chunks/{client-W4L4L76Q.js → client-O2YCQZT7.js} +1 -1
  27. package/dist/chunks/{client-actions-6CIMGIDV.js → client-actions-L7II3NNB.js} +5 -5
  28. package/dist/chunks/{dangerous-MKUWMKP2.js → dangerous-RSWVATGA.js} +3 -3
  29. package/dist/chunks/{delete-current-file-VXCBT5UK.js → delete-current-file-E46EEPRC.js} +5 -5
  30. package/dist/chunks/{editor-seams-BT4QWT5U.js → editor-seams-UO4QUUQH.js} +10 -10
  31. package/dist/chunks/{editor-store-5N4YRWV2.js → editor-store-V43NADG6.js} +1 -1
  32. package/dist/chunks/{export-watermark-Z2LPEDSP.js → export-watermark-XHQOOPR7.js} +5 -5
  33. package/dist/chunks/{eyedropper-YG6WXAMC.js → eyedropper-4D6OK4VM.js} +1 -1
  34. package/dist/chunks/{generate-media-OUKD27QT.js → generate-media-XMD232CS.js} +3 -3
  35. package/dist/chunks/{host-ID3XQKWC.js → host-WX77JQ2K.js} +6 -6
  36. package/dist/chunks/{integrations-OW6CMKMO.js → integrations-LOGIGZY2.js} +1 -1
  37. package/dist/chunks/{libraries-X6HB7FPR.js → libraries-R63ARXMI.js} +5 -5
  38. package/dist/chunks/{live-YWRRPA6G.js → live-QLSNGZ3Y.js} +1 -1
  39. package/dist/chunks/{media-tool-DCHP5P2O.js → media-tool-TXQINVAR.js} +1 -1
  40. package/dist/chunks/{new-file-5T4Y7FST.js → new-file-UUBSWKHK.js} +3 -3
  41. package/dist/chunks/{plugin-UMUQ76Y6.js → plugin-CUBE33JW.js} +2 -2
  42. package/dist/chunks/{plugin-import-BCP4JHKO.js → plugin-import-C5S2SHFZ.js} +14 -14
  43. package/dist/chunks/{presence-7NKX5VRN.js → presence-UQHDKT4A.js} +2 -2
  44. package/dist/chunks/{project-RD62AMZA.js → project-KEEZ7XYP.js} +1 -1
  45. package/dist/chunks/{publish-site-JCSC5ZNC.js → publish-site-UL2ISNZU.js} +6 -6
  46. package/dist/chunks/{publish-store-MVUSRXXI.js → publish-store-2TTGS2LW.js} +4 -4
  47. package/dist/chunks/{raster-actions-53IZLIPK.js → raster-actions-KYYBZLGY.js} +1 -1
  48. package/dist/chunks/{runner-QXXCWTYC.js → runner-ULBSWTOK.js} +17 -17
  49. package/dist/chunks/{store-EI2MB4IN.js → store-OUZ5GTY5.js} +6 -6
  50. package/dist/chunks/{sync-KX7WMSPO.js → sync-A56IG32K.js} +5 -5
  51. package/dist/chunks/{tabs-O6XBUTGR.js → tabs-UWETDGQJ.js} +8 -8
  52. package/dist/chunks/{team-VCK5JGMP.js → team-5VEJ3OZ6.js} +1 -1
  53. package/dist/chunks/{team-client-IB45QZLF.js → team-client-SG3SVF4G.js} +1 -1
  54. package/dist/chunks/{tools-YU5CI5J5.js → tools-2TCRJ6YI.js} +2 -2
  55. package/dist/chunks/{ui-commands-OISNFY2F.js → ui-commands-HVPH6ZXC.js} +12 -12
  56. package/dist/chunks/{versions-O2XIV3FF.js → versions-BIJCROBJ.js} +5 -5
  57. package/dist/index.js +1 -1
  58. package/package.json +1 -1
@@ -18,7 +18,7 @@ import {
18
18
  renderDocument,
19
19
  toolView,
20
20
  underReviewKit
21
- } from "./chunk-YR6YKL6C.js";
21
+ } from "./chunk-6Q7JYDNH.js";
22
22
  import "./chunk-ZYK65XJJ.js";
23
23
  import "./chunk-CEVTHE4E.js";
24
24
  import "./chunk-OQZFD4BD.js";
@@ -7,8 +7,8 @@ const __dirname = __popcraftDirname(__filename);
7
7
  import {
8
8
  builtinTools,
9
9
  registerBuiltinTools
10
- } from "./chunk-6NVIZIQF.js";
11
- import "./chunk-IDWJKGNU.js";
10
+ } from "./chunk-B4DDU5KM.js";
11
+ import "./chunk-MY5CBA5H.js";
12
12
  import "./chunk-ZLWN6LBH.js";
13
13
  import "./chunk-Q7EITIAT.js";
14
14
  import "./chunk-X36CCQ76.js";
@@ -19,7 +19,7 @@ import "./chunk-A6XXXQQO.js";
19
19
  import "./chunk-ATSLWELA.js";
20
20
  import "./chunk-6B6ULEDJ.js";
21
21
  import "./chunk-VOOUF5TT.js";
22
- import "./chunk-YR6YKL6C.js";
22
+ import "./chunk-6Q7JYDNH.js";
23
23
  import "./chunk-ZYK65XJJ.js";
24
24
  import "./chunk-4LOAHKDJ.js";
25
25
  import "./chunk-UCNBKWJQ.js";
@@ -7,11 +7,11 @@ const __dirname = __popcraftDirname(__filename);
7
7
  import {
8
8
  HYPERY_TEAM_HEADER,
9
9
  hyperyRequestHeaders
10
- } from "./chunk-V66THETF.js";
10
+ } from "./chunk-U5UFIM2E.js";
11
11
  import "./chunk-7SMURRFY.js";
12
12
  import {
13
13
  useHyperyTeam
14
- } from "./chunk-KRUBAKYX.js";
14
+ } from "./chunk-GPNEAC5E.js";
15
15
  import {
16
16
  ApiError,
17
17
  inAppPurchases,
@@ -6,10 +6,10 @@ const __filename = __popcraftPath(import.meta.url);
6
6
  const __dirname = __popcraftDirname(__filename);
7
7
  import {
8
8
  appCommands
9
- } from "./chunk-CKS6JHCU.js";
9
+ } from "./chunk-5AMNMH7S.js";
10
10
  import {
11
11
  builtinCommands
12
- } from "./chunk-IDWJKGNU.js";
12
+ } from "./chunk-MY5CBA5H.js";
13
13
  import "./chunk-ZLWN6LBH.js";
14
14
  import "./chunk-Q7EITIAT.js";
15
15
  import "./chunk-X36CCQ76.js";
@@ -8,7 +8,7 @@ import {
8
8
  needsSelection,
9
9
  pageGo,
10
10
  selectionIsPicture
11
- } from "./chunk-IDWJKGNU.js";
11
+ } from "./chunk-MY5CBA5H.js";
12
12
  import {
13
13
  external_exports
14
14
  } from "./chunk-VOOUF5TT.js";
@@ -31,7 +31,7 @@ var none = external_exports.object({});
31
31
  var emit = (name, detail) => {
32
32
  if (typeof window !== "undefined") window.dispatchEvent(new CustomEvent(name, { detail }));
33
33
  };
34
- var store = () => import("./editor-store-5N4YRWV2.js").then((m) => m.useEditorStore.getState());
34
+ var store = () => import("./editor-store-V43NADG6.js").then((m) => m.useEditorStore.getState());
35
35
  var MODE_IDS = MODE_LIST.map((m) => m.id);
36
36
  var MODE_ALIASES = { JAM: "POPCORN", DEV: "VIEW" };
37
37
  var modeSet = defineCommand({
@@ -167,7 +167,7 @@ var dialogOpen = defineCommand({
167
167
  (await import("./plan-limit-YTIOM3WO.js")).openPlanDialog();
168
168
  break;
169
169
  case "credits":
170
- await (await import("./buy-credits-5C4ZIAPQ.js")).buyAiCredits();
170
+ await (await import("./buy-credits-YD6DBAQB.js")).buyAiCredits();
171
171
  break;
172
172
  case "tokens":
173
173
  emit("popcraft-open-tokens");
@@ -213,7 +213,7 @@ var aiOpen = defineCommand({
213
213
  ] } },
214
214
  run: async ({ dialog, skillId }) => {
215
215
  if (dialog) (await import("./client-store-3YCO6KV5.js")).openAiDialog(dialog);
216
- else (await import("./store-EI2MB4IN.js")).openAgentPanel({ skillId: skillId ?? null });
216
+ else (await import("./store-OUZ5GTY5.js")).openAgentPanel({ skillId: skillId ?? null });
217
217
  return { summary: dialog ? `Opened AI ${dialog}` : "Opened the agent" };
218
218
  }
219
219
  });
@@ -226,7 +226,7 @@ var agentContinue = defineCommand({
226
226
  params: external_exports.object({}),
227
227
  expose: { ui: { label: "AI: Continue the agent\u2019s last turn", keywords: ["ai", "agent", "continue", "resume", "retry", "keep going"] } },
228
228
  run: async () => {
229
- const resumed = await (await import("./runner-QXXCWTYC.js")).continueTurn();
229
+ const resumed = await (await import("./runner-ULBSWTOK.js")).continueTurn();
230
230
  return { summary: resumed ? "Continued the agent" : "Nothing to continue" };
231
231
  }
232
232
  });
@@ -305,11 +305,11 @@ var toolPlace = defineCommand({
305
305
  run: async ({ what }) => {
306
306
  if (what === "media") {
307
307
  const s = await store();
308
- const { placeMediaFromPicker } = await import("./media-tool-DCHP5P2O.js");
308
+ const { placeMediaFromPicker } = await import("./media-tool-TXQINVAR.js");
309
309
  await placeMediaFromPicker({ kind: "point", x: s.camera.x, y: s.camera.y });
310
310
  return { summary: "Placing media" };
311
311
  }
312
- const { beginEyedrop } = await import("./eyedropper-YG6WXAMC.js");
312
+ const { beginEyedrop } = await import("./eyedropper-4D6OK4VM.js");
313
313
  void beginEyedrop();
314
314
  return { summary: "Pick a color" };
315
315
  }
@@ -327,7 +327,7 @@ var nodeRasterize = defineCommand({
327
327
  keywords: ["rasterize", "raster", "flatten", "pixels", "paint layer", "erase", "bitmap"]
328
328
  } },
329
329
  run: async () => {
330
- const { flattenSelectionToPaintLayer } = await import("./raster-actions-53IZLIPK.js");
330
+ const { flattenSelectionToPaintLayer } = await import("./raster-actions-KYYBZLGY.js");
331
331
  await flattenSelectionToPaintLayer();
332
332
  return { summary: "Rasterized" };
333
333
  }
@@ -438,7 +438,7 @@ function pluginCommand(plugins) {
438
438
  params: external_exports.object({ pluginId: external_exports.string(), commandId: external_exports.string() }),
439
439
  expose: { ui: { label: "Run plugin", keywords: ["plugin", "extension", "run"], variants, palette: variants.length ? void 0 : false } },
440
440
  run: async ({ pluginId, commandId }) => {
441
- await (await import("./host-ID3XQKWC.js")).runPlugin(pluginId, commandId);
441
+ await (await import("./host-WX77JQ2K.js")).runPlugin(pluginId, commandId);
442
442
  return { summary: "Plugin started" };
443
443
  }
444
444
  });
@@ -57,19 +57,19 @@ async function renderDocument(doc, nodeIds, options) {
57
57
  function generateCapability(ctx) {
58
58
  return async (prompt, options = {}) => {
59
59
  if (options.format === "audio") {
60
- const { requestAudio } = await import("./client-DHB4LF4B.js");
60
+ const { requestAudio } = await import("./client-AMMTXTFS.js");
61
61
  const { signal: signal2, format: _f, ...rest2 } = options;
62
62
  void _f;
63
63
  return requestAudio({ prompt, ...rest2 }, signal2 ?? ctx.signal);
64
64
  }
65
65
  if (options.format === "video") {
66
- const { generateVideoFile } = await import("./generate-media-OUKD27QT.js");
66
+ const { generateVideoFile } = await import("./generate-media-XMD232CS.js");
67
67
  const { format: _f, signal: signal2, ...rest2 } = options;
68
68
  void _f;
69
69
  return generateVideoFile({ ...rest2, prompt, doc: ctx.doc() }, { signal: signal2 ?? ctx.signal });
70
70
  }
71
71
  const [{ requestImage }, { effectiveImageModel, useAiStore }] = await Promise.all([
72
- import("./client-DHB4LF4B.js"),
72
+ import("./client-AMMTXTFS.js"),
73
73
  import("./client-store-3YCO6KV5.js")
74
74
  ]);
75
75
  const modelId = effectiveImageModel(useAiStore.getState());
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-LRF3JAZW.js";
10
10
  import {
11
11
  notice
12
- } from "./chunk-AV6XTZEW.js";
12
+ } from "./chunk-VLEZSLRZ.js";
13
13
  import {
14
14
  effectiveChatModel,
15
15
  setModelPref,
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-A4CGHVJP.js";
18
18
  import {
19
19
  useEditorStore
20
- } from "./chunk-OMD5UZER.js";
20
+ } from "./chunk-EKKA4A5J.js";
21
21
  import {
22
22
  create
23
23
  } from "./chunk-QLJLPV5R.js";
@@ -1797,7 +1797,7 @@ async function sendMessage(text) {
1797
1797
  if (!useAgentStore.getState().activeThreadId) newThread();
1798
1798
  const mentions = pruneMentions(body, useAgentStore.getState().draftMentions);
1799
1799
  useAgentStore.setState({ draft: "", draftMentions: [], error: null });
1800
- const { runTurn } = await import("./runner-QXXCWTYC.js");
1800
+ const { runTurn } = await import("./runner-ULBSWTOK.js");
1801
1801
  await runTurn(body, mentions);
1802
1802
  }
1803
1803
  function stop() {
@@ -1900,7 +1900,7 @@ var clearTaskChildren = () => useAgentStore.setState({ taskChildren: {} });
1900
1900
  function subscribeChildTools() {
1901
1901
  let dispose;
1902
1902
  let cancelled = false;
1903
- void import("./runner-QXXCWTYC.js").then(({ onChildTool }) => {
1903
+ void import("./runner-ULBSWTOK.js").then(({ onChildTool }) => {
1904
1904
  const off = onChildTool((report) => {
1905
1905
  if (report?.status !== "running" || report.jobId) return;
1906
1906
  recordChildTool(report.toolCallId ?? "", report.name);
@@ -13,7 +13,7 @@ import {
13
13
  agentTool,
14
14
  agentToolList,
15
15
  registerCommands
16
- } from "./chunk-YR6YKL6C.js";
16
+ } from "./chunk-6Q7JYDNH.js";
17
17
  import {
18
18
  dispatch
19
19
  } from "./chunk-OQZFD4BD.js";
@@ -16,14 +16,14 @@ import {
16
16
  reportOpenStage,
17
17
  setCloudLink,
18
18
  trackOpen
19
- } from "./chunk-6OHSAJUQ.js";
19
+ } from "./chunk-HGUHRTIM.js";
20
20
  import {
21
21
  parseDeepLink,
22
22
  withDeepLink
23
23
  } from "./chunk-EUF3VFBW.js";
24
24
  import {
25
25
  activeTeamWorkspaceId
26
- } from "./chunk-KRUBAKYX.js";
26
+ } from "./chunk-GPNEAC5E.js";
27
27
  import {
28
28
  ApiError,
29
29
  api,
@@ -31,7 +31,7 @@ import {
31
31
  } from "./chunk-KWUXHRXD.js";
32
32
  import {
33
33
  attachPresence
34
- } from "./chunk-HKYBS2KY.js";
34
+ } from "./chunk-PUFEIOUT.js";
35
35
  import {
36
36
  isPersistableDocument,
37
37
  isUnsavedPlaceholder,
@@ -42,7 +42,7 @@ import {
42
42
  setCollabHistory,
43
43
  storedDocument,
44
44
  useEditorStore
45
- } from "./chunk-OMD5UZER.js";
45
+ } from "./chunk-EKKA4A5J.js";
46
46
  import {
47
47
  currentHistoryGroup
48
48
  } from "./chunk-76I6DIEM.js";
@@ -7,10 +7,10 @@ const __dirname = __popcraftDirname(__filename);
7
7
  import {
8
8
  builtinCommands,
9
9
  registerBuiltinCommands
10
- } from "./chunk-IDWJKGNU.js";
10
+ } from "./chunk-MY5CBA5H.js";
11
11
  import {
12
12
  toolView
13
- } from "./chunk-YR6YKL6C.js";
13
+ } from "./chunk-6Q7JYDNH.js";
14
14
  import {
15
15
  init_define_POPCRAFT_COMPONENT_IDS
16
16
  } from "./chunk-WKDVCZ45.js";
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-ZYK65XJJ.js";
16
16
  import {
17
17
  syncStatus
18
- } from "./chunk-AKRFU5IC.js";
18
+ } from "./chunk-AN2LMY4M.js";
19
19
  import {
20
20
  exportNodeToSVG
21
21
  } from "./chunk-T4FFRJAH.js";
@@ -28,7 +28,7 @@ import {
28
28
  import {
29
29
  setPluginTabs,
30
30
  useEditorStore
31
- } from "./chunk-OMD5UZER.js";
31
+ } from "./chunk-EKKA4A5J.js";
32
32
  import {
33
33
  openBeside
34
34
  } from "./chunk-PMLSPVLR.js";
@@ -69,22 +69,22 @@ init_define_POPCRAFT_COMPONENT_IDS();
69
69
  // lib/plugins/api.ts
70
70
  init_define_POPCRAFT_COMPONENT_IDS();
71
71
  async function handlePluginCall(env, method, params = {}) {
72
- const { dispatchPluginCall } = await import("./plugin-UMUQ76Y6.js");
72
+ const { dispatchPluginCall } = await import("./plugin-CUBE33JW.js");
73
73
  return dispatchPluginCall(env, method, params);
74
74
  }
75
75
 
76
- // node_modules/.pnpm/@popcraft+plugins@1.0.0_patch_hash=6826cb40a12857607fa1f7d7d102e5d8316bd483c1ff06865dac73139dfe709b/node_modules/@popcraft/plugins/dist/index.js
76
+ // node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/index.js
77
77
  init_define_POPCRAFT_COMPONENT_IDS();
78
78
 
79
- // node_modules/.pnpm/@popcraft+plugins@1.0.0_patch_hash=6826cb40a12857607fa1f7d7d102e5d8316bd483c1ff06865dac73139dfe709b/node_modules/@popcraft/plugins/dist/host.js
79
+ // node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/host.js
80
80
  init_define_POPCRAFT_COMPONENT_IDS();
81
81
 
82
- // node_modules/.pnpm/@popcraft+plugins@1.0.0_patch_hash=6826cb40a12857607fa1f7d7d102e5d8316bd483c1ff06865dac73139dfe709b/node_modules/@popcraft/plugins/dist/generated/runtime.js
82
+ // node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/generated/runtime.js
83
83
  init_define_POPCRAFT_COMPONENT_IDS();
84
- var MAIN_RUNTIME = '"use strict";\n(() => {\n // src/runtime/rpc.ts\n function createRpcClient() {\n let port = null;\n const queue = [];\n const pending = {};\n const listeners = {};\n let nextId = 1;\n function send(msg) {\n if (port) port.postMessage(msg);\n else queue.push(msg);\n }\n function call(method, params) {\n return new Promise((resolve, reject) => {\n const id = nextId++;\n pending[id] = { resolve, reject };\n send({ kind: "rpc", id, method, params });\n });\n }\n function emit(event, data) {\n for (const cb of (listeners[event] || []).slice()) {\n try {\n cb(data);\n } catch (e) {\n console.error(e);\n }\n }\n }\n window.addEventListener("message", (e) => {\n const data = e.data;\n if (e.source !== window.parent || !data || data.type !== "popcraft-plugin-port" || port) return;\n port = e.ports[0];\n port.onmessage = (ev) => {\n const m = ev.data || {};\n if (m.kind === "result" && m.id !== void 0 && pending[m.id]) {\n const p = pending[m.id];\n delete pending[m.id];\n if (m.error) p.reject(new Error(m.error));\n else p.resolve(m.result);\n } else if (m.kind === "event" && m.event) {\n emit(m.event, m.data);\n }\n };\n for (const msg of queue.splice(0)) port.postMessage(msg);\n });\n return {\n call,\n send,\n on(event, cb) {\n (listeners[event] = listeners[event] || []).push(cb);\n },\n off(event, cb) {\n listeners[event] = (listeners[event] || []).filter((x) => x !== cb);\n }\n };\n }\n\n // src/runtime/main.ts\n function clone(v) {\n return v === void 0 ? {} : JSON.parse(JSON.stringify(v));\n }\n function createMainApi(rpc = createRpcClient()) {\n const uiHandlers = [];\n let uiOnMessage = null;\n const uiQueue = [];\n function deliverUI(msg) {\n for (const cb of uiHandlers) {\n try {\n cb(msg);\n } catch (e) {\n console.error(e);\n }\n }\n if (typeof uiOnMessage === "function") {\n try {\n uiOnMessage(msg);\n } catch (e) {\n console.error(e);\n }\n }\n }\n function flushUI() {\n if (uiHandlers.length || typeof uiOnMessage === "function") uiQueue.splice(0).forEach(deliverUI);\n }\n rpc.on("uimessage", (msg) => {\n if (!uiHandlers.length && typeof uiOnMessage !== "function") uiQueue.push(msg);\n else deliverUI(msg);\n });\n let widgetDef = null;\n const widgetQueue = [];\n function renderWidget(state) {\n const handlers = {};\n function walk(el, path) {\n if (!el || typeof el !== "object") return el;\n const out = {};\n for (const k of Object.keys(el)) {\n const v = el[k];\n if (k === "children") {\n out.children = (Array.isArray(v) ? v : [v]).filter((c) => c !== null && c !== void 0 && c !== false).map((c, i) => walk(c, path + "." + i));\n } else if (k === "onClick" && typeof v === "function") {\n handlers[path] = v;\n out.onClick = path;\n } else {\n out[k] = v;\n }\n }\n return out;\n }\n return { tree: walk(widgetDef.render(state), "root"), handlers };\n }\n function initialWidgetState() {\n const s = widgetDef && widgetDef.initialState;\n return clone(typeof s === "function" ? s() : s);\n }\n function commitWidget(nodeId, state) {\n return rpc.call("widgetUpdate", { id: nodeId, state, tree: renderWidget(clone(state)).tree });\n }\n function handleWidgetClick(e) {\n Promise.resolve().then(() => {\n const state = clone(e.state);\n const rendered = renderWidget(state);\n const h = rendered.handlers[e.handler] || widgetDef.handlers && widgetDef.handlers[e.handler];\n if (typeof h !== "function") return;\n return Promise.resolve(h(state, { nodeId: e.nodeId })).then((ret) => commitWidget(e.nodeId, ret === void 0 ? state : ret));\n }).catch((err) => rpc.send({ kind: "error", message: String((err == null ? void 0 : err.message) || err) }));\n }\n rpc.on("widgetclick", (e) => {\n if (widgetDef) handleWidgetClick(e);\n else widgetQueue.push(e);\n });\n const popcraft = {\n /** Which menu command the user picked, or null when the plugin ran some other way. */\n command: null,\n /** Host import mode when launched as an importer, else null. */\n importMode: null,\n /** Pending import file when the host handed one over, else null. */\n importFile: null,\n /** Pending export request (File \u2192 Export \u2192 this plugin\'s format), else null. */\n exportRequest: null,\n getSelection: () => rpc.call("getSelection"),\n setSelection: (ids) => rpc.call("setSelection", { ids }),\n getNode: (id) => rpc.call("getNode", { id }),\n findNodes: (query) => rpc.call("findNodes", query || {}),\n getCurrentPage: () => rpc.call("getCurrentPage"),\n createNode: (type, props) => rpc.call("createNode", { type, props: props || {} }),\n updateNode: (id, props) => rpc.call("updateNode", { id, props }),\n deleteNode: (id) => rpc.call("deleteNode", { id }),\n setText: (id, characters) => rpc.call("setText", { id, characters }),\n /** Put TEXT layers on a path (another layer\'s outline, or their own arc, circle or wave), or tune one: brackets, alignment, placement, effect, overflow. */\n setTextPath: (opts) => rpc.call("setTextPath", opts || {}),\n /** Area type: flow a TEXT layer inside a closed shape, kept `inset` px in. */\n flowTextIntoShape: (opts) => rpc.call("flowTextIntoShape", opts || {}),\n /** Take TEXT layers off their path or out of their shape (or free every text linked to a path / shape). */\n detachText: (opts) => rpc.call("detachText", opts || {}),\n /** Auto-size TEXT layers\' type to their box, shape or path. */\n setTextFit: (opts) => rpc.call("setTextFit", opts || {}),\n createPage: (name) => rpc.call("createPage", name != null ? { name: String(name) } : {}),\n setCurrentPage: (pageId) => rpc.call("setCurrentPage", { pageId }),\n createImage: (opts) => rpc.call("createImage", opts || {}),\n createDocument: (opts) => rpc.call("createDocument", opts || {}),\n getImportMode: () => rpc.call("getImportMode"),\n getImportFile: () => rpc.call("getImportFile"),\n /**\n * The open page as a storefront design in a neutral form, for an exporter that writes its own store\'s templates:\n * each page\'s HTML with the store\'s data marked (`{{page.title}}`, `{{item.price}}`, `<!-- pc:each \u2026 -->` lists,\n * `data-pc-action` forms), and its collections with their commerce schema and sample records.\n */\n getStorefront: () => rpc.call("getStorefront"),\n /**\n * A design\'s data (docs: Collections): a collection and its fields (`schema`: what it stands for, e.g.\n * `commerce.product`, whose fields are made for it), its records, and reading them.\n */\n editCollection: (opts) => rpc.call("editCollection", opts || {}),\n editRecords: (opts) => rpc.call("editRecords", opts || {}),\n getRecords: (opts) => rpc.call("getRecords", opts || {}),\n /** A layer as a web page\'s form control (a FORM\'s `formAction`, an INPUT\'s name and value), repeated per record, a page\'s address, its semantics. */\n setControl: (opts) => rpc.call("setControl", opts || {}),\n setRepeat: (opts) => rpc.call("setRepeat", opts || {}),\n setRoute: (opts) => rpc.call("setRoute", opts || {}),\n setSemantics: (opts) => rpc.call("setSemantics", opts || {}),\n /** Which record layers are about (one product, picked from a collection), and which of its fields a layer\'s words, picture or an instance\'s properties follow. */\n setRecord: (opts) => rpc.call("setRecord", opts || {}),\n bindField: (opts) => rpc.call("bindField", opts || {}),\n /** The site\'s environment: public settings its host reads by name when it is deployed (never a secret: the file keeps them). */\n getSiteEnvironment: () => rpc.call("getSiteEnvironment"),\n setSiteEnvironment: (set) => rpc.call("setSiteEnvironment", { set }),\n /** What this plugin keeps with the open file (its settings for this design), under its own id; JSON only. */\n getFileData: (key) => rpc.call("getFileData", { key }),\n setFileData: (key, value) => rpc.call("setFileData", { key, value }),\n /** A store\'s project built from the open page, zipped (needs `export`): what an exporter saves with `saveExport`. */\n getStorefrontFiles: (target) => rpc.call("getStorefrontFiles", { target }),\n getExportRequest: () => rpc.call("getExportRequest"),\n /** Save the exporter\'s file (once per export request); the host enforces the contributed extension. */\n saveExport: (file) => rpc.call("saveExport", file || {}),\n /**\n * Presentation audio (docs/plugins/presentation-audio.md): the deck\'s slides, notes, narration and timing; the\n * soundtrack\'s settings, bed and stinger.\n */\n getPresentationAudio: (opts) => rpc.call("getPresentationAudio", opts || {}),\n /** Change the soundtrack\'s settings (voice, style, mood, loudness, beat alignment, levels) and re-time it. */\n setPresentationAudioSettings: (opts) => rpc.call("setPresentationAudioSettings", opts || {}),\n /** Put a sound in (a slide\'s narration, the bed or the stinger): bytes are normalised to the soundtrack\'s target and stored. */\n setPresentationAudioClip: (opts) => rpc.call("setPresentationAudioClip", opts || {}),\n removePresentationAudioClip: (opts) => rpc.call("removePresentationAudioClip", opts || {}),\n /** Re-time: fixed slide lengths (ms, null clears) and beat-aligned changes. */\n setPresentationTiming: (opts) => rpc.call("setPresentationTiming", opts || {}),\n /** The mix as the export carries it: loudness, true peak, and (wav: true) the 48 kHz stereo WAV. */\n getPresentationMix: (opts) => rpc.call("getPresentationMix", opts || {}),\n /** Ask the user to generate with AI (the panel opens with the request filled in; the user decides). */\n requestPresentationAudio: (opts) => rpc.call("requestPresentationAudio", opts || {}),\n /** Editor commands: each takes the arguments documented in docs/plugins/methods.md (the agent tool of the same purpose). */\n moveNodes: (opts) => rpc.call("moveNodes", opts || {}),\n resizeNodes: (opts) => rpc.call("resizeNodes", opts || {}),\n renameNodes: (opts) => rpc.call("renameNodes", opts || {}),\n reparentNodes: (opts) => rpc.call("reparentNodes", opts || {}),\n duplicateNodes: (opts) => rpc.call("duplicateNodes", opts || {}),\n groupNodes: (opts) => rpc.call("groupNodes", opts || {}),\n ungroupNodes: (opts) => rpc.call("ungroupNodes", opts || {}),\n alignNodes: (opts) => rpc.call("alignNodes", opts || {}),\n distributeNodes: (opts) => rpc.call("distributeNodes", opts || {}),\n flipNodes: (opts) => rpc.call("flipNodes", opts || {}),\n rotateNodes: (opts) => rpc.call("rotateNodes", opts || {}),\n reorderNodes: (opts) => rpc.call("reorderNodes", opts || {}),\n setLocked: (opts) => rpc.call("setLocked", opts || {}),\n setVisible: (opts) => rpc.call("setVisible", opts || {}),\n setAutoLayout: (opts) => rpc.call("setAutoLayout", opts || {}),\n importSvg: (opts) => rpc.call("importSvg", opts || {}),\n measureNodes: (opts) => rpc.call("measureNodes", opts || {}),\n setFills: (opts) => rpc.call("setFills", opts || {}),\n setStrokes: (opts) => rpc.call("setStrokes", opts || {}),\n setEffects: (opts) => rpc.call("setEffects", opts || {}),\n replaceColor: (opts) => rpc.call("replaceColor", opts || {}),\n setTypography: (opts) => rpc.call("setTypography", opts || {}),\n applyStyle: (opts) => rpc.call("applyStyle", opts || {}),\n createComponent: (opts) => rpc.call("createComponent", opts || {}),\n createInstance: (opts) => rpc.call("createInstance", opts || {}),\n renamePage: (opts) => rpc.call("renamePage", opts || {}),\n getDocumentOutline: (opts) => rpc.call("getDocumentOutline", opts || {}),\n setPageSetup: (opts) => rpc.call("setPageSetup", opts || {}),\n setShowAdvance: (opts) => rpc.call("setShowAdvance", opts || {}),\n booleanOperation: (opts) => rpc.call("booleanOperation", opts || {}),\n flattenNodes: (opts) => rpc.call("flattenNodes", opts || {}),\n outlineStroke: (opts) => rpc.call("outlineStroke", opts || {}),\n setMask: (opts) => rpc.call("setMask", opts || {}),\n setMaskType: (opts) => rpc.call("setMaskType", opts || {}),\n shapeBuilder: (opts) => rpc.call("shapeBuilder", opts || {}),\n setKeyframes: (opts) => rpc.call("setKeyframes", opts || {}),\n getAnimation: (opts) => rpc.call("getAnimation", opts || {}),\n getCompositions: (opts) => rpc.call("getCompositions", opts || {}),\n editBehaviours: (opts) => rpc.call("editBehaviours", opts || {}),\n setTimeline: (opts) => rpc.call("setTimeline", opts || {}),\n setLayerTiming: (opts) => rpc.call("setLayerTiming", opts || {}),\n editTextAnimation: (opts) => rpc.call("editTextAnimation", opts || {}),\n edit3DScene: (opts) => rpc.call("edit3DScene", opts || {}),\n setInstancePlayback: (opts) => rpc.call("setInstancePlayback", opts || {}),\n editComponentProperty: (opts) => rpc.call("editComponentProperty", opts || {}),\n setShaderFill: (opts) => rpc.call("setShaderFill", opts || {}),\n createComposition: (opts) => rpc.call("createComposition", opts || {}),\n editComposition: (opts) => rpc.call("editComposition", opts || {}),\n editStateMachine: (opts) => rpc.call("editStateMachine", opts || {}),\n getStateMachine: (opts) => rpc.call("getStateMachine", opts || {}),\n applyMotionPreset: (opts) => rpc.call("applyMotionPreset", opts || {}),\n staggerMotion: (opts) => rpc.call("staggerMotion", opts || {}),\n createMotionComponent: (opts) => rpc.call("createMotionComponent", opts || {}),\n addAudio: (opts) => rpc.call("addAudio", opts || {}),\n editFrameAudio: (opts) => rpc.call("editFrameAudio", opts || {}),\n editVideoClip: (opts) => rpc.call("editVideoClip", opts || {}),\n detectAudioOnsets: (opts) => rpc.call("detectAudioOnsets", opts || {}),\n cutToBeat: (opts) => rpc.call("cutToBeat", opts || {}),\n editPrototype: (opts) => rpc.call("editPrototype", opts || {}),\n usePresentationFallbackAudio: (opts) => rpc.call("usePresentationFallbackAudio", opts || {}),\n /** Bring a Lottie, PDF or PopCraft file into the open document (the `importFile` field is the file an importer was handed). */\n importDocumentFile: (opts) => rpc.call("importDocumentFile", opts || {}),\n getStyles: () => rpc.call("getStyles"),\n createPaintStyle: (name, paints) => rpc.call("createPaintStyle", { name, paints }),\n getVariables: () => rpc.call("getVariables"),\n setVariableValue: (variableId, modeId, value) => rpc.call("setVariableValue", { variableId, modeId, value }),\n exportNode: (id, options) => rpc.call("exportNode", { id, options: options || {} }),\n openExternal: (url) => rpc.call("openExternal", { url }),\n notify: (message, options) => rpc.call("notify", { message: String(message), error: !!(options && options.error) }),\n showUI: (options) => rpc.call("showUI", options || {}),\n hideUI: () => rpc.call("hideUI"),\n /** Ends the run. The optional message is shown as a notification. */\n closePlugin: (message) => rpc.call("closePlugin", { message }),\n storage: {\n get: (key) => rpc.call("storageGet", { key }),\n set: (key, value) => rpc.call("storageSet", { key, value })\n },\n ui: {\n get onmessage() {\n return uiOnMessage;\n },\n set onmessage(cb) {\n uiOnMessage = cb;\n flushUI();\n },\n postMessage: (msg) => rpc.send({ kind: "toUI", data: msg }),\n on: (cb) => {\n uiHandlers.push(cb);\n flushUI();\n }\n },\n widget: {\n register(def) {\n if (!def || typeof def.render !== "function") throw new Error("popcraft.widget.register needs a render(state) function");\n widgetDef = def;\n widgetQueue.splice(0).forEach(handleWidgetClick);\n },\n insert(options) {\n if (!widgetDef) return Promise.reject(new Error("Call popcraft.widget.register first"));\n const o = options || {};\n const state = o.state !== void 0 ? clone(o.state) : initialWidgetState();\n return rpc.call("widgetInsert", { state, tree: renderWidget(state).tree, x: o.x, y: o.y });\n },\n getState: (nodeId) => rpc.call("widgetGet", { id: nodeId }),\n setState(nodeId, state) {\n if (!widgetDef) return Promise.reject(new Error("Call popcraft.widget.register first"));\n return commitWidget(nodeId, clone(state));\n }\n },\n on: (event, cb) => rpc.on(event, cb),\n off: (event, cb) => rpc.off(event, cb)\n };\n rpc.on("init", (data) => {\n var _a, _b, _c;\n popcraft.command = data.command;\n popcraft.importMode = (_a = data.importMode) != null ? _a : null;\n popcraft.importFile = (_b = data.importFile) != null ? _b : null;\n popcraft.exportRequest = (_c = data.exportRequest) != null ? _c : null;\n });\n return popcraft;\n }\n function installMainApi() {\n const rpc = createRpcClient();\n const api = createMainApi(rpc);\n const w = window;\n w.__popcraftRpc = rpc;\n w.popcraft = api;\n w.vizpops = api;\n window.addEventListener("error", (e) => rpc.send({ kind: "error", message: String(e.message || e) }));\n window.addEventListener("unhandledrejection", (e) => rpc.send({ kind: "error", message: String(e.reason && e.reason.message || e.reason) }));\n return api;\n }\n\n // src/runtime/main.entry.ts\n installMainApi();\n})();';
84
+ var MAIN_RUNTIME = '"use strict";\n(() => {\n // src/runtime/rpc.ts\n function createRpcClient() {\n let port = null;\n const queue = [];\n const pending = {};\n const listeners = {};\n let nextId = 1;\n function send(msg) {\n if (port) port.postMessage(msg);\n else queue.push(msg);\n }\n function call(method, params) {\n return new Promise((resolve, reject) => {\n const id = nextId++;\n pending[id] = { resolve, reject };\n send({ kind: "rpc", id, method, params });\n });\n }\n function emit(event, data) {\n for (const cb of (listeners[event] || []).slice()) {\n try {\n cb(data);\n } catch (e) {\n console.error(e);\n }\n }\n }\n window.addEventListener("message", (e) => {\n const data = e.data;\n if (e.source !== window.parent || !data || data.type !== "popcraft-plugin-port" || port) return;\n port = e.ports[0];\n port.onmessage = (ev) => {\n const m = ev.data || {};\n if (m.kind === "result" && m.id !== void 0 && pending[m.id]) {\n const p = pending[m.id];\n delete pending[m.id];\n if (m.error) p.reject(new Error(m.error));\n else p.resolve(m.result);\n } else if (m.kind === "event" && m.event) {\n emit(m.event, m.data);\n }\n };\n for (const msg of queue.splice(0)) port.postMessage(msg);\n });\n return {\n call,\n send,\n on(event, cb) {\n (listeners[event] = listeners[event] || []).push(cb);\n },\n off(event, cb) {\n listeners[event] = (listeners[event] || []).filter((x) => x !== cb);\n }\n };\n }\n\n // src/runtime/main.ts\n function clone(v) {\n return v === void 0 ? {} : JSON.parse(JSON.stringify(v));\n }\n function createMainApi(rpc = createRpcClient()) {\n const uiHandlers = [];\n let uiOnMessage = null;\n const uiQueue = [];\n function deliverUI(msg) {\n for (const cb of uiHandlers) {\n try {\n cb(msg);\n } catch (e) {\n console.error(e);\n }\n }\n if (typeof uiOnMessage === "function") {\n try {\n uiOnMessage(msg);\n } catch (e) {\n console.error(e);\n }\n }\n }\n function flushUI() {\n if (uiHandlers.length || typeof uiOnMessage === "function") uiQueue.splice(0).forEach(deliverUI);\n }\n rpc.on("uimessage", (msg) => {\n if (!uiHandlers.length && typeof uiOnMessage !== "function") uiQueue.push(msg);\n else deliverUI(msg);\n });\n let widgetDef = null;\n const widgetQueue = [];\n function renderWidget(state) {\n const handlers = {};\n function walk(el, path) {\n if (!el || typeof el !== "object") return el;\n const out = {};\n for (const k of Object.keys(el)) {\n const v = el[k];\n if (k === "children") {\n out.children = (Array.isArray(v) ? v : [v]).filter((c) => c !== null && c !== void 0 && c !== false).map((c, i) => walk(c, path + "." + i));\n } else if (k === "onClick" && typeof v === "function") {\n handlers[path] = v;\n out.onClick = path;\n } else {\n out[k] = v;\n }\n }\n return out;\n }\n return { tree: walk(widgetDef.render(state), "root"), handlers };\n }\n function initialWidgetState() {\n const s = widgetDef && widgetDef.initialState;\n return clone(typeof s === "function" ? s() : s);\n }\n function commitWidget(nodeId, state) {\n return rpc.call("widgetUpdate", { id: nodeId, state, tree: renderWidget(clone(state)).tree });\n }\n function handleWidgetClick(e) {\n Promise.resolve().then(() => {\n const state = clone(e.state);\n const rendered = renderWidget(state);\n const h = rendered.handlers[e.handler] || widgetDef.handlers && widgetDef.handlers[e.handler];\n if (typeof h !== "function") return;\n return Promise.resolve(h(state, { nodeId: e.nodeId })).then((ret) => commitWidget(e.nodeId, ret === void 0 ? state : ret));\n }).catch((err) => rpc.send({ kind: "error", message: String((err == null ? void 0 : err.message) || err) }));\n }\n rpc.on("widgetclick", (e) => {\n if (widgetDef) handleWidgetClick(e);\n else widgetQueue.push(e);\n });\n const popcraft = {\n /** Which menu command the user picked, or null when the plugin ran some other way. */\n command: null,\n /** Host import mode when launched as an importer, else null. */\n importMode: null,\n /** Pending import file when the host handed one over, else null. */\n importFile: null,\n /** Pending export request (File \u2192 Export \u2192 this plugin\'s format), else null. */\n exportRequest: null,\n getSelection: () => rpc.call("getSelection"),\n setSelection: (ids) => rpc.call("setSelection", { ids }),\n getNode: (id) => rpc.call("getNode", { id }),\n findNodes: (query) => rpc.call("findNodes", query || {}),\n getCurrentPage: () => rpc.call("getCurrentPage"),\n createNode: (type, props) => rpc.call("createNode", { type, props: props || {} }),\n updateNode: (id, props) => rpc.call("updateNode", { id, props }),\n deleteNode: (id) => rpc.call("deleteNode", { id }),\n setText: (id, characters) => rpc.call("setText", { id, characters }),\n /** Put TEXT layers on a path (another layer\'s outline, or their own arc, circle or wave), or tune one: brackets, alignment, placement, effect, overflow. */\n setTextPath: (opts) => rpc.call("setTextPath", opts || {}),\n /** Area type: flow a TEXT layer inside a closed shape, kept `inset` px in. */\n flowTextIntoShape: (opts) => rpc.call("flowTextIntoShape", opts || {}),\n /** Take TEXT layers off their path or out of their shape (or free every text linked to a path / shape). */\n detachText: (opts) => rpc.call("detachText", opts || {}),\n /** Auto-size TEXT layers\' type to their box, shape or path. */\n setTextFit: (opts) => rpc.call("setTextFit", opts || {}),\n createPage: (name) => rpc.call("createPage", name != null ? { name: String(name) } : {}),\n setCurrentPage: (pageId) => rpc.call("setCurrentPage", { pageId }),\n createImage: (opts) => rpc.call("createImage", opts || {}),\n createDocument: (opts) => rpc.call("createDocument", opts || {}),\n getImportMode: () => rpc.call("getImportMode"),\n getImportFile: () => rpc.call("getImportFile"),\n /**\n * The open page as a storefront design in a neutral form, for an exporter that writes its own store\'s templates:\n * each page\'s HTML with the store\'s data marked (`{{page.title}}`, `{{item.price}}`, `<!-- pc:each \u2026 -->` lists,\n * `data-pc-action` forms), and its collections with their commerce schema and sample records.\n */\n getStorefront: () => rpc.call("getStorefront"),\n /**\n * A design\'s data (docs: Collections): a collection and its fields (`schema`: what it stands for, e.g.\n * `commerce.product`, whose fields are made for it), its records, and reading them.\n */\n editCollection: (opts) => rpc.call("editCollection", opts || {}),\n editRecords: (opts) => rpc.call("editRecords", opts || {}),\n getRecords: (opts) => rpc.call("getRecords", opts || {}),\n /** A layer as a web page\'s form control (a FORM\'s `formAction`, an INPUT\'s name and value), repeated per record, a page\'s address, its semantics. */\n setControl: (opts) => rpc.call("setControl", opts || {}),\n setRepeat: (opts) => rpc.call("setRepeat", opts || {}),\n setRoute: (opts) => rpc.call("setRoute", opts || {}),\n setSemantics: (opts) => rpc.call("setSemantics", opts || {}),\n /** Which record layers are about (one product, picked from a collection), and which of its fields a layer\'s words, picture or an instance\'s properties follow. */\n setRecord: (opts) => rpc.call("setRecord", opts || {}),\n bindField: (opts) => rpc.call("bindField", opts || {}),\n /** The site\'s environment: public settings its host reads by name when it is deployed (never a secret: the file keeps them). */\n getSiteEnvironment: () => rpc.call("getSiteEnvironment"),\n setSiteEnvironment: (set) => rpc.call("setSiteEnvironment", { set }),\n /** What this plugin keeps with the open file (its settings for this design), under its own id; JSON only. */\n getFileData: (key) => rpc.call("getFileData", { key }),\n setFileData: (key, value) => rpc.call("setFileData", { key, value }),\n /** A store\'s project built from the open page, zipped (needs `export`): what an exporter saves with `saveExport`. */\n getStorefrontFiles: (target) => rpc.call("getStorefrontFiles", { target }),\n getExportRequest: () => rpc.call("getExportRequest"),\n /** Save the exporter\'s file (once per export request); the host enforces the contributed extension. */\n saveExport: (file) => rpc.call("saveExport", file || {}),\n /**\n * Presentation audio (docs/plugins/presentation-audio.md): the deck\'s slides, notes, narration and timing; the\n * soundtrack\'s settings, bed and stinger.\n */\n getPresentationAudio: (opts) => rpc.call("getPresentationAudio", opts || {}),\n /** Change the soundtrack\'s settings (voice, style, mood, loudness, beat alignment, levels) and re-time it. */\n setPresentationAudioSettings: (opts) => rpc.call("setPresentationAudioSettings", opts || {}),\n /** Put a sound in (a slide\'s narration, the bed or the stinger): bytes are normalised to the soundtrack\'s target and stored. */\n setPresentationAudioClip: (opts) => rpc.call("setPresentationAudioClip", opts || {}),\n removePresentationAudioClip: (opts) => rpc.call("removePresentationAudioClip", opts || {}),\n /** Re-time: fixed slide lengths (ms, null clears) and beat-aligned changes. */\n setPresentationTiming: (opts) => rpc.call("setPresentationTiming", opts || {}),\n /** The mix as the export carries it: loudness, true peak, and (wav: true) the 48 kHz stereo WAV. */\n getPresentationMix: (opts) => rpc.call("getPresentationMix", opts || {}),\n /** Ask the user to generate with AI (the panel opens with the request filled in; the user decides). */\n requestPresentationAudio: (opts) => rpc.call("requestPresentationAudio", opts || {}),\n /** Editor commands: each takes the arguments documented in docs/plugins/methods.md (the agent tool of the same purpose). */\n moveNodes: (opts) => rpc.call("moveNodes", opts || {}),\n resizeNodes: (opts) => rpc.call("resizeNodes", opts || {}),\n renameNodes: (opts) => rpc.call("renameNodes", opts || {}),\n reparentNodes: (opts) => rpc.call("reparentNodes", opts || {}),\n duplicateNodes: (opts) => rpc.call("duplicateNodes", opts || {}),\n groupNodes: (opts) => rpc.call("groupNodes", opts || {}),\n ungroupNodes: (opts) => rpc.call("ungroupNodes", opts || {}),\n alignNodes: (opts) => rpc.call("alignNodes", opts || {}),\n distributeNodes: (opts) => rpc.call("distributeNodes", opts || {}),\n flipNodes: (opts) => rpc.call("flipNodes", opts || {}),\n rotateNodes: (opts) => rpc.call("rotateNodes", opts || {}),\n reorderNodes: (opts) => rpc.call("reorderNodes", opts || {}),\n setLocked: (opts) => rpc.call("setLocked", opts || {}),\n setVisible: (opts) => rpc.call("setVisible", opts || {}),\n setAutoLayout: (opts) => rpc.call("setAutoLayout", opts || {}),\n importSvg: (opts) => rpc.call("importSvg", opts || {}),\n measureNodes: (opts) => rpc.call("measureNodes", opts || {}),\n setFills: (opts) => rpc.call("setFills", opts || {}),\n setStrokes: (opts) => rpc.call("setStrokes", opts || {}),\n setEffects: (opts) => rpc.call("setEffects", opts || {}),\n replaceColor: (opts) => rpc.call("replaceColor", opts || {}),\n setTypography: (opts) => rpc.call("setTypography", opts || {}),\n applyStyle: (opts) => rpc.call("applyStyle", opts || {}),\n createComponent: (opts) => rpc.call("createComponent", opts || {}),\n createInstance: (opts) => rpc.call("createInstance", opts || {}),\n renamePage: (opts) => rpc.call("renamePage", opts || {}),\n getDocumentOutline: (opts) => rpc.call("getDocumentOutline", opts || {}),\n setPageSetup: (opts) => rpc.call("setPageSetup", opts || {}),\n setShowAdvance: (opts) => rpc.call("setShowAdvance", opts || {}),\n booleanOperation: (opts) => rpc.call("booleanOperation", opts || {}),\n flattenNodes: (opts) => rpc.call("flattenNodes", opts || {}),\n outlineStroke: (opts) => rpc.call("outlineStroke", opts || {}),\n setMask: (opts) => rpc.call("setMask", opts || {}),\n setMaskType: (opts) => rpc.call("setMaskType", opts || {}),\n shapeBuilder: (opts) => rpc.call("shapeBuilder", opts || {}),\n setKeyframes: (opts) => rpc.call("setKeyframes", opts || {}),\n getAnimation: (opts) => rpc.call("getAnimation", opts || {}),\n getCompositions: (opts) => rpc.call("getCompositions", opts || {}),\n editBehaviours: (opts) => rpc.call("editBehaviours", opts || {}),\n setTimeline: (opts) => rpc.call("setTimeline", opts || {}),\n setLayerTiming: (opts) => rpc.call("setLayerTiming", opts || {}),\n editTextAnimation: (opts) => rpc.call("editTextAnimation", opts || {}),\n edit3DScene: (opts) => rpc.call("edit3DScene", opts || {}),\n setInstancePlayback: (opts) => rpc.call("setInstancePlayback", opts || {}),\n editComponentProperty: (opts) => rpc.call("editComponentProperty", opts || {}),\n setShaderFill: (opts) => rpc.call("setShaderFill", opts || {}),\n createComposition: (opts) => rpc.call("createComposition", opts || {}),\n editComposition: (opts) => rpc.call("editComposition", opts || {}),\n editStateMachine: (opts) => rpc.call("editStateMachine", opts || {}),\n getStateMachine: (opts) => rpc.call("getStateMachine", opts || {}),\n applyMotionPreset: (opts) => rpc.call("applyMotionPreset", opts || {}),\n staggerMotion: (opts) => rpc.call("staggerMotion", opts || {}),\n createMotionComponent: (opts) => rpc.call("createMotionComponent", opts || {}),\n addAudio: (opts) => rpc.call("addAudio", opts || {}),\n editFrameAudio: (opts) => rpc.call("editFrameAudio", opts || {}),\n editVideoClip: (opts) => rpc.call("editVideoClip", opts || {}),\n detectAudioOnsets: (opts) => rpc.call("detectAudioOnsets", opts || {}),\n cutToBeat: (opts) => rpc.call("cutToBeat", opts || {}),\n editPrototype: (opts) => rpc.call("editPrototype", opts || {}),\n usePresentationFallbackAudio: (opts) => rpc.call("usePresentationFallbackAudio", opts || {}),\n /** Bring a Lottie, PDF or PopCraft file into the open document (the `importFile` field is the file an importer was handed). */\n importDocumentFile: (opts) => rpc.call("importDocumentFile", opts || {}),\n getStyles: () => rpc.call("getStyles"),\n createPaintStyle: (name, paints) => rpc.call("createPaintStyle", { name, paints }),\n getVariables: () => rpc.call("getVariables"),\n setVariableValue: (variableId, modeId, value) => rpc.call("setVariableValue", { variableId, modeId, value }),\n exportNode: (id, options) => rpc.call("exportNode", { id, options: options || {} }),\n openExternal: (url) => rpc.call("openExternal", { url }),\n /**\n * Send a file to an https URL. PopCraft makes the request, not the sandbox, so it works for files of\n * any size the server accepts, including straight to a presigned storage URL. Needs `network`.\n */\n upload: (url, options) => {\n const body = options.body instanceof ArrayBuffer ? new Uint8Array(options.body) : options.body;\n return rpc.call("upload", {\n url,\n body,\n method: options.method,\n contentType: options.contentType,\n headers: options.headers\n });\n },\n notify: (message, options) => rpc.call("notify", { message: String(message), error: !!(options && options.error) }),\n showUI: (options) => rpc.call("showUI", options || {}),\n hideUI: () => rpc.call("hideUI"),\n /** Ends the run. The optional message is shown as a notification. */\n closePlugin: (message) => rpc.call("closePlugin", { message }),\n storage: {\n get: (key) => rpc.call("storageGet", { key }),\n set: (key, value) => rpc.call("storageSet", { key, value })\n },\n ui: {\n get onmessage() {\n return uiOnMessage;\n },\n set onmessage(cb) {\n uiOnMessage = cb;\n flushUI();\n },\n postMessage: (msg) => rpc.send({ kind: "toUI", data: msg }),\n on: (cb) => {\n uiHandlers.push(cb);\n flushUI();\n }\n },\n widget: {\n register(def) {\n if (!def || typeof def.render !== "function") throw new Error("popcraft.widget.register needs a render(state) function");\n widgetDef = def;\n widgetQueue.splice(0).forEach(handleWidgetClick);\n },\n insert(options) {\n if (!widgetDef) return Promise.reject(new Error("Call popcraft.widget.register first"));\n const o = options || {};\n const state = o.state !== void 0 ? clone(o.state) : initialWidgetState();\n return rpc.call("widgetInsert", { state, tree: renderWidget(state).tree, x: o.x, y: o.y });\n },\n getState: (nodeId) => rpc.call("widgetGet", { id: nodeId }),\n setState(nodeId, state) {\n if (!widgetDef) return Promise.reject(new Error("Call popcraft.widget.register first"));\n return commitWidget(nodeId, clone(state));\n }\n },\n on: (event, cb) => rpc.on(event, cb),\n off: (event, cb) => rpc.off(event, cb)\n };\n rpc.on("init", (data) => {\n var _a, _b, _c;\n popcraft.command = data.command;\n popcraft.importMode = (_a = data.importMode) != null ? _a : null;\n popcraft.importFile = (_b = data.importFile) != null ? _b : null;\n popcraft.exportRequest = (_c = data.exportRequest) != null ? _c : null;\n });\n return popcraft;\n }\n function installMainApi() {\n const rpc = createRpcClient();\n const api = createMainApi(rpc);\n const w = window;\n w.__popcraftRpc = rpc;\n w.popcraft = api;\n w.vizpops = api;\n window.addEventListener("error", (e) => rpc.send({ kind: "error", message: String(e.message || e) }));\n window.addEventListener("unhandledrejection", (e) => rpc.send({ kind: "error", message: String(e.reason && e.reason.message || e.reason) }));\n return api;\n }\n\n // src/runtime/main.entry.ts\n installMainApi();\n})();';
85
85
  var UI_RUNTIME = '"use strict";\n(() => {\n // src/runtime/rpc.ts\n function createRpcClient() {\n let port = null;\n const queue = [];\n const pending = {};\n const listeners = {};\n let nextId = 1;\n function send(msg) {\n if (port) port.postMessage(msg);\n else queue.push(msg);\n }\n function call(method, params) {\n return new Promise((resolve, reject) => {\n const id = nextId++;\n pending[id] = { resolve, reject };\n send({ kind: "rpc", id, method, params });\n });\n }\n function emit(event, data) {\n for (const cb of (listeners[event] || []).slice()) {\n try {\n cb(data);\n } catch (e) {\n console.error(e);\n }\n }\n }\n window.addEventListener("message", (e) => {\n const data = e.data;\n if (e.source !== window.parent || !data || data.type !== "popcraft-plugin-port" || port) return;\n port = e.ports[0];\n port.onmessage = (ev) => {\n const m = ev.data || {};\n if (m.kind === "result" && m.id !== void 0 && pending[m.id]) {\n const p = pending[m.id];\n delete pending[m.id];\n if (m.error) p.reject(new Error(m.error));\n else p.resolve(m.result);\n } else if (m.kind === "event" && m.event) {\n emit(m.event, m.data);\n }\n };\n for (const msg of queue.splice(0)) port.postMessage(msg);\n });\n return {\n call,\n send,\n on(event, cb) {\n (listeners[event] = listeners[event] || []).push(cb);\n },\n off(event, cb) {\n listeners[event] = (listeners[event] || []).filter((x) => x !== cb);\n }\n };\n }\n\n // src/runtime/ui.ts\n function createUiApi(rpc = createRpcClient()) {\n const popcraft = {\n onmessage: null,\n postMessage: (msg) => rpc.send({ kind: "fromUI", data: msg }),\n close: () => rpc.send({ kind: "closeUI" })\n };\n rpc.on("message", (msg) => {\n if (typeof popcraft.onmessage === "function") popcraft.onmessage(msg);\n window.dispatchEvent(new MessageEvent("message", { data: { pluginMessage: msg } }));\n });\n return popcraft;\n }\n function installUiApi() {\n const rpc = createRpcClient();\n const api = createUiApi(rpc);\n const w = window;\n w.__popcraftRpc = rpc;\n w.popcraft = api;\n w.vizpops = api;\n return api;\n }\n\n // src/runtime/ui.entry.ts\n installUiApi();\n})();';
86
86
 
87
- // node_modules/.pnpm/@popcraft+plugins@1.0.0_patch_hash=6826cb40a12857607fa1f7d7d102e5d8316bd483c1ff06865dac73139dfe709b/node_modules/@popcraft/plugins/dist/host.js
87
+ // node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/host.js
88
88
  var escapeScript = (code) => code.replace(/<\/script/gi, "<\\/script");
89
89
  function csp(network) {
90
90
  const connect = network ? "connect-src * data: blob:;" : "connect-src 'none';";
@@ -112,16 +112,16 @@ function buildUIDocument(uiHtml, network) {
112
112
  return `<!doctype html><html><head>${head}</head><body>${uiHtml}</body></html>`;
113
113
  }
114
114
 
115
- // node_modules/.pnpm/@popcraft+plugins@1.0.0_patch_hash=6826cb40a12857607fa1f7d7d102e5d8316bd483c1ff06865dac73139dfe709b/node_modules/@popcraft/plugins/dist/runtime/main.js
115
+ // node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/runtime/main.js
116
116
  init_define_POPCRAFT_COMPONENT_IDS();
117
117
 
118
- // node_modules/.pnpm/@popcraft+plugins@1.0.0_patch_hash=6826cb40a12857607fa1f7d7d102e5d8316bd483c1ff06865dac73139dfe709b/node_modules/@popcraft/plugins/dist/runtime/rpc.js
118
+ // node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/runtime/rpc.js
119
119
  init_define_POPCRAFT_COMPONENT_IDS();
120
120
 
121
- // node_modules/.pnpm/@popcraft+plugins@1.0.0_patch_hash=6826cb40a12857607fa1f7d7d102e5d8316bd483c1ff06865dac73139dfe709b/node_modules/@popcraft/plugins/dist/types.js
121
+ // node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/types.js
122
122
  init_define_POPCRAFT_COMPONENT_IDS();
123
123
 
124
- // node_modules/.pnpm/@popcraft+plugins@1.0.0_patch_hash=6826cb40a12857607fa1f7d7d102e5d8316bd483c1ff06865dac73139dfe709b/node_modules/@popcraft/plugins/dist/widget.js
124
+ // node_modules/.pnpm/@popcraft+plugins@1.3.0/node_modules/@popcraft/plugins/dist/widget.js
125
125
  init_define_POPCRAFT_COMPONENT_IDS();
126
126
 
127
127
  // lib/plugins/ui-theme.ts
@@ -579,7 +579,7 @@ async function runPlugin(pluginId, commandId, opts = {}) {
579
579
  if (!openBeside(url)) throw new Error("The browser blocked the new tab");
580
580
  },
581
581
  createDocument: async (opts2) => {
582
- const { createFreshFileOrExplain } = await import("./new-file-5T4Y7FST.js");
582
+ const { createFreshFileOrExplain } = await import("./new-file-UUBSWKHK.js");
583
583
  const created = await createFreshFileOrExplain({}, { name: opts2?.name });
584
584
  if (!created.ok) throw new Error(created.reason === "plan" ? "Plan limit reached" : created.reason === "guest-limit" ? "Sign in to create another file" : `Could not create file (${created.reason})`);
585
585
  await useEditorStore.getState().openDocument(created.docId);
@@ -769,7 +769,7 @@ if (typeof window !== "undefined") {
769
769
  const name = d.name || "Imported";
770
770
  void (async () => {
771
771
  try {
772
- const { importViaPlugin, applyPluginLayoutIr } = await import("./plugin-import-BCP4JHKO.js");
772
+ const { importViaPlugin, applyPluginLayoutIr } = await import("./plugin-import-C5S2SHFZ.js");
773
773
  if (d.ir && typeof d.ir === "object") {
774
774
  await applyPluginLayoutIr(d.ir, { mode, name });
775
775
  return;
@@ -4588,7 +4588,7 @@ function createPopcornSlice(set2, get2) {
4588
4588
  privateMode: false,
4589
4589
  setPrivateMode: (on) => {
4590
4590
  set2({ privateMode: on });
4591
- void import("./presence-7NKX5VRN.js").then((m) => m.setPresencePrivate(on)).catch(() => {
4591
+ void import("./presence-UQHDKT4A.js").then((m) => m.setPresencePrivate(on)).catch(() => {
4592
4592
  });
4593
4593
  },
4594
4594
  /** Reveal every private item THIS user created (they sync to collaborators). Others' stay theirs. */
@@ -6652,7 +6652,7 @@ var useEditorStore = create()(
6652
6652
  // A copy is a new file, so it is cloud-backed like any other (see lib/client/cloud/new-file.ts).
6653
6653
  // Returns '' when it was refused (offline, signed out, plan full) or failed; nothing is left behind.
6654
6654
  duplicateDocument: async (id) => {
6655
- const { duplicateDocumentToCloud } = await import("./sync-KX7WMSPO.js");
6655
+ const { duplicateDocumentToCloud } = await import("./sync-A56IG32K.js");
6656
6656
  return duplicateDocumentToCloud(id);
6657
6657
  },
6658
6658
  deleteDocument: async (id) => {
@@ -10115,9 +10115,9 @@ if (typeof window !== "undefined") {
10115
10115
  if (typeof window !== "undefined" && navigator.webdriver) {
10116
10116
  window.__vpDesign = async (script, o = {}) => {
10117
10117
  const [{ registerBuiltinTools, runTool }, { editorToolContext }, { createDesignPreview }] = await Promise.all([
10118
- import("./tools-YU5CI5J5.js").then(async (m) => ({ ...m, registerBuiltinTools: (await import("./builtin-3US63AOP.js")).registerBuiltinTools })),
10119
- import("./editor-seams-BT4QWT5U.js"),
10120
- import("./live-YWRRPA6G.js")
10118
+ import("./tools-2TCRJ6YI.js").then(async (m) => ({ ...m, registerBuiltinTools: (await import("./builtin-B425EDUG.js")).registerBuiltinTools })),
10119
+ import("./editor-seams-UO4QUUQH.js"),
10120
+ import("./live-QLSNGZ3Y.js")
10121
10121
  ]);
10122
10122
  registerBuiltinTools();
10123
10123
  const args = JSON.stringify({ ...o.name ? { name: o.name } : {}, ...o.size ? { size: o.size } : {}, ...o.frame ? { frame: o.frame } : {}, script });
@@ -150,7 +150,7 @@ function startHyperyTeams() {
150
150
  maybePromptForTeam();
151
151
  void followFileTeam(linkedKey);
152
152
  });
153
- void import("./sync-KX7WMSPO.js").then(({ onSyncStatus, syncStatus }) => {
153
+ void import("./sync-A56IG32K.js").then(({ onSyncStatus, syncStatus }) => {
154
154
  linkedKey = syncStatus().link?.key ?? null;
155
155
  void followFileTeam(linkedKey);
156
156
  onSyncStatus((_s, link) => {
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-7SMURRFY.js";
10
10
  import {
11
11
  activeTeamWorkspaceId
12
- } from "./chunk-KRUBAKYX.js";
12
+ } from "./chunk-GPNEAC5E.js";
13
13
  import {
14
14
  ApiError,
15
15
  GUEST_FILE_LIMIT,
@@ -23,7 +23,7 @@ import {
23
23
  } from "./chunk-TZQJDYMB.js";
24
24
  import {
25
25
  markLibraryDocument
26
- } from "./chunk-OMD5UZER.js";
26
+ } from "./chunk-EKKA4A5J.js";
27
27
  import {
28
28
  create
29
29
  } from "./chunk-QLJLPV5R.js";
@@ -6,7 +6,7 @@ const __filename = __popcraftPath(import.meta.url);
6
6
  const __dirname = __popcraftDirname(__filename);
7
7
  import {
8
8
  hyperyRequestHeaders
9
- } from "./chunk-V66THETF.js";
9
+ } from "./chunk-U5UFIM2E.js";
10
10
  import {
11
11
  aiAvailability,
12
12
  effectiveChatModel,
@@ -91,9 +91,9 @@ async function placeStockPhoto(photo, opts = {}) {
91
91
  }
92
92
  async function placePicture(imported, opts = {}) {
93
93
  const [{ useEditorStore }, { photoFrameOf }, { placeImage }] = await Promise.all([
94
- import("./editor-store-5N4YRWV2.js"),
94
+ import("./editor-store-V43NADG6.js"),
95
95
  import("../lib/document/photo-frames.js"),
96
- import("./media-tool-DCHP5P2O.js")
96
+ import("./media-tool-TXQINVAR.js")
97
97
  ]);
98
98
  const st = useEditorStore.getState();
99
99
  const frame = photoFrameOf(st.document.nodes, opts.targetId !== void 0 ? opts.targetId : st.selection[0] ?? null);