@neta-art/cohub 9.0.1 → 11.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.
Files changed (240) hide show
  1. package/README.md +108 -102
  2. package/dist/board/editor/align.d.ts +11 -0
  3. package/dist/board/editor/align.js +72 -0
  4. package/dist/board/editor/animation.d.ts +17 -0
  5. package/dist/board/editor/animation.js +187 -0
  6. package/dist/board/editor/camera.d.ts +32 -0
  7. package/dist/board/editor/camera.js +137 -0
  8. package/dist/board/editor/clipboard.d.ts +41 -0
  9. package/dist/board/editor/clipboard.js +129 -0
  10. package/dist/board/editor/connection-ports.d.ts +19 -0
  11. package/dist/board/editor/connection-ports.js +85 -0
  12. package/dist/board/editor/context.d.ts +111 -0
  13. package/dist/board/editor/context.js +30 -0
  14. package/dist/board/editor/copy.d.ts +17 -0
  15. package/dist/board/editor/copy.js +121 -0
  16. package/dist/board/editor/creation.d.ts +51 -0
  17. package/dist/board/editor/creation.js +225 -0
  18. package/dist/board/editor/deletion.d.ts +9 -0
  19. package/dist/board/editor/deletion.js +90 -0
  20. package/dist/board/editor/document-edits.d.ts +22 -0
  21. package/dist/board/editor/document-edits.js +193 -0
  22. package/dist/board/editor/document.d.ts +41 -0
  23. package/dist/board/editor/document.js +302 -0
  24. package/dist/board/editor/editor.d.ts +225 -0
  25. package/dist/board/editor/editor.js +439 -0
  26. package/dist/board/editor/index.d.ts +18 -0
  27. package/dist/board/editor/index.js +12 -0
  28. package/dist/board/editor/interaction.d.ts +115 -0
  29. package/dist/board/editor/interaction.js +584 -0
  30. package/dist/board/editor/query.d.ts +27 -0
  31. package/dist/board/editor/query.js +203 -0
  32. package/dist/board/editor/remote.d.ts +11 -0
  33. package/dist/board/editor/remote.js +55 -0
  34. package/dist/board/editor/selection-transform.d.ts +24 -0
  35. package/dist/board/editor/selection-transform.js +81 -0
  36. package/dist/board/editor/selection.d.ts +33 -0
  37. package/dist/board/editor/selection.js +197 -0
  38. package/dist/board/editor/snapping.d.ts +33 -0
  39. package/dist/board/editor/snapping.js +75 -0
  40. package/dist/board/editor/snapshots.d.ts +27 -0
  41. package/dist/board/editor/snapshots.js +132 -0
  42. package/dist/board/editor/spatial.d.ts +41 -0
  43. package/dist/board/editor/spatial.js +191 -0
  44. package/dist/board/editor/state.d.ts +12 -0
  45. package/dist/board/editor/state.js +49 -0
  46. package/dist/board/editor/tool.d.ts +10 -0
  47. package/dist/board/editor/tool.js +19 -0
  48. package/dist/board/editor/wheel.d.ts +5 -0
  49. package/dist/board/editor/wheel.js +17 -0
  50. package/dist/board/export/index.d.ts +28 -6
  51. package/dist/board/export/index.js +47 -13
  52. package/dist/board/export/node/index.d.ts +56 -0
  53. package/dist/board/{headless → export/node}/index.js +26 -21
  54. package/dist/board/export/node/scripts.d.ts +16 -0
  55. package/dist/board/export/node/scripts.js +258 -0
  56. package/dist/board/export/scene.d.ts +8 -5
  57. package/dist/board/export/scene.js +24 -9
  58. package/dist/board/{animation.d.ts → model/animation.d.ts} +8 -5
  59. package/dist/board/{animation.js → model/animation.js} +37 -10
  60. package/dist/board/{core → model}/arrow-geometry.d.ts +2 -2
  61. package/dist/board/{core → model}/arrow-geometry.js +2 -2
  62. package/dist/board/model/authoring.d.ts +20 -0
  63. package/dist/board/model/authoring.js +185 -0
  64. package/dist/board/{core → model}/draw-geometry.d.ts +2 -2
  65. package/dist/board/{core → model}/draw-geometry.js +1 -1
  66. package/dist/board/model/draw-input.d.ts +14 -0
  67. package/dist/board/model/draw-input.js +28 -0
  68. package/dist/board/{core → model}/export-assets.d.ts +1 -1
  69. package/dist/board/{core → model}/export-assets.js +1 -1
  70. package/dist/board/{core → model}/export-plan.d.ts +2 -2
  71. package/dist/board/{core → model}/export-plan.js +3 -2
  72. package/dist/board/{core → model}/file-preview.d.ts +1 -1
  73. package/dist/board/{core → model}/file-preview.js +2 -2
  74. package/dist/board/{core → model}/file-snapshot.d.ts +1 -1
  75. package/dist/board/{core → model}/file-snapshot.js +4 -3
  76. package/dist/board/{geometry.d.ts → model/geometry.d.ts} +3 -3
  77. package/dist/board/{geometry.js → model/geometry.js} +1 -1
  78. package/dist/board/{image-key.d.ts → model/image-key.d.ts} +2 -2
  79. package/dist/board/{image-key.js → model/image-key.js} +7 -3
  80. package/dist/board/model/index.d.ts +42 -0
  81. package/dist/board/model/index.js +39 -0
  82. package/dist/board/model/items/builtin.d.ts +5 -0
  83. package/dist/board/model/items/builtin.js +119 -0
  84. package/dist/board/model/items/create.d.ts +61 -0
  85. package/dist/board/model/items/create.js +272 -0
  86. package/dist/board/model/items/definition.d.ts +35 -0
  87. package/dist/board/model/items/definition.js +18 -0
  88. package/dist/board/model/items/id.d.ts +5 -0
  89. package/dist/board/model/items/id.js +11 -0
  90. package/dist/board/model/items/index.d.ts +6 -0
  91. package/dist/board/model/items/index.js +6 -0
  92. package/dist/board/model/items/registry.d.ts +35 -0
  93. package/dist/board/model/items/registry.js +84 -0
  94. package/dist/board/{media-playback.d.ts → model/media-playback.d.ts} +4 -3
  95. package/dist/board/{media-playback.js → model/media-playback.js} +15 -5
  96. package/dist/board/{media.d.ts → model/media.d.ts} +1 -1
  97. package/dist/board/{media.js → model/media.js} +8 -2
  98. package/dist/board/{core → model}/palette.d.ts +1 -1
  99. package/dist/board/{core → model}/palette.js +1 -1
  100. package/dist/board/{presets.d.ts → model/presets.d.ts} +3 -3
  101. package/dist/board/{presets.js → model/presets.js} +1 -1
  102. package/dist/board/{replay.d.ts → model/replay.d.ts} +5 -5
  103. package/dist/board/{replay.js → model/replay.js} +2 -2
  104. package/dist/board/model/sampling.d.ts +19 -0
  105. package/dist/board/model/sampling.js +96 -0
  106. package/dist/board/{core → model}/scene.d.ts +1 -1
  107. package/dist/board/{core → model}/scene.js +1 -1
  108. package/dist/board/model/script-example.d.ts +4 -0
  109. package/dist/board/model/script-example.js +21 -0
  110. package/dist/board/model/script-hit.d.ts +10 -0
  111. package/dist/board/model/script-hit.js +52 -0
  112. package/dist/board/model/script-index.d.ts +7 -0
  113. package/dist/board/model/script-index.js +15 -0
  114. package/dist/board/model/script-scene.d.ts +24 -0
  115. package/dist/board/model/script-scene.js +267 -0
  116. package/dist/board/model/script.d.ts +105 -0
  117. package/dist/board/model/script.js +1 -0
  118. package/dist/board/model/shape-types.d.ts +8 -0
  119. package/dist/board/model/shape-types.js +8 -0
  120. package/dist/board/{task.d.ts → model/task.d.ts} +4 -4
  121. package/dist/board/{task.js → model/task.js} +3 -3
  122. package/dist/board/{core → model}/text-metrics.d.ts +1 -1
  123. package/dist/board/{core → model}/text-metrics.js +1 -1
  124. package/dist/board/{core → model}/tool-styles.d.ts +1 -1
  125. package/dist/board/{core → model}/tool-styles.js +1 -1
  126. package/dist/board/{runtime/board-player.d.ts → player/index.d.ts} +2 -2
  127. package/dist/board/{runtime/board-player.js → player/index.js} +5 -4
  128. package/dist/board/render/board-background.d.ts +1 -1
  129. package/dist/board/render/clip.d.ts +1 -1
  130. package/dist/board/render/css-color.d.ts +6 -1
  131. package/dist/board/render/css-color.js +34 -20
  132. package/dist/board/render/diagnostics.d.ts +20 -0
  133. package/dist/board/render/diagnostics.js +117 -0
  134. package/dist/board/render/index.d.ts +9 -6
  135. package/dist/board/render/index.js +10 -7
  136. package/dist/board/render/media-interaction.d.ts +2 -2
  137. package/dist/board/render/media-interaction.js +1 -1
  138. package/dist/board/render/palette.d.ts +3 -2
  139. package/dist/board/render/palette.js +7 -3
  140. package/dist/board/render/renderers/arrow-card-renderer.js +4 -3
  141. package/dist/board/render/renderers/audio-card-renderer.js +2 -1
  142. package/dist/board/render/renderers/board-renderer-registry.d.ts +20 -10
  143. package/dist/board/render/renderers/board-renderer-registry.js +17 -17
  144. package/dist/board/render/renderers/custom-card-renderer.d.ts +5 -0
  145. package/dist/board/render/renderers/{sketch-card-renderer.js → custom-card-renderer.js} +16 -15
  146. package/dist/board/render/renderers/draw-card-renderer.js +4 -3
  147. package/dist/board/render/renderers/effect-card-renderer.js +22 -5
  148. package/dist/board/render/renderers/far-plate.js +1 -1
  149. package/dist/board/render/renderers/file-card-renderer.d.ts +1 -1
  150. package/dist/board/render/renderers/file-card-renderer.js +2 -2
  151. package/dist/board/render/renderers/frame-card-renderer.js +30 -14
  152. package/dist/board/render/renderers/image-card-renderer.d.ts +1 -1
  153. package/dist/board/render/renderers/image-card-renderer.js +43 -4
  154. package/dist/board/render/renderers/shape-card-renderer.js +11 -28
  155. package/dist/board/render/renderers/task-card-renderer.js +1 -1
  156. package/dist/board/render/renderers/text-card-renderer.js +6 -4
  157. package/dist/board/render/renderers/unknown-card-renderer.js +1 -0
  158. package/dist/board/render/renderers/video-card-renderer.d.ts +1 -1
  159. package/dist/board/render/renderers/video-card-renderer.js +2 -1
  160. package/dist/board/render/sampling.d.ts +22 -0
  161. package/dist/board/render/sampling.js +21 -0
  162. package/dist/board/render/script-export.d.ts +11 -0
  163. package/dist/board/render/script-export.js +86 -0
  164. package/dist/board/render/script-host.d.ts +31 -0
  165. package/dist/board/render/script-host.js +421 -0
  166. package/dist/board/render/script-modules.d.ts +2 -0
  167. package/dist/board/render/script-modules.js +2 -0
  168. package/dist/board/render/script-runtime.d.ts +29 -0
  169. package/dist/board/render/script-runtime.js +213 -0
  170. package/dist/board/render/script-sandbox.d.ts +4 -0
  171. package/dist/board/render/script-sandbox.js +173 -0
  172. package/dist/board/render/stroke.d.ts +3 -2
  173. package/dist/board/render/stroke.js +23 -2
  174. package/dist/board/render/text-measurement.js +2 -2
  175. package/dist/board/replica/index.d.ts +70 -0
  176. package/dist/board/replica/index.js +276 -0
  177. package/dist/board/stage/assets.d.ts +41 -0
  178. package/dist/board/stage/assets.js +355 -0
  179. package/dist/board/stage/index.d.ts +8 -0
  180. package/dist/board/stage/index.js +8 -0
  181. package/dist/board/stage/lru.d.ts +32 -0
  182. package/dist/board/stage/lru.js +29 -0
  183. package/dist/board/stage/maintenance.d.ts +5 -0
  184. package/dist/board/stage/maintenance.js +11 -0
  185. package/dist/board/stage/pointer.d.ts +8 -0
  186. package/dist/board/stage/pointer.js +33 -0
  187. package/dist/board/stage/scene.d.ts +85 -0
  188. package/dist/board/stage/scene.js +515 -0
  189. package/dist/board/stage/script-pointer.d.ts +19 -0
  190. package/dist/board/stage/script-pointer.js +35 -0
  191. package/dist/board/stage/stage.d.ts +76 -0
  192. package/dist/board/stage/stage.js +774 -0
  193. package/dist/board/stage/texture-pool.d.ts +24 -0
  194. package/dist/board/stage/texture-pool.js +153 -0
  195. package/dist/board/stage/views.d.ts +38 -0
  196. package/dist/board/stage/views.js +93 -0
  197. package/dist/chunks/environment.d.ts +289 -23
  198. package/dist/chunks/host-bridge.d.ts +2 -2
  199. package/dist/chunks/http.d.ts +185 -71
  200. package/dist/chunks/http.js +368 -269
  201. package/dist/chunks/transport.js +3 -1
  202. package/dist/chunks/websocket.d.ts +9 -1
  203. package/dist/chunks/websocket.js +16 -2
  204. package/dist/host-bridge.js +2 -1
  205. package/dist/http.d.ts +2 -2
  206. package/dist/index.d.ts +182 -4
  207. package/dist/index.js +1393 -129
  208. package/dist/media.d.ts +1 -10
  209. package/dist/media.js +16 -27
  210. package/dist/protocol/dist/board-assets.d.ts +1 -0
  211. package/dist/protocol/dist/board-constants.js +2 -2
  212. package/dist/protocol/dist/board-model.d.ts +201 -11
  213. package/dist/protocol/dist/board-model.js +33 -14
  214. package/dist/protocol/dist/board-patch.js +3 -2
  215. package/dist/protocol/dist/board-schema.d.ts +4 -2
  216. package/dist/protocol/dist/board-schema.js +18 -4
  217. package/dist/protocol/dist/board-script-modules.d.ts +25 -0
  218. package/dist/protocol/dist/board-script-modules.js +127 -0
  219. package/dist/protocol/dist/board.d.ts +28 -2
  220. package/dist/protocol/dist/board.js +3 -1
  221. package/dist/protocol/dist/core/media.d.ts +5 -0
  222. package/dist/protocol/dist/core/media.js +39 -0
  223. package/dist/protocol/dist/display/index.d.ts +1 -0
  224. package/dist/protocol/dist/index.d.ts +7 -5
  225. package/dist/protocol/dist/realtime/types.d.ts +1 -0
  226. package/dist/protocol/dist/rtc/index.d.ts +1 -0
  227. package/dist/types.d.ts +1 -1
  228. package/package.json +21 -8
  229. package/dist/board/core/shape-definition.d.ts +0 -23
  230. package/dist/board/core/shape-definition.js +0 -45
  231. package/dist/board/core/shape-types.d.ts +0 -38
  232. package/dist/board/core/shape-types.js +0 -22
  233. package/dist/board/headless/index.d.ts +0 -55
  234. package/dist/board/headless/sketch.d.ts +0 -19
  235. package/dist/board/headless/sketch.js +0 -146
  236. package/dist/board/index.d.ts +0 -30
  237. package/dist/board/index.js +0 -29
  238. package/dist/board/render/renderers/sketch-card-renderer.d.ts +0 -5
  239. package/dist/board/render/sketch-host.d.ts +0 -14
  240. package/dist/board/render/sketch-host.js +0 -216
@@ -1,6 +1,6 @@
1
- import { BOARD_CAMERA_TARGET } from "../protocol/dist/board-model.js";
2
- import { resolveBoardProperty } from "../protocol/dist/board-patch.js";
3
- //#region src/board/animation.ts
1
+ import { BOARD_CAMERA_TARGET } from "../../protocol/dist/board-model.js";
2
+ import { resolveBoardProperty } from "../../protocol/dist/board-patch.js";
3
+ //#region src/board/model/animation.ts
4
4
  const linear = (x) => x;
5
5
  function cubicBezier(x1, y1, x2, y2) {
6
6
  const cx = 3 * x1;
@@ -183,11 +183,21 @@ function hex(color) {
183
183
  return `#${Math.max(0, Math.min(16777215, Math.round(color))).toString(16).padStart(6, "0")}`;
184
184
  }
185
185
  function mixColor(a, b, t, resolve) {
186
- const from = resolve(a);
187
- const to = resolve(b);
188
- if (from === null || to === null) return t < 1 ? a : b;
189
- const channel = (shift) => Math.round(lerp(from >> shift & 255, to >> shift & 255, t));
190
- return hex(channel(16) << 16 | channel(8) << 8 | channel(0));
186
+ const left = resolve(a);
187
+ const right = resolve(b);
188
+ if (left === null || right === null) return t < 1 ? a : b;
189
+ const from = typeof left === "number" ? {
190
+ color: left,
191
+ alpha: 1
192
+ } : left;
193
+ const to = typeof right === "number" ? {
194
+ color: right,
195
+ alpha: 1
196
+ } : right;
197
+ const alpha = lerp(from.alpha, to.alpha, t);
198
+ const channel = (shift) => alpha > 0 ? Math.round(lerp((from.color >> shift & 255) * from.alpha, (to.color >> shift & 255) * to.alpha, t) / alpha) : 0;
199
+ const rgb = hex(channel(16) << 16 | channel(8) << 8 | channel(0));
200
+ return alpha >= 1 ? rgb : `${rgb}${Math.round(Math.max(0, alpha) * 255).toString(16).padStart(2, "0")}`;
191
201
  }
192
202
  function parseHexColor(color) {
193
203
  if (typeof color !== "string") return null;
@@ -196,6 +206,23 @@ function parseHexColor(color) {
196
206
  const digits = match[1].length === 3 ? [...match[1]].map((digit) => digit + digit).join("") : match[1];
197
207
  return Number.parseInt(digits, 16);
198
208
  }
209
+ function parseAnimationColor(color) {
210
+ if (typeof color === "string") {
211
+ if (color.trim().toLowerCase() === "transparent") return {
212
+ color: 0,
213
+ alpha: 0
214
+ };
215
+ const match = /^#([0-9a-f]{4}|[0-9a-f]{8})$/i.exec(color.trim());
216
+ if (match?.[1]) {
217
+ const digits = match[1].length === 4 ? [...match[1]].map((digit) => digit + digit).join("") : match[1];
218
+ return {
219
+ color: Number.parseInt(digits.slice(0, 6), 16),
220
+ alpha: Number.parseInt(digits.slice(6), 16) / 255
221
+ };
222
+ }
223
+ }
224
+ return parseHexColor(color);
225
+ }
199
226
  function blend(track, index, time, resolveColor) {
200
227
  const { times, values } = track;
201
228
  const from = values[index];
@@ -229,7 +256,7 @@ function blend(track, index, time, resolveColor) {
229
256
  default: return progress >= 1 ? to : from;
230
257
  }
231
258
  }
232
- function sampleBoardTrack(track, time, resolveColor = parseHexColor) {
259
+ function sampleBoardTrack(track, time, resolveColor = parseAnimationColor) {
233
260
  const index = keyframeIndex(track.times, time);
234
261
  if (index < 0) return track.values[0];
235
262
  return blend(track, index, time, resolveColor);
@@ -302,7 +329,7 @@ function outranks(track, time, other, otherTime) {
302
329
  return track.id > other.id;
303
330
  }
304
331
  function evaluateBoardAnimations(compiled, times, options = {}) {
305
- const resolveColor = options.resolveColor ?? parseHexColor;
332
+ const resolveColor = options.resolveColor ?? parseAnimationColor;
306
333
  const local = new Map(times instanceof Map ? times : Object.entries(times));
307
334
  for (const id of compiled.order) {
308
335
  const animation = compiled.animations.get(id);
@@ -1,8 +1,8 @@
1
1
  import { BoardArrowAnchor, BoardArrowItem } from "../../protocol/dist/board-model.js";
2
2
  import { BoardFrame, BoardLayout, BoardMatrix } from "../../protocol/dist/board-layout.js";
3
3
  import "../../protocol/dist/index.js";
4
- import { Rect, WorldPoint } from "../geometry.js";
5
- //#region src/board/core/arrow-geometry.d.ts
4
+ import { Rect, WorldPoint } from "./geometry.js";
5
+ //#region src/board/model/arrow-geometry.d.ts
6
6
  declare const ARROW_BINDING_GAP = 4;
7
7
  type ResolvedArrowEnd = {
8
8
  point: WorldPoint;
@@ -1,7 +1,7 @@
1
1
  import { BOARD_ARROW_STROKE_SIZE } from "../../protocol/dist/board-constants.js";
2
2
  import { applyMatrix, autoAnchorSide, bendControl, framePoint, isArrowBinding, sideAnchor } from "../../protocol/dist/board-layout.js";
3
- import { worldPoint } from "../geometry.js";
4
- //#region src/board/core/arrow-geometry.ts
3
+ import { worldPoint } from "./geometry.js";
4
+ //#region src/board/model/arrow-geometry.ts
5
5
  const ARROW_BINDING_GAP = 4;
6
6
  const CURVE_SEGMENTS = 20;
7
7
  const ORTHOGONAL_SNAP = .5;
@@ -0,0 +1,20 @@
1
+ import { BoardAnimation, BoardDocument, BoardPatch, BoardTrack, BoardVec2 } from "../../protocol/dist/board-model.js";
2
+ import "../../protocol/dist/index.js";
3
+ //#region src/board/model/authoring.d.ts
4
+ type BoardChapter = {
5
+ animation: string;
6
+ frame?: string;
7
+ label?: string;
8
+ gap?: number;
9
+ pause?: boolean;
10
+ };
11
+ declare function boardSequence(document: BoardDocument, chapters: readonly BoardChapter[]): BoardAnimation;
12
+ declare function boardSequencePatch(document: BoardDocument, id: string, chapters: readonly BoardChapter[]): BoardPatch;
13
+ declare function boardPathTrack(target: string, points: readonly BoardVec2[], options: {
14
+ duration: number;
15
+ at?: number;
16
+ samples?: number;
17
+ orient?: boolean;
18
+ }): BoardTrack;
19
+ //#endregion
20
+ export { BoardChapter, boardPathTrack, boardSequence, boardSequencePatch };
@@ -0,0 +1,185 @@
1
+ import { BoardIdSchema } from "../../protocol/dist/board-model.js";
2
+ import { applyBoardPatchToDocument } from "../../protocol/dist/board-patch.js";
3
+ //#region src/board/model/authoring.ts
4
+ function validateChapterComposition(document, chapters) {
5
+ const uses = /* @__PURE__ */ new Map();
6
+ for (const [index, chapter] of chapters.entries()) for (const track of Object.values(document.animations[chapter.animation]?.tracks ?? {})) {
7
+ let properties = uses.get(track.target);
8
+ if (!properties) {
9
+ properties = /* @__PURE__ */ new Map();
10
+ uses.set(track.target, properties);
11
+ }
12
+ for (const [property, usage] of properties) if ((property === track.property || property.startsWith(`${track.property}.`) || track.property.startsWith(`${property}.`)) && (usage.additive || track.composite === "add") && [...usage.chapters].some((other) => other !== index)) throw new Error(`Chapters share additive tracks on ${track.target}.${track.property}; use distinct items or combine the tracks before sequencing.`);
13
+ const usage = properties.get(track.property) ?? {
14
+ chapters: /* @__PURE__ */ new Set(),
15
+ additive: false
16
+ };
17
+ usage.chapters.add(index);
18
+ usage.additive ||= track.composite === "add";
19
+ properties.set(track.property, usage);
20
+ }
21
+ }
22
+ function boardSequence(document, chapters) {
23
+ if (!chapters.length) throw new Error("A sequence needs at least one chapter.");
24
+ validateChapterComposition(document, chapters);
25
+ const tracks = {};
26
+ const markers = [];
27
+ let cursor = 0;
28
+ const seen = /* @__PURE__ */ new Set();
29
+ const seenFrames = /* @__PURE__ */ new Set();
30
+ for (const [index, chapter] of chapters.entries()) {
31
+ const animation = document.animations[chapter.animation];
32
+ if (!animation) throw new Error(`Animation ${chapter.animation} does not exist.`);
33
+ if (animation.play !== "manual") throw new Error(`Chapter ${chapter.animation} must use manual playback.`);
34
+ if (!Number.isFinite(animation.duration) || animation.duration <= 0) throw new Error("Chapter duration must be positive and finite.");
35
+ if (seen.has(chapter.animation)) throw new Error(`Animation ${chapter.animation} appears more than once; use separate animation IDs.`);
36
+ seen.add(chapter.animation);
37
+ if (chapter.frame && document.items[chapter.frame]?.type !== "frame") throw new Error(`Chapter ${chapter.animation} needs a valid frame.`);
38
+ if (chapter.frame && seenFrames.has(chapter.frame)) throw new Error("Each chapter needs a separate frame, or omit frame visibility control.");
39
+ if (chapter.frame) seenFrames.add(chapter.frame);
40
+ const gap = chapter.gap ?? 0;
41
+ if (!Number.isFinite(gap) || gap < 0) throw new Error("Chapter gap must be finite and non-negative.");
42
+ cursor += gap;
43
+ const start = cursor;
44
+ const end = start + animation.duration;
45
+ const rankWidth = String(Object.keys(animation.tracks).length).length;
46
+ const ranks = new Map(Object.keys(animation.tracks).sort().map((id, rank) => [id, String(rank).padStart(rankWidth, "0")]));
47
+ const chapterIndex = String(index).padStart(String(chapters.length).length, "0");
48
+ for (const [id, track] of Object.entries(animation.tracks)) {
49
+ if (document.animations[track.target]) throw new Error(`Chapter ${chapter.animation} contains nested clocks; compose its leaf animations instead.`);
50
+ if (chapter.frame && track.target === "camera" && track.property === "focus") continue;
51
+ tracks[`chapter-${chapterIndex}-${ranks.get(id)}`] = {
52
+ ...track,
53
+ keyframes: track.keyframes.map((keyframe) => ({
54
+ ...keyframe,
55
+ at: start + keyframe.at
56
+ }))
57
+ };
58
+ }
59
+ const boundary = end + (chapter.pause && index < chapters.length - 1 ? 1 : 0);
60
+ if (chapter.frame) {
61
+ tracks[`visibility-${index}`] = {
62
+ target: chapter.frame,
63
+ property: "opacity",
64
+ composite: "add",
65
+ interpolation: "step",
66
+ keyframes: [
67
+ ...start > 0 ? [{
68
+ at: 0,
69
+ value: 0
70
+ }] : [],
71
+ {
72
+ at: start,
73
+ value: 1
74
+ },
75
+ ...index < chapters.length - 1 ? [{
76
+ at: boundary + (chapters[index + 1]?.gap ?? 0),
77
+ value: 0
78
+ }] : []
79
+ ]
80
+ };
81
+ tracks[`camera-${index}`] = {
82
+ target: "camera",
83
+ property: "focus",
84
+ composite: "replace",
85
+ interpolation: "step",
86
+ keyframes: [{
87
+ at: start,
88
+ value: chapter.frame
89
+ }]
90
+ };
91
+ }
92
+ markers.push({
93
+ at: start,
94
+ label: chapter.label ?? animation.name ?? chapter.animation
95
+ });
96
+ for (const marker of animation.markers) markers.push({
97
+ ...marker,
98
+ at: start + marker.at
99
+ });
100
+ if (chapter.pause) markers.push({
101
+ at: end,
102
+ pause: true
103
+ });
104
+ cursor = boundary;
105
+ }
106
+ const byTime = /* @__PURE__ */ new Map();
107
+ for (const marker of markers) {
108
+ const previous = byTime.get(marker.at);
109
+ byTime.set(marker.at, {
110
+ ...previous,
111
+ ...marker,
112
+ pause: Boolean(previous?.pause || marker.pause)
113
+ });
114
+ }
115
+ return {
116
+ duration: cursor,
117
+ play: "manual",
118
+ end: "hold",
119
+ delay: 0,
120
+ loop: false,
121
+ tracks,
122
+ markers: [...byTime.values()].sort((a, b) => a.at - b.at)
123
+ };
124
+ }
125
+ function boardSequencePatch(document, id, chapters) {
126
+ BoardIdSchema.parse(id);
127
+ if (chapters.some((chapter) => chapter.animation === id)) throw new Error("A sequence cannot overwrite one of its source chapters.");
128
+ const animation = boardSequence(document, chapters);
129
+ const tracks = { ...animation.tracks };
130
+ for (const key of Object.keys(document.animations[id]?.tracks ?? {})) if (!(key in tracks)) tracks[key] = null;
131
+ const patch = { animations: { [id]: {
132
+ ...animation,
133
+ tracks
134
+ } } };
135
+ const result = applyBoardPatchToDocument(document, patch);
136
+ if (!result.ok) throw new Error(result.diagnostics.map((entry) => `${entry.path}: ${entry.message}`).join("; "));
137
+ return patch;
138
+ }
139
+ function boardPathTrack(target, points, options) {
140
+ const { duration, at = 0, samples = 64, orient = false } = options;
141
+ if (points.length < 2 || points.length > 1e4 || points.some((p) => !Number.isFinite(p.x) || !Number.isFinite(p.y))) throw new Error("A path needs 2 to 10000 finite points.");
142
+ if (!Number.isFinite(duration) || duration <= 0 || !Number.isFinite(at) || at < 0) throw new Error("Path duration must be positive and start time non-negative.");
143
+ if (!Number.isInteger(samples) || samples < 2 || samples > 1e4) throw new Error("Path samples must be an integer from 2 to 10000.");
144
+ const segments = [];
145
+ let total = 0;
146
+ let previous = points[0];
147
+ for (const point of points.slice(1)) {
148
+ if (!previous) break;
149
+ const start = total;
150
+ total += Math.hypot(point.x - previous.x, point.y - previous.y);
151
+ segments.push({
152
+ a: previous,
153
+ b: point,
154
+ start,
155
+ end: total
156
+ });
157
+ previous = point;
158
+ }
159
+ const distances = [.../* @__PURE__ */ new Set([...segments.map((segment) => segment.end), ...Array.from({ length: samples }, (_, index) => total * index / (samples - 1))])].sort((a, b) => a - b);
160
+ let segmentIndex = 0;
161
+ return {
162
+ target,
163
+ property: "position",
164
+ composite: "replace",
165
+ interpolation: "auto",
166
+ orient,
167
+ keyframes: distances.map((distance) => {
168
+ const progress = total > 0 ? distance / total : 0;
169
+ while (segmentIndex < segments.length - 1 && (segments[segmentIndex]?.end ?? 0) < distance) segmentIndex++;
170
+ const segment = segments[segmentIndex];
171
+ if (!segment) throw new Error("Path has no segments.");
172
+ const { a, b, start, end } = segment;
173
+ const fraction = end > start ? (distance - start) / (end - start) : 0;
174
+ return {
175
+ at: at + duration * progress,
176
+ value: {
177
+ x: a.x + (b.x - a.x) * fraction,
178
+ y: a.y + (b.y - a.y) * fraction
179
+ }
180
+ };
181
+ })
182
+ };
183
+ }
184
+ //#endregion
185
+ export { boardPathTrack, boardSequence, boardSequencePatch };
@@ -1,8 +1,8 @@
1
1
  import { BoardDrawPoint } from "../../protocol/dist/board-model.js";
2
2
  import { drawPointsBounds, drawSampleRadius } from "../../protocol/dist/board-layout.js";
3
3
  import "../../protocol/dist/index.js";
4
- import { WorldPoint } from "../geometry.js";
5
- //#region src/board/core/draw-geometry.d.ts
4
+ import { WorldPoint } from "./geometry.js";
5
+ //#region src/board/model/draw-geometry.d.ts
6
6
  declare const sampleRadius: typeof drawSampleRadius;
7
7
  declare const computeDrawBounds: typeof drawPointsBounds;
8
8
  declare function simplifyDrawIndices(points: BoardDrawPoint[], tolerance: number): number[];
@@ -1,6 +1,6 @@
1
1
  import { drawPointsBounds, drawSampleRadius } from "../../protocol/dist/board-layout.js";
2
2
  import { getStroke } from "perfect-freehand";
3
- //#region src/board/core/draw-geometry.ts
3
+ //#region src/board/model/draw-geometry.ts
4
4
  const sampleRadius = drawSampleRadius;
5
5
  const computeDrawBounds = drawPointsBounds;
6
6
  function simplifyDrawIndices(points, tolerance) {
@@ -0,0 +1,14 @@
1
+ import { BoardDrawPoint } from "../../protocol/dist/board-model.js";
2
+ import "../../protocol/dist/index.js";
3
+ //#region src/board/model/draw-input.d.ts
4
+ type BoardDrawInputSample = {
5
+ world: {
6
+ x: number;
7
+ y: number;
8
+ };
9
+ pressure: number;
10
+ };
11
+ declare function quantizeDrawCoordinate(value: number): number;
12
+ declare function appendBoardDrawSamples(points: BoardDrawPoint[], samples: Iterable<BoardDrawInputSample>, zoom: number): boolean;
13
+ //#endregion
14
+ export { BoardDrawInputSample, appendBoardDrawSamples, quantizeDrawCoordinate };
@@ -0,0 +1,28 @@
1
+ //#region src/board/model/draw-input.ts
2
+ const COORDINATE_SCALE = 100;
3
+ const PRESSURE_SCALE = 100;
4
+ function quantizeDrawCoordinate(value) {
5
+ return Math.round(value * COORDINATE_SCALE) / COORDINATE_SCALE;
6
+ }
7
+ function quantizePressure(value) {
8
+ return Math.round(Math.min(1, Math.max(0, value)) * PRESSURE_SCALE) / PRESSURE_SCALE;
9
+ }
10
+ function appendBoardDrawSamples(points, samples, zoom) {
11
+ const minimum = .5 / Math.max(zoom, 1e-4);
12
+ let grew = false;
13
+ for (const sample of samples) {
14
+ const x = quantizeDrawCoordinate(sample.world.x);
15
+ const y = quantizeDrawCoordinate(sample.world.y);
16
+ const last = points.at(-1);
17
+ if (last && Math.hypot(x - last.x, y - last.y) < minimum) continue;
18
+ points.push({
19
+ x,
20
+ y,
21
+ p: quantizePressure(sample.pressure)
22
+ });
23
+ grew = true;
24
+ }
25
+ return grew;
26
+ }
27
+ //#endregion
28
+ export { appendBoardDrawSamples, quantizeDrawCoordinate };
@@ -1,5 +1,5 @@
1
1
  import { BoardSceneItem } from "./scene.js";
2
- //#region src/board/core/export-assets.d.ts
2
+ //#region src/board/model/export-assets.d.ts
3
3
  declare const BOARD_EXPORT_MAX_TEXTURES = 64;
4
4
  type BoardExportAssetSelection = {
5
5
  items: BoardSceneItem[];
@@ -1,4 +1,4 @@
1
- //#region src/board/core/export-assets.ts
1
+ //#region src/board/model/export-assets.ts
2
2
  const BOARD_EXPORT_MAX_TEXTURES = 64;
3
3
  function selectBoardExportAssets(items, assetKey, maxTextures = 64) {
4
4
  const limit = Number.isSafeInteger(maxTextures) ? Math.max(0, maxTextures) : 64;
@@ -1,8 +1,8 @@
1
1
  import { BoardDocument } from "../../protocol/dist/board-model.js";
2
2
  import "../../protocol/dist/index.js";
3
- import { Rect } from "../geometry.js";
3
+ import { Rect } from "./geometry.js";
4
4
  import { BoardScene, BoardSceneItem } from "./scene.js";
5
- //#region src/board/core/export-plan.d.ts
5
+ //#region src/board/model/export-plan.d.ts
6
6
  type BoardExportRegion = {
7
7
  kind: "all";
8
8
  } | {
@@ -1,8 +1,8 @@
1
1
  import { arrowBindings } from "../../protocol/dist/board-layout.js";
2
2
  import { parseBoardDocument } from "../../protocol/dist/board-patch.js";
3
- import { itemBounds, rectsIntersect, unionRects } from "../geometry.js";
3
+ import { itemBounds, rectsIntersect, unionRects } from "./geometry.js";
4
4
  import { arrowPathBounds, resolveSceneArrow } from "./arrow-geometry.js";
5
- //#region src/board/core/export-plan.ts
5
+ //#region src/board/model/export-plan.ts
6
6
  function normalizeBoardDocument(document) {
7
7
  const parsed = parseBoardDocument(document);
8
8
  if (!parsed.ok) throw new Error(`Invalid Board document: ${parsed.diagnostics.map((entry) => `${entry.path}: ${entry.message}`).join("; ")}`);
@@ -43,6 +43,7 @@ function resolveRegion(scene, region) {
43
43
  return boundsOf.get(item.id) ?? null;
44
44
  };
45
45
  const visible = (item, rect) => {
46
+ if (item.type === "effect" && item.props.kind === "trail" && item.props.follow) return true;
46
47
  const box = bounds(item);
47
48
  return box !== null && rectsIntersect(box, rect);
48
49
  };
@@ -1,5 +1,5 @@
1
1
  import { BoardFileSnapshotFacts, BuildSnapshotInput, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FileCategory, ResolvedCover, buildCodeExcerpt, buildFileExcerpt, buildFileSnapshot, fileBaseName, fileCategory, fileStem, readCoverFromFrontmatter, readFrontmatterScalars, readTitleFromFrontmatter, resolveCoverRef, resolveFileTitle, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter } from "./file-snapshot.js";
2
- //#region src/board/core/file-preview.d.ts
2
+ //#region src/board/model/file-preview.d.ts
3
3
  type FilePreviewKind = "cover" | "text" | "blank";
4
4
  /**
5
5
  * Which tier a card renders at. Derived rather than stored: presentation follows
@@ -1,5 +1,5 @@
1
1
  import { FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, buildCodeExcerpt, buildFileExcerpt, buildFileSnapshot, fileBaseName, fileCategory, fileStem, readCoverFromFrontmatter, readFrontmatterScalars, readTitleFromFrontmatter, resolveCoverRef, resolveFileTitle, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter } from "./file-snapshot.js";
2
- //#region src/board/core/file-preview.ts
2
+ //#region src/board/model/file-preview.ts
3
3
  /**
4
4
  * Which tier a card renders at. Derived rather than stored: presentation follows
5
5
  * from the facts present, so there is no second piece of state to fall out of
@@ -13,7 +13,7 @@ function filePreviewKind(snapshot) {
13
13
  }
14
14
  /** Short uppercase type label for a file card (`MD`, `JSON`, `FILE`). */
15
15
  function fileTypeLabel(path) {
16
- const name = path.split("/").filter(Boolean).pop() ?? path;
16
+ const name = fileBaseName(path);
17
17
  const dot = name.lastIndexOf(".");
18
18
  if (dot <= 0) return (name.replace(/^\./, "") || "file").toUpperCase();
19
19
  return name.slice(dot + 1).toUpperCase();
@@ -1,4 +1,4 @@
1
- //#region src/board/core/file-snapshot.d.ts
1
+ //#region src/board/model/file-snapshot.d.ts
2
2
  /**
3
3
  * File-card snapshot derivation — pure, renderer-agnostic, dependency-free.
4
4
  *
@@ -1,4 +1,5 @@
1
- //#region src/board/core/file-snapshot.ts
1
+ import { getMediaResourceTitle } from "./media.js";
2
+ //#region src/board/model/file-snapshot.ts
2
3
  /**
3
4
  * File-card snapshot derivation — pure, renderer-agnostic, dependency-free.
4
5
  *
@@ -134,7 +135,7 @@ const MEDIA_EXTENSIONS = /* @__PURE__ */ new Set([
134
135
  ]);
135
136
  const IMAGE_REF_RE = /\.(png|jpe?g|gif|webp|avif|svg|bmp|ico)(\?|#|$)/i;
136
137
  function extensionOf(path) {
137
- const name = path.split("/").filter(Boolean).pop() ?? path;
138
+ const name = fileBaseName(path);
138
139
  const dot = name.lastIndexOf(".");
139
140
  if (dot <= 0) return "";
140
141
  return name.slice(dot + 1).toLowerCase();
@@ -162,7 +163,7 @@ function fileCategory(path, mimeType) {
162
163
  }
163
164
  /** Basename of a path, used as a last-resort card title. */
164
165
  function fileBaseName(path) {
165
- return path.split("/").filter(Boolean).pop() ?? path;
166
+ return getMediaResourceTitle(path);
166
167
  }
167
168
  /** Basename with a trailing extension stripped. Dotfiles keep their full name. */
168
169
  function fileStem(path) {
@@ -1,6 +1,6 @@
1
- import { BoardFrame } from "../protocol/dist/board-layout.js";
2
- import "../protocol/dist/index.js";
3
- //#region src/board/geometry.d.ts
1
+ import { BoardFrame } from "../../protocol/dist/board-layout.js";
2
+ import "../../protocol/dist/index.js";
3
+ //#region src/board/model/geometry.d.ts
4
4
  type BoardViewport = {
5
5
  x: number;
6
6
  y: number;
@@ -1,4 +1,4 @@
1
- //#region src/board/geometry.ts
1
+ //#region src/board/model/geometry.ts
2
2
  function screenPoint(x, y) {
3
3
  return {
4
4
  x,
@@ -1,5 +1,5 @@
1
- import { BoardSceneItem } from "./core/scene.js";
2
- //#region src/board/image-key.d.ts
1
+ import { BoardSceneItem } from "./scene.js";
2
+ //#region src/board/model/image-key.d.ts
3
3
  declare function imageAssetKey(item: BoardSceneItem): string | null;
4
4
  declare function boardImageKeySource(key: string): {
5
5
  kind: "file" | "url";
@@ -1,11 +1,15 @@
1
+ import { parseBoardMediaSource } from "../../protocol/dist/board-model.js";
1
2
  import { featuredTaskArtifact, taskArtifactPreviewUrl } from "./task.js";
2
- //#region src/board/image-key.ts
3
+ //#region src/board/model/image-key.ts
3
4
  function imageAssetKey(item) {
4
- if (item.type === "image") return `file:${item.props.src}`;
5
+ if (item.type === "image") {
6
+ const source = parseBoardMediaSource(item.props.src);
7
+ return source ? `${source.kind}:${source.value}` : null;
8
+ }
5
9
  if (item.type === "file") {
6
10
  const snapshot = item.props.snapshot;
7
- if (snapshot?.coverPath) return `file:${snapshot.coverPath}`;
8
11
  if (snapshot?.coverUrl) return `url:${snapshot.coverUrl}`;
12
+ if (snapshot?.coverPath) return `file:${snapshot.coverPath}`;
9
13
  return null;
10
14
  }
11
15
  if (item.type === "task") {
@@ -0,0 +1,42 @@
1
+ import { BOARD_ANCHOR_SIDES, BOARD_ARROW_ROUTES, BOARD_CAMERA_TARGET, BOARD_COLOR_TOKENS, BOARD_DASHES, BOARD_DERIVED_SIZE_TYPES, BOARD_EFFECT_KINDS, BOARD_EFFECT_KIND_INFO, BOARD_ENTER_PRESETS, BOARD_EXTENSION_TYPE_PATTERN, BOARD_GRID_DEFAULT_SIZE, BOARD_GRID_MAX_SIZE, BOARD_GRID_MIN_SIZE, BOARD_ID_MAX_LENGTH, BOARD_ITEM_SCHEMAS, BOARD_ITEM_TYPES, BOARD_PLAY_MODES, BOARD_SHAPE_GEOMETRIES, BOARD_TASK_ARTIFACT_LIMIT, BOARD_TEXT_ALIGNS, BoardAnchorSide, BoardAnimation, BoardAnimationHeader, BoardAnimationHeaderSchema, BoardAnimationSchema, BoardArrowAnchor, BoardArrowAnchorSchema, BoardArrowBinding, BoardArrowBindingSchema, BoardArrowEnd, BoardArrowEndSchema, BoardArrowItem, BoardArrowItemSchema, BoardArrowRoute, BoardAudioItem, BoardAudioItemSchema, BoardBackgroundSchema, BoardBuiltinItem, BoardBuiltinItemType, BoardColor, BoardColorSchema, BoardColorToken, BoardCropSchema, BoardCustomItem, BoardCustomItemSchema, BoardDash, BoardDelta, BoardDiagnostic, BoardDocument, BoardDrawItem, BoardDrawItemSchema, BoardDrawPoint, BoardDrawPointSchema, BoardEaseSchema, BoardEffectItem, BoardEffectItemSchema, BoardEffectKind, BoardEnterPreset, BoardExtensionItem, BoardExtensionItemSchema, BoardFileBackedItem, BoardFileItem, BoardFileItemSchema, BoardFrameItem, BoardFrameItemSchema, BoardIdSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemType, BoardKeySchema, BoardKeyframe, BoardKeyframeSchema, BoardMarker, BoardMarkerSchema, BoardMediaSnapshot, BoardMediaSnapshotSchema, BoardMediaSource, BoardMediaSourceSchema, BoardPatch, BoardPatchSchema, BoardPlayMode, BoardScript, BoardScriptSchema, BoardSettings, BoardSettingsSchema, BoardShapeGeometry, BoardShapeItem, BoardShapeItemSchema, BoardSize, BoardSizeSchema, BoardStyle, BoardStyleSchema, BoardTaskArtifact, BoardTaskArtifactSchema, BoardTaskItem, BoardTaskItemSchema, BoardTaskSnapshot, BoardTaskSnapshotSchema, BoardTextItem, BoardTextItemSchema, BoardTrack, BoardTrackSchema, BoardVec2, BoardVec2Schema, BoardVideoItem, BoardVideoItemSchema, boardItemSchema, emptyBoardDocument, hasAuthoredSize, isBoardColorString, isBoardEase, isBuiltinItem, isBuiltinItemType, isEmptyBoardDelta, isFileBackedItem, isMediaItem, isSafeBoardSourcePath, parseBoardItem, parseBoardMediaSource } from "../../protocol/dist/board-model.js";
2
+ import { BoardFrame, BoardItemLookup, BoardLayout, BoardMatrix, BoardRect, BoardTextLayout, BoardTextMeasurer, IDENTITY_MATRIX, anchorPoint, applyMatrix, arrowBindings, autoAnchorSide, bendControl, clampBoardFontSize, createBoardLayout, createDocumentLayout, drawPointsBounds, drawSampleRadius, estimateTextWidth, framePoint, invertMatrix, isArrowBinding, layoutBoardText, multiplyMatrix, pointsRect, rotateAround, scaleVector, setBoardTextMeasurer, sideAnchor } from "../../protocol/dist/board-layout.js";
3
+ import { BoardApplyOptions, BoardPatchResult, BoardPropertySpec, BoardState, BoardValueKind, applyBoardDelta, applyBoardPatch, applyBoardPatchToDocument, boardPatchTouches, createDocumentState, diffBoardDocuments, diffMergePatch, isEmptyBoardPatch, listBoardProperties, mergePatch, parseBoardDocument, pruneBoardTrack, resolveBoardProperty, trackReferences } from "../../protocol/dist/board-patch.js";
4
+ import { isBoardPath, parseBoardManifest, serializeBoardManifest } from "../../protocol/dist/board.js";
5
+ import { BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, clampBoardStrokeSize } from "../../protocol/dist/board-constants.js";
6
+ import { BOARD_SCHEMA_TARGETS, boardJsonSchema, boardSchemaOverview } from "../../protocol/dist/board-schema.js";
7
+ import { isPublicBoardRemoteAddress, normalizeBoardRemoteUrl } from "../../protocol/dist/board-url.js";
8
+ import "../../protocol/dist/index.js";
9
+ import { BoardScriptContext, BoardScriptEvent, BoardScriptFrame, BoardScriptHit, BoardScriptItemPatch, BoardScriptModule, BoardScriptOutput, BoardScriptParameter, BoardScriptSnapshot } from "./script.js";
10
+ import { boardScriptItems, hasBoardScripts } from "./script-index.js";
11
+ import { BoardCameraFit, BoardCameraFocus, BoardCameraState, BoardNormalizedPoint, BoardScreenOffset, BoardScreenPoint, BoardViewport, BoardWorldOffset, BoardWorldPoint, BoardWorldRect, CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, CornerResizeHandle, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, Point, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, Rect, ResizeHandle, ScreenPoint, Size, VIEWPORT_MARGIN_RATIO, WorldPoint, angleFromCenter, cameraForFocus, cameraForRect, cameraForState, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, normalizedPoint, panBy, pointToWorld, pointsBounds, radToDeg, rectCenter, rectContainsPoint, rectForCameraFocus, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenOffset, screenPoint, screenToWorld, selectionBounds, stableCullRect, unionRects, visibleWorldRect, worldOffset, worldPoint, worldRect, worldToScreen, zoomAround } from "./geometry.js";
12
+ import { BoardScene, BoardSceneItem, SceneItem, buildBoardScene, orderBoardItems, placeItem, refreshBoardScene, sceneItemToItem, sceneItemsToRecord, toSceneItem } from "./scene.js";
13
+ import { boardScriptTarget } from "./script-hit.js";
14
+ import { BOARD_SCRIPT_DRAWING_EXAMPLE } from "./script-example.js";
15
+ import { boardScriptScope, composeBoardScriptItems, prepareBoardScriptOutput, scriptTemporaryPrefix, validateBoardScriptCommit, validateBoardScriptOutput } from "./script-scene.js";
16
+ import { BoardCameraOverride, BoardColorResolver, BoardEaseFunction, BoardEvaluateOptions, BoardEvaluation, CompiledAnimation, CompiledBoardAnimations, CompiledTrack, applyBoardEvaluation, boardAnimationTime, boardDocumentAt, boardEase, compileBoardAnimations, evaluateBoardAnimations, parseHexColor, sampleBoardTrack } from "./animation.js";
17
+ import { BoardAnimationSampler, createBoardAnimationSampler, resolveBoardAnimationCamera } from "./sampling.js";
18
+ import { BoardChapter, boardPathTrack, boardSequence, boardSequencePatch } from "./authoring.js";
19
+ import { BOARD_PRESET_NAMES, BoardNestedAnimationOptions, BoardPresetName, BoardPresetOptions, boardNestedAnimation, boardNestedAnimationTrack, boardPresetTracks, isBoardPresetName, listBoardPresets } from "./presets.js";
20
+ import { ARROW_BINDING_GAP, ArrowFrameLookup, ResolvedArrow, ResolvedArrowEnd, arrowHitRadius, arrowPathBounds, distanceToArrow, pathMidpoint, pathPointAt, resolveAnchor, resolveArrow, resolveSceneArrow } from "./arrow-geometry.js";
21
+ import { StrokeRibbonBuilder, StrokeRibbonGeometry, StrokeRibbonMesh, buildStrokeOutline, buildStrokeRibbonGeometry, computeDrawBounds, createStrokeRibbonBuilder, distanceToStroke, isStrokeCorner, sampleRadius, simplifyDrawIndices, trimDrawPoints } from "./draw-geometry.js";
22
+ import { BoardDrawInputSample, appendBoardDrawSamples, quantizeDrawCoordinate } from "./draw-input.js";
23
+ import { BOARD_EXPORT_MAX_TEXTURES, BoardExportAssetSelection, selectBoardExportAssets } from "./export-assets.js";
24
+ import { BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, BoardExportPlan, BoardExportPlanInput, BoardExportRegion, exportItemBounds, normalizeBoardDocument, planBoardExport } from "./export-plan.js";
25
+ import { BoardFileSnapshotFacts, BuildSnapshotInput, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FileCategory, ResolvedCover, buildCodeExcerpt, buildFileExcerpt, buildFileSnapshot, fileBaseName, fileCategory, fileStem, readCoverFromFrontmatter, readFrontmatterScalars, readTitleFromFrontmatter, resolveCoverRef, resolveFileTitle, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter } from "./file-snapshot.js";
26
+ import { FileAvailability, FilePreviewKind, availabilityFromError, fileCategoryAccent, fileMetaLine, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot } from "./file-preview.js";
27
+ import { BOARD_COLORS, BoardColorEntry, BoardColorId, BoardColorValue, BoardShapeColors, DEFAULT_BOARD_COLOR, boardColorCssVar, buildFallbackShapeColors, isBoardColorId, pickBoardColor, resolveBoardColor, resolveItemColor } from "./palette.js";
28
+ import { SHAPE_KINDS, ShapeKind, isShapeKind } from "./shape-types.js";
29
+ import { TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, boardFontFamily } from "./text-metrics.js";
30
+ import { BoardStyledToolId, BoardToolStyleMap, BoardToolStylePatch, DEFAULT_BOARD_TOOL_STYLES, createBoardToolStyles } from "./tool-styles.js";
31
+ import { boardImageKeySource, imageAssetKey } from "./image-key.js";
32
+ import { BoardItemCapabilities, BoardItemDefinition, BoardItemOf, BoardItemResizeMode, FULL_CAPABILITIES, defineBoardItem } from "./items/definition.js";
33
+ import { builtinBoardItems } from "./items/builtin.js";
34
+ import { BoardAppMetadata, BoardItemEntry, BoardMediaItemKind, createAppBoardItem, createArrowBoardItem, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTextBoardItem, mediaFrameSize, titleForBoardItem } from "./items/create.js";
35
+ import { createBoardEntityId, createBoardItemId } from "./items/id.js";
36
+ import { BoardItemInput, BoardRegistry, createBoardRegistry, defaultBoardRegistry } from "./items/registry.js";
37
+ import "./items/index.js";
38
+ import { BoardMediaKind, getMediaExtension, getMediaResourceTitle, inferBoardMediaKind } from "./media.js";
39
+ import { BoardAssetSource, BoardPlayableMedia, playableBoardMedia, playableBoardMediaList, resetBoardPlaybackUrlCache, resolveBoardMediaUrl } from "./media-playback.js";
40
+ import { BoardReplayActorKind, BoardReplayEntry, BoardReplayPlayer, boardReplayActorKind, createBoardReplayPlayer } from "./replay.js";
41
+ import { featuredTaskArtifact, rankedTaskArtifacts, taskArtifactPreviewUrl, taskArtifacts, taskRunToBoardTaskSnapshot } from "./task.js";
42
+ export { ARROW_BINDING_GAP, ArrowFrameLookup, BOARD_ANCHOR_SIDES, BOARD_ARROW_ROUTES, BOARD_CAMERA_TARGET, BOARD_COLORS, BOARD_COLOR_TOKENS, BOARD_DASHES, BOARD_DERIVED_SIZE_TYPES, BOARD_EFFECT_KINDS, BOARD_EFFECT_KIND_INFO, BOARD_ENTER_PRESETS, BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, BOARD_EXPORT_MAX_TEXTURES, BOARD_EXTENSION_TYPE_PATTERN, BOARD_GRID_DEFAULT_SIZE, BOARD_GRID_MAX_SIZE, BOARD_GRID_MIN_SIZE, BOARD_ID_MAX_LENGTH, BOARD_ITEM_SCHEMAS, BOARD_ITEM_TYPES, BOARD_PLAY_MODES, BOARD_PRESET_NAMES, BOARD_SCHEMA_TARGETS, BOARD_SCRIPT_DRAWING_EXAMPLE, BOARD_SHAPE_GEOMETRIES, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BOARD_TASK_ARTIFACT_LIMIT, BOARD_TEXT_ALIGNS, BoardAnchorSide, BoardAnimation, BoardAnimationHeader, BoardAnimationHeaderSchema, BoardAnimationSampler, BoardAnimationSchema, BoardAppMetadata, BoardApplyOptions, BoardArrowAnchor, BoardArrowAnchorSchema, BoardArrowBinding, BoardArrowBindingSchema, BoardArrowEnd, BoardArrowEndSchema, BoardArrowItem, BoardArrowItemSchema, BoardArrowRoute, BoardAssetSource, BoardAudioItem, BoardAudioItemSchema, BoardBackgroundSchema, BoardBuiltinItem, BoardBuiltinItemType, BoardCameraFit, BoardCameraFocus, BoardCameraOverride, BoardCameraState, BoardChapter, BoardColor, BoardColorEntry, BoardColorId, BoardColorResolver, BoardColorSchema, BoardColorToken, BoardColorValue, BoardCropSchema, BoardCustomItem, BoardCustomItemSchema, BoardDash, BoardDelta, BoardDiagnostic, BoardDocument, BoardDrawInputSample, BoardDrawItem, BoardDrawItemSchema, BoardDrawPoint, BoardDrawPointSchema, BoardEaseFunction, BoardEaseSchema, BoardEffectItem, BoardEffectItemSchema, BoardEffectKind, BoardEnterPreset, BoardEvaluateOptions, BoardEvaluation, BoardExportAssetSelection, BoardExportPlan, BoardExportPlanInput, BoardExportRegion, BoardExtensionItem, BoardExtensionItemSchema, BoardFileBackedItem, BoardFileItem, BoardFileItemSchema, type BoardFileSnapshotFacts, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardIdSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemCapabilities, BoardItemDefinition, BoardItemEntry, BoardItemInput, BoardItemLookup, BoardItemOf, BoardItemResizeMode, BoardItemType, BoardKeySchema, BoardKeyframe, BoardKeyframeSchema, BoardLayout, BoardMarker, BoardMarkerSchema, BoardMatrix, BoardMediaItemKind, BoardMediaKind, BoardMediaSnapshot, BoardMediaSnapshotSchema, BoardMediaSource, BoardMediaSourceSchema, BoardNestedAnimationOptions, BoardNormalizedPoint, BoardPatch, BoardPatchResult, BoardPatchSchema, BoardPlayMode, BoardPlayableMedia, BoardPresetName, BoardPresetOptions, BoardPropertySpec, BoardRect, BoardRegistry, BoardReplayActorKind, BoardReplayEntry, BoardReplayPlayer, BoardScene, BoardSceneItem, BoardScreenOffset, BoardScreenPoint, BoardScript, BoardScriptContext, BoardScriptEvent, BoardScriptFrame, BoardScriptHit, BoardScriptItemPatch, BoardScriptModule, BoardScriptOutput, BoardScriptParameter, BoardScriptSchema, BoardScriptSnapshot, BoardSettings, BoardSettingsSchema, BoardShapeColors, BoardShapeGeometry, BoardShapeItem, BoardShapeItemSchema, BoardSize, BoardSizeSchema, BoardState, BoardStyle, BoardStyleSchema, BoardStyledToolId, BoardTaskArtifact, BoardTaskArtifactSchema, BoardTaskItem, BoardTaskItemSchema, BoardTaskSnapshot, BoardTaskSnapshotSchema, BoardTextItem, BoardTextItemSchema, BoardTextLayout, BoardTextMeasurer, BoardToolStyleMap, BoardToolStylePatch, BoardTrack, BoardTrackSchema, BoardValueKind, BoardVec2, BoardVec2Schema, BoardVideoItem, BoardVideoItemSchema, BoardViewport, BoardWorldOffset, BoardWorldPoint, BoardWorldRect, type BuildSnapshotInput, CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, CompiledAnimation, CompiledBoardAnimations, CompiledTrack, CornerResizeHandle, DEFAULT_BOARD_COLOR, DEFAULT_BOARD_TOOL_STYLES, EDGE_RESIZE_HANDLES, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FIT_PADDING, FULL_CAPABILITIES, FileAvailability, type FileCategory, FilePreviewKind, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, IDENTITY_MATRIX, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, Point, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, Rect, ResizeHandle, ResolvedArrow, ResolvedArrowEnd, type ResolvedCover, SHAPE_KINDS, SceneItem, ScreenPoint, ShapeKind, Size, StrokeRibbonBuilder, StrokeRibbonGeometry, StrokeRibbonMesh, TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, VIEWPORT_MARGIN_RATIO, WorldPoint, anchorPoint, angleFromCenter, appendBoardDrawSamples, applyBoardDelta, applyBoardEvaluation, applyBoardPatch, applyBoardPatchToDocument, applyMatrix, arrowBindings, arrowHitRadius, arrowPathBounds, autoAnchorSide, availabilityFromError, bendControl, boardAnimationTime, boardColorCssVar, boardDocumentAt, boardEase, boardFontFamily, boardImageKeySource, boardItemSchema, boardJsonSchema, boardNestedAnimation, boardNestedAnimationTrack, boardPatchTouches, boardPathTrack, boardPresetTracks, boardReplayActorKind, boardSchemaOverview, boardScriptItems, boardScriptScope, boardScriptTarget, boardSequence, boardSequencePatch, buildBoardScene, buildCodeExcerpt, buildFallbackShapeColors, buildFileExcerpt, buildFileSnapshot, buildStrokeOutline, buildStrokeRibbonGeometry, builtinBoardItems, cameraForFocus, cameraForRect, cameraForState, clamp, clampBoardFontSize, clampBoardStrokeSize, clampBoardFontSize as clampBoardTextFontSize, clampZoom, compileBoardAnimations, composeBoardScriptItems, computeDrawBounds, createAppBoardItem, createArrowBoardItem, createBoardAnimationSampler, createBoardEntityId, createBoardItemId, createBoardLayout, createBoardRegistry, createBoardReplayPlayer, createBoardToolStyles, createDocumentLayout, createDocumentState, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createStrokeRibbonBuilder, createTaskBoardItem, createTextBoardItem, defaultBoardRegistry, defineBoardItem, degToRad, diffBoardDocuments, diffMergePatch, distanceToArrow, distanceToStroke, drawPointsBounds, drawSampleRadius, emptyBoardDocument, estimateTextWidth, evaluateBoardAnimations, expandRect, exportItemBounds, featuredTaskArtifact, fileBaseName, fileCategory, fileCategoryAccent, fileMetaLine, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileStem, fileTypeLabel, fitToContent, formatFileSize, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, framePoint, frameRayIntersection, frameRect, getMediaExtension, getMediaResourceTitle, handlePosition, hasAuthoredSize, hasBoardScripts, imageAssetKey, inferBoardMediaKind, invertMatrix, isArrowBinding, isBoardColorId, isBoardColorString, isBoardEase, isBoardPath, isBoardPresetName, isBuiltinItem, isBuiltinItemType, isEmptyBoardDelta, isEmptyBoardPatch, isFileBackedItem, isFileSnapshotFresh, isMediaItem, isPublicBoardRemoteAddress, isSafeBoardSourcePath, isShapeKind, isStrokeCorner, itemBounds, layoutBoardText, listBoardPresets, listBoardProperties, mediaFrameSize, mergeFileSnapshot, mergePatch, multiplyMatrix, normalizeBoardDocument, normalizeBoardRemoteUrl, normalizeRotation, normalizeViewport, normalizedPoint, orderBoardItems, panBy, parseBoardDocument, parseBoardItem, parseBoardManifest, parseBoardMediaSource, parseHexColor, pathMidpoint, pathPointAt, pickBoardColor, placeItem, planBoardExport, playableBoardMedia, playableBoardMediaList, pointToWorld, pointsBounds, pointsRect, prepareBoardScriptOutput, pruneBoardTrack, quantizeDrawCoordinate, radToDeg, rankedTaskArtifacts, readCoverFromFrontmatter, readFrontmatterScalars, readTitleFromFrontmatter, rectCenter, rectContainsPoint, rectForCameraFocus, rectsIntersect, refreshBoardScene, resetBoardPlaybackUrlCache, resizeFrame, resizeFrameToSize, resolveAnchor, resolveArrow, resolveBoardAnimationCamera, resolveBoardColor, resolveBoardMediaUrl, resolveBoardProperty, resolveCoverRef, resolveFileTitle, resolveItemColor, resolveSceneArrow, resolveSpacePath, rotateAround, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, sampleBoardTrack, sampleRadius, scaleFrames, scaleVector, sceneItemToItem, sceneItemsToRecord, screenOffset, screenPoint, screenToWorld, scriptTemporaryPrefix, selectBoardExportAssets, selectionBounds, serializeBoardManifest, setBoardTextMeasurer, shouldFetchFileExcerpt, sideAnchor, simplifyDrawIndices, splitFrontmatter, stableCullRect, taskArtifactPreviewUrl, taskArtifacts, taskRunToBoardTaskSnapshot, titleForBoardItem, toSceneItem, trackReferences, trimDrawPoints, unionRects, validateBoardScriptCommit, validateBoardScriptOutput, visibleWorldRect, worldOffset, worldPoint, worldRect, worldToScreen, zoomAround };