@neta-art/cohub 12.3.0 → 12.5.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 (43) hide show
  1. package/README.md +14 -4
  2. package/dist/board/editor/clipboard.js +1 -1
  3. package/dist/board/editor/context.d.ts +2 -0
  4. package/dist/board/editor/creation.js +1 -1
  5. package/dist/board/editor/editor.js +8 -3
  6. package/dist/board/editor/interaction.js +6 -1
  7. package/dist/board/editor/selection.js +14 -2
  8. package/dist/board/export/index.js +1 -1
  9. package/dist/board/export/node/scripts.js +1 -1
  10. package/dist/board/export/scene.js +1 -1
  11. package/dist/board/model/asset-key.d.ts +3 -3
  12. package/dist/board/model/asset-key.js +22 -14
  13. package/dist/board/model/index.js +16 -16
  14. package/dist/board/model/items/create.js +1 -1
  15. package/dist/board/model/sampling.js +1 -1
  16. package/dist/board/model/themes.d.ts +34 -34
  17. package/dist/board/model/themes.js +34 -34
  18. package/dist/board/render/media-interaction.js +1 -1
  19. package/dist/board/render/renderers/arrow-card-renderer.js +1 -1
  20. package/dist/board/render/renderers/audio-card-renderer.js +1 -1
  21. package/dist/board/render/renderers/draw-card-renderer.js +1 -1
  22. package/dist/board/render/renderers/file-card-renderer.js +2 -2
  23. package/dist/board/render/renderers/frame-card-renderer.js +1 -1
  24. package/dist/board/render/renderers/model-card-renderer.js +3 -3
  25. package/dist/board/render/renderers/shape-card-renderer.js +1 -1
  26. package/dist/board/render/renderers/video-card-renderer.js +1 -1
  27. package/dist/board/render/script-export.js +1 -1
  28. package/dist/board/render/script-host.js +3 -3
  29. package/dist/board/replica/index.js +12 -10
  30. package/dist/board/stage/assets.js +1 -1
  31. package/dist/board/stage/stage.d.ts +4 -0
  32. package/dist/board/stage/stage.js +11 -10
  33. package/dist/board/stage/views.d.ts +1 -1
  34. package/dist/board/stage/views.js +2 -2
  35. package/dist/chunks/environment.d.ts +80 -2
  36. package/dist/chunks/http.d.ts +17 -2
  37. package/dist/chunks/http.js +24 -0
  38. package/dist/chunks/websocket.d.ts +1 -1
  39. package/dist/http.d.ts +1 -1
  40. package/dist/index.d.ts +2 -2
  41. package/dist/index.js +28 -1
  42. package/dist/protocol/dist/board-patch.js +1 -1
  43. package/package.json +1 -1
package/README.md CHANGED
@@ -244,7 +244,10 @@ detail and text work reaches your Board without code changes.
244
244
  Pictures your own items show go through `itemAsset`. They share the built-in
245
245
  loader: CDN variants sized to the screen, loads ordered by where the view is
246
246
  heading, prefetch, compact copies when panned away, device budgets, one cache
247
- and exports. Call `invalidateItemAssets()` when the data it reads changes:
247
+ and exports. `src` is a Space path, resolved like an image item's, or a URL;
248
+ `fit: "cover"` sizes pictures cropped to fill their box by the short edge. Call
249
+ `invalidateItemAssets()` when the data it reads changes, and `invalidatePath`
250
+ when a file changes:
248
251
 
249
252
  ```ts
250
253
  const assets = createBoardAssetManager({
@@ -252,8 +255,8 @@ const assets = createBoardAssetManager({
252
255
  // undefined keeps the built-in rule; null shows no picture.
253
256
  itemAsset: (item) => {
254
257
  if (item.type !== "acme.order") return undefined;
255
- const cover = covers.get(item.props.orderId as string);
256
- return cover ? { url: cover, fit: "cover" } : null;
258
+ const cover = covers.get(item.props.orderId as string); // "orders/o-1.webp"
259
+ return cover ? { src: cover, fit: "cover" } : null;
257
260
  },
258
261
  });
259
262
  ```
@@ -276,7 +279,14 @@ const assets = createBoardAssetManager({
276
279
  - **Card keys.** A renderer's `hitAt(item, point, context)` returns `{ action, cursor? }`
277
280
  for keys it draws; the stage shows the cursor, passes the hovered key to renderers as
278
281
  `context.hoveredHit` and sends presses to `onHit` (return `false` to let the editor
279
- have them). Media cards report `BOARD_PLAY_MEDIA` this way.
282
+ have them). Media cards report `BOARD_PLAY_MEDIA` this way. `handlesHit(item, action)`
283
+ names the keys you act on; the rest show no cursor and go to the editor.
284
+ - **Touch.** A touch on the selected item drags it, never a port. Pass
285
+ `touchRotation: false` to `createBoardEditor` to move and resize by touch and pen
286
+ without a rotation handle.
287
+ - **DOM views.** `viewLayer: "below"` puts them under the canvas, so selection and
288
+ strokes draw over them; views there get no input. Use a theme with `imageBackground`
289
+ and paint the Board background behind the host, or the canvas covers them.
280
290
  - **Previews.** Write `preview: { title, excerpt, cover, src }` on your items so
281
291
  clients without your renderer, exports and agents show them as cards. Keep it out
282
292
  of undo with `editor.commitPatch(patch, { record: false })`.
@@ -1,6 +1,6 @@
1
1
  import { parseBoardItem } from "../../protocol/dist/board-model.js";
2
- import { BOARD_CLIPBOARD_KIND, BOARD_CLIPBOARD_MIME } from "../../protocol/dist/board.js";
3
2
  import { arrowBindings, isArrowBinding } from "../../protocol/dist/board-layout.js";
3
+ import { BOARD_CLIPBOARD_KIND, BOARD_CLIPBOARD_MIME } from "../../protocol/dist/board.js";
4
4
  import { createBoardItemId } from "../model/items/id.js";
5
5
  //#region src/board/editor/clipboard.ts
6
6
  /** How far a duplicate or repeated paste lands from its source. */
@@ -84,6 +84,8 @@ type BoardEditorOptions = {
84
84
  initialTool?: BoardToolId;
85
85
  key?: string;
86
86
  readonly?: boolean;
87
+ /** false: touch and pen move and resize the selection but never rotate it. */
88
+ touchRotation?: boolean;
87
89
  preferences?: Partial<BoardEditorPreferences>;
88
90
  onPreferencesChange?: (preferences: BoardEditorPreferences) => void;
89
91
  onCommit: (patch: BoardPatch) => void | Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import { IDENTITY_MATRIX, applyMatrix, invertMatrix } from "../../protocol/dist/board-layout.js";
2
- import { buildBoardScene } from "../model/scene.js";
3
2
  import { rectCenter } from "../model/geometry.js";
3
+ import { buildBoardScene } from "../model/scene.js";
4
4
  import { isShapeKind } from "../model/shape-types.js";
5
5
  import { createBoardItemId } from "../model/items/id.js";
6
6
  import { createAppBoardItem, createArrowBoardItem, createDrawBoardItem, createFileNodeForPath, createFrameBoardItem, createMediaBoardItem, createShapeBoardItem, createTaskBoardItem, createTextBoardItem } from "../model/items/create.js";
@@ -1,8 +1,8 @@
1
1
  import { clampBoardStrokeSize } from "../../protocol/dist/board-constants.js";
2
- import { buildBoardScene } from "../model/scene.js";
2
+ import { hasBoardScripts } from "../model/script-index.js";
3
3
  import { normalizeViewport } from "../model/geometry.js";
4
+ import { buildBoardScene } from "../model/scene.js";
4
5
  import { isBoardColorId } from "../model/palette.js";
5
- import { hasBoardScripts } from "../model/script-index.js";
6
6
  import { isShapeKind } from "../model/shape-types.js";
7
7
  import { createBoardToolStyles } from "../model/tool-styles.js";
8
8
  import { titleForBoardItem } from "../model/items/create.js";
@@ -96,6 +96,11 @@ function createBoardEditor(options) {
96
96
  ctx.snapshots = createSnapshotsModule(ctx);
97
97
  ctx.remote = createRemoteModule(ctx);
98
98
  const { document, query, camera, selection, creation, deletion, copy, interaction, animation, snapshots, remote } = ctx;
99
+ const transformChannels = options.touchRotation === false ? [
100
+ "scene",
101
+ "selection",
102
+ "hover"
103
+ ] : ["scene", "selection"];
99
104
  let viewStateQueued = false;
100
105
  function emitViewState() {
101
106
  viewStateQueued = false;
@@ -193,7 +198,7 @@ function createBoardEditor(options) {
193
198
  return read(["scene", "selection"], selection.bounds);
194
199
  },
195
200
  get selectionTransform() {
196
- return read(["scene", "selection"], selection.transform);
201
+ return read(transformChannels, selection.transform);
197
202
  },
198
203
  get camera() {
199
204
  return read("camera", () => state.camera);
@@ -170,6 +170,11 @@ function createInteractionModule(ctx) {
170
170
  size: arrow.size
171
171
  };
172
172
  }
173
+ function onSelectedItem(event) {
174
+ if (!canTapSelectWithHand(event.pointerType)) return false;
175
+ const item = ctx.query.itemAt(event.world);
176
+ return item !== null && state.selection.includes(item.id);
177
+ }
173
178
  function plainPrimary(event) {
174
179
  return event.button === 0 && !event.shiftKey && !event.metaKey && !event.ctrlKey && !event.altKey;
175
180
  }
@@ -296,7 +301,7 @@ function createInteractionModule(ctx) {
296
301
  ctx.creation.beginTextDraft(event.world);
297
302
  return;
298
303
  }
299
- const port = connectionPortAt$1(event.world, event.pointerType);
304
+ const port = onSelectedItem(event) ? null : connectionPortAt$1(event.world, event.pointerType);
300
305
  if (port) {
301
306
  state.interaction = arrowGesture(port.point, event.world, port.itemId, port.side);
302
307
  return;
@@ -1,6 +1,7 @@
1
- import { sceneItemToItem } from "../model/scene.js";
2
1
  import { selectionBounds } from "../model/geometry.js";
2
+ import { sceneItemToItem } from "../model/scene.js";
3
3
  import { alignFrames, distributeFrames } from "./align.js";
4
+ import { canTapSelectWithHand } from "./tool.js";
4
5
  import { resolveSelectionTransform } from "./selection-transform.js";
5
6
  import { memo } from "./state.js";
6
7
  //#region src/board/editor/selection.ts
@@ -17,7 +18,18 @@ function createSelectionModule(ctx) {
17
18
  return result;
18
19
  });
19
20
  const bounds = memo(() => [items()], (selected) => selectionBounds(selected.map((item) => item.frame)));
20
- const transform = memo(() => [items(), bounds()], (selected, rect) => resolveSelectionTransform(registry, selected, rect));
21
+ const rotatesOnTouch = ctx.options.touchRotation !== false;
22
+ const transform = memo(() => [
23
+ items(),
24
+ bounds(),
25
+ rotatesOnTouch || !canTapSelectWithHand(state.hoverPointerType)
26
+ ], (selected, rect, rotates) => {
27
+ const resolved = resolveSelectionTransform(registry, selected, rect);
28
+ return resolved && !rotates ? {
29
+ ...resolved,
30
+ canRotate: false
31
+ } : resolved;
32
+ });
21
33
  function set(ids) {
22
34
  state.selection = ids.filter((id) => Boolean(state.base.items[id]));
23
35
  }
@@ -1,9 +1,9 @@
1
1
  import { buildBoardScene } from "../model/scene.js";
2
2
  import { resolveBoardAnimationCamera } from "../model/sampling.js";
3
+ import { normalizeBoardDocument, planBoardExport } from "../model/export-plan.js";
3
4
  import { parseBoardCssColor } from "../render/css-color.js";
4
5
  import { defaultBoardPalette } from "../render/palette.js";
5
6
  import { createBoardRenderSampler } from "../render/sampling.js";
6
- import { normalizeBoardDocument, planBoardExport } from "../model/export-plan.js";
7
7
  import { ensureBoardTextMeasurement } from "../render/text-measurement.js";
8
8
  import { createBoardExportScene } from "./scene.js";
9
9
  import { Rectangle, RendererType } from "pixi.js";
@@ -1,5 +1,5 @@
1
- import { buildBoardScene } from "../../model/scene.js";
2
1
  import { boardScriptScope, composeBoardScriptItems } from "../../model/script-scene.js";
2
+ import { buildBoardScene } from "../../model/scene.js";
3
3
  import { createBoardScriptModuleReader, loadBoardScriptSources } from "../../../protocol/dist/board-script-modules.js";
4
4
  import { createScriptRuntime } from "../../render/script-runtime.js";
5
5
  import { initializeBoardFonts } from "./fonts.js";
@@ -1,9 +1,9 @@
1
+ import { boardAssetKey } from "../model/asset-key.js";
1
2
  import { buildFallbackShapeColors } from "../model/palette.js";
2
3
  import { defaultBoardPalette } from "../render/palette.js";
3
4
  import { clippingAncestor, isClippingFrame, syncClipGroup } from "../render/clip.js";
4
5
  import { DEFAULT_BOARD_RENDER_LABELS, getBoardCardRenderer } from "../render/renderers/board-renderer-registry.js";
5
6
  import { resolveBoardRenderStyle } from "../render/style.js";
6
- import { boardAssetKey } from "../model/asset-key.js";
7
7
  import { Container, Graphics, Sprite, TilingSprite } from "pixi.js";
8
8
  //#region src/board/export/scene.ts
9
9
  function buildContext(input) {
@@ -7,13 +7,13 @@ type BoardAssetKeySource = {
7
7
  value: string;
8
8
  fit?: "cover";
9
9
  };
10
- /** `fit` applies to images: `cover` bounds the short edge instead of the long one. */
10
+ /** `src` is a Space file path or a URL; `fit: "cover"` sizes an image by its short edge. */
11
11
  type BoardAssetRef = {
12
- url: string;
12
+ src: string;
13
13
  media?: "image" | "video";
14
14
  fit?: "contain" | "cover";
15
15
  };
16
- declare function boardAssetRefKey({ url, media, fit }: BoardAssetRef): string;
16
+ declare function boardAssetRefKey({ src, media, fit }: BoardAssetRef): string | null;
17
17
  declare function imageAssetKey(item: BoardSceneItem): string | null;
18
18
  declare function boardAssetKey(item: BoardSceneItem): string | null;
19
19
  declare function boardAssetKeySource(key: string): BoardAssetKeySource | null;
@@ -1,11 +1,18 @@
1
1
  import { mediaVariantSize, videoFrameUrl } from "../../media.js";
2
- import { boardItemPreview, parseBoardMediaSource } from "../../protocol/dist/board-model.js";
2
+ import { boardItemPreview, isSafeBoardSourcePath, parseBoardMediaSource } from "../../protocol/dist/board-model.js";
3
3
  import { featuredTaskArtifact, taskArtifactPreviewUrl } from "../../protocol/dist/board-task.js";
4
4
  import { isBoardModelItem } from "./media.js";
5
5
  //#region src/board/model/asset-key.ts
6
- function boardAssetRefKey({ url, media = "image", fit }) {
7
- if (media === "video") return `video-url:${encodeURIComponent(url)}`;
8
- return fit === "cover" ? `cover-url:${url}` : `url:${url}`;
6
+ const COVER = "cover:";
7
+ function boardAssetRefKey({ src, media = "image", fit }) {
8
+ if (!src) return null;
9
+ const source = {
10
+ kind: isSafeBoardSourcePath(src) ? "file" : "url",
11
+ value: src
12
+ };
13
+ if (media === "video") return stillKey("video", source, void 0);
14
+ const key = `${source.kind}:${source.value}`;
15
+ return fit === "cover" ? COVER + key : key;
9
16
  }
10
17
  function imageAssetKey(item) {
11
18
  if (item.type === "image") {
@@ -27,8 +34,7 @@ function imageAssetKey(item) {
27
34
  return source ? `${source.kind}:${source.value}` : null;
28
35
  }
29
36
  const STILL_MEDIA = ["video", "model"];
30
- function stillKey(media, src, mtimeMs) {
31
- const source = parseBoardMediaSource(src);
37
+ function stillKey(media, source, mtimeMs) {
32
38
  if (!source) return null;
33
39
  return source.kind === "url" ? `${media}-url:${encodeURIComponent(source.value)}` : `${media}:${encodeURIComponent(source.value)}:${mtimeMs ?? "unknown"}`;
34
40
  }
@@ -42,8 +48,8 @@ function taskPreviewKey(item) {
42
48
  }
43
49
  function boardAssetKey(item) {
44
50
  if (item.type === "task") return taskPreviewKey(item);
45
- if (item.type === "video") return stillKey("video", item.props.src, item.props.snapshot?.mtimeMs);
46
- if (item.type === "file" && isBoardModelItem(item)) return stillKey("model", item.props.src, item.props.snapshot?.mtimeMs);
51
+ if (item.type === "video") return stillKey("video", parseBoardMediaSource(item.props.src), item.props.snapshot?.mtimeMs);
52
+ if (item.type === "file" && isBoardModelItem(item)) return stillKey("model", parseBoardMediaSource(item.props.src), item.props.snapshot?.mtimeMs);
47
53
  return imageAssetKey(item);
48
54
  }
49
55
  function boardAssetKeySource(key) {
@@ -53,6 +59,14 @@ function boardAssetKeySource(key) {
53
59
  if (separator < 0) return null;
54
60
  base = key.slice(separator + 1);
55
61
  }
62
+ if (!base.startsWith(COVER)) return sourceOf(base);
63
+ const source = sourceOf(base.slice(6));
64
+ return source?.media === "image" ? {
65
+ ...source,
66
+ fit: "cover"
67
+ } : null;
68
+ }
69
+ function sourceOf(base) {
56
70
  try {
57
71
  for (const media of STILL_MEDIA) {
58
72
  if (base.startsWith(`${media}-url:`)) return {
@@ -82,12 +96,6 @@ function boardAssetKeySource(key) {
82
96
  media: "image",
83
97
  value: base.slice(4)
84
98
  };
85
- if (base.startsWith("cover-url:")) return {
86
- kind: "url",
87
- media: "image",
88
- value: base.slice(10),
89
- fit: "cover"
90
- };
91
99
  return null;
92
100
  }
93
101
  function boardTexturePixels(item, scale) {
@@ -1,36 +1,36 @@
1
1
  import { BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, clampBoardStrokeSize } from "../../protocol/dist/board-constants.js";
2
2
  import { isPublicBoardRemoteAddress, normalizeBoardRemoteUrl } from "../../protocol/dist/board-url.js";
3
3
  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, BoardAnimationHeaderSchema, BoardAnimationSchema, BoardArrowAnchorSchema, BoardArrowBindingSchema, BoardArrowEndSchema, BoardArrowItemSchema, BoardAudioItemSchema, BoardBackgroundSchema, BoardColorSchema, BoardCropSchema, BoardCustomItemSchema, BoardDrawItemSchema, BoardDrawPointSchema, BoardEaseSchema, BoardEffectItemSchema, BoardExtensionItemSchema, BoardFileItemSchema, BoardFrameItemSchema, BoardIdSchema, BoardImageItemSchema, BoardItemPreviewSchema, BoardKeySchema, BoardKeyframeSchema, BoardMarkerSchema, BoardMediaOriginSchema, BoardMediaSnapshotSchema, BoardMediaSourceSchema, BoardPatchSchema, BoardScriptSchema, BoardSettingsSchema, BoardShapeItemSchema, BoardSizeSchema, BoardStyleSchema, BoardTaskArtifactSchema, BoardTaskItemSchema, BoardTaskSnapshotSchema, BoardTextItemSchema, BoardTrackSchema, BoardVec2Schema, BoardVideoItemSchema, boardItemPreview, boardItemSchema, emptyBoardDocument, hasAuthoredSize, isBoardColorString, isBoardEase, isBuiltinItem, isBuiltinItemType, isEmptyBoardDelta, isFileBackedItem, isMediaItem, isSafeBoardSourcePath, parseBoardItem, parseBoardMediaSource } from "../../protocol/dist/board-model.js";
4
- import { isBoardPath, parseBoardManifest, serializeBoardManifest } from "../../protocol/dist/board.js";
5
4
  import { BOARD_TASK_SOURCE_PREFIX, boardTaskSource, featuredTaskArtifact, rankedTaskArtifacts, taskArtifactPreviewUrl, taskArtifacts, taskRunArtifacts, taskRunToBoardTaskSnapshot, withObservedArtifactFacts } from "../../protocol/dist/board-task.js";
6
5
  import { IDENTITY_MATRIX, adoptBoardNaturalSize, anchorPoint, applyMatrix, arrowBindings, autoAnchorSide, bendControl, clampBoardFontSize, createBoardLayout, createDocumentLayout, drawPointsBounds, drawSampleRadius, estimateTextWidth, fitBoardMediaSize, framePoint, invertMatrix, isArrowBinding, layoutBoardText, multiplyMatrix, pointsRect, rotateAround, scaleVector, setBoardTextLayouter, sideAnchor } from "../../protocol/dist/board-layout.js";
7
6
  import { applyBoardDelta, applyBoardPatch, applyBoardPatchToDocument, boardPatchTouches, createDocumentState, diffBoardDocuments, diffMergePatch, isEmptyBoardPatch, listBoardProperties, mergePatch, parseBoardDocument, pruneBoardTrack, resolveBoardProperty, trackReferences } from "../../protocol/dist/board-patch.js";
7
+ import { isBoardPath, parseBoardManifest, serializeBoardManifest } from "../../protocol/dist/board.js";
8
8
  import { BOARD_SCHEMA_TARGETS, boardJsonSchema, boardSchemaOverview } from "../../protocol/dist/board-schema.js";
9
- import { applyBoardEvaluation, boardAnimationTime, boardDocumentAt, boardEase, compileBoardAnimations, evaluateBoardAnimations, parseHexColor, sampleBoardTrack } from "./animation.js";
10
- import { buildBoardScene, orderBoardItems, placeItem, refreshBoardScene, sceneItemToItem, sceneItemsToRecord, toSceneItem } from "./scene.js";
11
- import { CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, VIEWPORT_MARGIN_RATIO, 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 { createBoardAnimationSampler, resolveBoardAnimationCamera } from "./sampling.js";
13
- import { BOARD_THEME_IDS } from "./themes.js";
14
- import { BOARD_COLORS, DEFAULT_BOARD_COLOR, boardColorCssVar, buildFallbackShapeColors, isBoardColorId, pickBoardColor, resolveBoardColor, resolveItemColor } from "./palette.js";
15
- import { ARROW_BINDING_GAP, arrowHitRadius, arrowPathBounds, distanceToArrow, pathMidpoint, pathPointAt, resolveAnchor, resolveArrow, resolveSceneArrow } from "./arrow-geometry.js";
16
- import { BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, exportItemBounds, normalizeBoardDocument, planBoardExport } from "./export-plan.js";
17
- import { BOARD_FRAME_LABEL_LINE_HEIGHT, BOARD_FRAME_LABEL_SIZE, SHAPE_LABEL_PADDING, TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, boardEditableText, boardFontFamily, frameLabelHitRect, frameLabelOffset, layoutShapeLabel } from "./text-metrics.js";
18
- import { boardModelFormat, getMediaExtension, getMediaResourceTitle, inferBoardMediaKind, isBoardModelItem } from "./media.js";
19
- 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";
20
- import { availabilityFromError, fileCategoryAccent, fileMetaLine, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot } from "./file-preview.js";
21
- import { buildStrokeOutline, buildStrokeRibbonGeometry, computeDrawBounds, createStrokeRibbonBuilder, distanceToStroke, isStrokeCorner, sampleRadius, simplifyDrawIndices, trimDrawPoints } from "./draw-geometry.js";
9
+ import { placeBoardOverlay } from "./overlay-placement.js";
22
10
  import { boardScriptItems, hasBoardScripts } from "./script-index.js";
11
+ import { CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, VIEWPORT_MARGIN_RATIO, 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";
23
12
  import { boardScriptScope, composeBoardScriptItems, prepareBoardScriptOutput, scriptTemporaryPrefix, validateBoardScriptCommit, validateBoardScriptOutput } from "./script-scene.js";
24
13
  import { boardScriptHitVisible, boardScriptTarget, resolveBoardScriptHit } from "./script-hit.js";
25
- import { BOARD_THUMBNAIL_EDGE, boardAssetKey, boardAssetKeySource, boardAssetRefKey, boardTextureEdge, boardTexturePixels, imageAssetKey } from "./asset-key.js";
26
- import { placeBoardOverlay } from "./overlay-placement.js";
27
14
  import { BOARD_SCRIPT_API } from "./script-api.js";
28
15
  import { BOARD_SCRIPT_DRAWING_EXAMPLE } from "./script-example.js";
16
+ import { applyBoardEvaluation, boardAnimationTime, boardDocumentAt, boardEase, compileBoardAnimations, evaluateBoardAnimations, parseHexColor, sampleBoardTrack } from "./animation.js";
17
+ import { buildBoardScene, orderBoardItems, placeItem, refreshBoardScene, sceneItemToItem, sceneItemsToRecord, toSceneItem } from "./scene.js";
18
+ import { createBoardAnimationSampler, resolveBoardAnimationCamera } from "./sampling.js";
29
19
  import { boardPathTrack, boardSequence, boardSequencePatch } from "./authoring.js";
30
20
  import { BOARD_PRESET_NAMES, boardNestedAnimation, boardNestedAnimationTrack, boardPresetTracks, isBoardPresetName, listBoardPresets } from "./presets.js";
21
+ import { ARROW_BINDING_GAP, arrowHitRadius, arrowPathBounds, distanceToArrow, pathMidpoint, pathPointAt, resolveAnchor, resolveArrow, resolveSceneArrow } from "./arrow-geometry.js";
22
+ import { buildStrokeOutline, buildStrokeRibbonGeometry, computeDrawBounds, createStrokeRibbonBuilder, distanceToStroke, isStrokeCorner, sampleRadius, simplifyDrawIndices, trimDrawPoints } from "./draw-geometry.js";
31
23
  import { appendBoardDrawSamples, quantizeDrawCoordinate } from "./draw-input.js";
24
+ import { boardModelFormat, getMediaExtension, getMediaResourceTitle, inferBoardMediaKind, isBoardModelItem } from "./media.js";
25
+ import { BOARD_THUMBNAIL_EDGE, boardAssetKey, boardAssetKeySource, boardAssetRefKey, boardTextureEdge, boardTexturePixels, imageAssetKey } from "./asset-key.js";
32
26
  import { BOARD_EXPORT_TEXTURE_BYTES, boardTextureBytes, selectBoardExportAssets } from "./export-assets.js";
27
+ import { BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, exportItemBounds, normalizeBoardDocument, planBoardExport } from "./export-plan.js";
28
+ 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";
29
+ import { availabilityFromError, fileCategoryAccent, fileMetaLine, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot } from "./file-preview.js";
30
+ import { BOARD_THEME_IDS } from "./themes.js";
31
+ import { BOARD_COLORS, DEFAULT_BOARD_COLOR, boardColorCssVar, buildFallbackShapeColors, isBoardColorId, pickBoardColor, resolveBoardColor, resolveItemColor } from "./palette.js";
33
32
  import { SHAPE_KINDS, isShapeKind } from "./shape-types.js";
33
+ import { BOARD_FRAME_LABEL_LINE_HEIGHT, BOARD_FRAME_LABEL_SIZE, SHAPE_LABEL_PADDING, TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, boardEditableText, boardFontFamily, frameLabelHitRect, frameLabelOffset, layoutShapeLabel } from "./text-metrics.js";
34
34
  import { DEFAULT_BOARD_TOOL_STYLES, createBoardToolStyles } from "./tool-styles.js";
35
35
  import { clientToLocal, elementClientToLocal } from "./client-geometry.js";
36
36
  import { boardMediaTarget, probeBoardMediaSize, settleBoardMediaSizes } from "./media-sizes.js";
@@ -3,10 +3,10 @@ import { BoardMediaOriginSchema, parseBoardItem } from "../../../protocol/dist/b
3
3
  import { featuredTaskArtifact } from "../../../protocol/dist/board-task.js";
4
4
  import { fitBoardMediaSize, pointsRect } from "../../../protocol/dist/board-layout.js";
5
5
  import "../geometry.js";
6
+ import { quantizeDrawCoordinate } from "../draw-input.js";
6
7
  import { boardModelFormat, getMediaResourceTitle, inferBoardMediaKind } from "../media.js";
7
8
  import { fileStem } from "../file-snapshot.js";
8
9
  import { filePreviewKind } from "../file-preview.js";
9
- import { quantizeDrawCoordinate } from "../draw-input.js";
10
10
  import { DEFAULT_BOARD_TOOL_STYLES } from "../tool-styles.js";
11
11
  import { createBoardItemId } from "./id.js";
12
12
  //#region src/board/model/items/create.ts
@@ -1,7 +1,7 @@
1
1
  import { arrowBindings } from "../../protocol/dist/board-layout.js";
2
+ import { cameraForFocus, cameraForState } from "./geometry.js";
2
3
  import { applyBoardEvaluation, boardAnimationTime, compileBoardAnimations, evaluateBoardAnimations } from "./animation.js";
3
4
  import { buildBoardScene } from "./scene.js";
4
- import { cameraForFocus, cameraForState } from "./geometry.js";
5
5
  //#region src/board/model/sampling.ts
6
6
  function createBoardAnimationSampler(document, animation, options = {}) {
7
7
  const selected = animation ? document.animations[animation] : void 0;
@@ -258,12 +258,12 @@ declare const BOARD_THEME_DATA: {
258
258
  readonly colorScheme: "dark";
259
259
  readonly palette: {
260
260
  readonly bg: 329221;
261
- readonly surface: 2039072;
262
- readonly hover: 1842202;
261
+ readonly surface: 1249814;
262
+ readonly hover: 1973788;
263
263
  readonly border: 1842202;
264
264
  readonly brand: 3900150;
265
- readonly text: 15920612;
266
- readonly muted: 9999759;
265
+ readonly text: 16314853;
266
+ readonly muted: 7630695;
267
267
  readonly rare: 9235170;
268
268
  readonly epic: 7266776;
269
269
  readonly legendary: 15449187;
@@ -272,47 +272,47 @@ declare const BOARD_THEME_DATA: {
272
272
  readonly brand: {
273
273
  readonly stroke: 15524306;
274
274
  readonly fill: 15524306;
275
- readonly label: 15920612;
275
+ readonly label: 16314853;
276
276
  };
277
277
  readonly neutral: {
278
- readonly stroke: 15920612;
279
- readonly fill: 15920612;
280
- readonly label: 15920612;
278
+ readonly stroke: 15524306;
279
+ readonly fill: 15524306;
280
+ readonly label: 16314853;
281
281
  };
282
282
  readonly black: {
283
283
  readonly stroke: 0;
284
284
  readonly fill: 0;
285
- readonly label: 15920612;
285
+ readonly label: 16314853;
286
286
  };
287
287
  readonly white: {
288
288
  readonly stroke: 16777215;
289
289
  readonly fill: 16777215;
290
- readonly label: 15920612;
290
+ readonly label: 16314853;
291
291
  };
292
292
  readonly blue: {
293
293
  readonly stroke: 9235170;
294
294
  readonly fill: 9235170;
295
- readonly label: 15920612;
295
+ readonly label: 16314853;
296
296
  };
297
297
  readonly green: {
298
298
  readonly stroke: 8177036;
299
299
  readonly fill: 8177036;
300
- readonly label: 15920612;
300
+ readonly label: 16314853;
301
301
  };
302
302
  readonly amber: {
303
303
  readonly stroke: 15449187;
304
304
  readonly fill: 15449187;
305
- readonly label: 15920612;
305
+ readonly label: 16314853;
306
306
  };
307
307
  readonly violet: {
308
308
  readonly stroke: 11971327;
309
309
  readonly fill: 11971327;
310
- readonly label: 15920612;
310
+ readonly label: 16314853;
311
311
  };
312
312
  readonly rose: {
313
313
  readonly stroke: 15562341;
314
314
  readonly fill: 15562341;
315
- readonly label: 15920612;
315
+ readonly label: 16314853;
316
316
  };
317
317
  };
318
318
  readonly style: {
@@ -327,8 +327,8 @@ declare const BOARD_THEME_DATA: {
327
327
  readonly palette: {
328
328
  readonly bg: 16185078;
329
329
  readonly surface: 16777215;
330
- readonly hover: 15461355;
331
- readonly border: 14935011;
330
+ readonly hover: 16185078;
331
+ readonly border: 15527149;
332
332
  readonly brand: 1824230;
333
333
  readonly text: 1447704;
334
334
  readonly muted: 7566452;
@@ -409,13 +409,13 @@ declare const BOARD_THEME_DATA: {
409
409
  readonly "neta-pixel-dark": {
410
410
  readonly colorScheme: "dark";
411
411
  readonly palette: {
412
- readonly bg: 1447704;
413
- readonly surface: 2631979;
414
- readonly hover: 3224115;
415
- readonly border: 3618875;
412
+ readonly bg: 1118739;
413
+ readonly surface: 1842463;
414
+ readonly hover: 2237220;
415
+ readonly border: 2763565;
416
416
  readonly brand: 1824230;
417
- readonly text: 15921907;
418
- readonly muted: 9408656;
417
+ readonly text: 16185078;
418
+ readonly muted: 9079436;
419
419
  readonly rare: 1824230;
420
420
  readonly epic: 1824230;
421
421
  readonly legendary: 16766287;
@@ -424,47 +424,47 @@ declare const BOARD_THEME_DATA: {
424
424
  readonly brand: {
425
425
  readonly stroke: 16185078;
426
426
  readonly fill: 16185078;
427
- readonly label: 15921907;
427
+ readonly label: 16185078;
428
428
  };
429
429
  readonly neutral: {
430
- readonly stroke: 9408656;
431
- readonly fill: 9408656;
432
- readonly label: 15921907;
430
+ readonly stroke: 9079436;
431
+ readonly fill: 9079436;
432
+ readonly label: 16185078;
433
433
  };
434
434
  readonly black: {
435
435
  readonly stroke: 0;
436
436
  readonly fill: 0;
437
- readonly label: 15921907;
437
+ readonly label: 16185078;
438
438
  };
439
439
  readonly white: {
440
440
  readonly stroke: 16777215;
441
441
  readonly fill: 16777215;
442
- readonly label: 15921907;
442
+ readonly label: 16185078;
443
443
  };
444
444
  readonly blue: {
445
445
  readonly stroke: 6010853;
446
446
  readonly fill: 6010853;
447
- readonly label: 15921907;
447
+ readonly label: 16185078;
448
448
  };
449
449
  readonly green: {
450
450
  readonly stroke: 9683613;
451
451
  readonly fill: 9683613;
452
- readonly label: 15921907;
452
+ readonly label: 16185078;
453
453
  };
454
454
  readonly amber: {
455
455
  readonly stroke: 14264410;
456
456
  readonly fill: 14264410;
457
- readonly label: 15921907;
457
+ readonly label: 16185078;
458
458
  };
459
459
  readonly violet: {
460
460
  readonly stroke: 11441117;
461
461
  readonly fill: 11441117;
462
- readonly label: 15921907;
462
+ readonly label: 16185078;
463
463
  };
464
464
  readonly rose: {
465
465
  readonly stroke: 15043210;
466
466
  readonly fill: 15043210;
467
- readonly label: 15921907;
467
+ readonly label: 16185078;
468
468
  };
469
469
  };
470
470
  readonly style: {