@neta-art/cohub 5.9.0 → 6.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 (55) hide show
  1. package/README.md +42 -46
  2. package/dist/board/animation.d.ts +156 -67
  3. package/dist/board/animation.js +162 -277
  4. package/dist/board/codec.js +1 -1
  5. package/dist/board/export/index.d.ts +6 -0
  6. package/dist/board/export/index.js +6 -3
  7. package/dist/board/export/scene.d.ts +6 -0
  8. package/dist/board/export/scene.js +26 -2
  9. package/dist/board/geometry.d.ts +27 -1
  10. package/dist/board/geometry.js +92 -1
  11. package/dist/board/headless/index.d.ts +7 -1
  12. package/dist/board/headless/index.js +6 -2
  13. package/dist/board/index.d.ts +8 -6
  14. package/dist/board/index.js +7 -6
  15. package/dist/board/mutation.d.ts +15 -0
  16. package/dist/board/mutation.js +67 -0
  17. package/dist/board/render/css-color.d.ts +4 -0
  18. package/dist/board/render/css-color.js +36 -0
  19. package/dist/board/render/index.d.ts +2 -1
  20. package/dist/board/render/index.js +2 -1
  21. package/dist/board/render/renderers/base-card-renderer.js +3 -20
  22. package/dist/board/render/themes/clean-theme.js +6 -3
  23. package/dist/chunks/http.d.ts +30 -7
  24. package/dist/chunks/http.js +785 -289
  25. package/dist/chunks/websocket.d.ts +2675 -187
  26. package/dist/http.d.ts +3 -3
  27. package/dist/index.d.ts +158 -299
  28. package/dist/index.js +164 -279
  29. package/dist/protocol/dist/board-authoring.d.ts +1 -0
  30. package/dist/protocol/dist/board-authoring.js +217 -0
  31. package/dist/protocol/dist/board-capability-registry.d.ts +2 -0
  32. package/dist/protocol/dist/board-capability-registry.js +74 -0
  33. package/dist/protocol/dist/board-codec.d.ts +2 -0
  34. package/dist/protocol/dist/board-codec.js +4 -0
  35. package/dist/protocol/dist/board-composition.d.ts +258 -0
  36. package/dist/protocol/dist/board-composition.js +318 -0
  37. package/dist/protocol/dist/board-constants.d.ts +2 -1
  38. package/dist/protocol/dist/board-constants.js +40 -10
  39. package/dist/protocol/dist/board-document.d.ts +28 -2
  40. package/dist/protocol/dist/board-document.js +16 -3
  41. package/dist/protocol/dist/board-node.d.ts +1 -11
  42. package/dist/protocol/dist/board-node.js +1 -81
  43. package/dist/protocol/dist/board-upgrade.d.ts +1 -0
  44. package/dist/protocol/dist/board-upgrade.js +2 -0
  45. package/dist/protocol/dist/board-url.d.ts +2 -1
  46. package/dist/protocol/dist/board-url.js +8 -3
  47. package/dist/protocol/dist/board.d.ts +135 -76
  48. package/dist/protocol/dist/board.js +50 -69
  49. package/dist/protocol/dist/index.d.ts +9 -4
  50. package/dist/protocol/dist/index.js +9 -4
  51. package/dist/types.d.ts +3 -2
  52. package/docs/work-runtime-guide.md +19 -3
  53. package/package.json +3 -2
  54. package/dist/board/nodes.d.ts +0 -113
  55. package/dist/board/nodes.js +0 -154
@@ -1,3 +1,5 @@
1
+ import { BoardCameraFocus, BoardCameraFocusParams, BoardCameraState } from "../protocol/dist/board.js";
2
+ import "../protocol/dist/index.js";
1
3
  import { BoardFrame, BoardViewport } from "../protocol/dist/board-document.js";
2
4
  //#region src/board/geometry.d.ts
3
5
  type Point = {
@@ -27,8 +29,27 @@ type WorldPoint = {
27
29
  y: number;
28
30
  readonly [coordBrand]: "world";
29
31
  };
32
+ type BoardScreenPoint = ScreenPoint;
33
+ type BoardWorldPoint = WorldPoint;
34
+ declare const coordinateKindBrand: unique symbol;
35
+ type BoardWorldOffset = Point & {
36
+ readonly [coordinateKindBrand]: "world-offset";
37
+ };
38
+ type BoardScreenOffset = Point & {
39
+ readonly [coordinateKindBrand]: "screen-offset";
40
+ };
41
+ type BoardNormalizedPoint = Point & {
42
+ readonly [coordinateKindBrand]: "normalized";
43
+ };
44
+ type BoardWorldRect = Rect & {
45
+ readonly [coordinateKindBrand]: "world-rect";
46
+ };
30
47
  declare function screenPoint(x: number, y: number): ScreenPoint;
31
48
  declare function worldPoint(x: number, y: number): WorldPoint;
49
+ declare function worldOffset(x: number, y: number): BoardWorldOffset;
50
+ declare function screenOffset(x: number, y: number): BoardScreenOffset;
51
+ declare function normalizedPoint(x: number, y: number): BoardNormalizedPoint;
52
+ declare function worldRect(x: number, y: number, width: number, height: number): BoardWorldRect;
32
53
  declare const MIN_BOARD_ZOOM = 0.05;
33
54
  declare const MAX_BOARD_ZOOM = 8;
34
55
  /** Smallest an item can be resized to, in world units. */
@@ -52,6 +73,7 @@ declare function rectCenter(rect: Rect): WorldPoint;
52
73
  declare function rectsIntersect(a: Rect, b: Rect): boolean;
53
74
  declare function rectContainsPoint(rect: Rect, point: Point, tolerance?: number): boolean;
54
75
  declare function expandRect(rect: Rect, amount: number): Rect;
76
+ declare function pointsBounds(points: readonly Point[], minSize?: number): Rect | null;
55
77
  declare function unionRects(rects: Rect[]): Rect | null;
56
78
  declare function rotatePointAround<P extends Point>(point: P, center: Point, angleRad: number): P;
57
79
  /** Axis-aligned bounding box of a (possibly rotated) frame. */
@@ -131,9 +153,13 @@ declare function screenToWorld(clientX: number, clientY: number, rect: DOMRect,
131
153
  /** Zoom while keeping a surface-relative screen point fixed under the cursor. */
132
154
  declare function zoomAround(viewport: BoardViewport, anchor: ScreenPoint, nextZoom: number): BoardViewport;
133
155
  declare function panBy(viewport: BoardViewport, dx: number, dy: number): BoardViewport;
156
+ declare function cameraForState(state: BoardCameraState, surface: Size): BoardViewport;
157
+ declare function cameraForRect(content: Rect, surface: Size, options?: Pick<BoardCameraFocusParams, "fit" | "padding" | "minZoom" | "maxZoom">): BoardViewport;
158
+ declare function rectForCameraFocus(focus: BoardCameraFocus, getFrame: (id: string) => BoardFrame | null | undefined): Rect | null;
159
+ declare function cameraForFocus(params: BoardCameraFocusParams, getFrame: (id: string) => BoardFrame | null | undefined, surface: Size): BoardViewport | null;
134
160
  /** Compute a viewport that frames the given world rect within the surface. */
135
161
  declare function fitToContent(content: Rect, surface: Size, padding?: number): BoardViewport;
136
162
  /** World-space rectangle currently visible in the board stage. */
137
163
  declare function visibleWorldRect(viewport: BoardViewport, surfaceWidth: number, surfaceHeight: number): Rect;
138
164
  //#endregion
139
- export { 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, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround };
165
+ export { BoardNormalizedPoint, BoardScreenOffset, BoardScreenPoint, 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, unionRects, visibleWorldRect, worldOffset, worldPoint, worldRect, worldToScreen, zoomAround };
@@ -11,6 +11,32 @@ function worldPoint(x, y) {
11
11
  y
12
12
  };
13
13
  }
14
+ function worldOffset(x, y) {
15
+ return {
16
+ x,
17
+ y
18
+ };
19
+ }
20
+ function screenOffset(x, y) {
21
+ return {
22
+ x,
23
+ y
24
+ };
25
+ }
26
+ function normalizedPoint(x, y) {
27
+ return {
28
+ x: clamp(x, 0, 1),
29
+ y: clamp(y, 0, 1)
30
+ };
31
+ }
32
+ function worldRect(x, y, width, height) {
33
+ return {
34
+ x,
35
+ y,
36
+ width,
37
+ height
38
+ };
39
+ }
14
40
  const MIN_BOARD_ZOOM = .05;
15
41
  const MAX_BOARD_ZOOM = 8;
16
42
  const DEFAULT_BOARD_VIEWPORT = {
@@ -77,6 +103,25 @@ function expandRect(rect, amount) {
77
103
  height: rect.height + amount * 2
78
104
  };
79
105
  }
106
+ function pointsBounds(points, minSize = 0) {
107
+ if (points.length === 0) return null;
108
+ let minX = Number.POSITIVE_INFINITY;
109
+ let minY = Number.POSITIVE_INFINITY;
110
+ let maxX = Number.NEGATIVE_INFINITY;
111
+ let maxY = Number.NEGATIVE_INFINITY;
112
+ for (const point of points) {
113
+ minX = Math.min(minX, point.x);
114
+ minY = Math.min(minY, point.y);
115
+ maxX = Math.max(maxX, point.x);
116
+ maxY = Math.max(maxY, point.y);
117
+ }
118
+ return {
119
+ x: minX,
120
+ y: minY,
121
+ width: Math.max(minSize, maxX - minX),
122
+ height: Math.max(minSize, maxY - minY)
123
+ };
124
+ }
80
125
  function unionRects(rects) {
81
126
  if (rects.length === 0) return null;
82
127
  let minX = Number.POSITIVE_INFINITY;
@@ -465,6 +510,52 @@ function panBy(viewport, dx, dy) {
465
510
  y: viewport.y + dy
466
511
  };
467
512
  }
513
+ function cameraForState(state, surface) {
514
+ const zoom = clampZoom(state.zoom);
515
+ return normalizeViewport({
516
+ x: surface.width / 2 - state.centerX * zoom,
517
+ y: surface.height / 2 - state.centerY * zoom,
518
+ zoom
519
+ });
520
+ }
521
+ function cameraForRect(content, surface, options = {
522
+ fit: "contain",
523
+ padding: 32
524
+ }) {
525
+ const padding = Math.max(0, Number.isFinite(options.padding) ? options.padding : 32);
526
+ const availableW = Math.max(1, surface.width - padding * 2);
527
+ const availableH = Math.max(1, surface.height - padding * 2);
528
+ const fitZoom = options.fit === "cover" ? Math.max(availableW / content.width, availableH / content.height) : Math.min(availableW / content.width, availableH / content.height);
529
+ const minZoom = clampZoom(options.minZoom ?? .05);
530
+ const maxZoom = clampZoom(options.maxZoom ?? 8);
531
+ const zoom = Math.min(Math.max(fitZoom, Math.min(minZoom, maxZoom)), Math.max(minZoom, maxZoom));
532
+ const center = rectCenter(content);
533
+ return cameraForState({
534
+ centerX: center.x,
535
+ centerY: center.y,
536
+ zoom
537
+ }, surface);
538
+ }
539
+ function rectForCameraFocus(focus, getFrame) {
540
+ if (focus.type === "rect") return focus.rect;
541
+ if (focus.type === "item") {
542
+ const frame = getFrame(focus.itemId);
543
+ return frame ? itemBounds(frame) : null;
544
+ }
545
+ if (focus.type === "frame") {
546
+ const frame = getFrame(focus.frameId);
547
+ return frame ? itemBounds(frame) : null;
548
+ }
549
+ const frames = focus.itemIds.flatMap((id) => {
550
+ const frame = getFrame(id);
551
+ return frame ? [frame] : [];
552
+ });
553
+ return frames.length === focus.itemIds.length ? selectionBounds(frames) : null;
554
+ }
555
+ function cameraForFocus(params, getFrame, surface) {
556
+ const rect = rectForCameraFocus(params.focus, getFrame);
557
+ return rect ? cameraForRect(rect, surface, params) : null;
558
+ }
468
559
  /** Compute a viewport that frames the given world rect within the surface. */
469
560
  function fitToContent(content, surface, padding = 64) {
470
561
  const availableW = Math.max(1, surface.width - padding * 2);
@@ -489,4 +580,4 @@ function visibleWorldRect(viewport, surfaceWidth, surfaceHeight) {
489
580
  };
490
581
  }
491
582
  //#endregion
492
- export { 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, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround };
583
+ export { 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, unionRects, visibleWorldRect, worldOffset, worldPoint, worldRect, worldToScreen, zoomAround };
@@ -51,9 +51,15 @@ type BoardHeadlessRenderer = {
51
51
  */
52
52
  declare function createBoardHeadlessRenderer(options?: BoardHeadlessRendererOptions): Promise<BoardHeadlessRenderer>;
53
53
  type BoardHeadlessExportFormat = "png" | "jpeg" | "webp";
54
- type BoardHeadlessExportOptions = Omit<BoardExportOptions, "textures"> & {
54
+ type BoardHeadlessExportOptions = Omit<BoardExportOptions, "textures" | "backgroundImage"> & {
55
55
  /** Textures from `decodeImage`, keyed by image key. */
56
56
  textures?: Map<string, BoardHeadlessTexture>;
57
+ backgroundImage?: {
58
+ texture: BoardHeadlessTexture;
59
+ fit: "cover" | "contain" | "repeat";
60
+ position: "center" | "top" | "bottom" | "left" | "right";
61
+ opacity: number;
62
+ };
57
63
  format?: BoardHeadlessExportFormat;
58
64
  /** JPEG/WebP quality, 0–1. Ignored for PNG. */
59
65
  quality?: number;
@@ -131,10 +131,14 @@ function boardHeadlessMimeType(format) {
131
131
  }
132
132
  /** Render a document to encoded image bytes. Returns null for an empty region. */
133
133
  function exportBoardImageBytes(headless, document, options = {}) {
134
- const { format = "png", quality = .92, textures, ...rest } = options;
134
+ const { format = "png", quality = .92, textures, backgroundImage, ...rest } = options;
135
135
  const result = renderBoardExport(headless.renderer, document, {
136
136
  ...rest,
137
- ...textures ? { textures } : {}
137
+ ...textures ? { textures } : {},
138
+ ...backgroundImage ? { backgroundImage: {
139
+ ...backgroundImage,
140
+ texture: backgroundImage.texture
141
+ } } : {}
138
142
  });
139
143
  if (!result) return null;
140
144
  const canvas = result.canvas;
@@ -1,12 +1,14 @@
1
1
  import { BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, clampBoardStrokeSize } from "../protocol/dist/board-constants.js";
2
2
  import { AUTO_BOARD_CONNECTION_ANCHOR, BOARD_CONNECTION_DIRECTIONS, BOARD_CONNECTION_LINES, BOARD_CONNECTION_ROUTINGS, BOARD_CONNECTION_SIDES, BoardConnection, BoardConnectionAnchor, BoardConnectionAnchorSchema, BoardConnectionDirection, BoardConnectionEndpoint, BoardConnectionEndpointSchema, BoardConnectionInput, BoardConnectionLine, BoardConnectionPatch, BoardConnectionPatchSchema, BoardConnectionRecord, BoardConnectionRouting, BoardConnectionRoutingConfig, BoardConnectionRoutingSchema, BoardConnectionSchema, BoardConnectionSide, BoardConnectionStyle, BoardConnectionStyleSchema, BoardConnectionWaypointSchema, BoardRelationSchema, DEFAULT_BOARD_CONNECTION_ROUTING, DEFAULT_BOARD_CONNECTION_STYLE, DEFAULT_BOARD_RELATION, connectionNodeIds, connectionOtherNodeId, connectionTouchesNode, createBoardConnection, flipBoardConnection, normalizeBoardConnectionStyle } from "../protocol/dist/board-connection.js";
3
+ import { BoardTrackInterpolation } from "../protocol/dist/board-composition.js";
3
4
  import { BoardColorId } from "../protocol/dist/board-node.js";
4
- import { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, BoardManifest, BoardNodeRecord, BoardRecord, InvalidBoardFileError, isBoardPath, parseBoardManifest, serializeBoardManifest } from "../protocol/dist/board.js";
5
- import { BoardExtensionDefinition, BoardExtensionRegistry, BoardPresetDefinition, CompiledSequence, DEFAULT_BOARD_LIMITS, QualityProfile, RenderBounds, TimelineClipInput, TimelineInput, clip, compileSequence, createBoardExtensionRegistry, timeline } from "./animation.js";
6
- import { BOARD_REMOTE_URL_MAX_LENGTH, BoardRemoteUrlSchema, normalizeBoardRemoteUrl } from "../protocol/dist/board-url.js";
5
+ import { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, BoardCameraFocus, BoardCameraFocusParams, BoardCameraFocusParamsSchema, BoardCameraFocusSchema, BoardCameraState, BoardCameraStateSchema, BoardManifest, BoardNodeRecord, BoardRecord, InvalidBoardFileError, isBoardPath, parseBoardManifest, serializeBoardManifest } from "../protocol/dist/board.js";
6
+ import "../protocol/dist/index.js";
7
+ import { BOARD_CHANNELS, BoardExtensionDefinition, BoardExtensionRegistry, BoardPresetDefinition, CompositionInput, DEFAULT_BOARD_LIMITS, ProceduralClipInput, QualityProfile, RenderBounds, SampledTrack, TrackInput, compileComposition, composition, createBoardExtensionRegistry, proceduralClip, sampleCompositionTracks, sampleEasing, sampleTrack, track } from "./animation.js";
8
+ import { BOARD_REMOTE_URL_MAX_LENGTH, BoardRemoteUrlSchema, isPublicBoardRemoteAddress, normalizeBoardRemoteUrl } from "../protocol/dist/board-url.js";
7
9
  import { BOARD_TASK_ARTIFACT_LIMIT, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardAudioItem, BoardAudioItemSchema, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemSchema, BoardItemStyle, BoardItemStyleSchema, BoardKnownItem, BoardMediaSnapshot, BoardMediaSnapshotSchema, BoardPoint, BoardPointSchema, BoardTaskArtifact, BoardTaskArtifactSchema, BoardTaskItem, BoardTaskItemSchema, BoardTaskSnapshot, BoardTaskSnapshotSchema, BoardTextItem, BoardTextItemSchema, BoardUnknownItem, BoardVideoItem, BoardVideoItemSchema, BoardViewport, BoardViewportSchema, DrawPoint, DrawPointSchema, KNOWN_BOARD_ITEM_TYPES, KnownBoardItemType, SpaceFileRef, SpaceFileRefSchema, UNKNOWN_BOARD_ITEM_TYPE, isFileBackedItem, isMediaItem, isUnknownItem, parseBoardDocument, parseBoardItemLoose, unknownRealType, withResolvedConnections } from "../protocol/dist/board-document.js";
8
10
  import { BOARD_NODE_SOURCE, DEFAULT_BOARD_APPEARANCE, ITEM_BASE_KEYS, WireBackedBoardItem, boardBootstrapToDocument, boardNodeToItem, isRecord, nodeInputFromRecord, sourceForItem } from "./codec.js";
9
- import { 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, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround } from "./geometry.js";
11
+ import { BoardNormalizedPoint, BoardScreenOffset, BoardScreenPoint, 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, unionRects, visibleWorldRect, worldOffset, worldPoint, worldRect, worldToScreen, zoomAround } from "./geometry.js";
10
12
  import { ResolvedArrow, arrowBounds, arrowFrame, distanceToArrow, resolveArrow, sampleArrow, translateArrow } from "./core/arrow-geometry.js";
11
13
  import { CONNECTION_ENDPOINT_GAP, ConnectionIndex, FrameLookup, ResolvedConnection, ResolvedConnectionEndpoint, anchorPointOnFrame, anchorToWorld, autoConnectionSide, connectionArrowheads, connectionBounds, connectionHitTest, createConnectionIndex, distanceToConnection, pathMidpoint, resolveConnection, worldToAnchor } from "./core/connections.js";
12
14
  import { buildStrokeOutline, computeDrawBounds, distanceToStroke, sampleRadius, simplifyDrawIndices } from "./core/draw-geometry.js";
@@ -21,6 +23,6 @@ import { BoardStyledToolId, BoardToolStyleMap, BoardToolStylePatch, DEFAULT_BOAR
21
23
  import { boardImageKeySource, imageAssetKey } from "./image-key.js";
22
24
  import { BoardMediaKind, getMediaExtension, getMediaResourceTitle, inferBoardMediaKind } from "./media.js";
23
25
  import { BoardAssetSource, BoardPlayableMedia, playableBoardMedia, playableBoardMediaList, resetBoardPlaybackUrlCache } from "./media-playback.js";
24
- import { BoardInputError, BoardNodeFrameInput, BoardNodeSpec, assertBoardNodes, assertBoardTransactionNodeCreates, createBoardNode, validateBoardNodes } from "./nodes.js";
26
+ import { boardAppearanceOperation, boardCompositionApplyOperation, boardCompositionDeleteOperation, boardEffectDeleteOperation, boardEffectUpsertOperation, boardPlaybackPolicyOperation, boardTitleOperation, patchBoardAppearance } from "./mutation.js";
25
27
  import { featuredTaskArtifact, rankedTaskArtifacts, taskArtifactPreviewUrl, taskArtifacts, taskRunToBoardTaskSnapshot } from "./task.js";
26
- export { AUTO_BOARD_CONNECTION_ANCHOR, type ArrowShapeProps, type AudioShapeProps, BOARD_COLORS, BOARD_CONNECTION_DIRECTIONS, BOARD_CONNECTION_LINES, BOARD_CONNECTION_ROUTINGS, BOARD_CONNECTION_SIDES, BOARD_DOCUMENT_KIND, 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, BOARD_NODE_SOURCE, BOARD_REMOTE_URL_MAX_LENGTH, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BOARD_TASK_ARTIFACT_LIMIT, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardAssetSource, BoardAudioItem, BoardAudioItemSchema, BoardColorEntry, type BoardColorId, BoardColorValue, BoardConnection, BoardConnectionAnchor, BoardConnectionAnchorSchema, BoardConnectionDirection, BoardConnectionEndpoint, BoardConnectionEndpointSchema, BoardConnectionInput, BoardConnectionLine, BoardConnectionPatch, BoardConnectionPatchSchema, BoardConnectionRecord, BoardConnectionRouting, BoardConnectionRoutingConfig, BoardConnectionRoutingSchema, BoardConnectionSchema, BoardConnectionSide, BoardConnectionStyle, BoardConnectionStyleSchema, BoardConnectionWaypointSchema, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardExportAssetSelection, BoardExportPlan, BoardExportPlanInput, BoardExportRegion, BoardExtensionDefinition, BoardExtensionRegistry, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotFacts, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema, BoardInputError, BoardItem, BoardItemSchema, BoardItemStyle, BoardItemStyleSchema, BoardKnownItem, type BoardManifest, BoardMediaKind, BoardMediaSnapshot, BoardMediaSnapshotSchema, BoardNodeFrameInput, type BoardNodeRecord, BoardNodeSpec, BoardPlayableMedia, BoardPoint, BoardPointSchema, BoardPresetDefinition, type BoardRecord, BoardRelationSchema, BoardRemoteUrlSchema, BoardShapeColors, BoardStyledToolId, BoardTaskArtifact, BoardTaskArtifactSchema, BoardTaskItem, BoardTaskItemSchema, BoardTaskSnapshot, BoardTaskSnapshotSchema, BoardTextItem, BoardTextItemSchema, BoardToolStyleMap, BoardToolStylePatch, BoardUnknownItem, BoardVideoItem, BoardVideoItemSchema, BoardViewport, BoardViewportSchema, BuildSnapshotInput, CONNECTION_ENDPOINT_GAP, CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, CompiledSequence, ConnectionIndex, CornerResizeHandle, DEFAULT_BOARD_APPEARANCE, DEFAULT_BOARD_COLOR, DEFAULT_BOARD_CONNECTION_ROUTING, DEFAULT_BOARD_CONNECTION_STYLE, DEFAULT_BOARD_LIMITS, DEFAULT_BOARD_RELATION, DEFAULT_BOARD_TOOL_STYLES, DrawPoint, DrawPointSchema, type DrawShapeProps, EDGE_RESIZE_HANDLES, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FIT_PADDING, FULL_CAPABILITIES, FileAvailability, FilePreviewKind, FrameLookup, GEO_KINDS, type GeoKind, type GeoShapeProps, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, type HandleDragResult, ITEM_BASE_KEYS, type ImageShapeProps, InvalidBoardFileError, KNOWN_BOARD_ITEM_TYPES, KnownBoardItemType, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, Point, QualityProfile, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, Rect, RenderBounds, ResizeHandle, ResolvedArrow, ResolvedConnection, ResolvedConnectionEndpoint, ResolvedCover, ScreenPoint, type ShapeCapabilities, ShapeDefinition, type ShapeGeometry, type ShapeHandle, type ShapeHandleId, type ShapeResizeMode, Size, SpaceFileRef, SpaceFileRefSchema, TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, type TextShapeProps, TimelineClipInput, TimelineInput, UNKNOWN_BOARD_ITEM_TYPE, VIEWPORT_MARGIN_RATIO, type VideoShapeProps, WireBackedBoardItem, WorldPoint, anchorPointOnFrame, anchorToWorld, angleFromCenter, arrowBounds, arrowFrame, assertBoardNodes, assertBoardTransactionNodeCreates, autoConnectionSide, availabilityFromError, boardBootstrapToDocument, boardColorCssVar, boardFrameLookup, boardImageKeySource, boardNodeToItem, boardTextLineHeight, buildFallbackShapeColors, buildFileExcerpt, buildFileSnapshot, buildStrokeOutline, clamp, clampBoardStrokeSize, clampBoardTextFontSize, clampZoom, clip, compileSequence, computeDrawBounds, connectionArrowheads, connectionBounds, connectionHitTest, connectionNodeIds, connectionOtherNodeId, connectionTouchesNode, createBoardConnection, createBoardExtensionRegistry, createBoardNode, createBoardToolStyles, createConnectionIndex, definitionForItem, degToRad, distanceToArrow, distanceToConnection, distanceToStroke, expandRect, exportConnectionBounds, exportItemBounds, featuredTaskArtifact, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, fitToContent, flipBoardConnection, formatFileSize, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, getMediaExtension, getMediaResourceTitle, getShapeDefinition, handlePosition, imageAssetKey, inferBoardMediaKind, isBoardColorId, isBoardPath, isFileBackedItem, isFileSnapshotFresh, isGeoKind, isMediaItem, isRecord, isUnknownItem, itemBounds, measureBoardText, mergeFileSnapshot, nodeInputFromRecord, normalizeBoardConnectionStyle, normalizeBoardDocument, normalizeBoardRemoteUrl, normalizeRotation, normalizeViewport, panBy, parseBoardDocument, parseBoardItemLoose, parseBoardManifest, pathMidpoint, pickBoardColor, planBoardExport, playableBoardMedia, playableBoardMediaList, pointToWorld, radToDeg, rankedTaskArtifacts, readCoverFromFrontmatter, readTitleFromFrontmatter, rectCenter, rectContainsPoint, rectsIntersect, registerShapeDefinition, resetBoardPlaybackUrlCache, resizeFrame, resizeFrameToSize, resizeModeForCapabilities, resolveArrow, resolveBoardColor, resolveConnection, resolveCoverRef, resolveSpacePath, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, sampleArrow, sampleRadius, scaleFrames, screenPoint, screenToWorld, selectBoardExportAssets, selectionBounds, serializeBoardManifest, setBoardTextMeasurer, shapeBounds, shapeCapabilities, shapeHandles, shapeHitTest, shapeResizeMode, shouldFetchFileExcerpt, simplifyDrawIndices, sourceForItem, splitFrontmatter, taskArtifactPreviewUrl, taskArtifacts, taskRunToBoardTaskSnapshot, timeline, translateArrow, unionRects, unknownRealType, unknownShapeDefinition, validateBoardNodes, visibleWorldRect, withResolvedConnections, worldPoint, worldToAnchor, worldToScreen, zoomAround };
28
+ export { AUTO_BOARD_CONNECTION_ANCHOR, type ArrowShapeProps, type AudioShapeProps, BOARD_CHANNELS, BOARD_COLORS, BOARD_CONNECTION_DIRECTIONS, BOARD_CONNECTION_LINES, BOARD_CONNECTION_ROUTINGS, BOARD_CONNECTION_SIDES, BOARD_DOCUMENT_KIND, 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, BOARD_NODE_SOURCE, BOARD_REMOTE_URL_MAX_LENGTH, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BOARD_TASK_ARTIFACT_LIMIT, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardAssetSource, BoardAudioItem, BoardAudioItemSchema, type BoardCameraFocus, type BoardCameraFocusParams, BoardCameraFocusParamsSchema, BoardCameraFocusSchema, type BoardCameraState, BoardCameraStateSchema, BoardColorEntry, type BoardColorId, BoardColorValue, BoardConnection, BoardConnectionAnchor, BoardConnectionAnchorSchema, BoardConnectionDirection, BoardConnectionEndpoint, BoardConnectionEndpointSchema, BoardConnectionInput, BoardConnectionLine, BoardConnectionPatch, BoardConnectionPatchSchema, BoardConnectionRecord, BoardConnectionRouting, BoardConnectionRoutingConfig, BoardConnectionRoutingSchema, BoardConnectionSchema, BoardConnectionSide, BoardConnectionStyle, BoardConnectionStyleSchema, BoardConnectionWaypointSchema, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardExportAssetSelection, BoardExportPlan, BoardExportPlanInput, BoardExportRegion, BoardExtensionDefinition, BoardExtensionRegistry, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotFacts, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemSchema, BoardItemStyle, BoardItemStyleSchema, BoardKnownItem, type BoardManifest, BoardMediaKind, BoardMediaSnapshot, BoardMediaSnapshotSchema, type BoardNodeRecord, BoardNormalizedPoint, BoardPlayableMedia, BoardPoint, BoardPointSchema, BoardPresetDefinition, type BoardRecord, BoardRelationSchema, BoardRemoteUrlSchema, BoardScreenOffset, BoardScreenPoint, BoardShapeColors, BoardStyledToolId, BoardTaskArtifact, BoardTaskArtifactSchema, BoardTaskItem, BoardTaskItemSchema, BoardTaskSnapshot, BoardTaskSnapshotSchema, BoardTextItem, BoardTextItemSchema, BoardToolStyleMap, BoardToolStylePatch, type BoardTrackInterpolation, BoardUnknownItem, BoardVideoItem, BoardVideoItemSchema, BoardViewport, BoardViewportSchema, BoardWorldOffset, BoardWorldPoint, BoardWorldRect, BuildSnapshotInput, CONNECTION_ENDPOINT_GAP, CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, CompositionInput, ConnectionIndex, CornerResizeHandle, DEFAULT_BOARD_APPEARANCE, DEFAULT_BOARD_COLOR, DEFAULT_BOARD_CONNECTION_ROUTING, DEFAULT_BOARD_CONNECTION_STYLE, DEFAULT_BOARD_LIMITS, DEFAULT_BOARD_RELATION, DEFAULT_BOARD_TOOL_STYLES, DrawPoint, DrawPointSchema, type DrawShapeProps, EDGE_RESIZE_HANDLES, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FIT_PADDING, FULL_CAPABILITIES, FileAvailability, FilePreviewKind, FrameLookup, GEO_KINDS, type GeoKind, type GeoShapeProps, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, type HandleDragResult, ITEM_BASE_KEYS, type ImageShapeProps, InvalidBoardFileError, KNOWN_BOARD_ITEM_TYPES, KnownBoardItemType, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, Point, ProceduralClipInput, QualityProfile, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, Rect, RenderBounds, ResizeHandle, ResolvedArrow, ResolvedConnection, ResolvedConnectionEndpoint, ResolvedCover, SampledTrack, ScreenPoint, type ShapeCapabilities, ShapeDefinition, type ShapeGeometry, type ShapeHandle, type ShapeHandleId, type ShapeResizeMode, Size, SpaceFileRef, SpaceFileRefSchema, TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, type TextShapeProps, TrackInput, UNKNOWN_BOARD_ITEM_TYPE, VIEWPORT_MARGIN_RATIO, type VideoShapeProps, WireBackedBoardItem, WorldPoint, anchorPointOnFrame, anchorToWorld, angleFromCenter, arrowBounds, arrowFrame, autoConnectionSide, availabilityFromError, boardAppearanceOperation, boardBootstrapToDocument, boardColorCssVar, boardCompositionApplyOperation, boardCompositionDeleteOperation, boardEffectDeleteOperation, boardEffectUpsertOperation, boardFrameLookup, boardImageKeySource, boardNodeToItem, boardPlaybackPolicyOperation, boardTextLineHeight, boardTitleOperation, buildFallbackShapeColors, buildFileExcerpt, buildFileSnapshot, buildStrokeOutline, cameraForFocus, cameraForRect, cameraForState, clamp, clampBoardStrokeSize, clampBoardTextFontSize, clampZoom, compileComposition, composition, computeDrawBounds, connectionArrowheads, connectionBounds, connectionHitTest, connectionNodeIds, connectionOtherNodeId, connectionTouchesNode, createBoardConnection, createBoardExtensionRegistry, createBoardToolStyles, createConnectionIndex, definitionForItem, degToRad, distanceToArrow, distanceToConnection, distanceToStroke, expandRect, exportConnectionBounds, exportItemBounds, featuredTaskArtifact, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, fitToContent, flipBoardConnection, formatFileSize, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, getMediaExtension, getMediaResourceTitle, getShapeDefinition, handlePosition, imageAssetKey, inferBoardMediaKind, isBoardColorId, isBoardPath, isFileBackedItem, isFileSnapshotFresh, isGeoKind, isMediaItem, isPublicBoardRemoteAddress, isRecord, isUnknownItem, itemBounds, measureBoardText, mergeFileSnapshot, nodeInputFromRecord, normalizeBoardConnectionStyle, normalizeBoardDocument, normalizeBoardRemoteUrl, normalizeRotation, normalizeViewport, normalizedPoint, panBy, parseBoardDocument, parseBoardItemLoose, parseBoardManifest, patchBoardAppearance, pathMidpoint, pickBoardColor, planBoardExport, playableBoardMedia, playableBoardMediaList, pointToWorld, pointsBounds, proceduralClip, radToDeg, rankedTaskArtifacts, readCoverFromFrontmatter, readTitleFromFrontmatter, rectCenter, rectContainsPoint, rectForCameraFocus, rectsIntersect, registerShapeDefinition, resetBoardPlaybackUrlCache, resizeFrame, resizeFrameToSize, resizeModeForCapabilities, resolveArrow, resolveBoardColor, resolveConnection, resolveCoverRef, resolveSpacePath, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, sampleArrow, sampleCompositionTracks, sampleEasing, sampleRadius, sampleTrack, scaleFrames, screenOffset, screenPoint, screenToWorld, selectBoardExportAssets, selectionBounds, serializeBoardManifest, setBoardTextMeasurer, shapeBounds, shapeCapabilities, shapeHandles, shapeHitTest, shapeResizeMode, shouldFetchFileExcerpt, simplifyDrawIndices, sourceForItem, splitFrontmatter, taskArtifactPreviewUrl, taskArtifacts, taskRunToBoardTaskSnapshot, track, translateArrow, unionRects, unknownRealType, unknownShapeDefinition, visibleWorldRect, withResolvedConnections, worldOffset, worldPoint, worldRect, worldToAnchor, worldToScreen, zoomAround };
@@ -1,12 +1,13 @@
1
1
  import { BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, clampBoardStrokeSize } from "../protocol/dist/board-constants.js";
2
- import { BoardExtensionRegistry, DEFAULT_BOARD_LIMITS, clip, compileSequence, createBoardExtensionRegistry, timeline } from "./animation.js";
3
2
  import { AUTO_BOARD_CONNECTION_ANCHOR, BOARD_CONNECTION_DIRECTIONS, BOARD_CONNECTION_LINES, BOARD_CONNECTION_ROUTINGS, BOARD_CONNECTION_SIDES, BoardConnectionAnchorSchema, BoardConnectionEndpointSchema, BoardConnectionPatchSchema, BoardConnectionRoutingSchema, BoardConnectionSchema, BoardConnectionStyleSchema, BoardConnectionWaypointSchema, BoardRelationSchema, DEFAULT_BOARD_CONNECTION_ROUTING, DEFAULT_BOARD_CONNECTION_STYLE, DEFAULT_BOARD_RELATION, connectionNodeIds, connectionOtherNodeId, connectionTouchesNode, createBoardConnection, flipBoardConnection, normalizeBoardConnectionStyle } from "../protocol/dist/board-connection.js";
4
- import { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, InvalidBoardFileError, isBoardPath, parseBoardManifest, serializeBoardManifest } from "../protocol/dist/board.js";
5
- import { BOARD_REMOTE_URL_MAX_LENGTH, BoardRemoteUrlSchema, normalizeBoardRemoteUrl } from "../protocol/dist/board-url.js";
3
+ import { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, BoardCameraFocusParamsSchema, BoardCameraFocusSchema, BoardCameraStateSchema, InvalidBoardFileError, isBoardPath, parseBoardManifest, serializeBoardManifest } from "../protocol/dist/board.js";
4
+ import { BOARD_REMOTE_URL_MAX_LENGTH, BoardRemoteUrlSchema, isPublicBoardRemoteAddress, normalizeBoardRemoteUrl } from "../protocol/dist/board-url.js";
6
5
  import { BOARD_TASK_ARTIFACT_LIMIT, BoardAppearanceSchema, BoardArrowItemSchema, BoardAudioItemSchema, BoardDocumentSchema, BoardDrawItemSchema, BoardFileItemSchema, BoardFileSnapshotSchema, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItemSchema, BoardImageItemSchema, BoardItemSchema, BoardItemStyleSchema, BoardMediaSnapshotSchema, BoardPointSchema, BoardTaskArtifactSchema, BoardTaskItemSchema, BoardTaskSnapshotSchema, BoardTextItemSchema, BoardVideoItemSchema, BoardViewportSchema, DrawPointSchema, KNOWN_BOARD_ITEM_TYPES, SpaceFileRefSchema, UNKNOWN_BOARD_ITEM_TYPE, isFileBackedItem, isMediaItem, isUnknownItem, parseBoardDocument, parseBoardItemLoose, unknownRealType, withResolvedConnections } from "../protocol/dist/board-document.js";
6
+ import "../protocol/dist/index.js";
7
+ import { BOARD_CHANNELS, BoardExtensionRegistry, DEFAULT_BOARD_LIMITS, compileComposition, composition, createBoardExtensionRegistry, proceduralClip, sampleCompositionTracks, sampleEasing, sampleTrack, track } from "./animation.js";
7
8
  import { TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, boardTextLineHeight, clampBoardTextFontSize, measureBoardText, setBoardTextMeasurer } from "./core/text-metrics.js";
8
9
  import { BOARD_NODE_SOURCE, DEFAULT_BOARD_APPEARANCE, ITEM_BASE_KEYS, boardBootstrapToDocument, boardNodeToItem, isRecord, nodeInputFromRecord, sourceForItem } from "./codec.js";
9
- 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, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround } from "./geometry.js";
10
+ 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, unionRects, visibleWorldRect, worldOffset, worldPoint, worldRect, worldToScreen, zoomAround } from "./geometry.js";
10
11
  import { featuredTaskArtifact, rankedTaskArtifacts, taskArtifactPreviewUrl, taskArtifacts, taskRunToBoardTaskSnapshot } from "./task.js";
11
12
  import { boardImageKeySource, imageAssetKey } from "./image-key.js";
12
13
  import { arrowBounds, arrowFrame, distanceToArrow, resolveArrow, sampleArrow, translateArrow } from "./core/arrow-geometry.js";
@@ -21,5 +22,5 @@ import { definitionForItem, getShapeDefinition, registerShapeDefinition, shapeBo
21
22
  import { DEFAULT_BOARD_TOOL_STYLES, createBoardToolStyles } from "./core/tool-styles.js";
22
23
  import { getMediaExtension, getMediaResourceTitle, inferBoardMediaKind } from "./media.js";
23
24
  import { playableBoardMedia, playableBoardMediaList, resetBoardPlaybackUrlCache } from "./media-playback.js";
24
- import { BoardInputError, assertBoardNodes, assertBoardTransactionNodeCreates, createBoardNode, validateBoardNodes } from "./nodes.js";
25
- export { AUTO_BOARD_CONNECTION_ANCHOR, BOARD_COLORS, BOARD_CONNECTION_DIRECTIONS, BOARD_CONNECTION_LINES, BOARD_CONNECTION_ROUTINGS, BOARD_CONNECTION_SIDES, BOARD_DOCUMENT_KIND, 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, BOARD_NODE_SOURCE, BOARD_REMOTE_URL_MAX_LENGTH, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BOARD_TASK_ARTIFACT_LIMIT, BoardAppearanceSchema, BoardArrowItemSchema, BoardAudioItemSchema, BoardConnectionAnchorSchema, BoardConnectionEndpointSchema, BoardConnectionPatchSchema, BoardConnectionRoutingSchema, BoardConnectionSchema, BoardConnectionStyleSchema, BoardConnectionWaypointSchema, BoardDocumentSchema, BoardDrawItemSchema, BoardExtensionRegistry, BoardFileItemSchema, BoardFileSnapshotSchema, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItemSchema, BoardImageItemSchema, BoardInputError, BoardItemSchema, BoardItemStyleSchema, BoardMediaSnapshotSchema, BoardPointSchema, BoardRelationSchema, BoardRemoteUrlSchema, BoardTaskArtifactSchema, BoardTaskItemSchema, BoardTaskSnapshotSchema, BoardTextItemSchema, BoardVideoItemSchema, BoardViewportSchema, CONNECTION_ENDPOINT_GAP, CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, DEFAULT_BOARD_APPEARANCE, DEFAULT_BOARD_COLOR, DEFAULT_BOARD_CONNECTION_ROUTING, DEFAULT_BOARD_CONNECTION_STYLE, DEFAULT_BOARD_LIMITS, DEFAULT_BOARD_RELATION, DEFAULT_BOARD_TOOL_STYLES, DrawPointSchema, EDGE_RESIZE_HANDLES, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FIT_PADDING, FULL_CAPABILITIES, GEO_KINDS, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, ITEM_BASE_KEYS, InvalidBoardFileError, KNOWN_BOARD_ITEM_TYPES, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, SpaceFileRefSchema, TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, UNKNOWN_BOARD_ITEM_TYPE, VIEWPORT_MARGIN_RATIO, anchorPointOnFrame, anchorToWorld, angleFromCenter, arrowBounds, arrowFrame, assertBoardNodes, assertBoardTransactionNodeCreates, autoConnectionSide, availabilityFromError, boardBootstrapToDocument, boardColorCssVar, boardFrameLookup, boardImageKeySource, boardNodeToItem, boardTextLineHeight, buildFallbackShapeColors, buildFileExcerpt, buildFileSnapshot, buildStrokeOutline, clamp, clampBoardStrokeSize, clampBoardTextFontSize, clampZoom, clip, compileSequence, computeDrawBounds, connectionArrowheads, connectionBounds, connectionHitTest, connectionNodeIds, connectionOtherNodeId, connectionTouchesNode, createBoardConnection, createBoardExtensionRegistry, createBoardNode, createBoardToolStyles, createConnectionIndex, definitionForItem, degToRad, distanceToArrow, distanceToConnection, distanceToStroke, expandRect, exportConnectionBounds, exportItemBounds, featuredTaskArtifact, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, fitToContent, flipBoardConnection, formatFileSize, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, getMediaExtension, getMediaResourceTitle, getShapeDefinition, handlePosition, imageAssetKey, inferBoardMediaKind, isBoardColorId, isBoardPath, isFileBackedItem, isFileSnapshotFresh, isGeoKind, isMediaItem, isRecord, isUnknownItem, itemBounds, measureBoardText, mergeFileSnapshot, nodeInputFromRecord, normalizeBoardConnectionStyle, normalizeBoardDocument, normalizeBoardRemoteUrl, normalizeRotation, normalizeViewport, panBy, parseBoardDocument, parseBoardItemLoose, parseBoardManifest, pathMidpoint, pickBoardColor, planBoardExport, playableBoardMedia, playableBoardMediaList, pointToWorld, radToDeg, rankedTaskArtifacts, readCoverFromFrontmatter, readTitleFromFrontmatter, rectCenter, rectContainsPoint, rectsIntersect, registerShapeDefinition, resetBoardPlaybackUrlCache, resizeFrame, resizeFrameToSize, resizeModeForCapabilities, resolveArrow, resolveBoardColor, resolveConnection, resolveCoverRef, resolveSpacePath, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, sampleArrow, sampleRadius, scaleFrames, screenPoint, screenToWorld, selectBoardExportAssets, selectionBounds, serializeBoardManifest, setBoardTextMeasurer, shapeBounds, shapeCapabilities, shapeHandles, shapeHitTest, shapeResizeMode, shouldFetchFileExcerpt, simplifyDrawIndices, sourceForItem, splitFrontmatter, taskArtifactPreviewUrl, taskArtifacts, taskRunToBoardTaskSnapshot, timeline, translateArrow, unionRects, unknownRealType, unknownShapeDefinition, validateBoardNodes, visibleWorldRect, withResolvedConnections, worldPoint, worldToAnchor, worldToScreen, zoomAround };
25
+ import { boardAppearanceOperation, boardCompositionApplyOperation, boardCompositionDeleteOperation, boardEffectDeleteOperation, boardEffectUpsertOperation, boardPlaybackPolicyOperation, boardTitleOperation, patchBoardAppearance } from "./mutation.js";
26
+ export { AUTO_BOARD_CONNECTION_ANCHOR, BOARD_CHANNELS, BOARD_COLORS, BOARD_CONNECTION_DIRECTIONS, BOARD_CONNECTION_LINES, BOARD_CONNECTION_ROUTINGS, BOARD_CONNECTION_SIDES, BOARD_DOCUMENT_KIND, 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, BOARD_NODE_SOURCE, BOARD_REMOTE_URL_MAX_LENGTH, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BOARD_TASK_ARTIFACT_LIMIT, BoardAppearanceSchema, BoardArrowItemSchema, BoardAudioItemSchema, BoardCameraFocusParamsSchema, BoardCameraFocusSchema, BoardCameraStateSchema, BoardConnectionAnchorSchema, BoardConnectionEndpointSchema, BoardConnectionPatchSchema, BoardConnectionRoutingSchema, BoardConnectionSchema, BoardConnectionStyleSchema, BoardConnectionWaypointSchema, BoardDocumentSchema, BoardDrawItemSchema, BoardExtensionRegistry, BoardFileItemSchema, BoardFileSnapshotSchema, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItemSchema, BoardImageItemSchema, BoardItemSchema, BoardItemStyleSchema, BoardMediaSnapshotSchema, BoardPointSchema, BoardRelationSchema, BoardRemoteUrlSchema, BoardTaskArtifactSchema, BoardTaskItemSchema, BoardTaskSnapshotSchema, BoardTextItemSchema, BoardVideoItemSchema, BoardViewportSchema, CONNECTION_ENDPOINT_GAP, CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, DEFAULT_BOARD_APPEARANCE, DEFAULT_BOARD_COLOR, DEFAULT_BOARD_CONNECTION_ROUTING, DEFAULT_BOARD_CONNECTION_STYLE, DEFAULT_BOARD_LIMITS, DEFAULT_BOARD_RELATION, DEFAULT_BOARD_TOOL_STYLES, DrawPointSchema, EDGE_RESIZE_HANDLES, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FIT_PADDING, FULL_CAPABILITIES, GEO_KINDS, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, ITEM_BASE_KEYS, InvalidBoardFileError, KNOWN_BOARD_ITEM_TYPES, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, SpaceFileRefSchema, TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, UNKNOWN_BOARD_ITEM_TYPE, VIEWPORT_MARGIN_RATIO, anchorPointOnFrame, anchorToWorld, angleFromCenter, arrowBounds, arrowFrame, autoConnectionSide, availabilityFromError, boardAppearanceOperation, boardBootstrapToDocument, boardColorCssVar, boardCompositionApplyOperation, boardCompositionDeleteOperation, boardEffectDeleteOperation, boardEffectUpsertOperation, boardFrameLookup, boardImageKeySource, boardNodeToItem, boardPlaybackPolicyOperation, boardTextLineHeight, boardTitleOperation, buildFallbackShapeColors, buildFileExcerpt, buildFileSnapshot, buildStrokeOutline, cameraForFocus, cameraForRect, cameraForState, clamp, clampBoardStrokeSize, clampBoardTextFontSize, clampZoom, compileComposition, composition, computeDrawBounds, connectionArrowheads, connectionBounds, connectionHitTest, connectionNodeIds, connectionOtherNodeId, connectionTouchesNode, createBoardConnection, createBoardExtensionRegistry, createBoardToolStyles, createConnectionIndex, definitionForItem, degToRad, distanceToArrow, distanceToConnection, distanceToStroke, expandRect, exportConnectionBounds, exportItemBounds, featuredTaskArtifact, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, fitToContent, flipBoardConnection, formatFileSize, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, getMediaExtension, getMediaResourceTitle, getShapeDefinition, handlePosition, imageAssetKey, inferBoardMediaKind, isBoardColorId, isBoardPath, isFileBackedItem, isFileSnapshotFresh, isGeoKind, isMediaItem, isPublicBoardRemoteAddress, isRecord, isUnknownItem, itemBounds, measureBoardText, mergeFileSnapshot, nodeInputFromRecord, normalizeBoardConnectionStyle, normalizeBoardDocument, normalizeBoardRemoteUrl, normalizeRotation, normalizeViewport, normalizedPoint, panBy, parseBoardDocument, parseBoardItemLoose, parseBoardManifest, patchBoardAppearance, pathMidpoint, pickBoardColor, planBoardExport, playableBoardMedia, playableBoardMediaList, pointToWorld, pointsBounds, proceduralClip, radToDeg, rankedTaskArtifacts, readCoverFromFrontmatter, readTitleFromFrontmatter, rectCenter, rectContainsPoint, rectForCameraFocus, rectsIntersect, registerShapeDefinition, resetBoardPlaybackUrlCache, resizeFrame, resizeFrameToSize, resizeModeForCapabilities, resolveArrow, resolveBoardColor, resolveConnection, resolveCoverRef, resolveSpacePath, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, sampleArrow, sampleCompositionTracks, sampleEasing, sampleRadius, sampleTrack, scaleFrames, screenOffset, screenPoint, screenToWorld, selectBoardExportAssets, selectionBounds, serializeBoardManifest, setBoardTextMeasurer, shapeBounds, shapeCapabilities, shapeHandles, shapeHitTest, shapeResizeMode, shouldFetchFileExcerpt, simplifyDrawIndices, sourceForItem, splitFrontmatter, taskArtifactPreviewUrl, taskArtifacts, taskRunToBoardTaskSnapshot, track, translateArrow, unionRects, unknownRealType, unknownShapeDefinition, visibleWorldRect, withResolvedConnections, worldOffset, worldPoint, worldRect, worldToAnchor, worldToScreen, zoomAround };
@@ -0,0 +1,15 @@
1
+ import { BoardComposition } from "../protocol/dist/board-composition.js";
2
+ import { BoardEffect, BoardOperation, BoardPlaybackPolicy } from "../protocol/dist/board.js";
3
+ import "../protocol/dist/index.js";
4
+ import { BoardAppearance } from "../protocol/dist/board-document.js";
5
+ //#region src/board/mutation.d.ts
6
+ declare function patchBoardAppearance(current: BoardAppearance, patch: Partial<BoardAppearance>): BoardAppearance;
7
+ declare function boardAppearanceOperation(appearance: BoardAppearance): BoardOperation;
8
+ declare function boardTitleOperation(title: string): BoardOperation;
9
+ declare function boardPlaybackPolicyOperation(metadata: Record<string, unknown>, policy: BoardPlaybackPolicy | null): BoardOperation;
10
+ declare function boardEffectUpsertOperation(effect: Omit<BoardEffect, "boardId" | "revision">): BoardOperation;
11
+ declare function boardEffectDeleteOperation(effectId: string): BoardOperation;
12
+ declare function boardCompositionApplyOperation(composition: Omit<BoardComposition, "revision">): BoardOperation;
13
+ declare function boardCompositionDeleteOperation(compositionId: string): BoardOperation;
14
+ //#endregion
15
+ export { boardAppearanceOperation, boardCompositionApplyOperation, boardCompositionDeleteOperation, boardEffectDeleteOperation, boardEffectUpsertOperation, boardPlaybackPolicyOperation, boardTitleOperation, patchBoardAppearance };
@@ -0,0 +1,67 @@
1
+ import { parseBoardCompositionInput } from "../protocol/dist/board-composition.js";
2
+ import { BoardEffectSchema } from "../protocol/dist/board.js";
3
+ import { BoardAppearanceSchema } from "../protocol/dist/board-document.js";
4
+ import "../protocol/dist/index.js";
5
+ //#region src/board/mutation.ts
6
+ const EffectInputSchema = BoardEffectSchema.omit({
7
+ boardId: true,
8
+ revision: true
9
+ });
10
+ function patchBoardAppearance(current, patch) {
11
+ return BoardAppearanceSchema.parse({
12
+ ...current,
13
+ ...patch,
14
+ background: patch.background ?? current.background,
15
+ grid: patch.grid ?? current.grid
16
+ });
17
+ }
18
+ function boardAppearanceOperation(appearance) {
19
+ return {
20
+ type: "board.patch",
21
+ payload: { patch: { metadataPatch: { appearance } } }
22
+ };
23
+ }
24
+ function boardTitleOperation(title) {
25
+ return {
26
+ type: "board.patch",
27
+ payload: { patch: { title } }
28
+ };
29
+ }
30
+ function boardPlaybackPolicyOperation(metadata, policy) {
31
+ if (policy) return {
32
+ type: "board.patch",
33
+ payload: { patch: { metadataPatch: { playback: policy } } }
34
+ };
35
+ const next = { ...metadata };
36
+ delete next.playback;
37
+ return {
38
+ type: "board.patch",
39
+ payload: { patch: { metadata: next } }
40
+ };
41
+ }
42
+ function boardEffectUpsertOperation(effect) {
43
+ return {
44
+ type: "effect.upsert",
45
+ payload: { effect: EffectInputSchema.parse(effect) }
46
+ };
47
+ }
48
+ function boardEffectDeleteOperation(effectId) {
49
+ return {
50
+ type: "effect.delete",
51
+ payload: { effectId }
52
+ };
53
+ }
54
+ function boardCompositionApplyOperation(composition) {
55
+ return {
56
+ type: "composition.apply",
57
+ payload: { composition: parseBoardCompositionInput(composition) }
58
+ };
59
+ }
60
+ function boardCompositionDeleteOperation(compositionId) {
61
+ return {
62
+ type: "composition.delete",
63
+ payload: { compositionId }
64
+ };
65
+ }
66
+ //#endregion
67
+ export { boardAppearanceOperation, boardCompositionApplyOperation, boardCompositionDeleteOperation, boardEffectDeleteOperation, boardEffectUpsertOperation, boardPlaybackPolicyOperation, boardTitleOperation, patchBoardAppearance };
@@ -0,0 +1,4 @@
1
+ //#region src/board/render/css-color.d.ts
2
+ declare function parseBoardCssColor(value: string): number | null;
3
+ //#endregion
4
+ export { parseBoardCssColor };
@@ -0,0 +1,36 @@
1
+ import { DOMAdapter } from "pixi.js";
2
+ //#region src/board/render/css-color.ts
3
+ const CACHE_LIMIT = 256;
4
+ const cache = /* @__PURE__ */ new Map();
5
+ let canvas = null;
6
+ function parseBoardCssColor(value) {
7
+ const key = value.trim();
8
+ if (!key) return null;
9
+ const cached = cache.get(key);
10
+ if (cached !== void 0 || cache.has(key)) return cached ?? null;
11
+ let result = null;
12
+ try {
13
+ const direct = /^#([0-9a-f]{6})$/i.exec(key);
14
+ if (direct?.[1]) result = Number.parseInt(direct[1], 16);
15
+ else {
16
+ canvas ??= DOMAdapter.get().createCanvas(1, 1);
17
+ const context = canvas.getContext("2d");
18
+ if (context) {
19
+ context.fillStyle = "#010203";
20
+ context.fillStyle = key;
21
+ const first = String(context.fillStyle);
22
+ context.fillStyle = "#040506";
23
+ context.fillStyle = key;
24
+ const match = first === String(context.fillStyle) ? /^#([0-9a-f]{6})$/i.exec(first) : null;
25
+ if (match?.[1]) result = Number.parseInt(match[1], 16);
26
+ }
27
+ }
28
+ } catch {
29
+ result = null;
30
+ }
31
+ if (cache.size >= CACHE_LIMIT) cache.clear();
32
+ cache.set(key, result);
33
+ return result;
34
+ }
35
+ //#endregion
36
+ export { parseBoardCssColor };
@@ -1,4 +1,5 @@
1
1
  import { ConnectionLayer, ConnectionRenderInput, createConnectionLayer, framesFromItems } from "./connection-layer.js";
2
+ import { parseBoardCssColor } from "./css-color.js";
2
3
  import { BoardMediaAction, boardMediaActionAt, mediaPlayBadgeHit, mediaPlayBadgeVisible } from "./media-interaction.js";
3
4
  import { BoardCardRenderer, BoardRenderContext, BoardRenderPalette, boardCardRenderersForTest, getBoardCardRenderer, registerBoardCardRenderer } from "./renderers/board-renderer-registry.js";
4
5
  import { defaultBoardPalette } from "./palette.js";
@@ -7,4 +8,4 @@ import { ensureBoardTextMeasurement, installBoardTextMeasurement } from "./text-
7
8
  import { getBoardResolution, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket } from "./text-resolution.js";
8
9
  import { BoardThemeContext, BoardThemeRenderer, getBoardThemeRenderer, registerBoardThemeRenderer } from "./themes/board-theme-registry.js";
9
10
  import { VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, loadVideoThumbnailTexture, videoTextureNaturalSize, videoThumbnailSize } from "./video-thumbnail.js";
10
- export { BoardCardRenderer, BoardMediaAction, BoardRenderContext, BoardRenderPalette, BoardThemeContext, BoardThemeRenderer, ConnectionLayer, ConnectionRenderInput, TASK_CARD_FULL_DETAIL_ZOOM, VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, boardCardRenderersForTest, boardMediaActionAt, createConnectionLayer, defaultBoardPalette, ensureBoardTextMeasurement, framesFromItems, getBoardCardRenderer, getBoardResolution, getBoardThemeRenderer, installBoardTextMeasurement, loadVideoThumbnailTexture, mediaPlayBadgeHit, mediaPlayBadgeVisible, registerBoardCardRenderer, registerBoardThemeRenderer, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket, videoTextureNaturalSize, videoThumbnailSize };
11
+ export { BoardCardRenderer, BoardMediaAction, BoardRenderContext, BoardRenderPalette, BoardThemeContext, BoardThemeRenderer, ConnectionLayer, ConnectionRenderInput, TASK_CARD_FULL_DETAIL_ZOOM, VIDEO_THUMBNAIL_MAX_EDGE, VideoNaturalSize, boardCardRenderersForTest, boardMediaActionAt, createConnectionLayer, defaultBoardPalette, ensureBoardTextMeasurement, framesFromItems, getBoardCardRenderer, getBoardResolution, getBoardThemeRenderer, installBoardTextMeasurement, loadVideoThumbnailTexture, mediaPlayBadgeHit, mediaPlayBadgeVisible, parseBoardCssColor, registerBoardCardRenderer, registerBoardThemeRenderer, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket, videoTextureNaturalSize, videoThumbnailSize };
@@ -1,3 +1,4 @@
1
+ import { parseBoardCssColor } from "./css-color.js";
1
2
  import { getBoardResolution, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket } from "./text-resolution.js";
2
3
  import { createConnectionLayer, framesFromItems } from "./connection-layer.js";
3
4
  import { TASK_CARD_FULL_DETAIL_ZOOM } from "./renderers/task-card-renderer.js";
@@ -7,4 +8,4 @@ import { ensureBoardTextMeasurement, installBoardTextMeasurement } from "./text-
7
8
  import { boardCardRenderersForTest, getBoardCardRenderer, registerBoardCardRenderer } from "./renderers/board-renderer-registry.js";
8
9
  import { getBoardThemeRenderer, registerBoardThemeRenderer } from "./themes/board-theme-registry.js";
9
10
  import { VIDEO_THUMBNAIL_MAX_EDGE, loadVideoThumbnailTexture, videoTextureNaturalSize, videoThumbnailSize } from "./video-thumbnail.js";
10
- export { TASK_CARD_FULL_DETAIL_ZOOM, VIDEO_THUMBNAIL_MAX_EDGE, boardCardRenderersForTest, boardMediaActionAt, createConnectionLayer, defaultBoardPalette, ensureBoardTextMeasurement, framesFromItems, getBoardCardRenderer, getBoardResolution, getBoardThemeRenderer, installBoardTextMeasurement, loadVideoThumbnailTexture, mediaPlayBadgeHit, mediaPlayBadgeVisible, registerBoardCardRenderer, registerBoardThemeRenderer, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket, videoTextureNaturalSize, videoThumbnailSize };
11
+ export { TASK_CARD_FULL_DETAIL_ZOOM, VIDEO_THUMBNAIL_MAX_EDGE, boardCardRenderersForTest, boardMediaActionAt, createConnectionLayer, defaultBoardPalette, ensureBoardTextMeasurement, framesFromItems, getBoardCardRenderer, getBoardResolution, getBoardThemeRenderer, installBoardTextMeasurement, loadVideoThumbnailTexture, mediaPlayBadgeHit, mediaPlayBadgeVisible, parseBoardCssColor, registerBoardCardRenderer, registerBoardThemeRenderer, syncTextResolution, syncTextWrapWidth, textResolutionForZoom, textZoomBucket, videoTextureNaturalSize, videoThumbnailSize };
@@ -1,6 +1,7 @@
1
1
  import { BOARD_FONT_STACK } from "../../../protocol/dist/board-constants.js";
2
+ import { parseBoardCssColor } from "../css-color.js";
2
3
  import { getBoardResolution } from "../text-resolution.js";
3
- import { Container, DOMAdapter, Graphics, Text } from "pixi.js";
4
+ import { Container, Graphics, Text } from "pixi.js";
4
5
  //#region src/board/render/renderers/base-card-renderer.ts
5
6
  const CARD_RADIUS = 10;
6
7
  const CARD_PADDING = 12;
@@ -11,7 +12,7 @@ const TEXT_OPTIONS = {
11
12
  };
12
13
  function emphasisColor(item, palette) {
13
14
  if (item.style?.accentColor) {
14
- const normalized = parseCssColor(item.style.accentColor);
15
+ const normalized = parseBoardCssColor(item.style.accentColor);
15
16
  if (normalized != null) return normalized;
16
17
  }
17
18
  switch (item.style?.emphasis) {
@@ -21,24 +22,6 @@ function emphasisColor(item, palette) {
21
22
  default: return palette.brand;
22
23
  }
23
24
  }
24
- /**
25
- * Normalise any CSS color to a number by letting a 2D context parse it.
26
- *
27
- * Goes through `DOMAdapter` rather than `document` so a headless export resolves
28
- * accent colors exactly as the browser does; without it, custom accents would
29
- * silently fall back to the emphasis palette only when exporting.
30
- */
31
- function parseCssColor(value) {
32
- try {
33
- const context = DOMAdapter.get().createCanvas(1, 1).getContext("2d");
34
- if (!context) return null;
35
- context.fillStyle = value;
36
- const match = /^#([0-9a-f]{6})$/i.exec(String(context.fillStyle));
37
- return match?.[1] ? Number.parseInt(match[1], 16) : null;
38
- } catch {
39
- return null;
40
- }
41
- }
42
25
  function createLabel(text, style) {
43
26
  return new Text({
44
27
  ...TEXT_OPTIONS,
@@ -1,3 +1,4 @@
1
+ import { parseBoardCssColor } from "../css-color.js";
1
2
  import { Container, Graphics, RenderTexture, TilingSprite } from "pixi.js";
2
3
  //#region src/board/render/themes/clean-theme.ts
3
4
  const partsByContainer = /* @__PURE__ */ new WeakMap();
@@ -31,16 +32,18 @@ function sync(parts, context) {
31
32
  const { app, document, viewport, palette } = context;
32
33
  const width = app.screen.width;
33
34
  const height = app.screen.height;
35
+ const declaredBackground = document.appearance.background;
36
+ const bgColor = declaredBackground.color ? parseBoardCssColor(declaredBackground.color) ?? palette.bg : palette.bg;
34
37
  const bgAlpha = context.hasImageBackground ? 0 : 1;
35
- if (parts.lastWidth !== width || parts.lastHeight !== height || parts.lastBg !== palette.bg || parts.lastBgAlpha !== bgAlpha) {
38
+ if (parts.lastWidth !== width || parts.lastHeight !== height || parts.lastBg !== bgColor || parts.lastBgAlpha !== bgAlpha) {
36
39
  parts.fill.clear();
37
40
  parts.fill.rect(0, 0, width, height).fill({
38
- color: palette.bg,
41
+ color: bgColor,
39
42
  alpha: bgAlpha
40
43
  });
41
44
  parts.lastWidth = width;
42
45
  parts.lastHeight = height;
43
- parts.lastBg = palette.bg;
46
+ parts.lastBg = bgColor;
44
47
  parts.lastBgAlpha = bgAlpha;
45
48
  }
46
49
  const appearance = document.appearance;