@neta-art/cohub-cli 10.2.0 → 10.4.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/README.md +40 -2
- package/dist/board-export-resources.d.ts +8 -0
- package/dist/board-export-resources.js +39 -0
- package/dist/board-export.d.ts +6 -0
- package/dist/board-export.js +58 -8
- package/dist/board-kernel.d.ts +1 -1
- package/dist/board-kernel.js +211 -141
- package/dist/commands/boards/authoring.js +14 -16
- package/dist/commands/boards.d.ts +1 -0
- package/dist/commands/boards.js +44 -13
- package/dist/commands/rooms-connect.d.ts +17 -0
- package/dist/commands/rooms-connect.js +140 -0
- package/dist/commands/rooms-rtc-binary.d.ts +2 -0
- package/dist/commands/rooms-rtc-binary.js +107 -0
- package/dist/commands/rooms-rtc.d.ts +21 -0
- package/dist/commands/rooms-rtc.js +171 -0
- package/dist/commands/rooms.js +45 -0
- package/dist/commands/sandboxd-binary.d.ts +3 -3
- package/dist/commands/sandboxd-binary.js +27 -17
- package/dist/runtime/harness.d.ts +5 -0
- package/dist/runtime/harness.js +29 -3
- package/dist/runtime/json-rpc.js +1 -1
- package/dist/runtime/launch.js +21 -6
- package/dist/runtime/native/attach.js +5 -2
- package/dist/runtime/native/codex-link.d.ts +2 -0
- package/dist/runtime/native/codex-link.js +3 -1
- package/dist/runtime/native/execution.js +3 -3
- package/dist/runtime/native/ingest.js +4 -4
- package/dist/runtime/native/paths.d.ts +2 -0
- package/dist/runtime/native/paths.js +7 -0
- package/dist/runtime/native/pi-extension.js +12 -2
- package/dist/runtime/native/pi-link.js +21 -4
- package/dist/runtime/native/version.js +4 -1
- package/dist/runtime/supervisor.js +33 -4
- package/package.json +3 -2
package/dist/board-kernel.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as groupD8, A as bgr2rgb, B as Bounds, C as Sprite, D as TexturePool, E as RenderGroup, G as TextureStyle, H as Texture, I as BigPool, J as deprecation, K as definedProps, L as GlobalResourceRegistry, M as multiplyHexColors, N as getGlobalBounds, O as InstructionSet, P as FilterEffect, Q as Rectangle, R as warn, S as DOMAdapter, T as Container, U as TextureMatrix, V as updateQuadBounds, W as TextureSource, X as v8_3_4, Y as v8_0_0, Z as uid$1, _ as Cache, a as Geometry, at as extensions, b as ImageSource, c as Filter, d as RendererType, et as Matrix, f as BindGroup, g as getTestContext, h as GlProgram, i as canUseNewCanvasBlendModes, it as ExtensionType, j as multiplyColors, k as getLocalBounds, l as State, m as GpuProgram, n as CanvasPool, nt as eventemitter3_default, o as Buffer
|
|
1
|
+
import { $ as groupD8, A as bgr2rgb, B as Bounds, C as Sprite, D as TexturePool, E as RenderGroup, G as TextureStyle, H as Texture, I as BigPool, J as deprecation, K as definedProps, L as GlobalResourceRegistry, M as multiplyHexColors, N as getGlobalBounds, O as InstructionSet, P as FilterEffect, Q as Rectangle, R as warn, S as DOMAdapter, T as Container, U as TextureMatrix, V as updateQuadBounds, W as TextureSource, X as v8_3_4, Y as v8_0_0, Z as uid$1, _ as Cache, a as Geometry, at as extensions, b as ImageSource, c as Filter, d as RendererType, et as Matrix, f as BindGroup, g as getTestContext, h as GlProgram, i as canUseNewCanvasBlendModes, it as ExtensionType, j as multiplyColors, k as getLocalBounds, l as State, m as GpuProgram, n as CanvasPool, nt as eventemitter3_default, o as Buffer, p as UniformGroup, q as nextPow2, r as canvasUtils, rt as ObservablePoint, s as BufferUsage, t as getPo2TextureFromSource, tt as Point, u as Shader, v as Ticker, w as ViewContainer, x as CanvasSource, z as Color } from "./board-kernel/getPo2TextureFromSource.js";
|
|
2
2
|
import { Worker } from "node:worker_threads";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
//#region ../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/core/util.js
|
|
@@ -5772,10 +5772,10 @@ const colorString$1 = string().max(120).refine(isBoardColorString$1, "expected a
|
|
|
5772
5772
|
const BoardColorSchema$1 = union([colorString$1, object({
|
|
5773
5773
|
light: colorString$1,
|
|
5774
5774
|
dark: colorString$1
|
|
5775
|
-
}).strict()]);
|
|
5775
|
+
}).strict()]).describe("Palette token (follows the theme), CSS color, or { light, dark }.");
|
|
5776
5776
|
const BoardStyleSchema$1 = object({
|
|
5777
5777
|
fill: BoardColorSchema$1.optional(),
|
|
5778
|
-
fillOpacity: ratio$1.optional(),
|
|
5778
|
+
fillOpacity: ratio$1.optional().describe("Fill opacity, independent of the item's opacity."),
|
|
5779
5779
|
stroke: BoardColorSchema$1.optional(),
|
|
5780
5780
|
strokeWidth: finite$1.min(0).max(64).optional(),
|
|
5781
5781
|
dash: _enum([
|
|
@@ -5783,8 +5783,8 @@ const BoardStyleSchema$1 = object({
|
|
|
5783
5783
|
"dashed",
|
|
5784
5784
|
"dotted"
|
|
5785
5785
|
]).optional(),
|
|
5786
|
-
radius: nonNegative$1.optional(),
|
|
5787
|
-
trim: ratio$1.optional()
|
|
5786
|
+
radius: nonNegative$1.optional().describe("Corner radius in board units."),
|
|
5787
|
+
trim: ratio$1.optional().describe("Fraction of the outline drawn; animate 0 → 1 to draw it in.")
|
|
5788
5788
|
}).strict();
|
|
5789
5789
|
function isSafeBoardSourcePath$1(value) {
|
|
5790
5790
|
return value.length > 0 && value.length <= 4096 && !value.startsWith("/") && !/^[a-z][a-z\d+.-]*:/i.test(value.trimStart()) && !value.includes("\\") && value.split("/").every((part) => part.length > 0 && part !== "." && part !== "..");
|
|
@@ -5800,18 +5800,18 @@ function parseBoardMediaSource$1(src) {
|
|
|
5800
5800
|
value: src
|
|
5801
5801
|
} : null;
|
|
5802
5802
|
}
|
|
5803
|
-
const BoardMediaSourceSchema$1 = string().max(4096).refine((src) => parseBoardMediaSource$1(src) !== null, "src must be a public HTTP(S) URL or relative Space file path").describe("Prefer a
|
|
5803
|
+
const BoardMediaSourceSchema$1 = string().max(4096).refine((src) => parseBoardMediaSource$1(src) !== null, "src must be a public HTTP(S) URL or relative Space file path").describe("Prefer a public HTTP(S) URL; a Space path relative to the workspace root also works.");
|
|
5804
5804
|
const BoardScriptSchema$1 = object({
|
|
5805
|
-
src: srcSchema$1.refine((path) => /\.m?js$/.test(path), "script src must be a .js or .mjs module"),
|
|
5806
|
-
params: record(string(), json()).default({}),
|
|
5807
|
-
targets: record(string().min(1).max(80), BoardIdSchema$1).default({}),
|
|
5808
|
-
seed: string().min(1).max(160).optional(),
|
|
5805
|
+
src: srcSchema$1.refine((path) => /\.m?js$/.test(path), "script src must be a .js or .mjs module").describe("A .js or .mjs Space file."),
|
|
5806
|
+
params: record(string(), json()).default({}).describe("Values the module reads as params."),
|
|
5807
|
+
targets: record(string().min(1).max(80), BoardIdSchema$1).default({}).describe("Named items the module can reach, as ctx.targets."),
|
|
5808
|
+
seed: string().min(1).max(160).optional().describe("Seed for ctx.random(); defaults to the item id."),
|
|
5809
5809
|
enabled: boolean().default(true)
|
|
5810
|
-
}).strict();
|
|
5810
|
+
}).strict().describe("A JavaScript module attached to the item; `cohub boards schema script` lists its API.");
|
|
5811
5811
|
const itemEnvelope$1 = {
|
|
5812
5812
|
script: BoardScriptSchema$1.optional(),
|
|
5813
|
-
parent: BoardIdSchema$1.optional(),
|
|
5814
|
-
z: finite$1.optional(),
|
|
5813
|
+
parent: BoardIdSchema$1.optional().describe("A frame id; position becomes relative to the frame, and the item moves with it."),
|
|
5814
|
+
z: finite$1.optional().describe("Order among siblings; new items go on top."),
|
|
5815
5815
|
position: BoardVec2Schema$1.default({
|
|
5816
5816
|
x: 0,
|
|
5817
5817
|
y: 0
|
|
@@ -5821,7 +5821,7 @@ const itemEnvelope$1 = {
|
|
|
5821
5821
|
origin: BoardVec2Schema$1.default({
|
|
5822
5822
|
x: .5,
|
|
5823
5823
|
y: .5
|
|
5824
|
-
}),
|
|
5824
|
+
}).describe("Rotation and scale origin as fractions of the size."),
|
|
5825
5825
|
opacity: ratio$1.default(1),
|
|
5826
5826
|
style: BoardStyleSchema$1.default({}),
|
|
5827
5827
|
locked: boolean().optional(),
|
|
@@ -5854,8 +5854,8 @@ const BoardFrameItemSchema$1 = object({
|
|
|
5854
5854
|
type: literal("frame"),
|
|
5855
5855
|
props: object({
|
|
5856
5856
|
label: string().max(280).default(""),
|
|
5857
|
-
decoration: _enum(["frame", "none"]).optional(),
|
|
5858
|
-
clip: boolean().default(true)
|
|
5857
|
+
decoration: _enum(["frame", "none"]).optional().describe("none hides the title, border and background: an invisible group whose tracks move every child."),
|
|
5858
|
+
clip: boolean().default(true).describe("Hide children outside the frame.")
|
|
5859
5859
|
}).strict().prefault({})
|
|
5860
5860
|
}).strict();
|
|
5861
5861
|
const BoardTextItemSchema$1 = object({
|
|
@@ -5865,12 +5865,12 @@ const BoardTextItemSchema$1 = object({
|
|
|
5865
5865
|
text: string().default(""),
|
|
5866
5866
|
fontSize: fontSize$1.default(24),
|
|
5867
5867
|
fontWeight: finite$1.min(100).max(900).default(500),
|
|
5868
|
-
font: string().min(1).max(120).default("sans"),
|
|
5868
|
+
font: string().min(1).max(120).default("sans").describe("sans, serif, mono, or a font family name."),
|
|
5869
5869
|
align: _enum(BOARD_TEXT_ALIGNS$1).default("left"),
|
|
5870
5870
|
lineHeight: finite$1.min(.5).max(4).default(4 / 3),
|
|
5871
|
-
width: finite$1.positive().optional(),
|
|
5872
|
-
reveal: ratio$1.default(1),
|
|
5873
|
-
caret: boolean().default(false)
|
|
5871
|
+
width: finite$1.positive().optional().describe("Wrap width; the height follows the text."),
|
|
5872
|
+
reveal: ratio$1.default(1).describe("Fraction of the text shown; animate 0 → 1 to type it."),
|
|
5873
|
+
caret: boolean().default(false).describe("Blink a caret while the text is being revealed.")
|
|
5874
5874
|
}).strict().prefault({})
|
|
5875
5875
|
}).strict();
|
|
5876
5876
|
const BoardShapeItemSchema$1 = object({
|
|
@@ -5878,7 +5878,7 @@ const BoardShapeItemSchema$1 = object({
|
|
|
5878
5878
|
type: literal("shape"),
|
|
5879
5879
|
props: object({
|
|
5880
5880
|
geometry: _enum(BOARD_SHAPE_GEOMETRIES$1).default("rectangle"),
|
|
5881
|
-
path: string().min(1).max(2e5).optional(),
|
|
5881
|
+
path: string().min(1).max(2e5).optional().describe("SVG path data for path geometry, fitted to the item size."),
|
|
5882
5882
|
text: string().default(""),
|
|
5883
5883
|
fontSize: fontSize$1.default(20),
|
|
5884
5884
|
align: _enum(BOARD_TEXT_ALIGNS$1).default("center")
|
|
@@ -5890,12 +5890,12 @@ const BoardShapeItemSchema$1 = object({
|
|
|
5890
5890
|
const BoardDrawPointSchema$1 = object({
|
|
5891
5891
|
x: finite$1,
|
|
5892
5892
|
y: finite$1,
|
|
5893
|
-
p: ratio$1.default(.5)
|
|
5893
|
+
p: ratio$1.default(.5).describe("Pen pressure.")
|
|
5894
5894
|
}).strict();
|
|
5895
5895
|
const BoardDrawItemSchema$1 = object({
|
|
5896
5896
|
...unsized$1,
|
|
5897
5897
|
type: literal("draw"),
|
|
5898
|
-
props: object({ points: array(BoardDrawPointSchema$1).min(1).max(1e5) }).strict()
|
|
5898
|
+
props: object({ points: array(BoardDrawPointSchema$1).min(1).max(1e5).describe("Stroke points relative to position; the size follows them.") }).strict()
|
|
5899
5899
|
}).strict();
|
|
5900
5900
|
const BoardArrowEndSchema$1 = union([BoardVec2Schema$1, object({
|
|
5901
5901
|
item: BoardIdSchema$1,
|
|
@@ -5914,9 +5914,9 @@ const BoardArrowEndSchema$1 = union([BoardVec2Schema$1, object({
|
|
|
5914
5914
|
x: ratio$1,
|
|
5915
5915
|
y: ratio$1
|
|
5916
5916
|
}).strict()
|
|
5917
|
-
]).default("auto"),
|
|
5917
|
+
]).default("auto").describe("auto uses the side facing the other end; or a side with an offset, or a point as fractions of the item."),
|
|
5918
5918
|
port: string().min(1).max(120).optional()
|
|
5919
|
-
}).strict()]);
|
|
5919
|
+
}).strict()]).describe("A point relative to position, or { item } to follow that item.");
|
|
5920
5920
|
const BOARD_ARROW_ROUTES$1 = [
|
|
5921
5921
|
"straight",
|
|
5922
5922
|
"curve",
|
|
@@ -5929,13 +5929,13 @@ const BoardArrowItemSchema$1 = object({
|
|
|
5929
5929
|
start: BoardArrowEndSchema$1,
|
|
5930
5930
|
end: BoardArrowEndSchema$1,
|
|
5931
5931
|
route: _enum(BOARD_ARROW_ROUTES$1).default("straight"),
|
|
5932
|
-
bend: finite$1.min(-.85).max(.85).default(0),
|
|
5933
|
-
waypoints: array(BoardVec2Schema$1).max(64).default([]),
|
|
5932
|
+
bend: finite$1.min(-.85).max(.85).default(0).describe("Sideways curve as a fraction of the length; the sign picks the side."),
|
|
5933
|
+
waypoints: array(BoardVec2Schema$1).max(64).default([]).describe("Points the route passes through."),
|
|
5934
5934
|
arrowStart: boolean().default(false),
|
|
5935
5935
|
arrowEnd: boolean().default(true),
|
|
5936
5936
|
label: string().max(280).default(""),
|
|
5937
5937
|
fontSize: fontSize$1.default(14),
|
|
5938
|
-
relation: string().max(64).regex(/^[a-z0-9]+(?:[.-][a-z0-9]+)*$/, "relation must be a lowercase slug").optional()
|
|
5938
|
+
relation: string().max(64).regex(/^[a-z0-9]+(?:[.-][a-z0-9]+)*$/, "relation must be a lowercase slug").optional().describe("What the arrow means, as a slug such as triggers or depends-on.")
|
|
5939
5939
|
}).strict()
|
|
5940
5940
|
}).strict();
|
|
5941
5941
|
const fileProps$1 = {
|
|
@@ -5951,26 +5951,26 @@ const fileProps$1 = {
|
|
|
5951
5951
|
excerpt: string().optional(),
|
|
5952
5952
|
coverPath: string().optional(),
|
|
5953
5953
|
coverUrl: string().optional()
|
|
5954
|
-
}).strict().optional()
|
|
5954
|
+
}).strict().describe("Cached facts for an instant preview; filled in when the media loads.").optional()
|
|
5955
5955
|
};
|
|
5956
5956
|
const BoardMediaOriginSchema$1 = object({
|
|
5957
5957
|
taskRunId: string().min(1).max(160),
|
|
5958
5958
|
artifactId: string().min(1).max(240)
|
|
5959
|
-
}).strict();
|
|
5959
|
+
}).strict().describe("The generation run and result this media came from.");
|
|
5960
5960
|
const mediaProps$1 = {
|
|
5961
5961
|
...fileProps$1,
|
|
5962
5962
|
origin: BoardMediaOriginSchema$1.optional()
|
|
5963
5963
|
};
|
|
5964
5964
|
const timedFileProps$1 = {
|
|
5965
5965
|
...mediaProps$1,
|
|
5966
|
-
time: nonNegative$1.optional()
|
|
5966
|
+
time: nonNegative$1.optional().describe("Playback position in milliseconds; animate props.time to play it on a timeline.")
|
|
5967
5967
|
};
|
|
5968
5968
|
const BoardCropSchema$1 = object({
|
|
5969
5969
|
x: ratio$1,
|
|
5970
5970
|
y: ratio$1,
|
|
5971
5971
|
w: ratio$1,
|
|
5972
5972
|
h: ratio$1
|
|
5973
|
-
}).strict();
|
|
5973
|
+
}).strict().describe("Region shown, as fractions of the image. Without it the whole image fits inside size.");
|
|
5974
5974
|
const BoardImageItemSchema$1 = object({
|
|
5975
5975
|
...boxed$1(640, 360),
|
|
5976
5976
|
type: literal("image"),
|
|
@@ -6050,8 +6050,8 @@ const BoardTaskItemSchema$1 = object({
|
|
|
6050
6050
|
...boxed$1(420, 240),
|
|
6051
6051
|
type: literal("task"),
|
|
6052
6052
|
props: object({
|
|
6053
|
-
taskRunId: string().min(1).max(160),
|
|
6054
|
-
snapshot: BoardTaskSnapshotSchema$1.describe("Maintained by the server
|
|
6053
|
+
taskRunId: string().min(1).max(160).describe("The generation run shown; the server keeps the card's status and results up to date."),
|
|
6054
|
+
snapshot: BoardTaskSnapshotSchema$1.describe("Maintained by the server; omit it.")
|
|
6055
6055
|
}).strict()
|
|
6056
6056
|
}).strict();
|
|
6057
6057
|
const BOARD_EFFECT_KINDS$1 = [
|
|
@@ -6074,8 +6074,8 @@ const BoardEffectItemSchema$1 = object({
|
|
|
6074
6074
|
spread: finite$1.min(0).max(360).default(360),
|
|
6075
6075
|
gravity: finite$1.default(0),
|
|
6076
6076
|
intensity: nonNegative$1.max(10).default(1),
|
|
6077
|
-
follow: BoardIdSchema$1.optional(),
|
|
6078
|
-
seed: string().min(1).max(160).optional()
|
|
6077
|
+
follow: BoardIdSchema$1.optional().describe("trail: the item to follow."),
|
|
6078
|
+
seed: string().min(1).max(160).optional().describe("Makes procedural motion repeatable.")
|
|
6079
6079
|
}).strict()
|
|
6080
6080
|
}).strict();
|
|
6081
6081
|
const BoardCustomItemSchema$1 = object({
|
|
@@ -6177,21 +6177,21 @@ function isBoardEase$1(value) {
|
|
|
6177
6177
|
}
|
|
6178
6178
|
const BoardEaseSchema$1 = string().max(120).refine(isBoardEase$1, "expected a CSS easing: linear, ease-in-out, cubic-bezier(…) or steps(…)");
|
|
6179
6179
|
const BoardKeyframeSchema$1 = object({
|
|
6180
|
-
at: nonNegative$1,
|
|
6180
|
+
at: nonNegative$1.describe("Time in milliseconds."),
|
|
6181
6181
|
value: unknown(),
|
|
6182
|
-
ease: BoardEaseSchema$1.optional()
|
|
6182
|
+
ease: BoardEaseSchema$1.optional().describe("Easing into this keyframe: a CSS keyword, cubic-bezier() or steps(); defaults to linear.")
|
|
6183
6183
|
}).strict();
|
|
6184
6184
|
const BoardTrackSchema$1 = object({
|
|
6185
|
-
target: string().min(1).max(160),
|
|
6186
|
-
property: string().min(1).max(200),
|
|
6187
|
-
keyframes: array(BoardKeyframeSchema$1).min(1).max(1e5),
|
|
6188
|
-
composite: _enum(["replace", "add"]).default("replace"),
|
|
6185
|
+
target: string().min(1).max(160).describe("An item id, camera, or another animation id (its time property nests that timeline)."),
|
|
6186
|
+
property: string().min(1).max(200).describe("JSON path in the target, e.g. position, opacity, style.fill, props.text."),
|
|
6187
|
+
keyframes: array(BoardKeyframeSchema$1).min(1).max(1e5).describe("Ordered by at. The value holds before the first and after the last keyframe."),
|
|
6188
|
+
composite: _enum(["replace", "add"]).default("replace").describe("replace: the latest-started track wins. add: positions and rotations add; scale and opacity multiply."),
|
|
6189
6189
|
interpolation: _enum([
|
|
6190
6190
|
"auto",
|
|
6191
6191
|
"step",
|
|
6192
6192
|
"spline"
|
|
6193
|
-
]).default("auto"),
|
|
6194
|
-
orient: boolean().optional()
|
|
6193
|
+
]).default("auto").describe("auto blends numbers, vectors and colors and steps other values; spline smooths position paths."),
|
|
6194
|
+
orient: boolean().optional().describe("Rotate the item along its path.")
|
|
6195
6195
|
}).strict().superRefine((track, context) => {
|
|
6196
6196
|
for (let index = 1; index < track.keyframes.length; index += 1) if ((track.keyframes[index]?.at ?? 0) < (track.keyframes[index - 1]?.at ?? 0)) context.addIssue({
|
|
6197
6197
|
code: "custom",
|
|
@@ -6206,20 +6206,20 @@ const BoardTrackSchema$1 = object({
|
|
|
6206
6206
|
const BoardMarkerSchema$1 = object({
|
|
6207
6207
|
at: nonNegative$1,
|
|
6208
6208
|
label: string().max(280).optional(),
|
|
6209
|
-
pause: boolean().optional()
|
|
6209
|
+
pause: boolean().optional().describe("Hold shared playback here until next.")
|
|
6210
6210
|
}).strict();
|
|
6211
6211
|
const BoardAnimationHeaderSchema$1 = object({
|
|
6212
6212
|
name: string().max(280).optional(),
|
|
6213
|
-
duration: finite$1.positive().max(864e5),
|
|
6213
|
+
duration: finite$1.positive().max(864e5).describe("Milliseconds; a new animation without it ends at its last keyframe."),
|
|
6214
6214
|
play: _enum([
|
|
6215
6215
|
"manual",
|
|
6216
6216
|
"auto",
|
|
6217
6217
|
"always"
|
|
6218
|
-
]).default("manual"),
|
|
6218
|
+
]).default("manual").describe("manual: only shared playback starts it. auto: plays when the Board opens. always: loops continuously."),
|
|
6219
6219
|
delay: nonNegative$1.default(0),
|
|
6220
6220
|
loop: boolean().default(false),
|
|
6221
|
-
end: _enum(["hold", "reset"]).default("hold"),
|
|
6222
|
-
markers: array(BoardMarkerSchema$1).max(1e4).default([])
|
|
6221
|
+
end: _enum(["hold", "reset"]).default("hold").describe("hold keeps the last frame; reset returns to the start."),
|
|
6222
|
+
markers: array(BoardMarkerSchema$1).max(1e4).default([]).describe("Labeled points on this timeline; a nested animation's markers do not carry over.")
|
|
6223
6223
|
}).strict();
|
|
6224
6224
|
BoardAnimationHeaderSchema$1.extend({ tracks: record(BoardKeySchema$1, BoardTrackSchema$1).default({}) }).strict();
|
|
6225
6225
|
const BOARD_ENTER_PRESETS$1 = [
|
|
@@ -6237,7 +6237,7 @@ const BoardBackgroundSchema$1 = object({
|
|
|
6237
6237
|
"image"
|
|
6238
6238
|
]).default("dots"),
|
|
6239
6239
|
color: BoardColorSchema$1.optional(),
|
|
6240
|
-
imageUrl: string().url().max(4096).optional(),
|
|
6240
|
+
imageUrl: string().url().max(4096).optional().describe("Background image for kind image."),
|
|
6241
6241
|
fit: _enum([
|
|
6242
6242
|
"cover",
|
|
6243
6243
|
"contain",
|
|
@@ -6249,13 +6249,13 @@ const BoardSettingsSchema$1 = object({
|
|
|
6249
6249
|
title: string().min(1).max(255).optional(),
|
|
6250
6250
|
background: BoardBackgroundSchema$1.default({ kind: "dots" }),
|
|
6251
6251
|
grid: object({
|
|
6252
|
-
visible: boolean().default(false),
|
|
6252
|
+
visible: boolean().default(false).describe("Show the grid overlay."),
|
|
6253
6253
|
size: finite$1.min(4).max(512).default(24)
|
|
6254
6254
|
}).strict().optional(),
|
|
6255
6255
|
enter: object({
|
|
6256
6256
|
preset: _enum(BOARD_ENTER_PRESETS$1),
|
|
6257
6257
|
duration: finite$1.positive().max(1e4).optional()
|
|
6258
|
-
}).strict().optional()
|
|
6258
|
+
}).strict().optional().describe("Motion for items as they are added.")
|
|
6259
6259
|
}).strict();
|
|
6260
6260
|
const patchObject$1 = record(string(), unknown());
|
|
6261
6261
|
const BoardPatchSchema$1 = object({
|
|
@@ -12305,13 +12305,13 @@ const placeHolderBufferData = /* @__PURE__ */ new Float32Array(1);
|
|
|
12305
12305
|
const placeHolderIndexData = /* @__PURE__ */ new Uint32Array(1);
|
|
12306
12306
|
var BatchGeometry = class extends Geometry {
|
|
12307
12307
|
constructor() {
|
|
12308
|
-
const attributeBuffer = new Buffer
|
|
12308
|
+
const attributeBuffer = new Buffer({
|
|
12309
12309
|
data: placeHolderBufferData,
|
|
12310
12310
|
label: "attribute-batch-buffer",
|
|
12311
12311
|
usage: BufferUsage.VERTEX | BufferUsage.COPY_DST,
|
|
12312
12312
|
shrinkToFit: false
|
|
12313
12313
|
});
|
|
12314
|
-
const indexBuffer = new Buffer
|
|
12314
|
+
const indexBuffer = new Buffer({
|
|
12315
12315
|
data: placeHolderIndexData,
|
|
12316
12316
|
label: "index-batch-buffer",
|
|
12317
12317
|
usage: BufferUsage.INDEX | BufferUsage.COPY_DST,
|
|
@@ -18288,19 +18288,19 @@ const _MeshGeometry = class _MeshGeometry extends Geometry {
|
|
|
18288
18288
|
3
|
|
18289
18289
|
]);
|
|
18290
18290
|
const shrinkToFit = options.shrinkBuffersToFit;
|
|
18291
|
-
const positionBuffer = new Buffer
|
|
18291
|
+
const positionBuffer = new Buffer({
|
|
18292
18292
|
data: positions,
|
|
18293
18293
|
label: "attribute-mesh-positions",
|
|
18294
18294
|
shrinkToFit,
|
|
18295
18295
|
usage: BufferUsage.VERTEX | BufferUsage.COPY_DST
|
|
18296
18296
|
});
|
|
18297
|
-
const uvBuffer = new Buffer
|
|
18297
|
+
const uvBuffer = new Buffer({
|
|
18298
18298
|
data: uvs,
|
|
18299
18299
|
label: "attribute-mesh-uvs",
|
|
18300
18300
|
shrinkToFit,
|
|
18301
18301
|
usage: BufferUsage.VERTEX | BufferUsage.COPY_DST
|
|
18302
18302
|
});
|
|
18303
|
-
const indexBuffer = new Buffer
|
|
18303
|
+
const indexBuffer = new Buffer({
|
|
18304
18304
|
data: indices,
|
|
18305
18305
|
label: "index-mesh-buffer",
|
|
18306
18306
|
shrinkToFit,
|
|
@@ -27161,12 +27161,24 @@ function measureBoardText(props) {
|
|
|
27161
27161
|
missingCharacters: characters
|
|
27162
27162
|
};
|
|
27163
27163
|
}
|
|
27164
|
-
function
|
|
27164
|
+
function inspectBoardItems(scene, ids) {
|
|
27165
|
+
return {
|
|
27166
|
+
diagnostics: inspectBoardScene(scene, 100, ids),
|
|
27167
|
+
items: scene.items.filter((item) => !ids || ids.has(item.id)).map((item) => ({
|
|
27168
|
+
id: item.id,
|
|
27169
|
+
bounds: item.frame,
|
|
27170
|
+
worldBounds: itemBounds(item.frame),
|
|
27171
|
+
opacity: scene.opacity(item.id),
|
|
27172
|
+
...item.type === "text" ? { text: measureBoardText(item.props) } : {}
|
|
27173
|
+
}))
|
|
27174
|
+
};
|
|
27175
|
+
}
|
|
27176
|
+
function inspectBoardScene(scene, limit = 100, ids) {
|
|
27165
27177
|
ensureBoardTextMeasurement();
|
|
27166
27178
|
const diagnostics = [];
|
|
27167
27179
|
const texts = scene.items.filter((item) => item.type === "text" && scene.opacity(item.id) > .01);
|
|
27168
27180
|
const push = (entry) => {
|
|
27169
|
-
if (diagnostics.length < limit) diagnostics.push(entry);
|
|
27181
|
+
if (diagnostics.length < limit && (!ids || ids.has(entry.item) || Boolean(entry.related && ids.has(entry.related)))) diagnostics.push(entry);
|
|
27170
27182
|
};
|
|
27171
27183
|
for (const item of scene.items) {
|
|
27172
27184
|
if (diagnostics.length >= limit) break;
|
|
@@ -27178,7 +27190,7 @@ function inspectBoardScene(scene, limit = 100) {
|
|
|
27178
27190
|
let glyphBudget = 256;
|
|
27179
27191
|
for (const item of texts) {
|
|
27180
27192
|
if (diagnostics.length >= limit || item.type !== "text") break;
|
|
27181
|
-
if (glyphBudget-- > 0) {
|
|
27193
|
+
if ((!ids || ids.has(item.id)) && glyphBudget-- > 0) {
|
|
27182
27194
|
const measured = measureBoardText(item.props);
|
|
27183
27195
|
if (measured.missingCharacters) push({
|
|
27184
27196
|
code: "glyph-unavailable",
|
|
@@ -27217,6 +27229,7 @@ function inspectBoardScene(scene, limit = 100) {
|
|
|
27217
27229
|
const b = sorted[j];
|
|
27218
27230
|
if (!b) continue;
|
|
27219
27231
|
if (b.rect.x >= a.rect.x + a.rect.width) break;
|
|
27232
|
+
if (ids && !ids.has(a.item.id) && !ids.has(b.item.id)) continue;
|
|
27220
27233
|
if (++comparisons > 1e4) return diagnostics;
|
|
27221
27234
|
if (a.item.parent === b.item.parent && rectsIntersect(a.rect, b.rect)) push({
|
|
27222
27235
|
code: "text-overlap",
|
|
@@ -30341,10 +30354,10 @@ const colorString = string().max(120).refine(isBoardColorString, "expected a pal
|
|
|
30341
30354
|
const BoardColorSchema = union([colorString, object({
|
|
30342
30355
|
light: colorString,
|
|
30343
30356
|
dark: colorString
|
|
30344
|
-
}).strict()]);
|
|
30357
|
+
}).strict()]).describe("Palette token (follows the theme), CSS color, or { light, dark }.");
|
|
30345
30358
|
const BoardStyleSchema = object({
|
|
30346
30359
|
fill: BoardColorSchema.optional(),
|
|
30347
|
-
fillOpacity: ratio.optional(),
|
|
30360
|
+
fillOpacity: ratio.optional().describe("Fill opacity, independent of the item's opacity."),
|
|
30348
30361
|
stroke: BoardColorSchema.optional(),
|
|
30349
30362
|
strokeWidth: finite.min(0).max(64).optional(),
|
|
30350
30363
|
dash: _enum([
|
|
@@ -30352,8 +30365,8 @@ const BoardStyleSchema = object({
|
|
|
30352
30365
|
"dashed",
|
|
30353
30366
|
"dotted"
|
|
30354
30367
|
]).optional(),
|
|
30355
|
-
radius: nonNegative.optional(),
|
|
30356
|
-
trim: ratio.optional()
|
|
30368
|
+
radius: nonNegative.optional().describe("Corner radius in board units."),
|
|
30369
|
+
trim: ratio.optional().describe("Fraction of the outline drawn; animate 0 → 1 to draw it in.")
|
|
30357
30370
|
}).strict();
|
|
30358
30371
|
function isSafeBoardSourcePath(value) {
|
|
30359
30372
|
return value.length > 0 && value.length <= 4096 && !value.startsWith("/") && !/^[a-z][a-z\d+.-]*:/i.test(value.trimStart()) && !value.includes("\\") && value.split("/").every((part) => part.length > 0 && part !== "." && part !== "..");
|
|
@@ -30369,18 +30382,18 @@ function parseBoardMediaSource(src) {
|
|
|
30369
30382
|
value: src
|
|
30370
30383
|
} : null;
|
|
30371
30384
|
}
|
|
30372
|
-
const BoardMediaSourceSchema = string().max(4096).refine((src) => parseBoardMediaSource(src) !== null, "src must be a public HTTP(S) URL or relative Space file path").describe("Prefer a
|
|
30385
|
+
const BoardMediaSourceSchema = string().max(4096).refine((src) => parseBoardMediaSource(src) !== null, "src must be a public HTTP(S) URL or relative Space file path").describe("Prefer a public HTTP(S) URL; a Space path relative to the workspace root also works.");
|
|
30373
30386
|
const BoardScriptSchema = object({
|
|
30374
|
-
src: srcSchema.refine((path) => /\.m?js$/.test(path), "script src must be a .js or .mjs module"),
|
|
30375
|
-
params: record(string(), json()).default({}),
|
|
30376
|
-
targets: record(string().min(1).max(80), BoardIdSchema).default({}),
|
|
30377
|
-
seed: string().min(1).max(160).optional(),
|
|
30387
|
+
src: srcSchema.refine((path) => /\.m?js$/.test(path), "script src must be a .js or .mjs module").describe("A .js or .mjs Space file."),
|
|
30388
|
+
params: record(string(), json()).default({}).describe("Values the module reads as params."),
|
|
30389
|
+
targets: record(string().min(1).max(80), BoardIdSchema).default({}).describe("Named items the module can reach, as ctx.targets."),
|
|
30390
|
+
seed: string().min(1).max(160).optional().describe("Seed for ctx.random(); defaults to the item id."),
|
|
30378
30391
|
enabled: boolean().default(true)
|
|
30379
|
-
}).strict();
|
|
30392
|
+
}).strict().describe("A JavaScript module attached to the item; `cohub boards schema script` lists its API.");
|
|
30380
30393
|
const itemEnvelope = {
|
|
30381
30394
|
script: BoardScriptSchema.optional(),
|
|
30382
|
-
parent: BoardIdSchema.optional(),
|
|
30383
|
-
z: finite.optional(),
|
|
30395
|
+
parent: BoardIdSchema.optional().describe("A frame id; position becomes relative to the frame, and the item moves with it."),
|
|
30396
|
+
z: finite.optional().describe("Order among siblings; new items go on top."),
|
|
30384
30397
|
position: BoardVec2Schema.default({
|
|
30385
30398
|
x: 0,
|
|
30386
30399
|
y: 0
|
|
@@ -30390,7 +30403,7 @@ const itemEnvelope = {
|
|
|
30390
30403
|
origin: BoardVec2Schema.default({
|
|
30391
30404
|
x: .5,
|
|
30392
30405
|
y: .5
|
|
30393
|
-
}),
|
|
30406
|
+
}).describe("Rotation and scale origin as fractions of the size."),
|
|
30394
30407
|
opacity: ratio.default(1),
|
|
30395
30408
|
style: BoardStyleSchema.default({}),
|
|
30396
30409
|
locked: boolean().optional(),
|
|
@@ -30423,8 +30436,8 @@ object({
|
|
|
30423
30436
|
type: literal("frame"),
|
|
30424
30437
|
props: object({
|
|
30425
30438
|
label: string().max(280).default(""),
|
|
30426
|
-
decoration: _enum(["frame", "none"]).optional(),
|
|
30427
|
-
clip: boolean().default(true)
|
|
30439
|
+
decoration: _enum(["frame", "none"]).optional().describe("none hides the title, border and background: an invisible group whose tracks move every child."),
|
|
30440
|
+
clip: boolean().default(true).describe("Hide children outside the frame.")
|
|
30428
30441
|
}).strict().prefault({})
|
|
30429
30442
|
}).strict();
|
|
30430
30443
|
object({
|
|
@@ -30434,12 +30447,12 @@ object({
|
|
|
30434
30447
|
text: string().default(""),
|
|
30435
30448
|
fontSize: fontSize.default(24),
|
|
30436
30449
|
fontWeight: finite.min(100).max(900).default(500),
|
|
30437
|
-
font: string().min(1).max(120).default("sans"),
|
|
30450
|
+
font: string().min(1).max(120).default("sans").describe("sans, serif, mono, or a font family name."),
|
|
30438
30451
|
align: _enum(BOARD_TEXT_ALIGNS).default("left"),
|
|
30439
30452
|
lineHeight: finite.min(.5).max(4).default(4 / 3),
|
|
30440
|
-
width: finite.positive().optional(),
|
|
30441
|
-
reveal: ratio.default(1),
|
|
30442
|
-
caret: boolean().default(false)
|
|
30453
|
+
width: finite.positive().optional().describe("Wrap width; the height follows the text."),
|
|
30454
|
+
reveal: ratio.default(1).describe("Fraction of the text shown; animate 0 → 1 to type it."),
|
|
30455
|
+
caret: boolean().default(false).describe("Blink a caret while the text is being revealed.")
|
|
30443
30456
|
}).strict().prefault({})
|
|
30444
30457
|
}).strict();
|
|
30445
30458
|
object({
|
|
@@ -30447,7 +30460,7 @@ object({
|
|
|
30447
30460
|
type: literal("shape"),
|
|
30448
30461
|
props: object({
|
|
30449
30462
|
geometry: _enum(BOARD_SHAPE_GEOMETRIES).default("rectangle"),
|
|
30450
|
-
path: string().min(1).max(2e5).optional(),
|
|
30463
|
+
path: string().min(1).max(2e5).optional().describe("SVG path data for path geometry, fitted to the item size."),
|
|
30451
30464
|
text: string().default(""),
|
|
30452
30465
|
fontSize: fontSize.default(20),
|
|
30453
30466
|
align: _enum(BOARD_TEXT_ALIGNS).default("center")
|
|
@@ -30459,12 +30472,12 @@ object({
|
|
|
30459
30472
|
const BoardDrawPointSchema = object({
|
|
30460
30473
|
x: finite,
|
|
30461
30474
|
y: finite,
|
|
30462
|
-
p: ratio.default(.5)
|
|
30475
|
+
p: ratio.default(.5).describe("Pen pressure.")
|
|
30463
30476
|
}).strict();
|
|
30464
30477
|
object({
|
|
30465
30478
|
...unsized,
|
|
30466
30479
|
type: literal("draw"),
|
|
30467
|
-
props: object({ points: array(BoardDrawPointSchema).min(1).max(1e5) }).strict()
|
|
30480
|
+
props: object({ points: array(BoardDrawPointSchema).min(1).max(1e5).describe("Stroke points relative to position; the size follows them.") }).strict()
|
|
30468
30481
|
}).strict();
|
|
30469
30482
|
const BoardArrowEndSchema = union([BoardVec2Schema, object({
|
|
30470
30483
|
item: BoardIdSchema,
|
|
@@ -30483,9 +30496,9 @@ const BoardArrowEndSchema = union([BoardVec2Schema, object({
|
|
|
30483
30496
|
x: ratio,
|
|
30484
30497
|
y: ratio
|
|
30485
30498
|
}).strict()
|
|
30486
|
-
]).default("auto"),
|
|
30499
|
+
]).default("auto").describe("auto uses the side facing the other end; or a side with an offset, or a point as fractions of the item."),
|
|
30487
30500
|
port: string().min(1).max(120).optional()
|
|
30488
|
-
}).strict()]);
|
|
30501
|
+
}).strict()]).describe("A point relative to position, or { item } to follow that item.");
|
|
30489
30502
|
const BOARD_ARROW_ROUTES = [
|
|
30490
30503
|
"straight",
|
|
30491
30504
|
"curve",
|
|
@@ -30498,13 +30511,13 @@ object({
|
|
|
30498
30511
|
start: BoardArrowEndSchema,
|
|
30499
30512
|
end: BoardArrowEndSchema,
|
|
30500
30513
|
route: _enum(BOARD_ARROW_ROUTES).default("straight"),
|
|
30501
|
-
bend: finite.min(-.85).max(.85).default(0),
|
|
30502
|
-
waypoints: array(BoardVec2Schema).max(64).default([]),
|
|
30514
|
+
bend: finite.min(-.85).max(.85).default(0).describe("Sideways curve as a fraction of the length; the sign picks the side."),
|
|
30515
|
+
waypoints: array(BoardVec2Schema).max(64).default([]).describe("Points the route passes through."),
|
|
30503
30516
|
arrowStart: boolean().default(false),
|
|
30504
30517
|
arrowEnd: boolean().default(true),
|
|
30505
30518
|
label: string().max(280).default(""),
|
|
30506
30519
|
fontSize: fontSize.default(14),
|
|
30507
|
-
relation: string().max(64).regex(/^[a-z0-9]+(?:[.-][a-z0-9]+)*$/, "relation must be a lowercase slug").optional()
|
|
30520
|
+
relation: string().max(64).regex(/^[a-z0-9]+(?:[.-][a-z0-9]+)*$/, "relation must be a lowercase slug").optional().describe("What the arrow means, as a slug such as triggers or depends-on.")
|
|
30508
30521
|
}).strict()
|
|
30509
30522
|
}).strict();
|
|
30510
30523
|
const fileProps = {
|
|
@@ -30520,26 +30533,26 @@ const fileProps = {
|
|
|
30520
30533
|
excerpt: string().optional(),
|
|
30521
30534
|
coverPath: string().optional(),
|
|
30522
30535
|
coverUrl: string().optional()
|
|
30523
|
-
}).strict().optional()
|
|
30536
|
+
}).strict().describe("Cached facts for an instant preview; filled in when the media loads.").optional()
|
|
30524
30537
|
};
|
|
30525
30538
|
const BoardMediaOriginSchema = object({
|
|
30526
30539
|
taskRunId: string().min(1).max(160),
|
|
30527
30540
|
artifactId: string().min(1).max(240)
|
|
30528
|
-
}).strict();
|
|
30541
|
+
}).strict().describe("The generation run and result this media came from.");
|
|
30529
30542
|
const mediaProps = {
|
|
30530
30543
|
...fileProps,
|
|
30531
30544
|
origin: BoardMediaOriginSchema.optional()
|
|
30532
30545
|
};
|
|
30533
30546
|
const timedFileProps = {
|
|
30534
30547
|
...mediaProps,
|
|
30535
|
-
time: nonNegative.optional()
|
|
30548
|
+
time: nonNegative.optional().describe("Playback position in milliseconds; animate props.time to play it on a timeline.")
|
|
30536
30549
|
};
|
|
30537
30550
|
const BoardCropSchema = object({
|
|
30538
30551
|
x: ratio,
|
|
30539
30552
|
y: ratio,
|
|
30540
30553
|
w: ratio,
|
|
30541
30554
|
h: ratio
|
|
30542
|
-
}).strict();
|
|
30555
|
+
}).strict().describe("Region shown, as fractions of the image. Without it the whole image fits inside size.");
|
|
30543
30556
|
object({
|
|
30544
30557
|
...boxed(640, 360),
|
|
30545
30558
|
type: literal("image"),
|
|
@@ -30619,8 +30632,8 @@ object({
|
|
|
30619
30632
|
...boxed(420, 240),
|
|
30620
30633
|
type: literal("task"),
|
|
30621
30634
|
props: object({
|
|
30622
|
-
taskRunId: string().min(1).max(160),
|
|
30623
|
-
snapshot: BoardTaskSnapshotSchema.describe("Maintained by the server
|
|
30635
|
+
taskRunId: string().min(1).max(160).describe("The generation run shown; the server keeps the card's status and results up to date."),
|
|
30636
|
+
snapshot: BoardTaskSnapshotSchema.describe("Maintained by the server; omit it.")
|
|
30624
30637
|
}).strict()
|
|
30625
30638
|
}).strict();
|
|
30626
30639
|
const BOARD_EFFECT_KINDS = [
|
|
@@ -30643,8 +30656,8 @@ object({
|
|
|
30643
30656
|
spread: finite.min(0).max(360).default(360),
|
|
30644
30657
|
gravity: finite.default(0),
|
|
30645
30658
|
intensity: nonNegative.max(10).default(1),
|
|
30646
|
-
follow: BoardIdSchema.optional(),
|
|
30647
|
-
seed: string().min(1).max(160).optional()
|
|
30659
|
+
follow: BoardIdSchema.optional().describe("trail: the item to follow."),
|
|
30660
|
+
seed: string().min(1).max(160).optional().describe("Makes procedural motion repeatable.")
|
|
30648
30661
|
}).strict()
|
|
30649
30662
|
}).strict();
|
|
30650
30663
|
object({
|
|
@@ -30684,21 +30697,21 @@ function isBoardEase(value) {
|
|
|
30684
30697
|
}
|
|
30685
30698
|
const BoardEaseSchema = string().max(120).refine(isBoardEase, "expected a CSS easing: linear, ease-in-out, cubic-bezier(…) or steps(…)");
|
|
30686
30699
|
const BoardKeyframeSchema = object({
|
|
30687
|
-
at: nonNegative,
|
|
30700
|
+
at: nonNegative.describe("Time in milliseconds."),
|
|
30688
30701
|
value: unknown(),
|
|
30689
|
-
ease: BoardEaseSchema.optional()
|
|
30702
|
+
ease: BoardEaseSchema.optional().describe("Easing into this keyframe: a CSS keyword, cubic-bezier() or steps(); defaults to linear.")
|
|
30690
30703
|
}).strict();
|
|
30691
30704
|
const BoardTrackSchema = object({
|
|
30692
|
-
target: string().min(1).max(160),
|
|
30693
|
-
property: string().min(1).max(200),
|
|
30694
|
-
keyframes: array(BoardKeyframeSchema).min(1).max(1e5),
|
|
30695
|
-
composite: _enum(["replace", "add"]).default("replace"),
|
|
30705
|
+
target: string().min(1).max(160).describe("An item id, camera, or another animation id (its time property nests that timeline)."),
|
|
30706
|
+
property: string().min(1).max(200).describe("JSON path in the target, e.g. position, opacity, style.fill, props.text."),
|
|
30707
|
+
keyframes: array(BoardKeyframeSchema).min(1).max(1e5).describe("Ordered by at. The value holds before the first and after the last keyframe."),
|
|
30708
|
+
composite: _enum(["replace", "add"]).default("replace").describe("replace: the latest-started track wins. add: positions and rotations add; scale and opacity multiply."),
|
|
30696
30709
|
interpolation: _enum([
|
|
30697
30710
|
"auto",
|
|
30698
30711
|
"step",
|
|
30699
30712
|
"spline"
|
|
30700
|
-
]).default("auto"),
|
|
30701
|
-
orient: boolean().optional()
|
|
30713
|
+
]).default("auto").describe("auto blends numbers, vectors and colors and steps other values; spline smooths position paths."),
|
|
30714
|
+
orient: boolean().optional().describe("Rotate the item along its path.")
|
|
30702
30715
|
}).strict().superRefine((track, context) => {
|
|
30703
30716
|
for (let index = 1; index < track.keyframes.length; index += 1) if ((track.keyframes[index]?.at ?? 0) < (track.keyframes[index - 1]?.at ?? 0)) context.addIssue({
|
|
30704
30717
|
code: "custom",
|
|
@@ -30713,20 +30726,20 @@ const BoardTrackSchema = object({
|
|
|
30713
30726
|
const BoardMarkerSchema = object({
|
|
30714
30727
|
at: nonNegative,
|
|
30715
30728
|
label: string().max(280).optional(),
|
|
30716
|
-
pause: boolean().optional()
|
|
30729
|
+
pause: boolean().optional().describe("Hold shared playback here until next.")
|
|
30717
30730
|
}).strict();
|
|
30718
30731
|
object({
|
|
30719
30732
|
name: string().max(280).optional(),
|
|
30720
|
-
duration: finite.positive().max(864e5),
|
|
30733
|
+
duration: finite.positive().max(864e5).describe("Milliseconds; a new animation without it ends at its last keyframe."),
|
|
30721
30734
|
play: _enum([
|
|
30722
30735
|
"manual",
|
|
30723
30736
|
"auto",
|
|
30724
30737
|
"always"
|
|
30725
|
-
]).default("manual"),
|
|
30738
|
+
]).default("manual").describe("manual: only shared playback starts it. auto: plays when the Board opens. always: loops continuously."),
|
|
30726
30739
|
delay: nonNegative.default(0),
|
|
30727
30740
|
loop: boolean().default(false),
|
|
30728
|
-
end: _enum(["hold", "reset"]).default("hold"),
|
|
30729
|
-
markers: array(BoardMarkerSchema).max(1e4).default([])
|
|
30741
|
+
end: _enum(["hold", "reset"]).default("hold").describe("hold keeps the last frame; reset returns to the start."),
|
|
30742
|
+
markers: array(BoardMarkerSchema).max(1e4).default([]).describe("Labeled points on this timeline; a nested animation's markers do not carry over.")
|
|
30730
30743
|
}).strict().extend({ tracks: record(BoardKeySchema, BoardTrackSchema).default({}) }).strict();
|
|
30731
30744
|
const BOARD_ENTER_PRESETS = [
|
|
30732
30745
|
"fade-in",
|
|
@@ -30743,7 +30756,7 @@ const BoardBackgroundSchema = object({
|
|
|
30743
30756
|
"image"
|
|
30744
30757
|
]).default("dots"),
|
|
30745
30758
|
color: BoardColorSchema.optional(),
|
|
30746
|
-
imageUrl: string().url().max(4096).optional(),
|
|
30759
|
+
imageUrl: string().url().max(4096).optional().describe("Background image for kind image."),
|
|
30747
30760
|
fit: _enum([
|
|
30748
30761
|
"cover",
|
|
30749
30762
|
"contain",
|
|
@@ -30755,13 +30768,13 @@ object({
|
|
|
30755
30768
|
title: string().min(1).max(255).optional(),
|
|
30756
30769
|
background: BoardBackgroundSchema.default({ kind: "dots" }),
|
|
30757
30770
|
grid: object({
|
|
30758
|
-
visible: boolean().default(false),
|
|
30771
|
+
visible: boolean().default(false).describe("Show the grid overlay."),
|
|
30759
30772
|
size: finite.min(4).max(512).default(24)
|
|
30760
30773
|
}).strict().optional(),
|
|
30761
30774
|
enter: object({
|
|
30762
30775
|
preset: _enum(BOARD_ENTER_PRESETS),
|
|
30763
30776
|
duration: finite.positive().max(1e4).optional()
|
|
30764
|
-
}).strict().optional()
|
|
30777
|
+
}).strict().optional().describe("Motion for items as they are added.")
|
|
30765
30778
|
}).strict();
|
|
30766
30779
|
const patchObject = record(string(), unknown());
|
|
30767
30780
|
object({
|
|
@@ -31338,13 +31351,24 @@ function renderBoardExport(renderer, input, options = {}) {
|
|
|
31338
31351
|
backgroundImage: options.backgroundImage
|
|
31339
31352
|
});
|
|
31340
31353
|
try {
|
|
31341
|
-
const
|
|
31354
|
+
const texture = renderer.textureGenerator.generateTexture({
|
|
31342
31355
|
target: exportScene.root,
|
|
31343
31356
|
frame: new Rectangle(0, 0, plan.width, plan.height),
|
|
31344
31357
|
resolution: 1,
|
|
31345
31358
|
antialias: true,
|
|
31346
31359
|
clearColor: options.background === "transparent" ? void 0 : palette.bg
|
|
31347
31360
|
});
|
|
31361
|
+
let canvas;
|
|
31362
|
+
const surface = renderer.type === RendererType.CANVAS ? texture.source.resource : void 0;
|
|
31363
|
+
try {
|
|
31364
|
+
canvas = renderer.texture.generateCanvas(texture);
|
|
31365
|
+
} finally {
|
|
31366
|
+
texture.destroy(true);
|
|
31367
|
+
if (surface) {
|
|
31368
|
+
surface.width = 1;
|
|
31369
|
+
surface.height = 1;
|
|
31370
|
+
}
|
|
31371
|
+
}
|
|
31348
31372
|
const warnings = [];
|
|
31349
31373
|
if (plan.clamped) warnings.push({
|
|
31350
31374
|
kind: "scale-clamped",
|
|
@@ -31369,11 +31393,55 @@ function renderBoardExport(renderer, input, options = {}) {
|
|
|
31369
31393
|
}
|
|
31370
31394
|
}
|
|
31371
31395
|
//#endregion
|
|
31396
|
+
//#region ../sdk/src/board/export/node/fonts.ts
|
|
31397
|
+
function initializeBoardFonts(registry, fonts) {
|
|
31398
|
+
for (const font of fonts) registry.registerFromPath(font.path, font.family);
|
|
31399
|
+
if (!registry.setAlias) return;
|
|
31400
|
+
for (const [alias, candidates] of Object.entries({
|
|
31401
|
+
"system-ui": [
|
|
31402
|
+
"Noto Sans",
|
|
31403
|
+
"DejaVu Sans",
|
|
31404
|
+
"Liberation Sans",
|
|
31405
|
+
"FreeSans",
|
|
31406
|
+
"Helvetica Neue",
|
|
31407
|
+
"Arial",
|
|
31408
|
+
"Segoe UI"
|
|
31409
|
+
],
|
|
31410
|
+
"sans-serif": [
|
|
31411
|
+
"Geist",
|
|
31412
|
+
"Noto Sans",
|
|
31413
|
+
"DejaVu Sans",
|
|
31414
|
+
"Liberation Sans",
|
|
31415
|
+
"FreeSans",
|
|
31416
|
+
"Arial"
|
|
31417
|
+
],
|
|
31418
|
+
serif: [
|
|
31419
|
+
"Noto Serif",
|
|
31420
|
+
"DejaVu Serif",
|
|
31421
|
+
"Liberation Serif",
|
|
31422
|
+
"FreeSerif",
|
|
31423
|
+
"Times New Roman"
|
|
31424
|
+
],
|
|
31425
|
+
monospace: [
|
|
31426
|
+
"Geist Mono",
|
|
31427
|
+
"DejaVu Sans Mono",
|
|
31428
|
+
"Liberation Mono",
|
|
31429
|
+
"FreeMono",
|
|
31430
|
+
"Courier New"
|
|
31431
|
+
]
|
|
31432
|
+
})) {
|
|
31433
|
+
if (registry.has(alias)) continue;
|
|
31434
|
+
const family = candidates.find((name) => registry.has(name));
|
|
31435
|
+
if (family) registry.setAlias(family, alias);
|
|
31436
|
+
}
|
|
31437
|
+
}
|
|
31438
|
+
//#endregion
|
|
31372
31439
|
//#region ../sdk/src/board/export/node/scripts.ts
|
|
31373
31440
|
const WORKER = `
|
|
31374
31441
|
const {parentPort, workerData} = require('node:worker_threads');
|
|
31375
31442
|
const {createContext, Script, SourceTextModule} = require('node:vm');
|
|
31376
|
-
const {createCanvas} = require(workerData.canvasModule);
|
|
31443
|
+
const {createCanvas, GlobalFonts} = require(workerData.canvasModule);
|
|
31444
|
+
(${initializeBoardFonts.toString()})(GlobalFonts, workerData.fonts);
|
|
31377
31445
|
const instances = new Map();
|
|
31378
31446
|
const graphs = new Map();
|
|
31379
31447
|
const update = new Script('__runtime.update(JSON.parse(__inputJson)); __runtime.step(__time)');
|
|
@@ -31382,7 +31450,10 @@ const output = new Script('JSON.stringify(__runtime.output())');
|
|
|
31382
31450
|
const dispose = new Script('__runtime.destroy()');
|
|
31383
31451
|
function release(id) {
|
|
31384
31452
|
const entry=instances.get(id);instances.delete(id);
|
|
31385
|
-
if(entry) {
|
|
31453
|
+
if(entry) {
|
|
31454
|
+
try {dispose.runInContext(entry.context,{timeout:workerData.timeout});} catch {}
|
|
31455
|
+
if(entry.canvas) {entry.canvas.width=1;entry.canvas.height=1;}
|
|
31456
|
+
}
|
|
31386
31457
|
}
|
|
31387
31458
|
async function create(data) {
|
|
31388
31459
|
const context = createContext({console:{log(){},warn(){},error(){}},structuredClone},{codeGeneration:{strings:false,wasm:false}});
|
|
@@ -31432,22 +31503,29 @@ parentPort.on('message',async data=>{
|
|
|
31432
31503
|
const width=Math.max(1,Math.round(data.input.width*data.scale));
|
|
31433
31504
|
const height=Math.max(1,Math.round(data.input.height*data.scale));
|
|
31434
31505
|
const canvas=entry.canvas??=createCanvas(width,height);
|
|
31435
|
-
canvas.width=width;canvas.height=height;
|
|
31436
|
-
const drawing=canvas.getContext('2d');drawing.scale(data.scale,data.scale);
|
|
31437
|
-
context.__drawing=drawing;
|
|
31438
|
-
|
|
31506
|
+
if(canvas.width!==width || canvas.height!==height) {canvas.width=width;canvas.height=height;}
|
|
31507
|
+
const drawing=canvas.getContext('2d');drawing.reset();drawing.scale(data.scale,data.scale);
|
|
31508
|
+
context.__drawing=drawing;
|
|
31509
|
+
try {
|
|
31510
|
+
draw.runInContext(context,{timeout:workerData.timeout});
|
|
31511
|
+
png=canvas.toBuffer('image/png');
|
|
31512
|
+
} finally {
|
|
31513
|
+
delete context.__drawing;canvas.width=1;canvas.height=1;
|
|
31514
|
+
}
|
|
31439
31515
|
}
|
|
31440
31516
|
parentPort.postMessage({png,output:JSON.parse(output.runInContext(context,{timeout:workerData.timeout}))});
|
|
31441
|
-
} catch(error) {
|
|
31517
|
+
} catch(error) { release(data.input?.id);parentPort.postMessage({error:String(error.stack||error)}); }
|
|
31442
31518
|
});
|
|
31443
31519
|
`;
|
|
31444
31520
|
function createNodeBoardScriptHost(renderer, options) {
|
|
31521
|
+
const concurrency = options.concurrency ?? 4;
|
|
31522
|
+
if (!Number.isSafeInteger(concurrency) || concurrency < 1 || concurrency > 4) throw new Error("Script concurrency must be an integer between 1 and 4.");
|
|
31445
31523
|
const textures = /* @__PURE__ */ new Map();
|
|
31446
31524
|
const outputs = /* @__PURE__ */ new Map();
|
|
31447
31525
|
const errors = /* @__PURE__ */ new Map();
|
|
31448
31526
|
const sources = /* @__PURE__ */ new Map();
|
|
31449
31527
|
const modules = createBoardScriptModuleReader(options.readModule, options.readTimeoutMs);
|
|
31450
|
-
const lanes = Array.from({ length:
|
|
31528
|
+
const lanes = Array.from({ length: concurrency }, () => ({
|
|
31451
31529
|
worker: null,
|
|
31452
31530
|
tail: Promise.resolve(),
|
|
31453
31531
|
graphs: /* @__PURE__ */ new Set()
|
|
@@ -31488,6 +31566,7 @@ function createNodeBoardScriptHost(renderer, options) {
|
|
|
31488
31566
|
workerData: {
|
|
31489
31567
|
runtime: createScriptRuntime.toString(),
|
|
31490
31568
|
timeout,
|
|
31569
|
+
fonts: renderer.fonts ?? [],
|
|
31491
31570
|
canvasModule: fileURLToPath(import.meta.resolve("@napi-rs/canvas"))
|
|
31492
31571
|
}
|
|
31493
31572
|
});
|
|
@@ -31621,20 +31700,6 @@ function createNodeBoardScriptHost(renderer, options) {
|
|
|
31621
31700
|
}
|
|
31622
31701
|
//#endregion
|
|
31623
31702
|
//#region ../sdk/src/board/export/node/index.ts
|
|
31624
|
-
const SYSTEM_UI_FAMILIES = [
|
|
31625
|
-
"Noto Sans",
|
|
31626
|
-
"DejaVu Sans",
|
|
31627
|
-
"Liberation Sans",
|
|
31628
|
-
"FreeSans",
|
|
31629
|
-
"Helvetica Neue",
|
|
31630
|
-
"Arial",
|
|
31631
|
-
"Segoe UI"
|
|
31632
|
-
];
|
|
31633
|
-
function aliasSystemUi(fonts) {
|
|
31634
|
-
if (!fonts.setAlias || fonts.has("system-ui")) return;
|
|
31635
|
-
const family = SYSTEM_UI_FAMILIES.find((name) => fonts.has(name));
|
|
31636
|
-
if (family) fonts.setAlias(family, "system-ui");
|
|
31637
|
-
}
|
|
31638
31703
|
const WEBGL_PROBE_STUB = {
|
|
31639
31704
|
getShaderPrecisionFormat: () => ({
|
|
31640
31705
|
precision: 1,
|
|
@@ -31681,8 +31746,11 @@ function installAnimationFrameShim() {
|
|
|
31681
31746
|
async function createNodeBoardRenderer(options = {}) {
|
|
31682
31747
|
const canvasModule = options.canvasModule ?? await loadCanvasModule();
|
|
31683
31748
|
extensions.add(CanvasGraphicsPipe, GraphicsPipe, CanvasGraphicsContextSystem, GraphicsContextSystem, CanvasRendererTextSystem, CanvasTextSystem, CanvasTextPipe);
|
|
31684
|
-
|
|
31685
|
-
|
|
31749
|
+
const fonts = (options.fonts ?? []).map((font) => ({
|
|
31750
|
+
...font,
|
|
31751
|
+
family: font.family ?? "Geist"
|
|
31752
|
+
}));
|
|
31753
|
+
initializeBoardFonts(canvasModule.GlobalFonts, fonts);
|
|
31686
31754
|
function createCanvas(width = 1, height = 1) {
|
|
31687
31755
|
const canvas = canvasModule.createCanvas(Math.max(1, Math.ceil(width)), Math.max(1, Math.ceil(height)));
|
|
31688
31756
|
const nativeGetContext = canvas.getContext.bind(canvas);
|
|
@@ -31719,14 +31787,16 @@ async function createNodeBoardRenderer(options = {}) {
|
|
|
31719
31787
|
return {
|
|
31720
31788
|
renderer,
|
|
31721
31789
|
canvasModule,
|
|
31722
|
-
|
|
31790
|
+
fonts,
|
|
31791
|
+
decodeImage: async (bytes) => {
|
|
31723
31792
|
const image = new canvasModule.Image();
|
|
31724
|
-
const base64 = Buffer.from(bytes).toString("base64");
|
|
31725
31793
|
await new Promise((resolve, reject) => {
|
|
31726
31794
|
image.onload = () => resolve();
|
|
31727
31795
|
image.onerror = (error) => reject(error);
|
|
31728
|
-
image.src =
|
|
31796
|
+
image.src = bytes;
|
|
31729
31797
|
});
|
|
31798
|
+
image.onload = void 0;
|
|
31799
|
+
image.onerror = void 0;
|
|
31730
31800
|
return new Texture({ source: new ImageSource({
|
|
31731
31801
|
resource: image,
|
|
31732
31802
|
width: image.width,
|
|
@@ -31760,7 +31830,7 @@ function exportBoardImageBytes(renderer, document, options = {}) {
|
|
|
31760
31830
|
try {
|
|
31761
31831
|
const bytes = format === "png" ? canvas.toBuffer(MIME.png) : canvas.toBuffer(MIME[format], Math.round(quality * 100));
|
|
31762
31832
|
return {
|
|
31763
|
-
bytes: new Uint8Array(bytes),
|
|
31833
|
+
bytes: new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength),
|
|
31764
31834
|
plan: result.plan,
|
|
31765
31835
|
warnings: result.warnings,
|
|
31766
31836
|
format
|
|
@@ -31771,4 +31841,4 @@ function exportBoardImageBytes(renderer, document, options = {}) {
|
|
|
31771
31841
|
}
|
|
31772
31842
|
}
|
|
31773
31843
|
//#endregion
|
|
31774
|
-
export { BOARD_SCRIPT_DRAWING_EXAMPLE, boardDocumentAt, boardImageKeySource, boardPathTrack, boardSequence, boardSequencePatch, buildBoardScene, createBoardAnimationSampler, createBoardRenderSampler, createNodeBoardRenderer, createNodeBoardScriptHost, exportBoardImageBytes, hasBoardScripts, imageAssetKey, inspectBoardScene, measureBoardText, parseBoardDocument, planBoardExport, prepareBoardExport, selectBoardExportAssets };
|
|
31844
|
+
export { BOARD_SCRIPT_DRAWING_EXAMPLE, boardDocumentAt, boardImageKeySource, boardPathTrack, boardSequence, boardSequencePatch, buildBoardScene, createBoardAnimationSampler, createBoardRenderSampler, createNodeBoardRenderer, createNodeBoardScriptHost, exportBoardImageBytes, hasBoardScripts, imageAssetKey, inspectBoardItems, inspectBoardScene, measureBoardText, parseBoardDocument, planBoardExport, prepareBoardExport, selectBoardExportAssets };
|