@neta-art/cohub-cli 9.1.1 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,21 @@
1
1
  import type { BoardDocument, BoardExportRegion, BoardSceneItem } from "@neta-art/cohub/board";
2
- import type { BoardHeadlessExportFormat, BoardHeadlessFont, BoardHeadlessRenderer, BoardHeadlessTexture } from "@neta-art/cohub/board/headless";
3
- export declare function resolveBundledFonts(): BoardHeadlessFont[];
2
+ import type { BoardNodeExportFormat, BoardNodeFont, BoardNodeRenderer, BoardNodeTexture } from "@neta-art/cohub/board/export/node";
3
+ export declare function resolveBundledFonts(): BoardNodeFont[];
4
4
  export type BoardExportSource = {
5
5
  document: BoardDocument;
6
6
  boardId: string;
7
7
  title: string | null;
8
8
  };
9
9
  export declare function loadBoardDocument(spaceId: string, target: string): Promise<BoardExportSource>;
10
- export declare function loadBoardTextures(headless: BoardHeadlessRenderer, spaceId: string, items: readonly BoardSceneItem[], options?: {
10
+ export type BoardExportTextureCache = {
11
+ textures: Map<string, BoardNodeTexture>;
12
+ failed: Set<string>;
13
+ };
14
+ export declare function loadBoardTextures(renderer: BoardNodeRenderer, spaceId: string, items: readonly BoardSceneItem[], options?: {
11
15
  concurrency?: number;
16
+ cache?: BoardExportTextureCache;
12
17
  }): Promise<{
13
- textures: Map<string, BoardHeadlessTexture>;
18
+ textures: Map<string, BoardNodeTexture>;
14
19
  failed: string[];
15
20
  omitted: string[];
16
21
  }>;
@@ -24,9 +29,17 @@ export type BoardExportRunOptions = {
24
29
  padding?: number;
25
30
  colorScheme: "dark" | "light";
26
31
  background: "paper" | "transparent";
27
- format: BoardHeadlessExportFormat;
32
+ format: BoardNodeExportFormat;
28
33
  quality?: number;
29
34
  withImages: boolean;
35
+ camera?: {
36
+ width: number;
37
+ height: number;
38
+ };
39
+ document?: BoardDocument;
40
+ signal?: AbortSignal;
41
+ onFrame?: (frame: BoardExportFrame, index: number) => Promise<void>;
42
+ onProgress?: (completed: number, total: number) => void;
30
43
  };
31
44
  export type BoardExportFrame = {
32
45
  time: number | null;
@@ -35,7 +48,7 @@ export type BoardExportFrame = {
35
48
  height: number;
36
49
  scale: number;
37
50
  itemCount: number;
38
- format: BoardHeadlessExportFormat;
51
+ format: BoardNodeExportFormat;
39
52
  };
40
53
  export type BoardExportRunResult = {
41
54
  frames: BoardExportFrame[];
@@ -46,6 +59,7 @@ export type BoardVideoExportOptions = Omit<BoardExportRunOptions, "format"> & {
46
59
  format: BoardVideoExportFormat;
47
60
  fps: number;
48
61
  output: string;
62
+ force?: boolean;
49
63
  };
50
64
  export declare function runBoardVideoExport(options: BoardVideoExportOptions): Promise<{
51
65
  width: number;
@@ -1,5 +1,7 @@
1
1
  import { existsSync } from "node:fs";
2
- import { mkdtemp, rm, writeFile } from "node:fs/promises";
2
+ import { mkdtemp, rm, writeFile, copyFile, link, rename, unlink } from "node:fs/promises";
3
+ import { constants } from "node:fs";
4
+ import { randomUUID } from "node:crypto";
3
5
  import { execFile as execFileCallback } from "node:child_process";
4
6
  import { promisify } from "node:util";
5
7
  import { createRequire } from "node:module";
@@ -7,11 +9,12 @@ import { dirname, join } from "node:path";
7
9
  import { fileURLToPath } from "node:url";
8
10
  import { tmpdir } from "node:os";
9
11
  const execFile = promisify(execFileCallback);
10
- import { boardDocumentAt, boardImageKeySource, buildBoardScene, createBoardHeadlessRenderer, createBoardHeadlessSketchHost, exportBoardImageBytes, imageAssetKey, parseBoardDocument, planBoardExport, selectBoardExportAssets, } from "./board-kernel.js";
12
+ import { parseBoardMediaSource } from "@neta-art/cohub/board";
13
+ import { hasBoardScripts, boardDocumentAt, createBoardRenderSampler, boardImageKeySource, buildBoardScene, createNodeBoardRenderer, createNodeBoardScriptHost, exportBoardImageBytes, imageAssetKey, parseBoardDocument, planBoardExport, prepareBoardExport, selectBoardExportAssets, } from "./board-kernel.js";
11
14
  import { resolveBoardId } from "./board-command-support.js";
12
15
  import { BOARD_EXPORT_FONTS } from "./board-fonts.js";
13
16
  import { createClient } from "./client.js";
14
- import { downloadPublicImage } from "./safe-remote-image.js";
17
+ import { downloadPublicAudio, downloadPublicImage } from "./safe-remote-image.js";
15
18
  export function resolveBundledFonts() {
16
19
  const require = createRequire(import.meta.url);
17
20
  const bundled = fileURLToPath(new URL("./fonts/", import.meta.url));
@@ -35,21 +38,34 @@ export function resolveBundledFonts() {
35
38
  export async function loadBoardDocument(spaceId, target) {
36
39
  const board = createClient().space(spaceId).board(await resolveBoardId(spaceId, target));
37
40
  let result = await board.get();
41
+ const snapshot = result;
38
42
  const items = { ...result.items };
39
43
  while (result.next) {
40
44
  result = await board.get({ only: ["items"], cursor: result.next });
45
+ if (result.version !== snapshot.version)
46
+ throw new Error("Board changed while reading. Retry the export.");
41
47
  Object.assign(items, result.items);
42
48
  }
43
- const parsed = parseBoardDocument({ board: result.board, items, animations: result.animations ?? {} });
49
+ const parsed = parseBoardDocument({ board: snapshot.board, items, animations: snapshot.animations ?? {} });
44
50
  if (!parsed.ok)
45
51
  throw new Error(`Board ${result.id} could not be read: ${parsed.diagnostics[0]?.path}: ${parsed.diagnostics[0]?.message}`);
46
52
  return { document: parsed.document, boardId: result.id, title: result.title };
47
53
  }
48
- export async function loadBoardTextures(headless, spaceId, items, options = {}) {
54
+ export async function loadBoardTextures(renderer, spaceId, items, options = {}) {
49
55
  const selection = selectBoardExportAssets([...items], imageAssetKey);
50
- const textures = new Map();
51
- const failed = [];
52
- const pending = [...selection.keys];
56
+ const cache = options.cache ?? { textures: new Map(), failed: new Set() };
57
+ const { textures, failed } = cache;
58
+ const wanted = new Set(selection.keys);
59
+ for (const [key, texture] of textures) {
60
+ if (wanted.has(key))
61
+ continue;
62
+ texture.destroy(true);
63
+ textures.delete(key);
64
+ }
65
+ for (const key of failed)
66
+ if (!wanted.has(key))
67
+ failed.delete(key);
68
+ const pending = selection.keys.filter((key) => !textures.has(key) && !failed.has(key));
53
69
  const concurrency = Math.max(1, Math.min(options.concurrency ?? 4, 16));
54
70
  const client = createClient();
55
71
  async function worker() {
@@ -59,23 +75,23 @@ export async function loadBoardTextures(headless, spaceId, items, options = {})
59
75
  return;
60
76
  const source = boardImageKeySource(key);
61
77
  if (!source) {
62
- failed.push(key);
78
+ failed.add(key);
63
79
  continue;
64
80
  }
65
81
  try {
66
82
  const { bytes, mimeType } = source.kind === "file"
67
83
  ? await readSpaceFileBytes(client, spaceId, source.value)
68
84
  : await downloadPublicImage(source.value);
69
- const texture = await headless.decodeImage(bytes, mimeType);
85
+ const texture = await renderer.decodeImage(bytes, mimeType);
70
86
  textures.set(key, texture);
71
87
  }
72
88
  catch {
73
- failed.push(key);
89
+ failed.add(key);
74
90
  }
75
91
  }
76
92
  }
77
93
  await Promise.all(Array.from({ length: Math.min(concurrency, pending.length) }, worker));
78
- return { textures, failed, omitted: selection.omittedKeys };
94
+ return { textures, failed: [...failed], omitted: selection.omittedKeys };
79
95
  }
80
96
  async function readSpaceFileBytes(client, spaceId, path) {
81
97
  const { blob, mimeType } = await client.space(spaceId).files.download(path);
@@ -93,24 +109,36 @@ export async function runBoardVideoExport(options) {
93
109
  const derivedFps = 1000 / step;
94
110
  if (Math.abs(options.fps - derivedFps) > 0.01)
95
111
  throw new Error(`--fps must match the --at step (${derivedFps.toFixed(3)} fps).`);
96
- const result = await runBoardExport({ ...options, format: "png" });
97
- if (!result)
98
- throw new Error("Nothing to export: the region contains no items.");
112
+ if (times.some((time, index) => index > 0 && Math.abs(time - times[index - 1] - step) > 0.001))
113
+ throw new Error("Video export needs evenly spaced times.");
114
+ await execFile("ffmpeg", ["-version"], { signal: options.signal }).catch(() => { throw new Error("Video export needs ffmpeg. Install ffmpeg and try again."); });
115
+ const document = options.document ?? (await loadBoardDocument(options.spaceId, options.target)).document;
99
116
  const tempDir = await mkdtemp(join(tmpdir(), "cohub-board-export-"));
100
117
  try {
101
- for (const [index, frame] of result.frames.entries())
102
- await writeFile(join(tempDir, `${String(index + 1).padStart(6, "0")}.png`), frame.bytes);
103
- const document = (await loadBoardDocument(options.spaceId, options.target)).document;
118
+ let count = 0;
119
+ let dimensions = { width: 0, height: 0 };
120
+ const result = await runBoardExport({ ...options, document, format: "png", onFrame: async (frame, index) => {
121
+ await writeFile(join(tempDir, `${String(index + 1).padStart(6, "0")}.png`), frame.bytes, { signal: options.signal });
122
+ dimensions = { width: frame.width, height: frame.height };
123
+ count++;
124
+ } });
125
+ if (!result || !count)
126
+ throw new Error("Nothing to export: the region contains no items.");
104
127
  const audioDocument = boardDocumentAt(document, options.animation, times[0]).document;
105
128
  const audio = Object.values(audioDocument.items).filter((item) => item.type === "audio");
106
129
  const audioInputs = [];
107
130
  for (const [index, item] of audio.entries()) {
108
- const { bytes } = await readSpaceFileBytes(createClient(), options.spaceId, item.props.src);
109
- const path = join(tempDir, `audio-${index}-${item.props.src.split("/").pop() ?? "track"}`);
131
+ const source = parseBoardMediaSource(item.props.src);
132
+ if (!source)
133
+ throw new Error("Invalid board audio source");
134
+ const { bytes } = source.kind === "url"
135
+ ? await downloadPublicAudio(source.value)
136
+ : await readSpaceFileBytes(createClient(), options.spaceId, source.value);
137
+ const path = join(tempDir, `audio-${index}`);
110
138
  await writeFile(path, bytes);
111
139
  audioInputs.push({ path, offset: Math.max(0, item.props.time ?? 0) / 1000 });
112
140
  }
113
- const duration = Math.max(0.001, result.frames.length / options.fps);
141
+ const duration = Math.max(0.001, count / options.fps);
114
142
  const args = ["-y", "-f", "image2", "-framerate", String(options.fps), "-i", join(tempDir, "%06d.png")];
115
143
  for (const input of audioInputs) {
116
144
  if (input.offset > 0)
@@ -130,9 +158,10 @@ export async function runBoardVideoExport(options) {
130
158
  args.push("-c:v", "libx264", "-pix_fmt", "yuv420p", "-c:a", "aac", "-movflags", "+faststart", "-f", "mp4");
131
159
  else
132
160
  args.push("-c:v", "libvpx-vp9", "-crf", "32", "-b:v", "0", "-c:a", "libopus", "-f", "webm");
133
- args.push("-t", duration.toFixed(3), options.output);
161
+ const encoded = join(tempDir, `video.${options.format}`);
162
+ args.push("-t", duration.toFixed(3), encoded);
134
163
  try {
135
- await execFile("ffmpeg", args, { encoding: "utf8", maxBuffer: 2 * 1024 * 1024 });
164
+ await execFile("ffmpeg", args, { encoding: "utf8", maxBuffer: 2 * 1024 * 1024, signal: options.signal });
136
165
  }
137
166
  catch (error) {
138
167
  const cause = error;
@@ -140,45 +169,50 @@ export async function runBoardVideoExport(options) {
140
169
  throw new Error("Video export needs ffmpeg. Install ffmpeg and try again.");
141
170
  throw new Error(`ffmpeg could not encode the video: ${(cause.stderr ?? cause.message ?? "unknown error").trim().split("\n").slice(-6).join("\n")}`);
142
171
  }
143
- return { width: result.frames[0]?.width ?? 0, height: result.frames[0]?.height ?? 0, frames: result.frames.length, warnings: result.warnings };
172
+ options.signal?.throwIfAborted();
173
+ const staged = `${options.output}.${randomUUID()}.tmp`;
174
+ try {
175
+ await copyFile(encoded, staged, constants.COPYFILE_EXCL);
176
+ options.signal?.throwIfAborted();
177
+ if (options.force)
178
+ await rename(staged, options.output);
179
+ else
180
+ await link(staged, options.output);
181
+ }
182
+ finally {
183
+ await unlink(staged).catch(() => undefined);
184
+ }
185
+ return { ...dimensions, frames: count, warnings: result.warnings };
144
186
  }
145
187
  finally {
146
188
  await rm(tempDir, { recursive: true, force: true });
147
189
  }
148
190
  }
149
191
  export async function runBoardExport(options) {
150
- const { document } = await loadBoardDocument(options.spaceId, options.target);
192
+ options.signal?.throwIfAborted();
193
+ const document = options.document ?? (await loadBoardDocument(options.spaceId, options.target)).document;
151
194
  if (options.animation && !document.animations[options.animation]) {
152
195
  throw new Error(`Animation ${options.animation} does not exist.`);
153
196
  }
154
197
  const times = options.times?.length ? options.times : [null];
155
- const documentAt = (time) => time === null ? document : boardDocumentAt(document, options.animation ?? null, time).document;
156
- const plan = planBoardExport({
157
- scene: buildBoardScene(documentAt(times[0] ?? null)),
158
- region: options.region,
159
- scale: options.scale,
160
- ...(options.padding === undefined ? {} : { padding: options.padding }),
161
- });
162
- if (!plan)
163
- return null;
164
- const headless = await createBoardHeadlessRenderer({ fonts: resolveBundledFonts() });
165
- let sketchHost = null;
198
+ const renderer = await createNodeBoardRenderer({ fonts: resolveBundledFonts() });
199
+ let scriptHost = null;
200
+ const textureCache = { textures: new Map(), failed: new Set() };
201
+ let backgroundTexture;
166
202
  try {
203
+ const sampler = createBoardRenderSampler(document, options.animation ?? null, { colorScheme: options.colorScheme });
204
+ const documentAt = (time) => time === null ? document : sampler.at(time).document;
205
+ const plan = planBoardExport({
206
+ scene: buildBoardScene(documentAt(times[0] ?? null)),
207
+ region: options.region,
208
+ scale: options.scale,
209
+ ...(options.padding === undefined ? {} : { padding: options.padding }),
210
+ });
211
+ if (!plan)
212
+ return null;
167
213
  const warnings = [];
168
- let textures;
169
- let backgroundTexture;
214
+ const textures = textureCache.textures;
170
215
  let omittedKeys = new Set();
171
- if (options.withImages) {
172
- const loaded = await loadBoardTextures(headless, options.spaceId, plan.items);
173
- textures = loaded.textures;
174
- omittedKeys = new Set(loaded.omitted);
175
- if (loaded.failed.length > 0) {
176
- warnings.push(`${loaded.failed.length} image${loaded.failed.length === 1 ? "" : "s"} could not be loaded: ${loaded.failed.slice(0, 3).join(", ")}${loaded.failed.length > 3 ? ", …" : ""}`);
177
- }
178
- if (loaded.omitted.length > 0) {
179
- warnings.push(`${loaded.omitted.length} previews were drawn as placeholders to stay within the export texture limit.`);
180
- }
181
- }
182
216
  const declaredBackground = document.board.background;
183
217
  if (options.withImages &&
184
218
  options.background === "paper" &&
@@ -186,41 +220,24 @@ export async function runBoardExport(options) {
186
220
  declaredBackground.imageUrl) {
187
221
  try {
188
222
  const { bytes, mimeType } = await downloadPublicImage(declaredBackground.imageUrl);
189
- backgroundTexture = await headless.decodeImage(bytes, mimeType);
223
+ backgroundTexture = await renderer.decodeImage(bytes, mimeType);
190
224
  }
191
225
  catch {
192
226
  warnings.push("The board background image could not be loaded; the fallback color was exported.");
193
227
  }
194
228
  }
195
229
  const videoCount = plan.items.filter((item) => item.type === "video").length;
196
- sketchHost = createBoardHeadlessSketchHost(headless, {
197
- readModule: async (src) => {
198
- const { bytes } = await readSpaceFileBytes(createClient(), options.spaceId, src);
199
- return new TextDecoder().decode(bytes);
200
- },
201
- });
202
- const region = times.length > 1 ? { kind: "rect", rect: plan.world } : options.region;
203
- const host = sketchHost;
204
- if (!host)
205
- throw new Error("Headless sketch host could not be created.");
206
- const sketchVariants = new Map();
207
- for (const time of times) {
208
- const sketchPlan = planBoardExport({
209
- scene: buildBoardScene(documentAt(time)),
210
- region,
211
- scale: options.scale,
212
- ...(times.length > 1 ? { padding: 0 } : options.padding === undefined ? {} : { padding: options.padding }),
230
+ if (hasBoardScripts(document))
231
+ scriptHost = createNodeBoardScriptHost(renderer, {
232
+ readModule: async (src) => {
233
+ const { bytes } = await readSpaceFileBytes(createClient(), options.spaceId, src);
234
+ return new TextDecoder().decode(bytes);
235
+ },
213
236
  });
214
- for (const item of sketchPlan?.items.filter((entry) => entry.type === "sketch") ?? []) {
215
- const key = `${item.id}:${item.frame.width}:${item.frame.height}:${item.props.src}:${item.props.seed ?? ""}:${JSON.stringify(item.props.params)}`;
216
- const variant = sketchVariants.get(key) ?? { item, times: [] };
217
- variant.times.push(time ?? 0);
218
- sketchVariants.set(key, variant);
219
- }
220
- }
221
- await Promise.all([...sketchVariants.values()].map((variant) => host.prepare([variant.item], variant.times, plan.scale)));
237
+ const region = times.length > 1 && !options.camera ? { kind: "rect", rect: plan.world } : options.region;
238
+ const host = scriptHost;
222
239
  if (videoCount > 0) {
223
- warnings.push(`${videoCount} video preview${videoCount === 1 ? " was" : "s were"} drawn as placeholders; headless video decoding is unavailable.`);
240
+ warnings.push(`${videoCount} video preview${videoCount === 1 ? " was" : "s were"} drawn as placeholders; video decoding is unavailable in Node.`);
224
241
  }
225
242
  const backgroundImage = backgroundTexture
226
243
  ? { texture: backgroundTexture, fit: declaredBackground.fit ?? "cover", position: "center", opacity: declaredBackground.opacity ?? 1 }
@@ -233,16 +250,46 @@ export async function runBoardExport(options) {
233
250
  : undefined;
234
251
  const frames = [];
235
252
  const reported = new Set();
253
+ let completed = 0;
236
254
  for (const time of times) {
237
- const result = exportBoardImageBytes(headless, document, {
238
- ...(time === null ? {} : { at: { ...(options.animation ? { animation: options.animation } : {}), time } }),
239
- region,
240
- scale: options.scale,
241
- padding: times.length > 1 ? 0 : options.padding,
255
+ options.signal?.throwIfAborted();
256
+ host?.clearFrames();
257
+ const frameOptions = { sampler, camera: options.camera, ...(time === null ? {} : { at: { animation: options.animation, time } }), region, scale: options.scale, padding: times.length > 1 ? 0 : options.padding };
258
+ const initial = prepareBoardExport(document, frameOptions);
259
+ if (!initial)
260
+ continue;
261
+ let prepared = initial;
262
+ if (host) {
263
+ await host.prepare(initial.scene.items, [time ?? 0], initial.plan.scale);
264
+ for (const item of initial.scene.items) {
265
+ const error = host.error(item.id);
266
+ if (error)
267
+ throw new Error(`${item.script?.src ?? item.id}: ${error}`);
268
+ }
269
+ const scripted = prepareBoardExport(document, { ...frameOptions, scripts: host });
270
+ if (!scripted)
271
+ continue;
272
+ prepared = scripted;
273
+ }
274
+ if (options.withImages) {
275
+ const loaded = await loadBoardTextures(renderer, options.spaceId, prepared.plan.items.filter((item) => prepared.scene.opacity(item.id) > 0), { cache: textureCache });
276
+ omittedKeys = new Set(loaded.omitted);
277
+ const assetWarnings = [
278
+ loaded.failed.length ? `${loaded.failed.length} image(s) could not be loaded: ${loaded.failed.slice(0, 3).join(", ")}` : null,
279
+ loaded.omitted.length ? `${loaded.omitted.length} previews were drawn as placeholders to stay within the export texture limit.` : null,
280
+ ];
281
+ for (const warning of assetWarnings)
282
+ if (warning && !reported.has(warning)) {
283
+ warnings.push(warning);
284
+ reported.add(warning);
285
+ }
286
+ }
287
+ const result = exportBoardImageBytes(renderer, document, {
288
+ ...frameOptions,
242
289
  colorScheme: options.colorScheme,
243
290
  background: options.background,
244
291
  textures,
245
- sketches: sketchHost ?? undefined,
292
+ scripts: scriptHost ?? undefined,
246
293
  backgroundImage,
247
294
  ...(assetKey ? { assetKey } : {}),
248
295
  format: options.format,
@@ -258,7 +305,7 @@ export async function runBoardExport(options) {
258
305
  warnings.push(text);
259
306
  reported.add(text);
260
307
  }
261
- frames.push({
308
+ const frame = {
262
309
  time,
263
310
  bytes: result.bytes,
264
311
  width: result.plan.width,
@@ -266,13 +313,22 @@ export async function runBoardExport(options) {
266
313
  scale: result.plan.scale,
267
314
  itemCount: result.plan.items.length,
268
315
  format: result.format,
269
- });
316
+ };
317
+ if (options.onFrame)
318
+ await options.onFrame(frame, completed);
319
+ else
320
+ frames.push(frame);
321
+ completed++;
322
+ options.onProgress?.(completed, times.length);
270
323
  }
271
- return frames.length ? { frames, warnings } : null;
324
+ return completed ? { frames, warnings } : null;
272
325
  }
273
326
  finally {
274
- sketchHost?.destroy();
275
- headless.destroy();
327
+ scriptHost?.destroy();
328
+ for (const texture of textureCache.textures.values())
329
+ texture.destroy(true);
330
+ backgroundTexture?.destroy(true);
331
+ renderer.destroy();
276
332
  }
277
333
  }
278
334
  function describeWarning(warning) {
@@ -0,0 +1,84 @@
1
+ (function(A) {
2
+ return A[A.Static = 1] = "Static", A[A.Dynamic = 2] = "Dynamic", A[A.ImportMeta = 3] = "ImportMeta", A[A.StaticSourcePhase = 4] = "StaticSourcePhase", A[A.DynamicSourcePhase = 5] = "DynamicSourcePhase", A[A.StaticDeferPhase = 6] = "StaticDeferPhase", A[A.DynamicDeferPhase = 7] = "DynamicDeferPhase", A;
3
+ })({});
4
+ const A = 1 === new Uint8Array(new Uint16Array([1]).buffer)[0];
5
+ function parse(C, g = "@") {
6
+ if (!E) return init.then(() => parse(C, g));
7
+ const I = C.length + 1, w = (E.__heap_base.value || E.__heap_base) + 4 * I - E.memory.buffer.byteLength;
8
+ w > 0 && E.memory.grow(Math.ceil(w / 65536));
9
+ const D = E.sa(I - 1);
10
+ if ("undefined" != typeof Buffer ? Buffer.from(E.memory.buffer, D, 2 * (I - 1)).write(C, "utf16le") : (A ? Q : B)(C, new Uint16Array(E.memory.buffer, D, I)), !E.parse()) throw Object.assign(/* @__PURE__ */ new Error(`Parse error ${g}:${C.slice(0, E.e()).split("\n").length}:${E.e() - C.lastIndexOf("\n", E.e() - 1)}`), { idx: E.e() });
11
+ const o = [], G = [];
12
+ for (; E.ri();) {
13
+ const A = E.is(), B = E.ie(), Q = E.it(), g = E.ai(), I = E.id(), w = E.ss(), D = E.se();
14
+ let G;
15
+ E.ip() && (G = i(C.slice(-1 === I ? A - 1 : A, -1 === I ? B + 1 : B)));
16
+ let J = null;
17
+ for (J = [], E.rsa(); E.ra();) {
18
+ const A = E.aks(), B = E.ake(), Q = E.avs(), g = E.ave();
19
+ J.push([s(C.slice(A, B)), s(C.slice(Q, g))]);
20
+ }
21
+ 0 === J.length && (J = null), o.push({
22
+ n: G,
23
+ t: Q,
24
+ s: A,
25
+ e: B,
26
+ ss: w,
27
+ se: D,
28
+ d: I,
29
+ a: g,
30
+ at: J
31
+ });
32
+ }
33
+ for (; E.re();) {
34
+ const A = E.es(), B = E.ee(), Q = E.els(), g = E.ele(), I = Q < 0 ? void 0 : s(C.slice(Q, g)), w = s(C.slice(A, B));
35
+ G.push({
36
+ s: A,
37
+ e: B,
38
+ ls: Q,
39
+ le: g,
40
+ ss: E.ess(),
41
+ n: w,
42
+ ln: I
43
+ });
44
+ }
45
+ function i(A) {
46
+ try {
47
+ return (0, eval)(A);
48
+ } catch (A) {}
49
+ }
50
+ function s(A) {
51
+ if (!A) return A;
52
+ const B = A[0];
53
+ return ("\"" === B || "'" === B) && i(A) || A;
54
+ }
55
+ return [
56
+ o,
57
+ G,
58
+ !!E.f(),
59
+ !!E.ms()
60
+ ];
61
+ }
62
+ function B(A, B) {
63
+ const Q = A.length;
64
+ let E = 0;
65
+ for (; E < Q;) {
66
+ const Q = A.charCodeAt(E);
67
+ B[E++] = (255 & Q) << 8 | Q >>> 8;
68
+ }
69
+ }
70
+ function Q(A, B) {
71
+ const Q = A.length;
72
+ let E = 0;
73
+ for (; E < Q;) B[E] = A.charCodeAt(E++);
74
+ }
75
+ let E;
76
+ const C = () => {
77
+ return A = "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DQECQAJAIABBAmoiAC8BACIHQdwAaw4FAAICAgUBCyACQQRqIQAMAQsgB0EkRw0AIAIvAQRB+wBHDQALC0GYCiABQQJrNgIADwsgABAmQZgKKAIAIQALQZgKIABBAmoiADYCAAJAAkACQEEBECVBKWsOBAECAgACC0GYCkGYCigCAEECajYCAEEBECUaIAMgADYCBEGYCigCACEAIANBAToAGCADIAA2AhAMCAtBggogBTsBACADIAA2AgRBmAooAgAhACADQQE6ABggAyAAQQJqNgIMQYAKIAQ7AQAPC0GYCkGYCigCAEECazYCAA8LIAdFIABB+wBHckUEQEGYCigCACEAQYIKLwEADQZBnAooAgAhAQNAAkACQCAAIAFJBEBBARAlIgBBIkYgAEEnRnINASAAQf0ARw0CQZgKQZgKKAIAQQJqNgIAC0EBECUhAUGYCigCACEAIAFB5gBGBEAgAEECakGcCEEGEB8NBwtBmAogAEEIajYCAEEBECUiAEEiRyAAQSdHcQ0GIAYgAEEAEDkPCyAAECYLQZgKQZgKKAIAQQJqIgA2AgAMAAsACwJAAkAgAEEnaw4EAwEBAwALIABBIkYNAgtBmAooAgAhBAsgBCAJRw0AQZgKIARBAms2AgAPCyAAQSpHIAVxDQJBggovAQANAkGYCigCACEAQZwKKAIAIQIDQCAAIAJPDQEgAC8BACIBQSdHIAFBIkdxBEBBmAogAEECaiIANgIADAEFIAYgASADEDkPCwALAAsQMgsPC0GYCkGYCigCAEECazYCAA8LQZgKIABBAms2AgALQwEDf0GYCigCACEAQZwKKAIAIQIDQAJAIABBAmohASAAIAJPDQAgASEAIAEvAQBBCmsOBAABAQABCwtBmAogATYCAAtwAQR/QZgKKAIAQQJqIQFBnAooAgAhBAJAA0AgASICQQJqIQEgAiAETw0BIAEvAQAhAwJAIABFBEAgA0EqRg0BIANBCmsOBAMCAgMCCyADQSpHDQELIAIvAQRBL0cNAAsgAkEEaiEBC0GYCiABNgIACwsAIABBn4CABBA8C30BBH9BnAooAgAhA0GYCigCACEBA0ACQAJAAkAgAS8BACICQS9GBEAgAS8BAiIBQSpHBEAgAUEvRg0CQS8PCyAAECMMAgsgAARAIAIQJA0CDAMLIAIQLg0BDAILECIL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", "undefined" != typeof Buffer ? Buffer.from(A, "base64") : Uint8Array.from(atob(A), (A) => A.charCodeAt(0));
78
+ var A;
79
+ };
80
+ const init = WebAssembly.compile(C()).then(WebAssembly.instantiate).then(({ exports: A }) => {
81
+ E = A;
82
+ });
83
+ //#endregion
84
+ export { init, parse };
@@ -1,2 +1,4 @@
1
- export { boardDocumentAt, boardImageKeySource, buildBoardScene, imageAssetKey, parseBoardDocument, planBoardExport, selectBoardExportAssets, } from "@neta-art/cohub/board";
2
- export { createBoardHeadlessRenderer, createBoardHeadlessSketchHost, exportBoardImageBytes } from "@neta-art/cohub/board/headless";
1
+ export { BOARD_SCRIPT_DRAWING_EXAMPLE, hasBoardScripts, boardDocumentAt, createBoardAnimationSampler, boardSequence, boardSequencePatch, boardPathTrack, boardImageKeySource, buildBoardScene, imageAssetKey, parseBoardDocument, planBoardExport, selectBoardExportAssets, } from "@neta-art/cohub/board";
2
+ export { prepareBoardExport } from "@neta-art/cohub/board/export";
3
+ export { createBoardRenderSampler, inspectBoardScene, measureBoardText } from "@neta-art/cohub/board/render";
4
+ export { createNodeBoardRenderer, createNodeBoardScriptHost, exportBoardImageBytes } from "@neta-art/cohub/board/export/node";