diff --git a/docs/CODE_MODE_SETUP.md b/docs/CODE_MODE_SETUP.md new file mode 100644 index 0000000..cb79332 --- /dev/null +++ b/docs/CODE_MODE_SETUP.md @@ -0,0 +1,102 @@ +# Code Mode setup + +The `cocos-code-mode` extension (in [extensions/cocos-code-mode](../extensions/cocos-code-mode)) +runs an HTTP server inside the Cocos Creator editor and exposes scene, asset and +inspector operations as [UTCP](https://www.utcp.io/) tools. That is how the editor +is driven from outside the UI — see [CODE_MODE_TOOLS.md](CODE_MODE_TOOLS.md) for +the tool reference. + +## Prerequisites + +- Cocos Creator 3.8.8 must be **running with this project open**. The tool server + lives inside the editor process; if the editor is closed, there are no tools. +- The extension registers itself in `~/.utcp_config.json` on startup. + +## The port changes on every editor restart + +The server binds to `127.0.0.1` on an OS-assigned port, and rewrites +`~/.utcp_config.json` each time. Always read the config file rather than +remembering a port: + +```bash +cat ~/.utcp_config.json +``` + +## Running a tool chain + +Pass the config path via `UTCP_CONFIG_FILE`. The script body runs as an async +function; tool calls look synchronous and `return` gives back the result. + +```bash +UTCP_CONFIG_FILE="$USERPROFILE/.utcp_config.json" npx -y @utcp/code-mode-cli run <<'EOF' +const tree = CocosEditor.nodeGetTree({}); +return { name: tree.name, children: (tree.children || []).map(c => c.name) }; +EOF +``` + +Discover tools by task instead of guessing names: + +```bash +UTCP_CONFIG_FILE="$USERPROFILE/.utcp_config.json" npx -y @utcp/code-mode-cli search "add a sprite to a node" +``` + +## Working discipline + +The tools are built around **discover, then act**: + +1. `nodeGetTree` / `assetGetTree` — find the thing. +2. `inspectorGetInstanceDefinition` — get its real TypeScript class. +3. `inspectorSetInstanceProperties` — set properties by confirmed name. + +`inspectorSetInstanceProperties` states it outright: if a property path or type +has not been confirmed via an `inspectorGet*` call, do not call a setter. Property +names differ from the engine docs often enough that guessing corrupts scenes. + +Batch reads and writes into one `run` script — each `npx` invocation re-registers +the manual, which costs a few seconds. + +## Regenerating the tool reference + +After updating the extension: + +```bash +curl -s "$(node -p "require(require('os').homedir()+'/.utcp_config.json').manual_call_templates[0].url")" -o manual.json +node docs/scripts/gen-tool-reference.js manual.json docs/CODE_MODE_TOOLS.md +``` + +## Known issue: `sharp` / libvips conflict on Windows + +**Symptom.** The editor logs `The plug-in main process failed to load` with either +`Could not load the "sharp" module using the win32-x64 runtime` or +`TypeError: Cannot read properties of undefined (reading 'output')` at +`node_modules/sharp/lib/utility.js`. No `~/.utcp_config.json` appears and no tools +are reachable. + +**Cause.** Two things stacked: + +1. The released extension zip was packaged on macOS, so its bundled `sharp` ships + only `darwin-arm64` binaries. +2. More fundamentally, Cocos Creator already has its own `sharp` **0.32.6** + (libvips 8.14) resident in the same process. On Windows a second libvips cannot + be loaded beside the first, so the extension's `sharp` 0.34.x binds against the + editor's older DLL. That DLL has no JPEG 2000 support, `format.jp2k` comes back + undefined, and the module throws while initialising — taking the whole plugin + with it. + +**Fix.** [asset-tools.js](../extensions/cocos-code-mode/dist/utcp/tools/asset-tools.js) +now loads `sharp` lazily, prefers the editor's own resident build under +`process.resourcesPath/app.asar.unpacked/node_modules/sharp`, and tolerates it +being unavailable. `sharp` is only a fast path for `assetGetPreview`, which +already had a renderer-based fallback, so a missing image library no longer stops +the tool server from starting. + +That file is tracked by git, so the fix survives — but **re-importing the extension +from a release zip will overwrite it.** If the extension is ever re-imported, +re-apply the patch and, on Windows, also install the matching native binaries: + +```bash +cd extensions/cocos-code-mode && npm install --no-save --os=win32 --cpu=x64 --include=optional sharp@0.34.5 +``` + +(`extensions/cocos-code-mode/node_modules` is gitignored, so that install does not +survive a clean checkout either.) diff --git a/docs/CODE_MODE_TOOLS.md b/docs/CODE_MODE_TOOLS.md new file mode 100644 index 0000000..7d66a97 --- /dev/null +++ b/docs/CODE_MODE_TOOLS.md @@ -0,0 +1,485 @@ +# Code Mode tool reference (`CocosEditor`) + +Generated from the live UTCP manual served by the `cocos-code-mode` extension +(UTCP 1.0.1, 24 tools). Regenerate with the command in +[CODE_MODE_SETUP.md](CODE_MODE_SETUP.md) whenever the extension is updated. + +All tools are called as `CocosEditor.({ ... })` inside a `utcp run` script. +Calls look synchronous — the host bridges the async work, so no `await` is needed. + +## Conventions + +Nodes, components and assets are passed around as UUID handles: + +```ts +interface IInstanceReference { id: string; type?: string; } // e.g. { id: "a1b2…", type: "cc.Sprite" } +``` + +Work **discover, then act**: get the tree, get the type definition, then set properties by name. +Never guess property names — `inspectorGetInstanceDefinition` returns the real TypeScript class. + +## Scene graph + +### `nodeGetTree` + +Get the hierarchy tree of specific node or scene root if no reference is provided. Children have recursive structure. + +```ts +CocosEditor.nodeGetTree(args: { + reference?: { + id: string; + type?: string; + }; +}): { + path?: string; + reference: { + id: string; + type?: string; + }; + name: string; + active: boolean; + components: { + id: string; + type?: string; + }[]; + children: Record[]; +} +``` + +### `nodeGetAtPath` + +Get nodes at specific path in the scene hierarchy. Usually returns one node, but can return multiple nodes with the same name. + +```ts +CocosEditor.nodeGetAtPath(args: { + hierarchyPath: string; // Path to the node in the scene hierarchy" +}): { + references?: { + id: string; + type?: string; + }[]; +} +``` + +### `nodeCreate` + +Create a new node in the scene. If no parent is specified, root node is used. Returns reference to the new node. + +```ts +CocosEditor.nodeCreate(args: { + name: string; + parentReference?: { + id: string; + type?: string; + }; + assetReference?: { + id: string; + type?: string; + }; + unwrapPrefab?: boolean; // default: false +}): { + reference: { + id: string; + type?: string; + }; +} +``` + +### `nodeCreatePrimitive` + +Create a new node with predefined primitive geometry MeshRenderer. If no parent is specified, root node is used. Returns reference to the new node. + +```ts +CocosEditor.nodeCreatePrimitive(args: { + name: string; + primitiveType: "Capsule" | "Cone" | "Cube" | "Cylinder" | "Plane" | "Quad" | "Sphere" | "Torus"; + parentReference?: { + id: string; + type?: string; + }; +}): { + reference: { + id: string; + type?: string; + }; +} +``` + +### `nodeOperate` + +Perform operation on referenced node, including prefab operations. + +```ts +CocosEditor.nodeOperate(args: { + operation: "move" | "copy" | "delete" | "create_prefab" | "revert_prefab" | "apply_prefab" | "unwrap_prefab" | "unwrap_prefab_completely" | "open_prefab"; + reference: { + id: string; + type?: string; + }; + newParentReference?: { + id: string; + type?: string; + }; + newPrefabPath?: string; // For create_prefab: target db:// path + siblingIndex?: integer; // For move/copy: target index in parent children array +}): { + success?: boolean; + createdPrefabAssetReference?: { + id: string; + type?: string; + }; + updatedNodeReference?: { + id: string; + type?: string; + }; + copiedNodeReference?: { + id: string; + type?: string; + }; +} +``` + +## Components + +### `nodeComponentsGet` + +Get components of specific type on a node. If componentType is not provided, returns all components on the node. + +```ts +CocosEditor.nodeComponentsGet(args: { + reference: { + id: string; + type?: string; + }; + componentType?: string; +}): { + references: { + id: string; + type?: string; + }[]; +} +``` + +### `nodeComponentAdd` + +Add a component to a referenced node, returns reference to the new component + +```ts +CocosEditor.nodeComponentAdd(args: { + reference: { + id: string; + type?: string; + }; + componentType: string; +}): { + reference: { + id: string; + type?: string; + }; +} +``` + +### `nodeComponentRemove` + +Remove referenced component from node it is attached to. + +```ts +CocosEditor.nodeComponentRemove(args: { + reference: { + id: string; + type?: string; + }; +}): { + success: boolean; + error?: string; +} +``` + +### `nodeGetAvailableComponentTypes` + +Get list of globally available component types (class names) at the moment. + +```ts +CocosEditor.nodeGetAvailableComponentTypes(args: { + includeInternal: boolean; // Whether to include internal engine components. — default: false + filter?: string; // Optional filter string to match component types or categories (case-insensitive substring match). +}): { + componentTypes: string[]; +} +``` + +## Inspector (types & properties) + +### `inspectorGetInstanceDefinition` + +Generates TypeScript definition based on properties and descriptions of instance (Node, Component, Asset). + +```ts +CocosEditor.inspectorGetInstanceDefinition(args: { + reference: { + id: string; + type?: string; + }; +}): { + definition: string; +} +``` + +### `inspectorGetSettingsDefinition` + +Generates TypeScript definition for specific settings. + +```ts +CocosEditor.inspectorGetSettingsDefinition(args: { + settingsType: "CommonTypes" | "CurrentSceneGlobals" | "ProjectSettings"; +}): { + definition: string; +} +``` + +### `inspectorGetInstanceProperties` + +Gets plain object of properties, with no serialization info for any instance (scene node, component, asset). + +```ts +CocosEditor.inspectorGetInstanceProperties(args: { + reference: { + id: string; + type?: string; + }; +}): { + dump: Record; +} +``` + +### `inspectorGetSettingsProperties` + +Gets plain object of properties for the specific settings. + +```ts +CocosEditor.inspectorGetSettingsProperties(args: { + settingsType: "CurrentSceneGlobals" | "ProjectSettings"; +}): { + dump: Record; +} +``` + +### `inspectorSetInstanceProperties` + +Sets a property on instance of Node, Component or Asset. If a property path or type is not confirmed via inspectorGet* tools, you MUST NOT call any setter. + +```ts +CocosEditor.inspectorSetInstanceProperties(args: { + reference: { + id: string; + type?: string; + }; + propertyPaths: string[]; // Plain paths to the properties (e.g., ['position.x', 'rotation.y']). Don't support code execution. Arrays are reached by indexes. (e.g. 'sharedMaterials.0') + values: array,object,string,number,boolean,null[]; +}): { + success: boolean; + error?: string; +} +``` + +### `inspectorSetSettingsProperties` + +Sets a property on the specific settings. If a property path or type is not confirmed via inspectorGet* tools, you MUST NOT call any setter. + +```ts +CocosEditor.inspectorSetSettingsProperties(args: { + settingsType: "CurrentSceneGlobals" | "ProjectSettings"; + propertyPath: string; // Plain path to the property (e.g., 'ambient.skyLightingColor.r'). Don't support code execution. + value: array,object,string,number,boolean,null; +}): { + success: boolean; + error?: string; +} +``` + +## Assets + +### `assetGetTree` + +Get the asset and subAsset hierarchy tree. Children have recursive structure. + +```ts +CocosEditor.assetGetTree(args: { + reference?: { + id: string; + type?: string; + }; + assetPath?: string; // Root path to start from +}): { + filesystemPath?: string; + reference: { + id: string; + type?: string; + }; + name: string; + children: Record[]; +} +``` + +### `assetGetAtPath` + +Get asset reference by given local path and name, including extension. Can be used for subassets too. Returns reference to the asset. + +```ts +CocosEditor.assetGetAtPath(args: { + assetPath: string; +}): { + reference: { + id: string; + type?: string; + }; +} +``` + +### `assetCreate` + +Create empty asset or folder of given type. Automatically handles folders creation along the path. Returns reference to the new asset. + +```ts +CocosEditor.assetCreate(args: { + assetPath: string; + preset: "folder" | "material" | "effect" | "scene" | "prefab" | "typescript" | "animation-clip" | "render-texture" | "physics-material" | "animation-graph" | "animation-graph-variant" | "animation-mask" | "auto-atlas" | "effect-header" | "label-atlas" | "terrain"; // Preset type for the new asset + options?: { + overwrite?: boolean; + rename?: boolean; + }; // Additional options for the operation +}): { + reference: { + id: string; + type?: string; + }; +} +``` + +### `assetImport` + +Import an external file as an asset into the project. Path must end with the extension. Returns reference to the new asset. + +```ts +CocosEditor.assetImport(args: { + sourceFilesystemPath: string; // Source filesystem path of the file to import + targetAssetPath: string; // Target path in the asset database + imageType?: "raw" | "texture" | "normal-map" | "sprite-frame" | "texture-cube"; // For image files, specify how to import them + options?: { + overwrite?: boolean; + rename?: boolean; + }; // Additional options for the operation +}): { + reference: { + id: string; + type?: string; + }; +} +``` + +### `assetOperate` + +Perform operations on assets (move, copy, delete, open). Returns reference to the affected asset (for delete/open returns the source asset reference). + +```ts +CocosEditor.assetOperate(args: { + operation: "move" | "copy" | "delete" | "open" | "refresh" | "reimport"; + reference: { + id: string; + type?: string; + }; + targetAssetPath?: string; // Target path (for move/copy/import) + options?: { + overwrite?: boolean; + rename?: boolean; + }; // Additional options for the operation +}): { + reference: { + id: string; + type?: string; + }; +} +``` + +### `assetGetPreview` + +Returns preview image of the asset (Prefab, Image, Model or Material is supported). IMPORTANT: To visualize the image, you must return the result of this function DIRECTLY as the final value of your code, do NOT wrap it in an object. + +```ts +CocosEditor.assetGetPreview(args: { + reference: { + id: string; + type?: string; + }; + imageSize?: number; // Size of the preview image (square) — default: 512 + jpegQuality?: integer; // JPEG Quality of the preview image — default: 80 + transparentColor?: { + r: integer; + g: integer; + b: integer; + }; // Background color for transparent images in RGB format +}): { + type: string; + data: string; + mimeType: string; +} +``` + +## Editor + +### `editorOperate` + +Common editor operations for scene and prefab view, game preview controls and asset database refresh + +```ts +CocosEditor.editorOperate(args: { + operation: "save_scene_or_prefab" | "close_scene_or_prefab" | "play_preview" | "pause" | "step" | "stop" | "refresh"; +}): { + success: boolean; + error?: string; +} +``` + +### `editorGetLogs` + +Get last N editor log entries + +```ts +CocosEditor.editorGetLogs(args: { + count: number; // Number of log entries to retrieve — default: 10 + showStack?: boolean; // Return full stack trace for each log entry + order: "newest-to-oldest" | "oldest-to-newest"; // Order of logs — default: "newest-to-oldest" +}): { + logLines: string[]; +} +``` + +### `editorGetScenePreview` + +Returns preview image of scene view. IMPORTANT: To visualize the image, you must return the result of this function DIRECTLY as the final value of your code, do NOT wrap it in an object. + +```ts +CocosEditor.editorGetScenePreview(args: { + imageSize?: { + width?: number; // default: 512 + height?: number; // default: 512 + }; + jpegQuality?: integer; // default: 80 + cameraPosition: { + x: number; + y: number; + z: number; + }; // Camera world position + targetPosition: { + x: number; + y: number; + z: number; + }; // Point the camera looks at + orthographic?: boolean; // Whether to use orthographic projection — default: false + orthographicSize?: number; // Orthographic size (only applies if orthographic is true) — default: 10 +}): { + type: string; + data: string; + mimeType: string; +} +``` diff --git a/docs/scripts/gen-tool-reference.js b/docs/scripts/gen-tool-reference.js new file mode 100644 index 0000000..2f3e280 --- /dev/null +++ b/docs/scripts/gen-tool-reference.js @@ -0,0 +1,101 @@ +const fs = require('fs'); +const manual = JSON.parse(fs.readFileSync(process.argv[2], 'utf8')); + +function render(schema, indent) { + if (!schema) return 'unknown'; + const pad = ' '.repeat(indent); + const padIn = ' '.repeat(indent + 1); + if (schema.enum) return schema.enum.map(v => JSON.stringify(v)).join(' | '); + switch (schema.type) { + case 'array': + return render(schema.items, indent) + '[]'; + case 'object': { + if (!schema.properties) return 'Record'; + const req = schema.required || []; + const lines = Object.entries(schema.properties).map(([k, v]) => { + const opt = req.includes(k) ? '' : '?'; + let line = `${padIn}${k}${opt}: ${render(v, indent + 1)};`; + const notes = []; + if (v.description) notes.push(v.description); + if (v.default !== undefined) notes.push(`default: ${JSON.stringify(v.default)}`); + if (notes.length) line += ` // ${notes.join(' — ')}`; + return line; + }); + return `{\n${lines.join('\n')}\n${pad}}`; + } + case undefined: + return 'unknown'; + default: + return schema.type; + } +} + +const groups = [ + ['Scene graph', ['nodeGetTree', 'nodeGetAtPath', 'nodeCreate', 'nodeCreatePrimitive', 'nodeOperate']], + ['Components', ['nodeComponentsGet', 'nodeComponentAdd', 'nodeComponentRemove', 'nodeGetAvailableComponentTypes']], + ['Inspector (types & properties)', ['inspectorGetInstanceDefinition', 'inspectorGetSettingsDefinition', 'inspectorGetInstanceProperties', 'inspectorGetSettingsProperties', 'inspectorSetInstanceProperties', 'inspectorSetSettingsProperties']], + ['Assets', ['assetGetTree', 'assetGetAtPath', 'assetCreate', 'assetImport', 'assetOperate', 'assetGetPreview']], + ['Editor', ['editorOperate', 'editorGetLogs', 'editorGetScenePreview']], +]; + +const byName = new Map(manual.tools.map(t => [t.name, t])); +const out = []; + +out.push('# Code Mode tool reference (`CocosEditor`)'); +out.push(''); +out.push('Generated from the live UTCP manual served by the `cocos-code-mode` extension'); +out.push(`(UTCP ${manual.utcp_version}, ${manual.tools.length} tools). Regenerate with the command in`); +out.push('[CODE_MODE_SETUP.md](CODE_MODE_SETUP.md) whenever the extension is updated.'); +out.push(''); +out.push('All tools are called as `CocosEditor.({ ... })` inside a `utcp run` script.'); +out.push('Calls look synchronous — the host bridges the async work, so no `await` is needed.'); +out.push(''); +out.push('## Conventions'); +out.push(''); +out.push('Nodes, components and assets are passed around as UUID handles:'); +out.push(''); +out.push('```ts'); +out.push('interface IInstanceReference { id: string; type?: string; } // e.g. { id: "a1b2…", type: "cc.Sprite" }'); +out.push('```'); +out.push(''); +out.push('Work **discover, then act**: get the tree, get the type definition, then set properties by name.'); +out.push('Never guess property names — `inspectorGetInstanceDefinition` returns the real TypeScript class.'); +out.push(''); + +const seen = new Set(); +for (const [title, names] of groups) { + out.push(`## ${title}`); + out.push(''); + for (const name of names) { + const t = byName.get(name); + if (!t) continue; + seen.add(name); + out.push(`### \`${name}\``); + out.push(''); + out.push(t.description); + out.push(''); + out.push('```ts'); + out.push(`CocosEditor.${name}(args: ${render(t.inputs, 0)}): ${render(t.outputs, 0)}`); + out.push('```'); + out.push(''); + } +} + +const rest = manual.tools.filter(t => !seen.has(t.name)); +if (rest.length) { + out.push('## Other'); + out.push(''); + for (const t of rest) { + out.push(`### \`${t.name}\``); + out.push(''); + out.push(t.description); + out.push(''); + out.push('```ts'); + out.push(`CocosEditor.${t.name}(args: ${render(t.inputs, 0)}): ${render(t.outputs, 0)}`); + out.push('```'); + out.push(''); + } +} + +fs.writeFileSync(process.argv[3], out.join('\n')); +console.log('wrote', process.argv[3], out.length, 'lines'); diff --git a/extensions/cocos-code-mode/dist/utcp/tools/asset-tools.js b/extensions/cocos-code-mode/dist/utcp/tools/asset-tools.js index 846cd10..ba69716 100644 --- a/extensions/cocos-code-mode/dist/utcp/tools/asset-tools.js +++ b/extensions/cocos-code-mode/dist/utcp/tools/asset-tools.js @@ -44,7 +44,34 @@ var __importDefault = (this && this.__importDefault) || function (mod) { Object.defineProperty(exports, "__esModule", { value: true }); exports.AssetTools = void 0; const package_json_1 = __importDefault(require("../../../package.json")); -const sharp_1 = __importDefault(require("sharp")); +let sharp_1; +/** + * Cocos Creator keeps its own sharp (0.32.6) resident in this process. On + * Windows a second libvips cannot be loaded beside it, so the copy bundled with + * this extension binds against the editor's older DLL and throws while loading. + * Prefer the editor's build, fall back to the bundled one, and tolerate neither + * being usable - asset previews fall back to the renderer-based path. + */ +function getSharp() { + if (sharp_1 !== undefined) + return sharp_1; + const { join } = require('path'); + const candidates = []; + if (process.resourcesPath) + candidates.push(join(process.resourcesPath, 'app.asar.unpacked', 'node_modules', 'sharp')); + candidates.push('sharp'); + for (const candidate of candidates) { + try { + sharp_1 = require(candidate); + return sharp_1; + } + catch (e) { + console.warn(`[cocos-code-mode] sharp not loadable from ${candidate}: ${e.message}`); + } + } + sharp_1 = null; + return sharp_1; +} const fs_extra_1 = __importDefault(require("fs-extra")); const decorators_1 = require("../decorators"); const schemas_1 = require("../schemas"); @@ -333,9 +360,10 @@ class AssetTools { sourcePath = fileInfo.file; } } - if (sourcePath && fs_extra_1.default.existsSync(sourcePath)) { + const sharp = sourcePath ? getSharp() : null; + if (sharp && fs_extra_1.default.existsSync(sourcePath)) { try { - const image = (0, sharp_1.default)(sourcePath); + const image = sharp(sourcePath); const metadata = await image.metadata(); const requestedSize = args.imageSize || 512; let processed = image; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..fb0d6dd --- /dev/null +++ b/package-lock.json @@ -0,0 +1,679 @@ +{ + "name": "fool-cardgame", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "fool-cardgame", + "dependencies": { + "@utcp/code-mode": "^1.2.13", + "sharp": "^0.35.4" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz", + "integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.3.3" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz", + "integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.3.3" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz", + "integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==", + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.4" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz", + "integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz", + "integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz", + "integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz", + "integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz", + "integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz", + "integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz", + "integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz", + "integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz", + "integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz", + "integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz", + "integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz", + "integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz", + "integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz", + "integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz", + "integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz", + "integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.3.3" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz", + "integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz", + "integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.3.3" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz", + "integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.3" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz", + "integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/sharp-wasm32": "0.35.4" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz", + "integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz", + "integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz", + "integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@utcp/code-mode": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@utcp/code-mode/-/code-mode-1.2.13.tgz", + "integrity": "sha512-HbDjHdOos/b5ZuU0hezvn8cJy6KUJ/NXxFlnb+iTRX6X30t9c2DxWJfJtz9EsSOVYBrN7Bh72e/S47MOPmK9bg==", + "license": "MPL-2.0", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@utcp/sdk": "^1.1.0", + "isolated-vm": "^6.0.0" + }, + "peerDependenciesMeta": { + "isolated-vm": { + "optional": false + } + } + }, + "node_modules/@utcp/sdk": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@utcp/sdk/-/sdk-1.1.2.tgz", + "integrity": "sha512-YOBhcOK5kbD27d3emuXNAb8gBb8nH2kr7BuqjrvmSGyUi9379jzusYeTuZDsAxyy5da9VZPnfC/cNCpTVkEtUw==", + "license": "MPL-2.0", + "peer": true, + "dependencies": { + "dotenv": "^17.2.1", + "zod": "^3.23.8" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/isolated-vm": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/isolated-vm/-/isolated-vm-6.2.0.tgz", + "integrity": "sha512-UuSlxSHWt2QuJ5WvBhzlIJx2VVZN/a44SqBbEZFKNdvuSyhOvhmyDo8SQ+njVbhnh/njoL/aW0bUTiFYlpweGQ==", + "hasInstallScript": true, + "license": "ISC", + "peer": true, + "dependencies": { + "node-gyp-build": "^4.8.4" + }, + "engines": { + "node": ">=22.0.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "peer": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz", + "integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==", + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.1.0", + "detect-libc": "^2.1.2", + "semver": "^7.8.5" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.35.4", + "@img/sharp-darwin-x64": "0.35.4", + "@img/sharp-freebsd-wasm32": "0.35.4", + "@img/sharp-libvips-darwin-arm64": "1.3.3", + "@img/sharp-libvips-darwin-x64": "1.3.3", + "@img/sharp-libvips-linux-arm": "1.3.3", + "@img/sharp-libvips-linux-arm64": "1.3.3", + "@img/sharp-libvips-linux-ppc64": "1.3.3", + "@img/sharp-libvips-linux-riscv64": "1.3.3", + "@img/sharp-libvips-linux-s390x": "1.3.3", + "@img/sharp-libvips-linux-x64": "1.3.3", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", + "@img/sharp-libvips-linuxmusl-x64": "1.3.3", + "@img/sharp-linux-arm": "0.35.4", + "@img/sharp-linux-arm64": "0.35.4", + "@img/sharp-linux-ppc64": "0.35.4", + "@img/sharp-linux-riscv64": "0.35.4", + "@img/sharp-linux-s390x": "0.35.4", + "@img/sharp-linux-x64": "0.35.4", + "@img/sharp-linuxmusl-arm64": "0.35.4", + "@img/sharp-linuxmusl-x64": "0.35.4", + "@img/sharp-webcontainers-wasm32": "0.35.4", + "@img/sharp-win32-arm64": "0.35.4", + "@img/sharp-win32-ia32": "0.35.4", + "@img/sharp-win32-x64": "0.35.4" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json index c92df96..1d27055 100644 --- a/package.json +++ b/package.json @@ -3,5 +3,9 @@ "uuid": "2d8862c1-33e6-4159-bb31-fc590692a1e5", "creator": { "version": "3.8.8" + }, + "dependencies": { + "@utcp/code-mode": "^1.2.13", + "sharp": "^0.35.4" } }