@popcraft/kit 0.52.0 → 0.53.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/dist/chunks/{agent-HRK56EXA.js → agent-B4XH7FCC.js} +1 -1
- package/dist/chunks/{builtin-3US63AOP.js → builtin-3TWJNRDI.js} +3 -3
- package/dist/chunks/{buy-credits-5C4ZIAPQ.js → buy-credits-VZ2J2SR7.js} +2 -2
- package/dist/chunks/{check-template-SUCKEUAH.js → check-template-GMNQVCCI.js} +2 -2
- package/dist/chunks/{chunk-KWETGFIB.js → chunk-5ICU2TQ2.js} +14 -14
- package/dist/chunks/{chunk-OMD5UZER.js → chunk-5JMMBP5Q.js} +5 -5
- package/dist/chunks/{chunk-DYSNP6UR.js → chunk-7CNZ5HLR.js} +45 -3
- package/dist/chunks/{chunk-IDWJKGNU.js → chunk-7XP5CWQO.js} +41 -41
- package/dist/chunks/{chunk-NGFWRQK3.js → chunk-AJPYEZRT.js} +2 -2
- package/dist/chunks/{chunk-YOPG6IGL.js → chunk-D7XGMFYM.js} +4 -4
- package/dist/chunks/{chunk-AKRFU5IC.js → chunk-DBGETMUH.js} +4 -4
- package/dist/chunks/{chunk-EWLFJFDO.js → chunk-DFY5UNVM.js} +1 -1
- package/dist/chunks/{chunk-CKS6JHCU.js → chunk-GNNRFMXK.js} +9 -9
- package/dist/chunks/{chunk-6OHSAJUQ.js → chunk-KPKVF2TA.js} +2 -2
- package/dist/chunks/{chunk-3MLA5BUJ.js → chunk-MYCQCAXZ.js} +4 -4
- package/dist/chunks/{chunk-6NVIZIQF.js → chunk-P5HF37GX.js} +2 -2
- package/dist/chunks/{chunk-AV6XTZEW.js → chunk-TCPSVZN3.js} +2 -2
- package/dist/chunks/{chunk-KHUWNPIW.js → chunk-U3PY5BWW.js} +11 -11
- package/dist/chunks/{chunk-YR6YKL6C.js → chunk-UNJ2Y726.js} +3 -3
- package/dist/chunks/{chunk-V66THETF.js → chunk-UT6GKZJF.js} +1 -1
- package/dist/chunks/{chunk-HKYBS2KY.js → chunk-XJFTD3EZ.js} +1 -1
- package/dist/chunks/{chunk-HJ7UVP3J.js → chunk-YHQGAEC5.js} +1 -1
- package/dist/chunks/{chunk-KRUBAKYX.js → chunk-Z557VFSN.js} +1 -1
- package/dist/chunks/{client-DHB4LF4B.js → client-77HZDECD.js} +3 -3
- package/dist/chunks/{client-W4L4L76Q.js → client-DNVGPZXT.js} +1 -1
- package/dist/chunks/{client-C5Y3Y5HH.js → client-SE7SVRWK.js} +2 -2
- package/dist/chunks/{client-actions-6CIMGIDV.js → client-actions-UNYIWTLI.js} +5 -5
- package/dist/chunks/{dangerous-MKUWMKP2.js → dangerous-WMMPM5TV.js} +3 -3
- package/dist/chunks/{delete-current-file-VXCBT5UK.js → delete-current-file-WB6ZWMBO.js} +5 -5
- package/dist/chunks/{editor-seams-BT4QWT5U.js → editor-seams-AZ2NUX6J.js} +10 -10
- package/dist/chunks/{editor-store-5N4YRWV2.js → editor-store-TPVGGNLW.js} +1 -1
- package/dist/chunks/{export-watermark-Z2LPEDSP.js → export-watermark-UGGZ5TX6.js} +5 -5
- package/dist/chunks/{eyedropper-YG6WXAMC.js → eyedropper-HPK6A4PE.js} +1 -1
- package/dist/chunks/{generate-media-OUKD27QT.js → generate-media-Y6MB3ENV.js} +3 -3
- package/dist/chunks/{host-ID3XQKWC.js → host-FNER4M32.js} +6 -6
- package/dist/chunks/{integrations-OW6CMKMO.js → integrations-LPVAVUUV.js} +1 -1
- package/dist/chunks/{libraries-X6HB7FPR.js → libraries-I6J7YJQE.js} +5 -5
- package/dist/chunks/{live-YWRRPA6G.js → live-ZRJ2GT3E.js} +1 -1
- package/dist/chunks/{media-tool-DCHP5P2O.js → media-tool-LTK46STY.js} +1 -1
- package/dist/chunks/{new-file-5T4Y7FST.js → new-file-XH7E3IEZ.js} +3 -3
- package/dist/chunks/{plugin-UMUQ76Y6.js → plugin-LAZVW4F4.js} +2 -2
- package/dist/chunks/{plugin-import-BCP4JHKO.js → plugin-import-P4PD76X3.js} +14 -14
- package/dist/chunks/{presence-7NKX5VRN.js → presence-WSPF6N32.js} +2 -2
- package/dist/chunks/{project-RD62AMZA.js → project-M3KF66GG.js} +1 -1
- package/dist/chunks/{publish-site-JCSC5ZNC.js → publish-site-PUHKHZF4.js} +6 -6
- package/dist/chunks/{publish-store-MVUSRXXI.js → publish-store-PZMIV6LJ.js} +4 -4
- package/dist/chunks/{raster-actions-53IZLIPK.js → raster-actions-NS2NSYLC.js} +1 -1
- package/dist/chunks/{runner-QXXCWTYC.js → runner-PGFSW23U.js} +17 -17
- package/dist/chunks/{store-EI2MB4IN.js → store-BXDDRMK7.js} +6 -6
- package/dist/chunks/{sync-KX7WMSPO.js → sync-4AHF7NWR.js} +5 -5
- package/dist/chunks/{tabs-O6XBUTGR.js → tabs-KFQNMNUM.js} +8 -8
- package/dist/chunks/{team-VCK5JGMP.js → team-QUBELR4W.js} +1 -1
- package/dist/chunks/{team-client-IB45QZLF.js → team-client-NCOTLKC5.js} +1 -1
- package/dist/chunks/{tools-YU5CI5J5.js → tools-T5XCKKCW.js} +2 -2
- package/dist/chunks/{ui-commands-OISNFY2F.js → ui-commands-77JZN35K.js} +12 -12
- package/dist/chunks/{versions-O2XIV3FF.js → versions-5HYBXUPA.js} +5 -5
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -7,8 +7,8 @@ const __dirname = __popcraftDirname(__filename);
|
|
|
7
7
|
import {
|
|
8
8
|
builtinTools,
|
|
9
9
|
registerBuiltinTools
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-P5HF37GX.js";
|
|
11
|
+
import "./chunk-7XP5CWQO.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-
|
|
22
|
+
import "./chunk-UNJ2Y726.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-
|
|
10
|
+
} from "./chunk-UT6GKZJF.js";
|
|
11
11
|
import "./chunk-7SMURRFY.js";
|
|
12
12
|
import {
|
|
13
13
|
useHyperyTeam
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-Z557VFSN.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-
|
|
9
|
+
} from "./chunk-GNNRFMXK.js";
|
|
10
10
|
import {
|
|
11
11
|
builtinCommands
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-7XP5CWQO.js";
|
|
13
13
|
import "./chunk-ZLWN6LBH.js";
|
|
14
14
|
import "./chunk-Q7EITIAT.js";
|
|
15
15
|
import "./chunk-X36CCQ76.js";
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from "./chunk-ZYK65XJJ.js";
|
|
16
16
|
import {
|
|
17
17
|
syncStatus
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-DBGETMUH.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-
|
|
31
|
+
} from "./chunk-5JMMBP5Q.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-
|
|
72
|
+
const { dispatchPluginCall } = await import("./plugin-LAZVW4F4.js");
|
|
73
73
|
return dispatchPluginCall(env, method, params);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
// node_modules/.pnpm/@popcraft+plugins@1.0
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
582
|
+
const { createFreshFileOrExplain } = await import("./new-file-XH7E3IEZ.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-
|
|
772
|
+
const { importViaPlugin, applyPluginLayoutIr } = await import("./plugin-import-P4PD76X3.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-
|
|
4591
|
+
void import("./presence-WSPF6N32.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-
|
|
6655
|
+
const { duplicateDocumentToCloud } = await import("./sync-4AHF7NWR.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-
|
|
10119
|
-
import("./editor-seams-
|
|
10120
|
-
import("./live-
|
|
10118
|
+
import("./tools-T5XCKKCW.js").then(async (m) => ({ ...m, registerBuiltinTools: (await import("./builtin-3TWJNRDI.js")).registerBuiltinTools })),
|
|
10119
|
+
import("./editor-seams-AZ2NUX6J.js"),
|
|
10120
|
+
import("./live-ZRJ2GT3E.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 });
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
hostEnv,
|
|
10
10
|
plain,
|
|
11
11
|
registerBuiltinCommands
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-7XP5CWQO.js";
|
|
13
13
|
import {
|
|
14
14
|
storeOpsSeam
|
|
15
15
|
} from "./chunk-KOAEKWIA.js";
|
|
@@ -391,6 +391,8 @@ function isOpenableUrl(v) {
|
|
|
391
391
|
return false;
|
|
392
392
|
}
|
|
393
393
|
}
|
|
394
|
+
var MAX_UPLOAD_BYTES = 500 * 1024 * 1024;
|
|
395
|
+
var MAX_UPLOAD_REPLY_CHARS = 1024 * 1024;
|
|
394
396
|
function pluginOf(ctx) {
|
|
395
397
|
if (ctx.actor.kind !== "plugin" || !ctx.actor.id) throw new PluginApiError("Only a plugin keeps file data");
|
|
396
398
|
return ctx.actor.id;
|
|
@@ -474,6 +476,46 @@ var commands = [
|
|
|
474
476
|
return { summary: "Opened link" };
|
|
475
477
|
}
|
|
476
478
|
}),
|
|
479
|
+
defineCommand({
|
|
480
|
+
id: pluginCommandId("upload"),
|
|
481
|
+
title: "Upload a file",
|
|
482
|
+
domain: "ui",
|
|
483
|
+
// The sandbox's own fetch is fine for small requests; a book-sized export goes through here so it can be
|
|
484
|
+
// PUT straight onto a presigned storage URL rather than through a server that caps its request body.
|
|
485
|
+
params: external_exports.object({
|
|
486
|
+
url: external_exports.string().refine(isOpenableUrl, { error: "url must be https, or http on localhost" }),
|
|
487
|
+
body: external_exports.union([external_exports.instanceof(Uint8Array), external_exports.string()]),
|
|
488
|
+
method: external_exports.enum(["PUT", "POST"]).optional(),
|
|
489
|
+
contentType: external_exports.string().max(200).optional(),
|
|
490
|
+
headers: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
491
|
+
}),
|
|
492
|
+
effect: "none",
|
|
493
|
+
permission: "network",
|
|
494
|
+
expose: { plugin: { method: "upload", shape: (r) => r.data } },
|
|
495
|
+
run: async (p) => {
|
|
496
|
+
const size2 = typeof p.body === "string" ? p.body.length : p.body.byteLength;
|
|
497
|
+
if (size2 > MAX_UPLOAD_BYTES) throw new PluginApiError(`upload is limited to ${MAX_UPLOAD_BYTES / 1024 / 1024} MB`, "invalid_params");
|
|
498
|
+
if (typeof location !== "undefined" && new URL(p.url).origin === location.origin) {
|
|
499
|
+
throw new PluginApiError("upload cannot send to PopCraft itself", "invalid_params");
|
|
500
|
+
}
|
|
501
|
+
const headers = new Headers(p.headers ?? {});
|
|
502
|
+
if (p.contentType) headers.set("content-type", p.contentType);
|
|
503
|
+
let res;
|
|
504
|
+
try {
|
|
505
|
+
res = await fetch(p.url, { method: p.method ?? "PUT", body: p.body, headers, credentials: "omit", mode: "cors" });
|
|
506
|
+
} catch (err) {
|
|
507
|
+
throw new PluginApiError(`Could not reach ${new URL(p.url).origin}: ${err instanceof Error ? err.message : String(err)}`, "unsupported");
|
|
508
|
+
}
|
|
509
|
+
const text = await res.text();
|
|
510
|
+
const data = {
|
|
511
|
+
ok: res.ok,
|
|
512
|
+
status: res.status,
|
|
513
|
+
headers: Object.fromEntries(res.headers.entries()),
|
|
514
|
+
body: text.length > MAX_UPLOAD_REPLY_CHARS ? text.slice(0, MAX_UPLOAD_REPLY_CHARS) : text
|
|
515
|
+
};
|
|
516
|
+
return { summary: `Uploaded ${size2} bytes (${res.status})`, data };
|
|
517
|
+
}
|
|
518
|
+
}),
|
|
477
519
|
defineCommand({
|
|
478
520
|
id: pluginCommandId("showUI"),
|
|
479
521
|
title: "Show plugin UI",
|
|
@@ -573,7 +615,7 @@ var commands = [
|
|
|
573
615
|
const [{ storefrontInputs }, { STOREFRONT_TARGETS }, { bytesOf }, { zipFiles }, { EXPORT_NODE_CAP }] = await Promise.all([
|
|
574
616
|
import("./storefront-prepare-EXR7OIWW.js"),
|
|
575
617
|
import("./storefront-BPMM6QWK.js"),
|
|
576
|
-
import("./project-
|
|
618
|
+
import("./project-M3KF66GG.js"),
|
|
577
619
|
import("./zip-export-ZYXDK4SM.js"),
|
|
578
620
|
import("./tree-YKYXBPRZ.js")
|
|
579
621
|
]);
|
|
@@ -770,7 +812,7 @@ var pluginRun = defineCommand({
|
|
|
770
812
|
}
|
|
771
813
|
},
|
|
772
814
|
run: async (p, ctx) => {
|
|
773
|
-
const { runPlugin } = await import("./host-
|
|
815
|
+
const { runPlugin } = await import("./host-FNER4M32.js");
|
|
774
816
|
await runPlugin(p.pluginId, p.commandId);
|
|
775
817
|
ctx.notice(`Started ${p.pluginId}.`);
|
|
776
818
|
return {
|