canvu-react 0.4.8 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react/presence/map-placement-preview.ts","../src/math/rect.ts","../src/renderer/svg-vector-renderer.ts","../src/scene/freehand-path.ts","../src/scene/custom-shape.ts","../src/scene/shape-builders.ts","../src/react/presence/peer-color.ts","../src/react/presence/PresenceRemoteLayer.tsx","../src/react/plugins/realtime/protocol.ts","../src/react/plugins/realtime/RealtimeSessionPanel.tsx","../src/react/plugins/types.ts","../src/react/tools/icons.tsx","../src/react/tools/default-tools.tsx","../src/react/plugins/realtime/realtime-comment-tool.tsx","../src/react/plugins/realtime/use-realtime-comments.tsx","../src/react/plugins/realtime/use-realtime-peer-follow.ts","../src/react/plugins/realtime/yjs-document.ts","../src/react/plugins/realtime/use-realtime-session.ts","../src/react/plugins/realtime/realtime-collaboration-plugin.tsx","../src/react/plugins/realtime/realtime-session-plugin.tsx","../src/react/plugins/realtime/use-realtime-canvas-document.ts"],"names":["base","d","getStroke","jsx","MousePointer2","document","jsxs","Fragment","createContext","useContext","useLayoutEffect","Hand","Square","Circle","Minus","ArrowUpRight","PenLine","Highlighter","Eraser","Type","Image","MessageSquare","isRecord","getString","getNumber","useState","useRef","useEffect","Sparkles","overlayShell","useMemo","useCallback","Y","id","options"],"mappings":"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","file":"realtime.cjs","sourcesContent":["import type { PlacementPreview } from \"../InteractionOverlay\";\nimport type { RemotePresenceMarkupStroke } from \"./types\";\n\n/**\n * Maps a local {@link PlacementPreview} stroke to {@link RemotePresenceMarkupStroke} for broadcasting.\n * Returns `null` when there is no in-progress stroke.\n */\nexport function remoteMarkupStrokeFromPlacementPreview(\n\tpreview: PlacementPreview | null,\n): RemotePresenceMarkupStroke | null {\n\tif (!preview || preview.kind !== \"stroke\" || preview.points.length === 0) {\n\t\treturn null;\n\t}\n\tconst tool = preview.tool;\n\tconst mapped: RemotePresenceMarkupStroke[\"tool\"] =\n\t\ttool === \"laser\" || tool === \"marker\" || tool === \"draw\" ? tool : \"draw\";\n\tconst style = preview.style;\n\treturn {\n\t\tpoints: preview.points,\n\t\ttool: mapped,\n\t\t...(style?.strokeWidth != null ? { strokeWidth: style.strokeWidth } : {}),\n\t\t...(style?.stroke ? { stroke: style.stroke } : {}),\n\t\t...(style?.strokeOpacity != null ? { strokeOpacity: style.strokeOpacity } : {}),\n\t};\n}\n","/**\n * Axis-aligned rectangle in 2D (world or screen space).\n */\nexport type Rect = {\n\treadonly x: number;\n\treadonly y: number;\n\treadonly width: number;\n\treadonly height: number;\n};\n\n/**\n * Returns whether two axis-aligned rectangles intersect (edges touching count).\n */\nexport function rectsIntersect(a: Rect, b: Rect): boolean {\n\treturn (\n\t\ta.x < b.x + b.width &&\n\t\ta.x + a.width > b.x &&\n\t\ta.y < b.y + b.height &&\n\t\ta.y + a.height > b.y\n\t);\n}\n\n/**\n * Normalizes a rect so width and height are non-negative.\n */\nexport function normalizeRect(r: Rect): Rect {\n\tconst x0 = r.width >= 0 ? r.x : r.x + r.width;\n\tconst y0 = r.height >= 0 ? r.y : r.y + r.height;\n\treturn {\n\t\tx: x0,\n\t\ty: y0,\n\t\twidth: Math.abs(r.width),\n\t\theight: Math.abs(r.height),\n\t};\n}\n","import type { Camera2D } from \"../camera/camera\";\nimport { normalizeRect } from \"../math/rect\";\nimport { cullItemsByViewport } from \"../scene/cull\";\nimport type { VectorScene } from \"../scene/scene\";\nimport type { VectorSceneItem } from \"../scene/types\";\n\n/**\n * Builds the SVG `transform` attribute for mapping world coordinates to viewport CSS pixels.\n */\nexport function formatCameraTransform(camera: Camera2D): string {\n\tconst z = camera.zoom;\n\treturn `matrix(${z}, 0, 0, ${z}, ${camera.x}, ${camera.y})`;\n}\n\n/**\n * Transform for item `<g>`: `translate(x,y)` plus optional rotation around the bounds center.\n * SVG `rotate` uses degrees.\n */\nexport function formatItemPlacementTransform(item: VectorSceneItem): string {\n\tconst r = normalizeRect(item.bounds);\n\tconst rot = item.rotation ?? 0;\n\tif (Math.abs(rot) < 1e-12) {\n\t\treturn `translate(${item.x}, ${item.y})`;\n\t}\n\tconst deg = (rot * 180) / Math.PI;\n\tconst cx = r.width / 2;\n\tconst cy = r.height / 2;\n\treturn `translate(${item.x}, ${item.y}) translate(${cx}, ${cy}) rotate(${deg}) translate(${-cx}, ${-cy})`;\n}\n\nexport type SvgVectorRendererOptions = {\n\t/** Root element (typically `position: relative` and fixed size). */\n\tcontainer: HTMLElement;\n\tscene: VectorScene;\n\tcamera: Camera2D;\n\t/**\n\t * When true, the scene SVG ignores pointer events so an overlay can own hit-testing\n\t * (interactive selection / resize / placement).\n\t */\n\tpointerEventsNone?: boolean;\n};\n\ntype CachedItemG = {\n\treadonly g: SVGGElement;\n\tlastChildrenSvg: string;\n\tlastTransform: string;\n};\n\n/**\n * Renders vector scene items into a single SVG: camera as an outer `<g>` transform,\n * so geometry stays sharp at any zoom (no fixed-resolution raster).\n *\n * Uses incremental DOM updates: keeps a stable `<g>` per visible item id, updates\n * `innerHTML` only when `childrenSvg` changes, and only adjusts the camera transform\n * when pan/zoom changes without content edits.\n */\nexport class SvgVectorRenderer {\n\tprivate readonly container: HTMLElement;\n\tprivate readonly scene: VectorScene;\n\tprivate readonly camera: Camera2D;\n\tprivate readonly svg: SVGSVGElement;\n\tprivate readonly rootG: SVGGElement;\n\tprivate readonly itemNodeCache = new Map<string, CachedItemG>();\n\tprivate liveOverlay: CachedItemG | null = null;\n\tprivate readonly resizeObserver: ResizeObserver;\n\n\tconstructor(options: SvgVectorRendererOptions) {\n\t\tthis.container = options.container;\n\t\tthis.scene = options.scene;\n\t\tthis.camera = options.camera;\n\n\t\tthis.svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\t\tthis.svg.setAttribute(\"width\", \"100%\");\n\t\tthis.svg.setAttribute(\"height\", \"100%\");\n\t\tthis.svg.setAttribute(\"shape-rendering\", \"geometricPrecision\");\n\t\tthis.svg.style.display = \"block\";\n\t\tthis.svg.setAttribute(\"role\", \"presentation\");\n\t\tthis.svg.setAttribute(\"focusable\", \"false\");\n\t\tthis.setPointerEventsNone(options.pointerEventsNone ?? false);\n\n\t\tthis.rootG = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n\t\tthis.svg.appendChild(this.rootG);\n\n\t\tthis.container.appendChild(this.svg);\n\n\t\tthis.resizeObserver = new ResizeObserver(() => this.render());\n\t\tthis.resizeObserver.observe(this.container);\n\t}\n\n\t/**\n\t * Reads container size, culls items, and updates the SVG (incrementally when possible).\n\t */\n\trender(): void {\n\t\tconst w = this.container.clientWidth;\n\t\tconst h = this.container.clientHeight;\n\t\tif (w <= 0 || h <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.svg.setAttribute(\"viewBox\", `0 0 ${w} ${h}`);\n\t\tthis.svg.setAttribute(\"preserveAspectRatio\", \"xMidYMid slice\");\n\n\t\tconst visible = this.camera.getVisibleWorldRect(w, h);\n\t\tconst items = cullItemsByViewport(this.scene.getItems(), visible);\n\n\t\tthis.syncVisibleItems(items);\n\t\tthis.rootG.setAttribute(\"transform\", formatCameraTransform(this.camera));\n\t\tthis.keepLiveOverlayOnTop();\n\t}\n\n\t/**\n\t * Updates only the in-progress (live) stroke node without re-culling or\n\t * re-syncing the committed scene items. Drawing tools call this on every\n\t * pointer move, so it must stay O(1) regardless of how many items the\n\t * board already contains.\n\t *\n\t * Pass `null` to remove the live overlay (e.g. when the stroke is committed).\n\t */\n\trenderLiveItem(item: VectorSceneItem | null): void {\n\t\tif (!item) {\n\t\t\tif (this.liveOverlay) {\n\t\t\t\tthis.liveOverlay.g.remove();\n\t\t\t\tthis.liveOverlay = null;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.liveOverlay) {\n\t\t\tconst g = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n\t\t\tg.setAttribute(\"data-live-overlay\", \"true\");\n\t\t\tthis.liveOverlay = {\n\t\t\t\tg,\n\t\t\t\tlastChildrenSvg: \"\",\n\t\t\t\tlastTransform: \"\",\n\t\t\t};\n\t\t\tthis.rootG.appendChild(g);\n\t\t}\n\n\t\tconst cached = this.liveOverlay;\n\t\tconst t = formatItemPlacementTransform(item);\n\t\tif (cached.lastTransform !== t) {\n\t\t\tcached.g.setAttribute(\"transform\", t);\n\t\t\tcached.lastTransform = t;\n\t\t}\n\t\tif (cached.lastChildrenSvg !== item.childrenSvg) {\n\t\t\t// Trusted SVG fragments only — sanitize untrusted strings in your app.\n\t\t\tcached.g.innerHTML = item.childrenSvg;\n\t\t\tcached.lastChildrenSvg = item.childrenSvg;\n\t\t}\n\t\tthis.keepLiveOverlayOnTop();\n\t}\n\n\tprivate keepLiveOverlayOnTop(): void {\n\t\tif (this.liveOverlay && this.rootG.lastChild !== this.liveOverlay.g) {\n\t\t\tthis.rootG.appendChild(this.liveOverlay.g);\n\t\t}\n\t}\n\n\tprivate syncVisibleItems(items: readonly VectorSceneItem[]): void {\n\t\tconst visibleIds = new Set<string>();\n\t\tfor (const item of items) {\n\t\t\tvisibleIds.add(item.id);\n\t\t}\n\n\t\tfor (const [id, cached] of this.itemNodeCache) {\n\t\t\tif (!visibleIds.has(id)) {\n\t\t\t\tcached.g.remove();\n\t\t\t}\n\t\t}\n\n\t\tlet previousNode: ChildNode | null = null;\n\t\tfor (const item of items) {\n\t\t\tlet cached = this.itemNodeCache.get(item.id);\n\t\t\tif (!cached) {\n\t\t\t\tconst g = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n\t\t\t\tg.setAttribute(\"data-item-id\", item.id);\n\t\t\t\tcached = {\n\t\t\t\t\tg,\n\t\t\t\t\tlastChildrenSvg: \"\",\n\t\t\t\t\tlastTransform: \"\",\n\t\t\t\t};\n\t\t\t\tthis.itemNodeCache.set(item.id, cached);\n\t\t\t}\n\n\t\t\tconst { g } = cached;\n\t\t\tconst t = formatItemPlacementTransform(item);\n\t\t\tif (cached.lastTransform !== t) {\n\t\t\t\tg.setAttribute(\"transform\", t);\n\t\t\t\tcached.lastTransform = t;\n\t\t\t}\n\n\t\t\tif (cached.lastChildrenSvg !== item.childrenSvg) {\n\t\t\t\t// Trusted SVG fragments only — sanitize untrusted strings in your app.\n\t\t\t\tg.innerHTML = item.childrenSvg;\n\t\t\t\tcached.lastChildrenSvg = item.childrenSvg;\n\t\t\t}\n\n\t\t\tconst expectedPosition: ChildNode | null = previousNode\n\t\t\t\t? previousNode.nextSibling\n\t\t\t\t: this.rootG.firstChild;\n\t\t\tif (expectedPosition !== g) {\n\t\t\t\tthis.rootG.insertBefore(g, expectedPosition);\n\t\t\t}\n\t\t\tpreviousNode = g;\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.resizeObserver.disconnect();\n\t\tthis.itemNodeCache.clear();\n\t\tthis.liveOverlay = null;\n\t\tthis.svg.remove();\n\t}\n\n\t/** Toggle whether the scene SVG receives pointer events (vs overlay handling them). */\n\tsetPointerEventsNone(value: boolean): void {\n\t\tthis.svg.style.pointerEvents = value ? \"none\" : \"auto\";\n\t}\n}\n","/**\n * Freehand stroke helpers: dedupe noisy samples and build smooth SVG path `d` values\n * (quadratic Béziers) so strokes don't look jagged / \"pixelated\" from many short L segments.\n */\n\n/** Drop intermediate samples closer than `minDist` (local/world units) to reduce jitter. */\nexport function dedupeFreehandPoints<T extends { x: number; y: number }>(\n\tpoints: readonly T[],\n\tminDist: number,\n): T[] {\n\tif (points.length <= 2) {\n\t\treturn points.map((p) => ({ ...p }));\n\t}\n\tconst minSq = minDist * minDist;\n\tconst first = points[0];\n\tif (!first) return [];\n\tconst out: T[] = [{ ...first }];\n\tfor (let i = 1; i < points.length - 1; i++) {\n\t\tconst p = points[i];\n\t\tconst last = out[out.length - 1];\n\t\tif (!p || !last) continue;\n\t\tconst dx = p.x - last.x;\n\t\tconst dy = p.y - last.y;\n\t\tif (dx * dx + dy * dy >= minSq) {\n\t\t\tout.push({ ...p });\n\t\t}\n\t}\n\tconst end = points[points.length - 1];\n\tconst lastKept = out[out.length - 1];\n\tif (!end || !lastKept) return out;\n\tif ((end.x - lastKept.x) ** 2 + (end.y - lastKept.y) ** 2 > 1e-12) {\n\t\tout.push({ ...end });\n\t}\n\treturn out;\n}\n\n/**\n * Smooth polyline → SVG path `d` using quadratic curves (canvas quadraticCurveTo midpoint pattern).\n * Avoids faceted \"broken\" lines from chaining many `L` commands.\n */\nexport function smoothFreehandPointsToPathD(\n\tpoints: readonly { x: number; y: number }[],\n): string {\n\tconst n = points.length;\n\tif (n === 0) return \"\";\n\tif (n === 1) {\n\t\tconst p = points[0];\n\t\tif (!p) return \"\";\n\t\treturn `M ${p.x} ${p.y}`;\n\t}\n\tif (n === 2) {\n\t\tconst a = points[0];\n\t\tconst b = points[1];\n\t\tif (!a || !b) return \"\";\n\t\treturn `M ${a.x} ${a.y} L ${b.x} ${b.y}`;\n\t}\n\tconst p0 = points[0];\n\tif (!p0) return \"\";\n\tlet d = `M ${p0.x} ${p0.y}`;\n\tlet i = 1;\n\tfor (; i < n - 2; i++) {\n\t\tconst pi = points[i];\n\t\tconst pi1 = points[i + 1];\n\t\tif (!pi || !pi1) continue;\n\t\tconst xc = (pi.x + pi1.x) / 2;\n\t\tconst yc = (pi.y + pi1.y) / 2;\n\t\td += ` Q ${pi.x} ${pi.y} ${xc} ${yc}`;\n\t}\n\tconst pLast = points[i];\n\tconst pEnd = points[i + 1];\n\tif (!pLast || !pEnd) return d;\n\td += ` Q ${pLast.x} ${pLast.y} ${pEnd.x} ${pEnd.y}`;\n\treturn d;\n}\n\n/**\n * Closed path from `perfect-freehand` outline → SVG `d` for fill.\n *\n * Uses the algorithm from the perfect-freehand README (`getSvgPathFromStroke`):\n * each outline point is a quadratic control point and the midpoint between\n * consecutive outline points is the curve endpoint. This produces\n * C1-continuous curves without the kinks that chained `T` or short `L` segments cause.\n */\nexport function outlineStrokeToClosedPathD(\n\toutline: readonly [number, number][],\n): string {\n\tconst len = outline.length;\n\tif (len === 0) return \"\";\n\tconst first = outline[0];\n\tif (!first) return \"\";\n\tif (len < 3) {\n\t\tlet d = `M ${first[0]} ${first[1]}`;\n\t\tfor (let i = 1; i < len; i++) {\n\t\t\tconst pt = outline[i];\n\t\t\tif (!pt) continue;\n\t\t\td += ` L ${pt[0]} ${pt[1]}`;\n\t\t}\n\t\treturn `${d} Z`;\n\t}\n\n\tlet d = `M ${first[0]} ${first[1]} Q`;\n\tfor (let i = 0; i < len; i++) {\n\t\tconst p0 = outline[i];\n\t\tconst p1 = outline[(i + 1) % len];\n\t\tif (!p0 || !p1) continue;\n\t\td += ` ${p0[0]} ${p0[1]} ${(p0[0] + p1[0]) / 2} ${(p0[1] + p1[1]) / 2}`;\n\t}\n\treturn `${d} Z`;\n}\n","import type { Rect } from \"../math/rect\";\nimport { normalizeRect } from \"../math/rect\";\nimport type { VectorSceneItem } from \"./types\";\n\n/** Width/height of the shape’s local drawing box (same as `bounds` at creation). */\nexport type CustomShapeSize = { width: number; height: number };\n\n/**\n * How to build the inner SVG (inside the item’s bounding box).\n *\n * - **`svg`**: paste-friendly markup. Use `{{w}}`, `{{h}}`, `{{width}}`, or `{{height}}` where the size should go.\n * - **`render`**: a small function when you prefer code over a string template.\n */\nexport type CreateCustomShapeContent =\n\t| {\n\t\t\t/**\n\t\t\t * SVG fragment for `<g>` contents (no outer `<svg>`). Placeholders are replaced with numeric sizes:\n\t\t\t * `{{w}}`, `{{h}}`, `{{width}}`, `{{height}}`.\n\t\t\t */\n\t\t\tsvg: string;\n\t }\n\t| {\n\t\t\t/** Returns inner SVG for the given box size (same coordinate range as `bounds`). */\n\t\t\trender: (size: CustomShapeSize) => string;\n\t };\n\n/**\n * Replaces `{{w}}`, `{{h}}`, `{{width}}`, and `{{height}}` in a string with the given dimensions.\n * Use this if you build SVG strings yourself and want the same rules as {@link createCustomShapeItem}.\n */\nexport function expandCustomShapeTemplate(\n\ttemplate: string,\n\twidth: number,\n\theight: number,\n): string {\n\treturn template\n\t\t.replace(/\\{\\{w\\}\\}/g, String(width))\n\t\t.replace(/\\{\\{h\\}\\}/g, String(height))\n\t\t.replace(/\\{\\{width\\}\\}/g, String(width))\n\t\t.replace(/\\{\\{height\\}\\}/g, String(height));\n}\n\nfunction resolveCustomInner(\n\tcontent: CreateCustomShapeContent,\n\tsize: CustomShapeSize,\n): string {\n\tif (\"render\" in content) {\n\t\treturn content.render(size);\n\t}\n\treturn expandCustomShapeTemplate(content.svg, size.width, size.height);\n}\n\n/**\n * Builds the scaled `<g>` wrapper used for `childrenSvg` on custom shapes that support resize.\n */\nexport function buildCustomShapeChildrenSvg(\n\tinner: string,\n\tintrinsic: CustomShapeSize,\n\tbounds: Rect,\n): string {\n\tconst b = normalizeRect(bounds);\n\tconst sx = b.width / intrinsic.width;\n\tconst sy = b.height / intrinsic.height;\n\treturn `<g transform=\"scale(${sx},${sy})\">${inner}</g>`;\n}\n\n/**\n * Creates a user-defined shape from SVG markup or a `render` callback.\n *\n * Coordinates are **local**: draw from `(0,0)` to `(width, height)` of `bounds`. The library stores an\n * intrinsic copy so resize handles (when interactive) scale the drawing uniformly.\n *\n * @example\n * ```ts\n * const star = createCustomShapeItem(createShapeId(), rect, {\n * svg: `<polygon points=\"...\" fill=\"gold\" stroke=\"#b45309\" stroke-width=\"2\" />`,\n * });\n * ```\n *\n * @example Template (good for copy-paste from design tools)\n * ```ts\n * createCustomShapeItem(id, rect, {\n * svg: `<rect width=\"{{w}}\" height=\"{{h}}\" rx=\"8\" fill=\"#e0e7ff\" stroke=\"#6366f1\" />`,\n * });\n * ```\n */\nexport function createCustomShapeItem(\n\tid: string,\n\tbounds: Rect,\n\tcontent: CreateCustomShapeContent,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst intrinsic: CustomShapeSize = { width: r.width, height: r.height };\n\tconst inner = resolveCustomInner(content, intrinsic);\n\treturn {\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"custom\",\n\t\tcustomIntrinsicSize: intrinsic,\n\t\tcustomInnerSvg: inner,\n\t\tchildrenSvg: buildCustomShapeChildrenSvg(inner, intrinsic, r),\n\t};\n}\n","import type { StrokeOptions } from \"perfect-freehand\";\nimport getStroke from \"perfect-freehand\";\nimport type { Rect } from \"../math/rect\";\nimport { normalizeRect } from \"../math/rect\";\nimport { buildCustomShapeChildrenSvg } from \"./custom-shape\";\nimport {\n\tbuildTextFixedBoundsSvg,\n\tbuildTextSvg,\n\tDEFAULT_TEXT_FONT_SIZE,\n\tmeasureTextBoundsLocal,\n} from \"./text-svg\";\nimport type {\n\tArrowBindings,\n\tLineEndpointsLocal,\n\tVectorPathPoint,\n\tVectorSceneItem,\n} from \"./types\";\n\nexport {\n\tbuildTextFixedBoundsSvg,\n\tbuildTextSvg,\n\tDEFAULT_TEXT_FONT_SIZE,\n\tmeasureTextBoundsLocal,\n};\n\n/**\n * While inline-editing: sync bounds to draft width/height and hide SVG so only the textarea shows text.\n */\nexport function applyTextDraftWhileEditing(\n\titem: VectorSceneItem,\n\tdraft: string,\n): VectorSceneItem {\n\tif (item.toolKind !== \"text\") return item;\n\tconst fs = item.textFontSize ?? DEFAULT_TEXT_FONT_SIZE;\n\tif (item.textFixedBounds) {\n\t\treturn {\n\t\t\t...item,\n\t\t\ttext: draft,\n\t\t\tchildrenSvg: \"\",\n\t\t};\n\t}\n\tconst m = measureTextBoundsLocal(draft, fs);\n\treturn {\n\t\t...item,\n\t\ttext: draft,\n\t\tbounds: {\n\t\t\tx: item.x,\n\t\t\ty: item.y,\n\t\t\twidth: m.width,\n\t\t\theight: m.height,\n\t\t},\n\t\tchildrenSvg: \"\",\n\t};\n}\n\n/** Stroke dash pattern for freehand drawings. `solid` = perfect-freehand fill; `dashed` = centerline stroke with dashes. */\nexport type StrokeDash = \"solid\" | \"dashed\";\n\n/** Resolved stroke for SVG generation. */\nexport type StrokeStyle = {\n\tstroke: string;\n\tstrokeWidth: number;\n\tstrokeOpacity?: number;\n\tstrokeDash?: StrokeDash;\n};\n\nexport const DEFAULT_STROKE_STYLE: StrokeStyle = {\n\tstroke: \"#1d1d1d\",\n\tstrokeWidth: 2,\n};\n\nconst TOOL_FREEHAND_DEFAULTS: Record<\n\t\"draw\" | \"pencil\" | \"brush\" | \"marker\",\n\tPartial<StrokeStyle>\n> = {\n\tdraw: { strokeWidth: 10 },\n\tpencil: { strokeWidth: 3 },\n\tbrush: { strokeWidth: 10 },\n\tmarker: { stroke: \"#fde047\", strokeWidth: 16, strokeOpacity: 0.5 },\n};\n\nfunction perfectFreehandOptions(\n\ttoolKind: \"draw\" | \"pencil\" | \"brush\" | \"marker\",\n\tstyle: StrokeStyle,\n\tstrokeComplete: boolean,\n\tpressureAware = false,\n): StrokeOptions {\n\tconst sw = style.strokeWidth;\n\tconst base: StrokeOptions = {\n\t\tlast: strokeComplete,\n\t\tsimulatePressure: true,\n\t};\n\tif (toolKind === \"draw\" || toolKind === \"pencil\") {\n\t\tif (pressureAware && toolKind === \"draw\") {\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tsize: Math.max(2, sw * 1.05),\n\t\t\t\tthinning: 0.42,\n\t\t\t\tsmoothing: 0.78,\n\t\t\t\tstreamline: 0.62,\n\t\t\t\tsimulatePressure: true,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\t...base,\n\t\t\tsize: Math.max(2, sw * 1.18),\n\t\t\tthinning: 0.12,\n\t\t\tsmoothing: 0.85,\n\t\t\tstreamline: 0.78,\n\t\t\tsimulatePressure: true,\n\t\t};\n\t}\n\tif (toolKind === \"brush\") {\n\t\treturn {\n\t\t\t...base,\n\t\t\tsize: Math.max(4, sw * 1.22),\n\t\t\tthinning: 0.52,\n\t\t\tsmoothing: 0.64,\n\t\t\tstreamline: 0.68,\n\t\t};\n\t}\n\treturn {\n\t\t...base,\n\t\tsize: Math.max(6, sw * 1.08),\n\t\tthinning: 0.08,\n\t\tsmoothing: 0.88,\n\t\tstreamline: 0.84,\n\t\tsimulatePressure: true,\n\t};\n}\n\nexport function resolveStrokeStyle(item: VectorSceneItem): StrokeStyle {\n\treturn {\n\t\tstroke: item.stroke ?? DEFAULT_STROKE_STYLE.stroke,\n\t\tstrokeWidth: item.strokeWidth ?? DEFAULT_STROKE_STYLE.strokeWidth,\n\t\tstrokeOpacity: item.strokeOpacity,\n\t\tstrokeDash: item.strokeDash,\n\t};\n}\n\nfunction strokeOpacityAttr(style: StrokeStyle): string {\n\treturn style.strokeOpacity != null\n\t\t? ` stroke-opacity=\"${style.strokeOpacity}\"`\n\t\t: \"\";\n}\n\nfunction svgNumber(value: number): string {\n\tif (!Number.isFinite(value)) return \"0\";\n\tconst rounded = Math.round(value * 100) / 100;\n\treturn Number.isInteger(rounded) ? String(rounded) : String(rounded);\n}\n\nconst ARCHITECTURAL_CLOUD_RADIUS = 38;\nconst ARCHITECTURAL_CLOUD_TARGET_SPACING = 50;\nconst ARCHITECTURAL_CLOUD_FLAT_RADIUS_RATIO = 0.38;\nconst ARCHITECTURAL_CLOUD_ROUNDED_RADIUS = 72;\nconst ARCHITECTURAL_CLOUD_ROUNDED_MIN_RADIUS = 44;\nconst ARCHITECTURAL_CLOUD_ROUNDED_TARGET_SPACING = 98;\n\ntype CloudPoint = readonly [number, number];\n\ntype CloudPathSegment = {\n\tlength: number;\n\tpointAt: (t: number) => CloudPoint;\n};\n\nfunction architecturalCloudCenterCount(edgeLength: number, radius: number): number {\n\tconst targetSpacing = Math.min(\n\t\tARCHITECTURAL_CLOUD_TARGET_SPACING,\n\t\tMath.max(1, radius * 1.3),\n\t);\n\treturn Math.max(2, Math.round(edgeLength / targetSpacing) + 1);\n}\n\nfunction distributeRange(start: number, end: number, count: number): number[] {\n\tif (count <= 1) return [start];\n\tconst step = (end - start) / (count - 1);\n\treturn Array.from({ length: count }, (_, index) => start + step * index);\n}\n\nfunction lineCloudPathSegment(start: CloudPoint, end: CloudPoint): CloudPathSegment {\n\tconst dx = end[0] - start[0];\n\tconst dy = end[1] - start[1];\n\tconst length = Math.hypot(dx, dy);\n\treturn {\n\t\tlength,\n\t\tpointAt: (t) => [start[0] + dx * t, start[1] + dy * t],\n\t};\n}\n\nfunction ellipsePoint(\n\tcenterX: number,\n\tcenterY: number,\n\tradiusX: number,\n\tradiusY: number,\n\tangle: number,\n): CloudPoint {\n\treturn [centerX + Math.cos(angle) * radiusX, centerY + Math.sin(angle) * radiusY];\n}\n\nfunction approximateEllipseArcLength(\n\tradiusX: number,\n\tradiusY: number,\n\tstartAngle: number,\n\tendAngle: number,\n): number {\n\tconst steps = Math.max(\n\t\t4,\n\t\tMath.ceil(Math.abs(endAngle - startAngle) / (Math.PI / 16)),\n\t);\n\tlet length = 0;\n\tlet previous = ellipsePoint(0, 0, radiusX, radiusY, startAngle);\n\tfor (let index = 1; index <= steps; index += 1) {\n\t\tconst angle = startAngle + ((endAngle - startAngle) * index) / steps;\n\t\tconst next = ellipsePoint(0, 0, radiusX, radiusY, angle);\n\t\tlength += Math.hypot(next[0] - previous[0], next[1] - previous[1]);\n\t\tprevious = next;\n\t}\n\treturn length;\n}\n\nfunction ellipseCloudPathSegment(\n\tcenterX: number,\n\tcenterY: number,\n\tradiusX: number,\n\tradiusY: number,\n\tstartAngle: number,\n\tendAngle: number,\n): CloudPathSegment {\n\treturn {\n\t\tlength: approximateEllipseArcLength(radiusX, radiusY, startAngle, endAngle),\n\t\tpointAt: (t) =>\n\t\t\tellipsePoint(\n\t\t\t\tcenterX,\n\t\t\t\tcenterY,\n\t\t\t\tradiusX,\n\t\t\t\tradiusY,\n\t\t\t\tstartAngle + (endAngle - startAngle) * t,\n\t\t\t),\n\t};\n}\n\nfunction cloudPathPerimeter(segments: CloudPathSegment[]): number {\n\tconst usableSegments = segments.filter((segment) => segment.length > 1e-9);\n\treturn usableSegments.reduce((sum, segment) => sum + segment.length, 0);\n}\n\nfunction pointOnCloudPath(\n\tsegments: CloudPathSegment[],\n\tdistance: number,\n): CloudPoint {\n\tconst perimeter = cloudPathPerimeter(segments);\n\tif (perimeter <= 0) return [0, 0];\n\n\tlet remaining = ((distance % perimeter) + perimeter) % perimeter;\n\tfor (const segment of segments) {\n\t\tif (segment.length <= 1e-9) continue;\n\t\tif (remaining <= segment.length) {\n\t\t\tconst t = remaining / segment.length;\n\t\t\treturn segment.pointAt(t);\n\t\t}\n\t\tremaining -= segment.length;\n\t}\n\n\tconst fallback = segments.find((segment) => segment.length > 1e-9);\n\treturn fallback?.pointAt(0) ?? [0, 0];\n}\n\nfunction buildRoundedCapsulePathSegments(\n\twidth: number,\n\theight: number,\n\tinset: number,\n): CloudPathSegment[] {\n\tconst left = inset;\n\tconst top = inset;\n\tconst right = width - inset;\n\tconst bottom = height - inset;\n\tconst capsuleWidth = Math.max(0, right - left);\n\tconst capsuleHeight = Math.max(0, bottom - top);\n\tconst radius = Math.min(capsuleWidth, capsuleHeight) / 2;\n\tif (radius <= 0) return [];\n\n\tconst leftCenterX = left + radius;\n\tconst rightCenterX = right - radius;\n\tconst topCenterY = top + radius;\n\tconst bottomCenterY = bottom - radius;\n\n\treturn [\n\t\tlineCloudPathSegment([leftCenterX, top], [rightCenterX, top]),\n\t\tellipseCloudPathSegment(\n\t\t\trightCenterX,\n\t\t\ttopCenterY,\n\t\t\tradius,\n\t\t\tradius,\n\t\t\t-Math.PI / 2,\n\t\t\t0,\n\t\t),\n\t\tlineCloudPathSegment([right, topCenterY], [right, bottomCenterY]),\n\t\tellipseCloudPathSegment(\n\t\t\trightCenterX,\n\t\t\tbottomCenterY,\n\t\t\tradius,\n\t\t\tradius,\n\t\t\t0,\n\t\t\tMath.PI / 2,\n\t\t),\n\t\tlineCloudPathSegment([rightCenterX, bottom], [leftCenterX, bottom]),\n\t\tellipseCloudPathSegment(\n\t\t\tleftCenterX,\n\t\t\tbottomCenterY,\n\t\t\tradius,\n\t\t\tradius,\n\t\t\tMath.PI / 2,\n\t\t\tMath.PI,\n\t\t),\n\t\tlineCloudPathSegment([left, bottomCenterY], [left, topCenterY]),\n\t\tellipseCloudPathSegment(\n\t\t\tleftCenterX,\n\t\t\ttopCenterY,\n\t\t\tradius,\n\t\t\tradius,\n\t\t\tMath.PI,\n\t\t\tMath.PI * 1.5,\n\t\t),\n\t];\n}\n\nfunction buildRoundedArcCloudPathD(\n\tcloudWidth: number,\n\tcloudHeight: number,\n\tcenter: CloudPoint,\n): string {\n\tconst minDimension = Math.min(cloudWidth, cloudHeight);\n\tconst radius = Math.min(\n\t\tARCHITECTURAL_CLOUD_ROUNDED_RADIUS,\n\t\tMath.max(ARCHITECTURAL_CLOUD_ROUNDED_MIN_RADIUS, minDimension * 0.16),\n\t);\n\tconst centerPath = buildRoundedCapsulePathSegments(\n\t\tcloudWidth,\n\t\tcloudHeight,\n\t\tradius,\n\t);\n\tconst centerPerimeter = cloudPathPerimeter(centerPath);\n\tif (centerPerimeter <= 0) return \"\";\n\n\tconst lobeCount = Math.max(\n\t\t8,\n\t\tMath.round(centerPerimeter / ARCHITECTURAL_CLOUD_ROUNDED_TARGET_SPACING),\n\t);\n\tconst centers = Array.from({ length: lobeCount }, (_, index) =>\n\t\tpointOnCloudPath(centerPath, (centerPerimeter * index) / lobeCount),\n\t);\n\tconst points = centers.map((point, index) => {\n\t\tconst previous = centers[(index - 1 + centers.length) % centers.length] ?? point;\n\t\treturn cloudCircleIntersection(previous, point, radius, center);\n\t});\n\tconst [startX, startY] = points[0] ?? [0, 0];\n\tconst segments = [`M${svgNumber(startX)} ${svgNumber(startY)}`];\n\n\tfor (const [endX, endY] of points.slice(1)) {\n\t\tsegments.push(\n\t\t\t`A ${svgNumber(radius)} ${svgNumber(radius)} 0 0 1 ${svgNumber(endX)} ${svgNumber(endY)}`,\n\t\t);\n\t}\n\tsegments.push(\n\t\t`A ${svgNumber(radius)} ${svgNumber(radius)} 0 0 1 ${svgNumber(startX)} ${svgNumber(startY)}`,\n\t);\n\n\tsegments.push(\"Z\");\n\treturn segments.join(\" \");\n}\n\nfunction cloudCircleIntersection(\n\ta: CloudPoint,\n\tb: CloudPoint,\n\tradius: number,\n\tcenter: CloudPoint,\n): [number, number] {\n\tconst midX = (a[0] + b[0]) / 2;\n\tconst midY = (a[1] + b[1]) / 2;\n\tconst dx = b[0] - a[0];\n\tconst dy = b[1] - a[1];\n\tconst distance = Math.hypot(dx, dy);\n\tif (distance <= 1e-9) return [midX, midY];\n\n\tconst halfDistance = distance / 2;\n\tconst offset = Math.sqrt(\n\t\tMath.max(0, radius * radius - halfDistance * halfDistance),\n\t);\n\tconst normalX = -dy / distance;\n\tconst normalY = dx / distance;\n\tconst first: [number, number] = [midX + normalX * offset, midY + normalY * offset];\n\tconst second: [number, number] = [\n\t\tmidX - normalX * offset,\n\t\tmidY - normalY * offset,\n\t];\n\tconst firstDistance =\n\t\t(first[0] - center[0]) * (first[0] - center[0]) +\n\t\t(first[1] - center[1]) * (first[1] - center[1]);\n\tconst secondDistance =\n\t\t(second[0] - center[0]) * (second[0] - center[0]) +\n\t\t(second[1] - center[1]) * (second[1] - center[1]);\n\treturn firstDistance >= secondDistance ? first : second;\n}\n\nfunction cloudEllipseIntersection(\n\ta: CloudPoint,\n\tb: CloudPoint,\n\tradiusX: number,\n\tradiusY: number,\n\tcenter: CloudPoint,\n): [number, number] {\n\tconst scaleY = radiusX / radiusY;\n\tconst [x, y] = cloudCircleIntersection(\n\t\t[a[0], a[1] * scaleY],\n\t\t[b[0], b[1] * scaleY],\n\t\tradiusX,\n\t\t[center[0], center[1] * scaleY],\n\t);\n\treturn [x, y / scaleY];\n}\n\nexport function buildRectSvg(\n\twidth: number,\n\theight: number,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\treturn `<rect width=\"${width}\" height=\"${height}\" fill=\"none\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\" rx=\"4\"${strokeOpacityAttr(style)} />`;\n}\n\nexport function buildEllipseSvg(\n\twidth: number,\n\theight: number,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\tconst rx = width / 2;\n\tconst ry = height / 2;\n\treturn `<ellipse cx=\"${rx}\" cy=\"${ry}\" rx=\"${rx}\" ry=\"${ry}\" fill=\"none\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\"${strokeOpacityAttr(style)} />`;\n}\n\n/**\n * Returns the local SVG path for a scalable architectural revision cloud.\n *\n * Use this low-level helper when you need to preview or inspect the shape without\n * creating a full scene item. Prefer {@link createArchitecturalCloudItem} when\n * adding a cloud to a `VectorSceneItem[]`, because it keeps `toolKind`, bounds,\n * stroke fields, and `childrenSvg` synchronized for editing.\n *\n * @example\n * ```ts\n * const d = buildArchitecturalCloudPathD(180, 90);\n * ```\n */\nexport function buildArchitecturalCloudPathD(\n\twidth: number,\n\theight: number,\n\tstrokeWidth = DEFAULT_STROKE_STYLE.strokeWidth,\n): string {\n\tconst w = Math.max(0, width);\n\tconst h = Math.max(0, height);\n\tif (w <= 0 || h <= 0) return \"\";\n\n\tconst padding = Math.max(0, strokeWidth * 2);\n\tconst cloudWidth = Math.max(0, w - padding);\n\tconst cloudHeight = Math.max(0, h - padding);\n\tif (cloudWidth <= 0 || cloudHeight <= 0) return \"\";\n\n\tconst radiusX = Math.min(\n\t\tARCHITECTURAL_CLOUD_RADIUS,\n\t\tcloudWidth * ARCHITECTURAL_CLOUD_FLAT_RADIUS_RATIO,\n\t);\n\tconst radiusY = Math.min(\n\t\tARCHITECTURAL_CLOUD_RADIUS,\n\t\tcloudHeight * ARCHITECTURAL_CLOUD_FLAT_RADIUS_RATIO,\n\t);\n\tif (radiusX <= 0 || radiusY <= 0) return \"\";\n\n\tconst center: CloudPoint = [cloudWidth / 2, cloudHeight / 2];\n\tconst leftCenterX = radiusX;\n\tconst rightCenterX = cloudWidth - radiusX;\n\tconst topCenterY = radiusY;\n\tconst bottomCenterY = cloudHeight - radiusY;\n\tconst horizontalCenters = distributeRange(\n\t\tleftCenterX,\n\t\trightCenterX,\n\t\tarchitecturalCloudCenterCount(Math.max(0, rightCenterX - leftCenterX), radiusX),\n\t);\n\tconst verticalCenters = distributeRange(\n\t\ttopCenterY,\n\t\tbottomCenterY,\n\t\tarchitecturalCloudCenterCount(Math.max(0, bottomCenterY - topCenterY), radiusY),\n\t);\n\tif (horizontalCenters.length > 3 && verticalCenters.length > 3) {\n\t\tconst roundedArcCloudPath = buildRoundedArcCloudPathD(\n\t\t\tcloudWidth,\n\t\t\tcloudHeight,\n\t\t\tcenter,\n\t\t);\n\t\tif (roundedArcCloudPath !== \"\") return roundedArcCloudPath;\n\t}\n\tconst rectangularCenters: CloudPoint[] = [\n\t\t...horizontalCenters.map((x) => [x, topCenterY] as const),\n\t\t...verticalCenters.slice(1).map((y) => [rightCenterX, y] as const),\n\t\t...horizontalCenters\n\t\t\t.slice(0, -1)\n\t\t\t.reverse()\n\t\t\t.map((x) => [x, bottomCenterY] as const),\n\t\t...verticalCenters\n\t\t\t.slice(1, -1)\n\t\t\t.reverse()\n\t\t\t.map((y) => [leftCenterX, y] as const),\n\t];\n\tconst centers = rectangularCenters;\n\tconst points = centers.map((point, index) => {\n\t\tconst previous = centers[(index - 1 + centers.length) % centers.length] ?? point;\n\t\treturn cloudEllipseIntersection(previous, point, radiusX, radiusY, center);\n\t});\n\tconst [startX, startY] = points[0] ?? [0, 0];\n\tconst segments = [`M${svgNumber(startX)} ${svgNumber(startY)}`];\n\n\tfor (const [endX, endY] of points.slice(1)) {\n\t\tsegments.push(\n\t\t\t`A ${svgNumber(radiusX)} ${svgNumber(radiusY)} 0 0 1 ${svgNumber(endX)} ${svgNumber(endY)}`,\n\t\t);\n\t}\n\tsegments.push(\n\t\t`A ${svgNumber(radiusX)} ${svgNumber(radiusY)} 0 0 1 ${svgNumber(startX)} ${svgNumber(startY)}`,\n\t);\n\n\tsegments.push(\"Z\");\n\treturn segments.join(\" \");\n}\n\n/**\n * Builds an SVG fragment for an architectural revision cloud outline.\n *\n * This is the renderer-level primitive behind the built-in `\"architectural-cloud\"`\n * tool. Prefer {@link createArchitecturalCloudItem} for app code that inserts a\n * normal editable scene item.\n */\nexport function buildArchitecturalCloudSvg(\n\twidth: number,\n\theight: number,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\tconst d = buildArchitecturalCloudPathD(width, height, style.strokeWidth);\n\treturn `<path d=\"${d}\" fill=\"none\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"${strokeOpacityAttr(style)} />`;\n}\n\nexport function buildLineSvg(\n\tline: LineEndpointsLocal,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\treturn `<line x1=\"${line.x1}\" y1=\"${line.y1}\" x2=\"${line.x2}\" y2=\"${line.y2}\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\"${strokeOpacityAttr(style)} />`;\n}\n\nexport type StraightArrowGeometry = {\n\tshaftEndX: number;\n\tshaftEndY: number;\n\theadTipX: number;\n\theadTipY: number;\n\theadLeftX: number;\n\theadLeftY: number;\n\theadRightX: number;\n\theadRightY: number;\n};\n\nexport function computeStraightArrowGeometry(\n\tline: LineEndpointsLocal,\n\tstrokeWidth: number,\n): StraightArrowGeometry | null {\n\tconst dx = line.x2 - line.x1;\n\tconst dy = line.y2 - line.y1;\n\tconst len = Math.hypot(dx, dy);\n\tif (len < 1e-6) return null;\n\tconst ux = dx / len;\n\tconst uy = dy / len;\n\tconst headLength = Math.min(Math.max(strokeWidth * 4.2, 12), len * 0.38);\n\tconst headAngle = Math.PI / 6;\n\tconst cos = Math.cos(headAngle);\n\tconst sin = Math.sin(headAngle);\n\tconst rx1 = ux * cos - uy * sin;\n\tconst ry1 = ux * sin + uy * cos;\n\tconst rx2 = ux * cos + uy * sin;\n\tconst ry2 = -ux * sin + uy * cos;\n\treturn {\n\t\tshaftEndX: line.x2,\n\t\tshaftEndY: line.y2,\n\t\theadTipX: line.x2,\n\t\theadTipY: line.y2,\n\t\theadLeftX: line.x2 - rx1 * headLength,\n\t\theadLeftY: line.y2 - ry1 * headLength,\n\t\theadRightX: line.x2 - rx2 * headLength,\n\t\theadRightY: line.y2 - ry2 * headLength,\n\t};\n}\n\nexport function buildArrowSvg(\n\titemId: string,\n\tline: LineEndpointsLocal,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\tvoid itemId;\n\tconst geometry = computeStraightArrowGeometry(line, style.strokeWidth);\n\tif (!geometry) {\n\t\treturn buildLineSvg(line, style);\n\t}\n\tconst op = strokeOpacityAttr(style);\n\treturn `\n\t\t<line x1=\"${line.x1}\" y1=\"${line.y1}\" x2=\"${geometry.shaftEndX}\" y2=\"${geometry.shaftEndY}\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\" stroke-linecap=\"round\"${op} />\n\t\t<path d=\"M ${geometry.headLeftX} ${geometry.headLeftY} L ${geometry.headTipX} ${geometry.headTipY} L ${geometry.headRightX} ${geometry.headRightY}\" fill=\"none\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" shape-rendering=\"geometricPrecision\"${op} />\n\t`;\n}\n\nexport function buildDrawDotSvg(\n\tr: number,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\tconst op =\n\t\tstyle.strokeOpacity != null ? ` fill-opacity=\"${style.strokeOpacity}\"` : \"\";\n\treturn `<circle cx=\"${r}\" cy=\"${r}\" r=\"${r}\" fill=\"${style.stroke}\" shape-rendering=\"geometricPrecision\"${op} />`;\n}\n\n/** Structured result for React overlays; scene uses {@link buildFreehandPathSvg} string. */\nexport type FreehandSvgPayload =\n\t| {\n\t\t\tkind: \"circle\";\n\t\t\tcx: number;\n\t\t\tcy: number;\n\t\t\tr: number;\n\t\t\tfill: string;\n\t\t\tfillOpacity?: number;\n\t }\n\t| {\n\t\t\tkind: \"fillPath\";\n\t\t\td: string;\n\t\t\tfill: string;\n\t\t\tfillOpacity?: number;\n\t }\n\t| {\n\t\t\tkind: \"strokePath\";\n\t\t\td: string;\n\t\t\tstroke: string;\n\t\t\tstrokeWidth: number;\n\t\t\tstrokeOpacity?: number;\n\t\t\tstrokeDasharray?: string;\n\t };\n\nfunction dashArrayForDrawStroke(strokeWidth: number): string {\n\tconst dash = Math.max(strokeWidth * 1.8, 4);\n\tconst gap = Math.max(strokeWidth * 1.4, 3);\n\treturn `${dash} ${gap}`;\n}\n\nfunction buildSmoothedCenterlinePath(\n\tpoints: readonly { x: number; y: number }[],\n): string | null {\n\tif (points.length < 2) return null;\n\tconst first = points[0];\n\tif (!first) return null;\n\tlet d = `M ${first.x} ${first.y}`;\n\tfor (let i = 1; i < points.length - 1; i++) {\n\t\tconst a = points[i];\n\t\tconst b = points[i + 1];\n\t\tif (!a || !b) continue;\n\t\tconst midX = (a.x + b.x) / 2;\n\t\tconst midY = (a.y + b.y) / 2;\n\t\td += ` Q ${a.x} ${a.y} ${midX} ${midY}`;\n\t}\n\tconst last = points[points.length - 1];\n\tif (last) {\n\t\td += ` L ${last.x} ${last.y}`;\n\t}\n\treturn d;\n}\n\n/**\n * Computes freehand geometry (perfect-freehand + fallback). Used by {@link buildFreehandPathSvg}\n * and React overlays without `dangerouslySetInnerHTML`.\n */\nexport function computeFreehandSvgPayload(\n\tpathPointsLocal: readonly VectorPathPoint[],\n\tstyle: StrokeStyle,\n\ttoolKind: \"draw\" | \"pencil\" | \"brush\" | \"marker\",\n\tstrokeComplete = true,\n): FreehandSvgPayload | null {\n\tif (pathPointsLocal.length === 0) return null;\n\tif (pathPointsLocal.length === 1) {\n\t\tconst p = pathPointsLocal[0];\n\t\tif (!p) return null;\n\t\treturn {\n\t\t\tkind: \"circle\",\n\t\t\tcx: p.x,\n\t\t\tcy: p.y,\n\t\t\tr: Math.max(0.5, style.strokeWidth / 2),\n\t\t\tfill: style.stroke,\n\t\t\tfillOpacity: style.strokeOpacity,\n\t\t};\n\t}\n\tif (\n\t\tstyle.strokeDash === \"dashed\" &&\n\t\t(toolKind === \"draw\" || toolKind === \"pencil\")\n\t) {\n\t\tconst d = buildSmoothedCenterlinePath(pathPointsLocal);\n\t\tif (!d) return null;\n\t\treturn {\n\t\t\tkind: \"strokePath\",\n\t\t\td,\n\t\t\tstroke: style.stroke,\n\t\t\tstrokeWidth: style.strokeWidth,\n\t\t\tstrokeOpacity: style.strokeOpacity,\n\t\t\tstrokeDasharray: dashArrayForDrawStroke(style.strokeWidth),\n\t\t};\n\t}\n\tconst hasPressure = pathPointsLocal.some(\n\t\t(p) => p.pressure != null && Number.isFinite(p.pressure),\n\t);\n\tconst input = hasPressure\n\t\t? pathPointsLocal.map(\n\t\t\t\t(p) =>\n\t\t\t\t\t[p.x, p.y, Math.min(1, Math.max(0, p.pressure ?? 0.5))] as [\n\t\t\t\t\t\tnumber,\n\t\t\t\t\t\tnumber,\n\t\t\t\t\t\tnumber,\n\t\t\t\t\t],\n\t\t\t)\n\t\t: pathPointsLocal.map((p) => [p.x, p.y] as [number, number]);\n\tconst stroke = getStroke(\n\t\tinput,\n\t\tperfectFreehandOptions(toolKind, style, strokeComplete, hasPressure),\n\t);\n\tif (stroke.length < 3) return null;\n\tconst first = stroke[0];\n\tif (!first) return null;\n\tlet d = `M ${first[0]} ${first[1]} Q`;\n\tfor (let i = 0; i < stroke.length; i++) {\n\t\tconst a = stroke[i];\n\t\tconst b = stroke[(i + 1) % stroke.length];\n\t\tif (!a || !b) continue;\n\t\td += ` ${a[0]} ${a[1]} ${(a[0] + b[0]) / 2} ${(a[1] + b[1]) / 2}`;\n\t}\n\td += \" Z\";\n\treturn {\n\t\tkind: \"fillPath\",\n\t\td,\n\t\tfill: style.stroke,\n\t\tfillOpacity: style.strokeOpacity,\n\t};\n}\n\nfunction freehandPayloadToSvgString(payload: FreehandSvgPayload): string {\n\tif (payload.kind === \"circle\") {\n\t\tconst op =\n\t\t\tpayload.fillOpacity != null ? ` fill-opacity=\"${payload.fillOpacity}\"` : \"\";\n\t\treturn `<circle cx=\"${payload.cx}\" cy=\"${payload.cy}\" r=\"${payload.r}\" fill=\"${payload.fill}\" shape-rendering=\"geometricPrecision\"${op} />`;\n\t}\n\tif (payload.kind === \"fillPath\") {\n\t\tconst op =\n\t\t\tpayload.fillOpacity != null ? ` fill-opacity=\"${payload.fillOpacity}\"` : \"\";\n\t\treturn `<path d=\"${payload.d}\" fill=\"${payload.fill}\" fill-rule=\"nonzero\" stroke=\"none\"${op} shape-rendering=\"geometricPrecision\" />`;\n\t}\n\tconst op = strokeOpacityAttr({\n\t\tstroke: payload.stroke,\n\t\tstrokeWidth: payload.strokeWidth,\n\t\tstrokeOpacity: payload.strokeOpacity,\n\t});\n\tconst dash = payload.strokeDasharray\n\t\t? ` stroke-dasharray=\"${payload.strokeDasharray}\"`\n\t\t: \"\";\n\treturn `<path d=\"${payload.d}\" fill=\"none\" stroke=\"${payload.stroke}\" stroke-width=\"${payload.strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" shape-rendering=\"geometricPrecision\"${op}${dash} />`;\n}\n\n/**\n * Freehand stroke in local coordinates using [perfect-freehand](https://github.com/steveruizok/perfect-freehand)\n * (filled outline, tapered caps — similar spirit to tldraw / Excalidraw ink).\n */\nexport function buildFreehandPathSvg(\n\tpathPointsLocal: readonly { x: number; y: number }[],\n\tstyle: StrokeStyle,\n\ttoolKind: \"draw\" | \"pencil\" | \"brush\" | \"marker\",\n\tstrokeComplete = true,\n): string {\n\tconst payload = computeFreehandSvgPayload(\n\t\tpathPointsLocal,\n\t\tstyle,\n\t\ttoolKind,\n\t\tstrokeComplete,\n\t);\n\tif (!payload) return \"\";\n\treturn freehandPayloadToSvgString(payload);\n}\n\n/**\n * Creates a new unique id for a shape (for `VectorSceneItem.id` when adding from code or API).\n */\nexport function createShapeId(): string {\n\tconst uid =\n\t\ttypeof crypto !== \"undefined\" && crypto.randomUUID\n\t\t\t? crypto.randomUUID()\n\t\t\t: String(Date.now());\n\treturn `user-shape-${uid}`;\n}\n\n/**\n * Converts line segment endpoints from **world** coordinates to **local** coordinates\n * (origin = top-left of `bounds`). Use with {@link createLineItem}.\n */\nexport function lineEndpointsToLocal(\n\tbounds: Rect,\n\tworldEndA: { x: number; y: number },\n\tworldEndB: { x: number; y: number },\n): LineEndpointsLocal {\n\tconst b = normalizeRect(bounds);\n\treturn {\n\t\tx1: worldEndA.x - b.x,\n\t\ty1: worldEndA.y - b.y,\n\t\tx2: worldEndB.x - b.x,\n\t\ty2: worldEndB.y - b.y,\n\t};\n}\n\n/**\n * Rebuilds the SVG fragment (`childrenSvg`) from geometry + stroke fields (after edits or resize).\n */\nexport function rebuildItemSvg(item: VectorSceneItem): VectorSceneItem {\n\tconst style = resolveStrokeStyle(item);\n\tconst k = item.toolKind;\n\n\tif (k === \"rect\") {\n\t\tconst b = normalizeRect(item.bounds);\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildRectSvg(b.width, b.height, style),\n\t\t};\n\t}\n\tif (k === \"ellipse\") {\n\t\tconst b = normalizeRect(item.bounds);\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildEllipseSvg(b.width, b.height, style),\n\t\t};\n\t}\n\tif (k === \"architectural-cloud\") {\n\t\tconst b = normalizeRect(item.bounds);\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildArchitecturalCloudSvg(b.width, b.height, style),\n\t\t};\n\t}\n\tif ((k === \"line\" || k === \"arrow\") && item.line) {\n\t\tconst line = item.line;\n\t\tconst childrenSvg =\n\t\t\tk === \"arrow\"\n\t\t\t\t? buildArrowSvg(item.id, line, style)\n\t\t\t\t: buildLineSvg(line, style);\n\t\treturn { ...item, childrenSvg };\n\t}\n\tif (k === \"text\" && item.text !== undefined) {\n\t\tconst fs = item.textFontSize ?? DEFAULT_TEXT_FONT_SIZE;\n\t\tif (item.textFixedBounds) {\n\t\t\tconst b = normalizeRect(item.bounds);\n\t\t\treturn {\n\t\t\t\t...item,\n\t\t\t\tx: b.x,\n\t\t\t\ty: b.y,\n\t\t\t\tbounds: b,\n\t\t\t\tchildrenSvg: buildTextFixedBoundsSvg(\n\t\t\t\t\titem.text,\n\t\t\t\t\tb.width,\n\t\t\t\t\tb.height,\n\t\t\t\t\tstyle.stroke,\n\t\t\t\t\tfs,\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t\tconst m = measureTextBoundsLocal(item.text, fs);\n\t\tconst b = normalizeRect({\n\t\t\tx: item.x,\n\t\t\ty: item.y,\n\t\t\twidth: m.width,\n\t\t\theight: m.height,\n\t\t});\n\t\treturn {\n\t\t\t...item,\n\t\t\tx: b.x,\n\t\t\ty: b.y,\n\t\t\tbounds: b,\n\t\t\tchildrenSvg: buildTextSvg(item.text, b.width, b.height, style.stroke, fs),\n\t\t};\n\t}\n\tif (\n\t\t(k === \"draw\" || k === \"pencil\" || k === \"brush\" || k === \"marker\") &&\n\t\titem.pathPointsLocal &&\n\t\titem.pathPointsLocal.length > 0\n\t) {\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildFreehandPathSvg(item.pathPointsLocal, style, k),\n\t\t};\n\t}\n\tif (k === \"draw\") {\n\t\tconst b = normalizeRect(item.bounds);\n\t\tconst r = Math.min(b.width, b.height) / 2;\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildDrawDotSvg(r, style),\n\t\t};\n\t}\n\tif (k === \"image\" && item.imageRasterHref && item.imageIntrinsicSize) {\n\t\tconst b = normalizeRect(item.bounds);\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildRasterImageChildrenSvg(\n\t\t\t\titem.imageRasterHref,\n\t\t\t\titem.imageIntrinsicSize,\n\t\t\t\tb,\n\t\t\t),\n\t\t};\n\t}\n\tif (k === \"custom\" && item.customIntrinsicSize && item.customInnerSvg) {\n\t\tconst b = normalizeRect(item.bounds);\n\t\treturn {\n\t\t\t...item,\n\t\t\tx: b.x,\n\t\t\ty: b.y,\n\t\t\tbounds: b,\n\t\t\tchildrenSvg: buildCustomShapeChildrenSvg(\n\t\t\t\titem.customInnerSvg,\n\t\t\t\titem.customIntrinsicSize,\n\t\t\t\tb,\n\t\t\t),\n\t\t};\n\t}\n\n\treturn item;\n}\n\n/** Updates stroke color / width / opacity and refreshes the item’s SVG. */\nexport function applyStrokeToItem(\n\titem: VectorSceneItem,\n\tpatch: Partial<\n\t\tPick<\n\t\t\tVectorSceneItem,\n\t\t\t\"stroke\" | \"strokeWidth\" | \"strokeOpacity\" | \"strokeDash\" | \"textFontSize\"\n\t\t>\n\t>,\n): VectorSceneItem {\n\treturn rebuildItemSvg({ ...item, ...patch });\n}\n\n/** Creates a rectangle shape ready to append to your scene `items` array. */\nexport function createRectangleItem(\n\tid: string,\n\tbounds: Rect,\n\tstyle?: Partial<StrokeStyle>,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"rect\",\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/** Creates an ellipse shape. */\nexport function createEllipseItem(\n\tid: string,\n\tbounds: Rect,\n\tstyle?: Partial<StrokeStyle>,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"ellipse\",\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/**\n * Creates an architectural revision cloud shape.\n *\n * Use this high-level builder when adding the built-in cloud shape from code or\n * from custom integrations. It creates an editable `VectorSceneItem` with\n * `toolKind: \"architectural-cloud\"`, so resize, stroke styling, selection, and\n * serialization continue to work like the built-in rectangle and ellipse tools.\n *\n * @example\n * ```ts\n * const cloud = createArchitecturalCloudItem(createShapeId(), {\n * x: 40,\n * y: 30,\n * width: 180,\n * height: 90,\n * });\n * ```\n */\nexport function createArchitecturalCloudItem(\n\tid: string,\n\tbounds: Rect,\n\tstyle?: Partial<StrokeStyle>,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"architectural-cloud\",\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/** Creates a straight line or arrow; `line` is usually from {@link lineEndpointsToLocal}. */\nexport function createLineItem(\n\tid: string,\n\tbounds: Rect,\n\tline: LineEndpointsLocal,\n\ttoolKind: \"line\" | \"arrow\",\n\tstyle?: Partial<StrokeStyle>,\n\tarrowBind?: ArrowBindings,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind,\n\t\tline: { ...line },\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\t...(arrowBind ? { arrowBind } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/** “Draw dot” tool: a small filled circle at (`worldX`, `worldY`). */\nexport function createDrawDotItem(\n\tid: string,\n\tworldX: number,\n\tworldY: number,\n\tradius: number,\n\tstyle?: Partial<StrokeStyle>,\n): VectorSceneItem {\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: worldX - radius,\n\t\ty: worldY - radius,\n\t\tbounds: {\n\t\t\tx: worldX - radius,\n\t\t\ty: worldY - radius,\n\t\t\twidth: radius * 2,\n\t\t\theight: radius * 2,\n\t\t},\n\t\ttoolKind: \"draw\",\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/** Creates an editable text box (`stroke` is used as text fill). */\nexport function createTextItem(\n\tid: string,\n\tbounds: Rect,\n\ttext = \"\",\n\tstyle?: Partial<StrokeStyle>,\n\ttextFontSize?: number,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"text\",\n\t\ttext,\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\t...(textFontSize != null ? { textFontSize } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/** Freehand stroke from world-space points (main pen or marker highlight). */\nexport function createFreehandStrokeItem(\n\tid: string,\n\tpointsWorld: readonly VectorPathPoint[],\n\ttoolKind: \"draw\" | \"marker\",\n\tstyle?: Partial<StrokeStyle>,\n): VectorSceneItem | null {\n\tif (pointsWorld.length === 0) return null;\n\n\tconst merged: StrokeStyle = {\n\t\t...DEFAULT_STROKE_STYLE,\n\t\t...TOOL_FREEHAND_DEFAULTS[toolKind],\n\t\t...style,\n\t};\n\n\tconst sw = merged.strokeWidth;\n\t/** Filled outline extends ~size/2 past the polyline; keep generous padding to avoid clipping. */\n\tconst pad = Math.max(sw * 0.75 + 4, sw / 2 + 6);\n\tconst xs = pointsWorld.map((p) => p.x);\n\tconst ys = pointsWorld.map((p) => p.y);\n\tconst minX = Math.min(...xs);\n\tconst maxX = Math.max(...xs);\n\tconst minY = Math.min(...ys);\n\tconst maxY = Math.max(...ys);\n\n\tconst x = minX - pad;\n\tconst y = minY - pad;\n\tconst w = Math.max(maxX - minX + 2 * pad, sw);\n\tconst h = Math.max(maxY - minY + 2 * pad, sw);\n\n\tconst pathPointsLocal = pointsWorld.map((p) => ({\n\t\tx: p.x - x,\n\t\ty: p.y - y,\n\t\t...(p.pressure != null ? { pressure: p.pressure } : {}),\n\t}));\n\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx,\n\t\ty,\n\t\tbounds: { x, y, width: w, height: h },\n\t\ttoolKind,\n\t\tstroke: merged.stroke,\n\t\tstrokeWidth: merged.strokeWidth,\n\t\t...(merged.strokeOpacity != null ? { strokeOpacity: merged.strokeOpacity } : {}),\n\t\t...(merged.strokeDash != null ? { strokeDash: merged.strokeDash } : {}),\n\t\tpathPointsLocal,\n\t\tchildrenSvg: \"\",\n\t});\n}\n\nfunction escapeSvgAttr(s: string): string {\n\treturn s.replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\").replace(/</g, \"&lt;\");\n}\n\n/**\n * Builds `<g><image href=\"data:...\"/></g>` inside `bounds` from intrinsic pixel dimensions.\n * When bounds match intrinsic aspect (normal after aspect-locked resize), uses a uniform **fill** scale.\n * Otherwise uses **contain** + center for legacy or pasted rects with wrong proportion.\n */\nexport function buildRasterImageChildrenSvg(\n\tdataUrl: string,\n\tintrinsic: { width: number; height: number },\n\tbounds: Rect,\n): string {\n\tconst r = normalizeRect(bounds);\n\tconst iw = Math.max(1e-6, intrinsic.width);\n\tconst ih = Math.max(1e-6, intrinsic.height);\n\tconst href = escapeSvgAttr(dataUrl);\n\tconst arB = r.width / Math.max(1e-9, r.height);\n\tconst arI = iw / ih;\n\tif (Math.abs(arB - arI) < 1e-3) {\n\t\tconst s = r.width / iw;\n\t\treturn `<g transform=\"scale(${s})\"><image href=\"${href}\" x=\"0\" y=\"0\" width=\"${iw}\" height=\"${ih}\" /></g>`;\n\t}\n\tconst s = Math.min(r.width / iw, r.height / ih);\n\tconst tx = (r.width - iw * s) / 2;\n\tconst ty = (r.height - ih * s) / 2;\n\treturn `<g transform=\"translate(${tx}, ${ty}) scale(${s})\"><image href=\"${href}\" x=\"0\" y=\"0\" width=\"${iw}\" height=\"${ih}\" /></g>`;\n}\n\n/** Places a bitmap (e.g. `data:image/png;base64,...`) inside `bounds`. */\nexport function createImageItem(\n\tid: string,\n\tbounds: Rect,\n\timageRasterHref: string,\n\timageIntrinsicSize: { width: number; height: number },\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst iw = Math.max(1e-6, imageIntrinsicSize.width);\n\tconst ih = Math.max(1e-6, imageIntrinsicSize.height);\n\treturn {\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"image\",\n\t\timageRasterHref,\n\t\timageIntrinsicSize: { width: iw, height: ih },\n\t\tchildrenSvg: buildRasterImageChildrenSvg(\n\t\t\timageRasterHref,\n\t\t\t{ width: iw, height: ih },\n\t\t\tr,\n\t\t),\n\t};\n}\n\n/** @internal Legacy traced path content — prefer {@link createImageItem} with a raster data URL. */\nexport function createImageFromVectorTrace(\n\tid: string,\n\tbounds: Rect,\n\timageVectorInnerSvg: string,\n\timageVectorLocalSize: { width: number; height: number },\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst lw = Math.max(1e-6, imageVectorLocalSize.width);\n\tconst lh = Math.max(1e-6, imageVectorLocalSize.height);\n\tconst arB = r.width / Math.max(1e-9, r.height);\n\tconst arI = lw / lh;\n\tlet childrenSvg: string;\n\tif (Math.abs(arB - arI) < 1e-3) {\n\t\tconst s = r.width / lw;\n\t\tchildrenSvg = `<g transform=\"scale(${s})\">${imageVectorInnerSvg}</g>`;\n\t} else {\n\t\tconst s = Math.min(r.width / lw, r.height / lh);\n\t\tconst tx = (r.width - lw * s) / 2;\n\t\tconst ty = (r.height - lh * s) / 2;\n\t\tchildrenSvg = `<g transform=\"translate(${tx}, ${ty}) scale(${s})\">${imageVectorInnerSvg}</g>`;\n\t}\n\treturn {\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"image\",\n\t\timageVectorInnerSvg,\n\t\timageVectorLocalSize: { width: lw, height: lh },\n\t\tchildrenSvg,\n\t};\n}\n","/**\n * Deterministic accent from a peer id when `color` is not provided.\n */\nexport function defaultPresenceColorForId(id: string): string {\n\tlet h = 2166136261;\n\tfor (let i = 0; i < id.length; i++) {\n\t\th ^= id.charCodeAt(i);\n\t\th = Math.imul(h, 16777619);\n\t}\n\tconst hue = (h >>> 0) % 360;\n\treturn `hsl(${hue} 72% 42%)`;\n}\n","\"use client\";\n\nimport { MousePointer2 } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport type { Camera2D } from \"../../camera/camera\";\nimport { formatCameraTransform } from \"../../renderer/svg-vector-renderer\";\nimport { smoothFreehandPointsToPathD } from \"../../scene/freehand-path\";\nimport {\n\tcomputeFreehandSvgPayload,\n\ttype StrokeStyle,\n} from \"../../scene/shape-builders\";\nimport { defaultPresenceColorForId } from \"./peer-color\";\nimport type { RemotePresenceMarkupStroke, RemotePresencePeer } from \"./types\";\n\nfunction strokePaint(\n\ttool: RemotePresenceMarkupStroke[\"tool\"],\n\tfallback: string,\n): { stroke: string; strokeOpacity: number; widthWorld: number } {\n\tswitch (tool) {\n\t\tcase \"laser\":\n\t\t\treturn { stroke: \"#f43f5e\", strokeOpacity: 0.92, widthWorld: 4 };\n\t\tcase \"marker\":\n\t\t\treturn { stroke: fallback, strokeOpacity: 0.45, widthWorld: 14 };\n\t\tcase \"brush\":\n\t\t\treturn { stroke: fallback, strokeOpacity: 0.85, widthWorld: 5 };\n\t\tcase \"pencil\":\n\t\t\treturn { stroke: fallback, strokeOpacity: 0.9, widthWorld: 2.5 };\n\t\tdefault:\n\t\t\treturn { stroke: fallback, strokeOpacity: 0.95, widthWorld: 3.5 };\n\t}\n}\n\nfunction isFreehandTool(\n\ttool: RemotePresenceMarkupStroke[\"tool\"],\n): tool is \"draw\" | \"marker\" | \"pencil\" | \"brush\" {\n\treturn (\n\t\ttool === \"draw\" || tool === \"marker\" || tool === \"pencil\" || tool === \"brush\"\n\t);\n}\n\nexport type PresenceRemoteLayerProps = {\n\tcamera: Camera2D;\n\t/** Bump when camera changes (same as {@link InteractionOverlay}). */\n\tcameraVersion: number;\n\tpeers: readonly RemotePresencePeer[];\n};\n\n/**\n * World-space SVG overlay: remote cursors + in-progress markup strokes.\n * Usually passed via {@link VectorViewport} `remotePresence` or `presenceOverlay`.\n */\nexport function PresenceRemoteLayer({\n\tcamera,\n\tcameraVersion: _cameraVersion,\n\tpeers,\n}: PresenceRemoteLayerProps) {\n\tvoid _cameraVersion;\n\tconst z = camera.zoom;\n\tconst rootTransform = formatCameraTransform(camera);\n\tconst overlayStrokePx = 1.25;\n\t/** Lucide `MousePointer2` viewBox; tip ≈ this point in icon space (see lucide `mouse-pointer-2`). */\n\tconst LUCIDE_POINTER_VIEWBOX = 24;\n\tconst LUCIDE_POINTER_TIP_X = 4.037;\n\tconst LUCIDE_POINTER_TIP_Y = 4.688;\n\t/** Target on-screen size (~px); scale in world space so it stays constant when zooming. */\n\tconst remoteCursorScreenPx = 22;\n\tconst iconWorldScale = remoteCursorScreenPx / (LUCIDE_POINTER_VIEWBOX * z);\n\n\treturn (\n\t\t<svg\n\t\t\tstyle={{\n\t\t\t\tposition: \"absolute\",\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\tright: 0,\n\t\t\t\tbottom: 0,\n\t\t\t\tzIndex: 9,\n\t\t\t\twidth: \"100%\",\n\t\t\t\theight: \"100%\",\n\t\t\t\ttouchAction: \"none\",\n\t\t\t\tpointerEvents: \"none\",\n\t\t\t}}\n\t\t\trole=\"presentation\"\n\t\t\taria-hidden\n\t\t\twidth=\"100%\"\n\t\t\theight=\"100%\"\n\t\t>\n\t\t\t<g transform={rootTransform}>\n\t\t\t\t{peers.map((peer) => {\n\t\t\t\t\tconst color = peer.color ?? defaultPresenceColorForId(peer.id);\n\t\t\t\t\tconst markup = peer.markupStroke;\n\t\t\t\t\tlet strokeNode: ReactNode = null;\n\t\t\t\t\tif (markup && markup.points.length > 0) {\n\t\t\t\t\t\tconst fallbackPaint = strokePaint(markup.tool, color);\n\t\t\t\t\t\tconst paint = {\n\t\t\t\t\t\t\tstroke: markup.stroke ?? fallbackPaint.stroke,\n\t\t\t\t\t\t\tstrokeOpacity: markup.strokeOpacity ?? fallbackPaint.strokeOpacity,\n\t\t\t\t\t\t\twidthWorld: markup.strokeWidth ?? fallbackPaint.widthWorld,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (markup.tool === \"laser\") {\n\t\t\t\t\t\t\tconst d =\n\t\t\t\t\t\t\t\tmarkup.points.length >= 2\n\t\t\t\t\t\t\t\t\t? smoothFreehandPointsToPathD([...markup.points])\n\t\t\t\t\t\t\t\t\t: null;\n\t\t\t\t\t\t\tif (d) {\n\t\t\t\t\t\t\t\tstrokeNode = (\n\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\td={d}\n\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\tstroke={paint.stroke}\n\t\t\t\t\t\t\t\t\t\tstrokeOpacity={paint.strokeOpacity}\n\t\t\t\t\t\t\t\t\t\tstrokeWidth={Math.max(paint.widthWorld / z, overlayStrokePx)}\n\t\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\tshapeRendering=\"geometricPrecision\"\n\t\t\t\t\t\t\t\t\t\tvectorEffect=\"non-scaling-stroke\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (isFreehandTool(markup.tool)) {\n\t\t\t\t\t\t\tconst style: StrokeStyle = {\n\t\t\t\t\t\t\t\tstroke: paint.stroke,\n\t\t\t\t\t\t\t\tstrokeWidth: paint.widthWorld,\n\t\t\t\t\t\t\t\t...(paint.strokeOpacity != null\n\t\t\t\t\t\t\t\t\t? { strokeOpacity: paint.strokeOpacity }\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tconst payload = computeFreehandSvgPayload(\n\t\t\t\t\t\t\t\tmarkup.points.map((p) => ({ x: p.x, y: p.y })),\n\t\t\t\t\t\t\t\tstyle,\n\t\t\t\t\t\t\t\tmarkup.tool,\n\t\t\t\t\t\t\t\tmarkup.points.length === 2,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (payload?.kind === \"circle\") {\n\t\t\t\t\t\t\t\tstrokeNode = (\n\t\t\t\t\t\t\t\t\t<circle\n\t\t\t\t\t\t\t\t\t\tcx={payload.cx}\n\t\t\t\t\t\t\t\t\t\tcy={payload.cy}\n\t\t\t\t\t\t\t\t\t\tr={payload.r}\n\t\t\t\t\t\t\t\t\t\tfill={payload.fill}\n\t\t\t\t\t\t\t\t\t\t{...(payload.fillOpacity != null\n\t\t\t\t\t\t\t\t\t\t\t? { fillOpacity: payload.fillOpacity }\n\t\t\t\t\t\t\t\t\t\t\t: {})}\n\t\t\t\t\t\t\t\t\t\tshapeRendering=\"geometricPrecision\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else if (payload?.kind === \"fillPath\") {\n\t\t\t\t\t\t\t\tstrokeNode = (\n\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\td={payload.d}\n\t\t\t\t\t\t\t\t\t\tfill={payload.fill}\n\t\t\t\t\t\t\t\t\t\tfillRule=\"nonzero\"\n\t\t\t\t\t\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t\t\t\t\t\t{...(payload.fillOpacity != null\n\t\t\t\t\t\t\t\t\t\t\t? { fillOpacity: payload.fillOpacity }\n\t\t\t\t\t\t\t\t\t\t\t: {})}\n\t\t\t\t\t\t\t\t\t\tshapeRendering=\"geometricPrecision\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else if (payload?.kind === \"strokePath\") {\n\t\t\t\t\t\t\t\tstrokeNode = (\n\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\td={payload.d}\n\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\tstroke={payload.stroke}\n\t\t\t\t\t\t\t\t\t\tstrokeWidth={payload.strokeWidth}\n\t\t\t\t\t\t\t\t\t\t{...(payload.strokeOpacity != null\n\t\t\t\t\t\t\t\t\t\t\t? { strokeOpacity: payload.strokeOpacity }\n\t\t\t\t\t\t\t\t\t\t\t: {})}\n\t\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\tshapeRendering=\"geometricPrecision\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst cur = peer.cursor;\n\t\t\t\t\tlet cursorNode: ReactNode = null;\n\t\t\t\t\tif (cur) {\n\t\t\t\t\t\tconst displayName = peer.displayName;\n\t\t\t\t\t\tconst labelOffsetX = 14 / z;\n\t\t\t\t\t\tconst labelOffsetY = 14 / z;\n\t\t\t\t\t\tconst labelFont = 12 / z;\n\t\t\t\t\t\tcursorNode = (\n\t\t\t\t\t\t\t<g>\n\t\t\t\t\t\t\t\t<g\n\t\t\t\t\t\t\t\t\ttransform={`translate(${cur.x}, ${cur.y}) scale(${iconWorldScale}) translate(${-LUCIDE_POINTER_TIP_X}, ${-LUCIDE_POINTER_TIP_Y})`}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<MousePointer2\n\t\t\t\t\t\t\t\t\t\tsize={LUCIDE_POINTER_VIEWBOX}\n\t\t\t\t\t\t\t\t\t\tcolor={color}\n\t\t\t\t\t\t\t\t\t\tfill={color}\n\t\t\t\t\t\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t\t\t\t\t\taria-hidden\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t\t\t{displayName ? (\n\t\t\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t\t\tx={cur.x + labelOffsetX}\n\t\t\t\t\t\t\t\t\t\ty={cur.y + labelOffsetY}\n\t\t\t\t\t\t\t\t\t\tfill={color}\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tfontSize: labelFont,\n\t\t\t\t\t\t\t\t\t\t\tfontFamily: \"system-ui, sans-serif\",\n\t\t\t\t\t\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tvectorEffect=\"non-scaling-stroke\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{displayName}\n\t\t\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<g key={peer.id}>\n\t\t\t\t\t\t\t{strokeNode}\n\t\t\t\t\t\t\t{cursorNode}\n\t\t\t\t\t\t</g>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</g>\n\t\t</svg>\n\t);\n}\n","import type { VectorSceneItem } from \"../../../scene/types\";\nimport type {\n\tRealtimeConnectionState,\n\tRemotePresenceCamera,\n\tRemotePresenceMarkupStroke,\n\tRemotePresencePeer,\n} from \"../../presence/types\";\n\nexport type RealtimeSessionPeer = RemotePresencePeer & {\n\treadonly clientId: string;\n\treadonly peerId: string;\n\treadonly roomId: string;\n\treadonly joinedAt: number;\n\treadonly lastSeenAt: number;\n\treadonly isSelf: boolean;\n\treadonly connectionState?: RealtimeConnectionState;\n};\n\nexport type RealtimeDocumentSnapshot = {\n\treadonly revision: number;\n\treadonly items: VectorSceneItem[];\n\treadonly updatedAt: number;\n\treadonly updatedByClientId?: string;\n};\n\nexport type RealtimeConnectionInfo = {\n\treadonly state: RealtimeConnectionState;\n\treadonly connected: boolean;\n\treadonly roomId: string;\n\treadonly clientId: string | null;\n\treadonly retryCount: number;\n\treadonly lastConnectedAt: number | null;\n\treadonly lastMessageAt: number | null;\n\treadonly lastPongAt: number | null;\n\treadonly lastError: string | null;\n};\n\nexport type RealtimePresencePayload = {\n\treadonly cursor: { readonly x: number; readonly y: number } | null;\n\treadonly markupStroke?: RemotePresenceMarkupStroke | null;\n\treadonly camera?: RemotePresenceCamera | null;\n\treadonly activeTool?: string;\n};\n\nexport type RealtimeClientPeer = {\n\treadonly clientId: string;\n\treadonly peerId: string;\n\treadonly displayName?: string;\n\treadonly color?: string;\n\treadonly image?: string;\n};\n\nexport type RealtimeClientMessage =\n\t| {\n\t\t\treadonly type: \"session:join\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly peer: RealtimeClientPeer;\n\t }\n\t| {\n\t\t\treadonly type: \"session:leave\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t }\n\t| {\n\t\t\treadonly type: \"session:ping\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t\t\treadonly sentAt: number;\n\t }\n\t| {\n\t\t\treadonly type: \"presence:update\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t\t\treadonly presence: RealtimePresencePayload;\n\t }\n\t| {\n\t\t\treadonly type: \"document:update\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t\t\treadonly baseRevision: number;\n\t\t\treadonly items: VectorSceneItem[];\n\t };\n\nexport type RealtimeServerMessage =\n\t| {\n\t\t\treadonly type: \"session:welcome\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t\t\treadonly serverTime: number;\n\t\t\treadonly document: RealtimeDocumentSnapshot;\n\t\t\treadonly peers: RealtimeSessionPeer[];\n\t }\n\t| {\n\t\t\treadonly type: \"session:peer-joined\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly peer: RealtimeSessionPeer;\n\t }\n\t| {\n\t\t\treadonly type: \"session:peer-left\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t }\n\t| {\n\t\t\treadonly type: \"session:pong\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t\t\treadonly sentAt: number;\n\t\t\treadonly serverTime: number;\n\t }\n\t| {\n\t\t\treadonly type: \"session:error\";\n\t\t\treadonly roomId?: string;\n\t\t\treadonly code: string;\n\t\t\treadonly message: string;\n\t }\n\t| {\n\t\t\treadonly type: \"presence:sync\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly peers: RealtimeSessionPeer[];\n\t\t\treadonly serverTime: number;\n\t }\n\t| {\n\t\t\treadonly type: \"document:sync\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly document: RealtimeDocumentSnapshot;\n\t }\n\t| {\n\t\t\treadonly type: \"document:resync-required\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly reason: string;\n\t\t\treadonly document: RealtimeDocumentSnapshot;\n\t };\n\ntype UnknownRecord = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction getString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction getNumber(value: unknown): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction parseCursor(value: unknown): { x: number; y: number } | null | undefined {\n\tif (value === null) return null;\n\tif (!isRecord(value)) return undefined;\n\tconst x = getNumber(value.x);\n\tconst y = getNumber(value.y);\n\tif (x == null || y == null) return undefined;\n\treturn { x, y };\n}\n\nfunction parseCamera(value: unknown): RemotePresenceCamera | null | undefined {\n\tif (value === null) return null;\n\tif (!isRecord(value)) return undefined;\n\tconst x = getNumber(value.x);\n\tconst y = getNumber(value.y);\n\tconst zoom = getNumber(value.zoom);\n\tconst viewportWidth = getNumber(value.viewportWidth);\n\tconst viewportHeight = getNumber(value.viewportHeight);\n\tif (\n\t\tx == null ||\n\t\ty == null ||\n\t\tzoom == null ||\n\t\tviewportWidth == null ||\n\t\tviewportHeight == null\n\t) {\n\t\treturn undefined;\n\t}\n\treturn { x, y, zoom, viewportWidth, viewportHeight };\n}\n\nfunction parseMarkupStroke(\n\tvalue: unknown,\n): RemotePresenceMarkupStroke | null | undefined {\n\tif (value === null) return null;\n\tif (!isRecord(value) || !Array.isArray(value.points)) return undefined;\n\tconst tool = getString(value.tool);\n\tif (\n\t\ttool !== \"draw\" &&\n\t\ttool !== \"pencil\" &&\n\t\ttool !== \"brush\" &&\n\t\ttool !== \"marker\" &&\n\t\ttool !== \"laser\"\n\t) {\n\t\treturn undefined;\n\t}\n\tconst points = value.points\n\t\t.map((point) => {\n\t\t\tif (!isRecord(point)) return null;\n\t\t\tconst x = getNumber(point.x);\n\t\t\tconst y = getNumber(point.y);\n\t\t\tif (x == null || y == null) return null;\n\t\t\treturn { x, y };\n\t\t})\n\t\t.filter((point): point is { x: number; y: number } => point != null);\n\tconst strokeWidth = getNumber(value.strokeWidth);\n\tconst stroke = getString(value.stroke);\n\tconst strokeOpacity = getNumber(value.strokeOpacity);\n\treturn {\n\t\tpoints,\n\t\ttool,\n\t\t...(strokeWidth != null ? { strokeWidth } : {}),\n\t\t...(stroke ? { stroke } : {}),\n\t\t...(strokeOpacity != null ? { strokeOpacity } : {}),\n\t};\n}\n\nfunction parsePresencePayload(value: unknown): RealtimePresencePayload | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst cursor = parseCursor(value.cursor);\n\tif (cursor === undefined) return undefined;\n\tconst markupStroke = parseMarkupStroke(value.markupStroke);\n\tif (markupStroke === undefined && value.markupStroke !== undefined)\n\t\treturn undefined;\n\tconst camera = parseCamera(value.camera);\n\tif (camera === undefined && value.camera !== undefined) return undefined;\n\treturn {\n\t\tcursor,\n\t\t...(markupStroke !== undefined ? { markupStroke } : {}),\n\t\t...(camera !== undefined ? { camera } : {}),\n\t\t...(getString(value.activeTool)\n\t\t\t? { activeTool: getString(value.activeTool) }\n\t\t\t: {}),\n\t};\n}\n\nfunction parseItems(value: unknown): VectorSceneItem[] | undefined {\n\treturn Array.isArray(value) ? (value as VectorSceneItem[]) : undefined;\n}\n\nfunction parseDocumentSnapshot(\n\tvalue: unknown,\n): RealtimeDocumentSnapshot | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst revision = getNumber(value.revision);\n\tconst updatedAt = getNumber(value.updatedAt);\n\tconst items = parseItems(value.items);\n\tif (revision == null || updatedAt == null || items == null) return undefined;\n\treturn {\n\t\trevision,\n\t\tupdatedAt,\n\t\titems,\n\t\t...(getString(value.updatedByClientId)\n\t\t\t? { updatedByClientId: getString(value.updatedByClientId) }\n\t\t\t: {}),\n\t};\n}\n\nexport function parseRealtimeSessionPeer(\n\tvalue: unknown,\n): RealtimeSessionPeer | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst clientId = getString(value.clientId);\n\tconst peerId = getString(value.peerId);\n\tconst roomId = getString(value.roomId);\n\tconst joinedAt = getNumber(value.joinedAt);\n\tconst lastSeenAt = getNumber(value.lastSeenAt);\n\tconst cursor = parseCursor(value.cursor);\n\tif (\n\t\tclientId == null ||\n\t\tpeerId == null ||\n\t\troomId == null ||\n\t\tjoinedAt == null ||\n\t\tlastSeenAt == null ||\n\t\tcursor === undefined\n\t) {\n\t\treturn undefined;\n\t}\n\tconst markupStroke = parseMarkupStroke(value.markupStroke);\n\tif (markupStroke === undefined && value.markupStroke !== undefined)\n\t\treturn undefined;\n\tconst camera = parseCamera(value.camera);\n\tif (camera === undefined && value.camera !== undefined) return undefined;\n\tconst isSelf = value.isSelf === true;\n\tconst connectionState = getString(value.connectionState) as\n\t\t| RealtimeConnectionState\n\t\t| undefined;\n\treturn {\n\t\tid: clientId,\n\t\tclientId,\n\t\tpeerId,\n\t\troomId,\n\t\tjoinedAt,\n\t\tlastSeenAt,\n\t\tisSelf,\n\t\tcursor,\n\t\t...(getString(value.displayName)\n\t\t\t? { displayName: getString(value.displayName) }\n\t\t\t: {}),\n\t\t...(getString(value.color) ? { color: getString(value.color) } : {}),\n\t\t...(getString(value.image) ? { image: getString(value.image) } : {}),\n\t\t...(markupStroke !== undefined ? { markupStroke } : {}),\n\t\t...(camera !== undefined ? { camera } : {}),\n\t\t...(getString(value.activeTool)\n\t\t\t? { activeTool: getString(value.activeTool) }\n\t\t\t: {}),\n\t\t...(connectionState ? { connectionState } : {}),\n\t};\n}\n\nfunction parsePeers(value: unknown): RealtimeSessionPeer[] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst peers = value\n\t\t.map((peer) => parseRealtimeSessionPeer(peer))\n\t\t.filter((peer): peer is RealtimeSessionPeer => peer != null);\n\treturn peers.length === value.length ? peers : undefined;\n}\n\nexport function parseRealtimeClientMessage(\n\tvalue: unknown,\n): RealtimeClientMessage | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst type = getString(value.type);\n\tif (type === \"session:join\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst peer = isRecord(value.peer) ? value.peer : undefined;\n\t\tconst clientId = peer ? getString(peer.clientId) : undefined;\n\t\tconst peerId = peer ? getString(peer.peerId) : undefined;\n\t\tif (!roomId || !peer || !clientId || !peerId) return undefined;\n\t\treturn {\n\t\t\ttype,\n\t\t\troomId,\n\t\t\tpeer: {\n\t\t\t\tclientId,\n\t\t\t\tpeerId,\n\t\t\t\t...(getString(peer.displayName)\n\t\t\t\t\t? { displayName: getString(peer.displayName) }\n\t\t\t\t\t: {}),\n\t\t\t\t...(getString(peer.color) ? { color: getString(peer.color) } : {}),\n\t\t\t\t...(getString(peer.image) ? { image: getString(peer.image) } : {}),\n\t\t\t},\n\t\t};\n\t}\n\tif (type === \"session:leave\" || type === \"session:ping\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tif (!roomId || !clientId) return undefined;\n\t\tif (type === \"session:leave\") {\n\t\t\treturn { type, roomId, clientId };\n\t\t}\n\t\tconst sentAt = getNumber(value.sentAt);\n\t\tif (sentAt == null) return undefined;\n\t\treturn { type, roomId, clientId, sentAt };\n\t}\n\tif (type === \"presence:update\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tconst presence = parsePresencePayload(value.presence);\n\t\tif (!roomId || !clientId || !presence) return undefined;\n\t\treturn { type, roomId, clientId, presence };\n\t}\n\tif (type === \"document:update\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tconst baseRevision = getNumber(value.baseRevision);\n\t\tconst items = parseItems(value.items);\n\t\tif (!roomId || !clientId || baseRevision == null || !items) return undefined;\n\t\treturn { type, roomId, clientId, baseRevision, items };\n\t}\n\treturn undefined;\n}\n\nexport function parseRealtimeServerMessage(\n\tvalue: unknown,\n): RealtimeServerMessage | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst type = getString(value.type);\n\tif (type === \"session:welcome\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tconst serverTime = getNumber(value.serverTime);\n\t\tconst document = parseDocumentSnapshot(value.document);\n\t\tconst peers = parsePeers(value.peers);\n\t\tif (!roomId || !clientId || serverTime == null || !document || !peers) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn { type, roomId, clientId, serverTime, document, peers };\n\t}\n\tif (type === \"session:peer-joined\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst peer = parseRealtimeSessionPeer(value.peer);\n\t\tif (!roomId || !peer) return undefined;\n\t\treturn { type, roomId, peer };\n\t}\n\tif (type === \"session:peer-left\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tif (!roomId || !clientId) return undefined;\n\t\treturn { type, roomId, clientId };\n\t}\n\tif (type === \"session:pong\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tconst sentAt = getNumber(value.sentAt);\n\t\tconst serverTime = getNumber(value.serverTime);\n\t\tif (!roomId || !clientId || sentAt == null || serverTime == null) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn { type, roomId, clientId, sentAt, serverTime };\n\t}\n\tif (type === \"session:error\") {\n\t\tconst code = getString(value.code);\n\t\tconst message = getString(value.message);\n\t\tif (!code || !message) return undefined;\n\t\treturn {\n\t\t\ttype,\n\t\t\tcode,\n\t\t\tmessage,\n\t\t\t...(getString(value.roomId) ? { roomId: getString(value.roomId) } : {}),\n\t\t};\n\t}\n\tif (type === \"presence:sync\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst peers = parsePeers(value.peers);\n\t\tconst serverTime = getNumber(value.serverTime);\n\t\tif (!roomId || !peers || serverTime == null) return undefined;\n\t\treturn { type, roomId, peers, serverTime };\n\t}\n\tif (type === \"document:sync\" || type === \"document:resync-required\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst document = parseDocumentSnapshot(value.document);\n\t\tif (!roomId || !document) return undefined;\n\t\tif (type === \"document:sync\") {\n\t\t\treturn { type, roomId, document };\n\t\t}\n\t\tconst reason = getString(value.reason);\n\t\tif (!reason) return undefined;\n\t\treturn { type, roomId, reason, document };\n\t}\n\treturn undefined;\n}\n","\"use client\";\n\nimport type { CSSProperties, ReactNode } from \"react\";\nimport type { RealtimeConnectionState } from \"../../presence/types\";\nimport type { RealtimeSessionPeer } from \"./protocol\";\n\nconst shell: CSSProperties = {\n\tposition: \"absolute\",\n\ttop: 12,\n\tleft: \"50%\",\n\ttransform: \"translateX(-50%)\",\n\tdisplay: \"flex\",\n\tflexDirection: \"row\",\n\talignItems: \"center\",\n\tflexWrap: \"wrap\",\n\tjustifyContent: \"center\",\n\tgap: \"0 14px\",\n\tmaxWidth: \"min(100% - 24px, 520px)\",\n\tpadding: \"6px 14px\",\n\tborderRadius: 9999,\n\tborder: \"1px solid rgba(15, 23, 42, 0.08)\",\n\tbackground: \"rgba(255, 255, 255, 0.78)\",\n\tbackdropFilter: \"blur(12px)\",\n\tWebkitBackdropFilter: \"blur(12px)\",\n\tboxShadow: \"0 1px 2px rgba(15, 23, 42, 0.04), 0 4px 16px rgba(15, 23, 42, 0.06)\",\n\tpointerEvents: \"auto\",\n\tuserSelect: \"none\",\n\tWebkitUserSelect: \"none\",\n\tWebkitTouchCallout: \"none\",\n\tfontSize: \"0.6875rem\",\n\tfontWeight: 500,\n\tletterSpacing: \"0.01em\",\n\tcolor: \"#334155\",\n};\n\nconst titleStyle: CSSProperties = {\n\tfontWeight: 600,\n\tcolor: \"#64748b\",\n\tletterSpacing: \"0.06em\",\n\ttextTransform: \"uppercase\",\n\tfontSize: \"0.625rem\",\n\twhiteSpace: \"nowrap\",\n};\n\nconst statusRow: CSSProperties = {\n\tdisplay: \"inline-flex\",\n\talignItems: \"center\",\n\tgap: 6,\n\tflexShrink: 0,\n};\n\nconst peerList: CSSProperties = {\n\tdisplay: \"flex\",\n\talignItems: \"center\",\n\tflexWrap: \"wrap\",\n\tgap: \"4px 10px\",\n\tmargin: 0,\n\tpadding: 0,\n\tlistStyle: \"none\",\n\tjustifyContent: \"center\",\n};\n\nconst peerItem: CSSProperties = {\n\tdisplay: \"inline-flex\",\n\talignItems: \"center\",\n\tgap: 5,\n\tmaxWidth: 140,\n};\n\nconst dot: CSSProperties = {\n\twidth: 6,\n\theight: 6,\n\tborderRadius: 999,\n\tflexShrink: 0,\n};\n\nconst avatarStyle: CSSProperties = {\n\twidth: 18,\n\theight: 18,\n\tborderRadius: 999,\n\tobjectFit: \"cover\",\n\tflexShrink: 0,\n\tborder: \"1px solid rgba(15, 23, 42, 0.08)\",\n};\n\nconst nameStyle: CSSProperties = {\n\toverflow: \"hidden\",\n\ttextOverflow: \"ellipsis\",\n\twhiteSpace: \"nowrap\",\n};\n\nexport type RealtimeSessionPanelProps = {\n\t/** @default \"Session\" */\n\ttitle?: string;\n\t/** Shown in the participant list (ids + optional display names from your presence layer). */\n\tpeers: readonly (\n\t\t| RealtimeSessionPeer\n\t\t| {\n\t\t\t\tid: string;\n\t\t\t\tdisplayName?: string;\n\t\t\t\tcolor?: string;\n\t\t\t\timage?: string;\n\t\t\t\tisSelf?: boolean;\n\t\t }\n\t)[];\n\t/** @default true */\n\tconnected?: boolean;\n\tconnectionState?: RealtimeConnectionState;\n\troomId?: string;\n\tchildren?: ReactNode;\n};\n\nfunction connectionAppearance(connectionState: RealtimeConnectionState): {\n\tcolor: string;\n\tlabel: string;\n\tshadow: string;\n} {\n\tif (connectionState === \"connected\") {\n\t\treturn {\n\t\t\tcolor: \"#16a34a\",\n\t\t\tlabel: \"Live\",\n\t\t\tshadow: \"0 0 0 2px rgba(22, 163, 74, 0.25)\",\n\t\t};\n\t}\n\tif (connectionState === \"connecting\") {\n\t\treturn {\n\t\t\tcolor: \"#2563eb\",\n\t\t\tlabel: \"Conectando\",\n\t\t\tshadow: \"0 0 0 2px rgba(37, 99, 235, 0.18)\",\n\t\t};\n\t}\n\tif (connectionState === \"reconnecting\") {\n\t\treturn {\n\t\t\tcolor: \"#d97706\",\n\t\t\tlabel: \"Reconectando\",\n\t\t\tshadow: \"0 0 0 2px rgba(217, 119, 6, 0.2)\",\n\t\t};\n\t}\n\tif (connectionState === \"error\") {\n\t\treturn {\n\t\t\tcolor: \"#dc2626\",\n\t\t\tlabel: \"Erro\",\n\t\t\tshadow: \"none\",\n\t\t};\n\t}\n\treturn {\n\t\tcolor: \"#64748b\",\n\t\tlabel: \"Offline\",\n\t\tshadow: \"none\",\n\t};\n}\n\n/**\n * Minimal roster + connection status, top-center above the viewport.\n * Pair with {@link realtimeSessionPlugin} and {@link VectorViewport} presence props.\n */\nexport function RealtimeSessionPanel({\n\ttitle = \"Session\",\n\tpeers,\n\tconnected = true,\n\tconnectionState,\n\troomId,\n\tchildren,\n}: RealtimeSessionPanelProps) {\n\tconst resolvedConnectionState =\n\t\tconnectionState ?? (connected ? \"connected\" : \"reconnecting\");\n\tconst status = connectionAppearance(resolvedConnectionState);\n\n\treturn (\n\t\t<div style={shell} data-slot=\"realtime-session-panel\">\n\t\t\t<span style={titleStyle}>{title}</span>\n\t\t\t{roomId ? (\n\t\t\t\t<>\n\t\t\t\t\t<span\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\twidth: 1,\n\t\t\t\t\t\t\theight: 14,\n\t\t\t\t\t\t\tbackground: \"rgba(15, 23, 42, 0.12)\",\n\t\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t}}\n\t\t\t\t\t\taria-hidden\n\t\t\t\t\t/>\n\t\t\t\t\t<span style={{ ...titleStyle, textTransform: \"none\", letterSpacing: 0 }}>\n\t\t\t\t\t\tSala {roomId}\n\t\t\t\t\t</span>\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t\t<span\n\t\t\t\tstyle={{\n\t\t\t\t\twidth: 1,\n\t\t\t\t\theight: 14,\n\t\t\t\t\tbackground: \"rgba(15, 23, 42, 0.12)\",\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t}}\n\t\t\t\taria-hidden\n\t\t\t/>\n\t\t\t<span style={statusRow}>\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\t...dot,\n\t\t\t\t\t\tbackground: status.color,\n\t\t\t\t\t\tboxShadow: status.shadow,\n\t\t\t\t\t}}\n\t\t\t\t\taria-hidden\n\t\t\t\t/>\n\t\t\t\t<span style={{ color: status.color, fontWeight: 600 }}>{status.label}</span>\n\t\t\t</span>\n\t\t\t{peers.length > 0 ? (\n\t\t\t\t<>\n\t\t\t\t\t<span\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\twidth: 1,\n\t\t\t\t\t\t\theight: 14,\n\t\t\t\t\t\t\tbackground: \"rgba(15, 23, 42, 0.12)\",\n\t\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t}}\n\t\t\t\t\t\taria-hidden\n\t\t\t\t\t/>\n\t\t\t\t\t<ul style={peerList}>\n\t\t\t\t\t\t{peers.map((p) => (\n\t\t\t\t\t\t\t<li key={p.id} style={peerItem}>\n\t\t\t\t\t\t\t\t{\"image\" in p && p.image ? (\n\t\t\t\t\t\t\t\t\t<img src={p.image} alt=\"\" aria-hidden style={avatarStyle} />\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\taria-hidden\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t...dot,\n\t\t\t\t\t\t\t\t\t\t\tbackground: p.color ?? \"#94a3b8\",\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<span style={nameStyle}>\n\t\t\t\t\t\t\t\t\t{p.displayName ?? p.id}\n\t\t\t\t\t\t\t\t\t{\"isSelf\" in p && p.isSelf ? \" (você)\" : \"\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport {\n\tcreateContext,\n\ttype ReactNode,\n\ttype RefObject,\n\tuseContext,\n\tuseLayoutEffect,\n} from \"react\";\nimport type { VectorSceneItem } from \"../../scene/types\";\nimport type { VectorToolDefinition } from \"../tools/types\";\nimport type {\n\tCustomShapePlacementOptions,\n\tVectorViewportHandle,\n\tVectorViewportProps,\n} from \"../VectorViewport\";\n\nexport type CanvasPluginRenderContext = {\n\t/** Live viewport handle when the plugin needs camera or viewport size. */\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n};\n\nexport type CanvasPluginItemsChangeMiddlewareContext = {\n\t/** Current board items before the pending change is applied. */\n\tcurrentItems: readonly VectorSceneItem[];\n\t/** Continue the item change pipeline. */\n\tnext: NonNullable<VectorViewportProps[\"onItemsChange\"]>;\n\t/** Original consumer callback passed to `VectorViewport`. */\n\tconsumerOnItemsChange?: VectorViewportProps[\"onItemsChange\"];\n\t/** Live viewport handle for advanced integrations. */\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n};\n\nexport type CanvasPluginContribution = {\n\t/** Additional tools injected into the board toolbar/runtime. */\n\ttools?: readonly VectorToolDefinition[];\n\t/** Transform the resolved tool list (reorder, replace, or filter existing tools). */\n\ttoolTransform?: (tools: VectorToolDefinition[]) => VectorToolDefinition[];\n\t/** Multiple custom placements contributed by plugins; the active one is resolved by `toolId`. */\n\tcustomPlacements?: readonly CustomShapePlacementOptions[];\n\t/** Simple viewport prop overrides owned by the plugin runtime. */\n\tviewportProps?: Partial<\n\t\tPick<VectorViewportProps, \"remotePresence\" | \"presenceOverlay\">\n\t>;\n\t/** Event callbacks chained into the viewport without manual wiring in app code. */\n\tcallbacks?: Partial<\n\t\tPick<\n\t\t\tVectorViewportProps,\n\t\t\t| \"onWorldPointerDown\"\n\t\t\t| \"onWorldPointerMove\"\n\t\t\t| \"onWorldPointerLeave\"\n\t\t\t| \"onPlacementPreviewChange\"\n\t\t\t| \"onCameraChange\"\n\t\t>\n\t>;\n\t/** Middleware around `onItemsChange` for collaboration, comments, persistence, etc. */\n\twrapOnItemsChange?: (\n\t\tnextItems: VectorSceneItem[],\n\t\tctx: CanvasPluginItemsChangeMiddlewareContext,\n\t) => void;\n};\n\nexport type CanvasPluginComponentProps = {\n\t/** Stable plugin id so the component can register contributions. */\n\tpluginId: string;\n};\n\nexport type CanvasPlugin = {\n\t/** Stable id, e.g. `canvu.plugin.chatbot`. */\n\tid: string;\n\t/**\n\t * Legacy/simple rendering path for purely visual plugins.\n\t *\n\t * Prefer `Component` for plugins that need hooks, document integration, tools, or runtime contributions.\n\t */\n\trender?: (ctx: CanvasPluginRenderContext) => ReactNode;\n\t/**\n\t * Preferred plugin entrypoint for first-party and advanced plugins.\n\t *\n\t * The component can use hooks and register contributions through `useCanvuPluginContribution`.\n\t */\n\tComponent?: (props: CanvasPluginComponentProps) => ReactNode;\n};\n\nexport type CanvuPluginViewportSnapshot = Pick<\n\tVectorViewportProps,\n\t| \"items\"\n\t| \"onItemsChange\"\n\t| \"toolId\"\n\t| \"interactive\"\n\t| \"toolLocked\"\n\t| \"onToolChangeRequest\"\n>;\n\nexport type CanvuPluginContextValue = {\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n\tviewport: CanvuPluginViewportSnapshot;\n\tresolvedTools: VectorToolDefinition[];\n\tregisterContribution: (\n\t\tpluginId: string,\n\t\tcontribution: CanvasPluginContribution,\n\t) => void;\n\tunregisterContribution: (pluginId: string) => void;\n};\n\nexport const CanvuPluginContext = createContext<CanvuPluginContextValue | null>(\n\tnull,\n);\n\n/**\n * Creates a typed canvu plugin descriptor.\n *\n * Use this helper when authoring custom plugins so your editor can infer the plugin shape\n * and surface better hover documentation for the returned object.\n */\nexport function createCanvuPlugin(plugin: CanvasPlugin): CanvasPlugin {\n\treturn plugin;\n}\n\n/**\n * Returns the low-level canvu plugin runtime context.\n *\n * This is an advanced API for custom plugin authors. Prefer first-party plugin factories such as\n * `chatbotPlugin(...)` and `realtimeCollaborationPlugin(...)` for the common path.\n */\nexport function useCanvuPluginContext(): CanvuPluginContextValue {\n\tconst ctx = useContext(CanvuPluginContext);\n\tif (!ctx) {\n\t\tthrow new Error(\n\t\t\t\"useCanvuPluginContext must be used inside a VectorViewport plugin runtime.\",\n\t\t);\n\t}\n\treturn ctx;\n}\n\n/**\n * Returns the current viewport-facing board state exposed to plugins.\n *\n * Use this when a custom plugin needs access to items, the active tool, or the consumer's\n * `onToolChangeRequest` callback.\n */\nexport function useCanvuViewportContext(): {\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n\tviewport: CanvuPluginViewportSnapshot;\n} {\n\tconst { viewportRef, viewport } = useCanvuPluginContext();\n\treturn { viewportRef, viewport };\n}\n\n/**\n * Returns the board document context exposed to plugins.\n *\n * This hook is intended for advanced plugins that need to read items or integrate with the board's\n * `onItemsChange` lifecycle.\n */\nexport function useCanvuDocumentContext(): {\n\titems: readonly VectorSceneItem[];\n\tonItemsChange?: VectorViewportProps[\"onItemsChange\"];\n} {\n\tconst { viewport } = useCanvuPluginContext();\n\treturn {\n\t\titems: viewport.items,\n\t\tonItemsChange: viewport.onItemsChange,\n\t};\n}\n\n/**\n * Returns the tool list already resolved by the plugin runtime.\n *\n * `VectorToolbar` consumes this automatically when you omit its `tools` prop, so most apps do not\n * need this hook directly.\n */\nexport function useCanvuResolvedTools(): VectorToolDefinition[] {\n\treturn useCanvuPluginContext().resolvedTools;\n}\n\n/**\n * Registers non-visual plugin contributions with the current `VectorViewport` runtime.\n *\n * Use this inside `plugin.Component` when you want to inject tools, pointer/camera behavior, or\n * document middleware without requiring the consumer to wire hooks manually.\n */\nexport function useCanvuPluginContribution(\n\tpluginId: string,\n\tcontribution: CanvasPluginContribution,\n): void {\n\tconst { registerContribution, unregisterContribution } = useCanvuPluginContext();\n\tuseLayoutEffect(() => {\n\t\tregisterContribution(pluginId, contribution);\n\t\treturn () => unregisterContribution(pluginId);\n\t}, [contribution, pluginId, registerContribution, unregisterContribution]);\n}\n","import type { SVGProps } from \"react\";\n\ntype IconProps = SVGProps<SVGSVGElement>;\n\nconst architecturalCloudIconPath =\n\t\"M1.5 12 A 4.94 5.23 0 0 1 9.07 6 A 4.94 5.23 0 0 1 14.93 6 A 4.94 5.23 0 0 1 22.5 12 A 4.94 5.23 0 0 1 14.93 18 A 4.94 5.23 0 0 1 9.07 18 A 4.94 5.23 0 0 1 1.5 12 Z\";\n\nconst base = {\n\twidth: 20,\n\theight: 20,\n\tviewBox: \"0 0 24 24\",\n\tfill: \"none\",\n\tstroke: \"currentColor\",\n\tstrokeWidth: 2,\n\tstrokeLinecap: \"round\" as const,\n\tstrokeLinejoin: \"round\" as const,\n};\n\nexport function IconHand(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M18 11V6a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2v0\" />\n\t\t\t<path d=\"M14 10V4a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2v2\" />\n\t\t\t<path d=\"M10 10.5V6a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2v8\" />\n\t\t\t<path d=\"M18 8a2 2 0 1 1 4 0v5a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconSelect(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z\" />\n\t\t\t<path d=\"M13 13l6 6\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconRect(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconEllipse(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<ellipse cx=\"12\" cy=\"12\" rx=\"9\" ry=\"6\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconArchitecturalCloud(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d={architecturalCloudIconPath} />\n\t\t</svg>\n\t);\n}\n\nexport function IconLine(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<line x1=\"5\" y1=\"19\" x2=\"19\" y2=\"5\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconArrow(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<line x1=\"5\" y1=\"19\" x2=\"19\" y2=\"5\" />\n\t\t\t<polyline points=\"12 5 19 5 19 12\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconDraw(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M12 19l7-7 3 3-7 7-3-3z\" />\n\t\t\t<path d=\"M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z\" />\n\t\t\t<path d=\"M2 2l7.586 7.586\" />\n\t\t\t<circle cx=\"11\" cy=\"11\" r=\"2\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconText(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2\" />\n\t\t\t<path d=\"M9 21h6\" />\n\t\t\t<path d=\"M12 3v18\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconImage(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n\t\t\t<circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n\t\t\t<polyline points=\"21 15 16 10 5 21\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconPencil(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M12 19l7-7 3 3-7 7-3-3z\" />\n\t\t\t<path d=\"M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z\" />\n\t\t\t<path d=\"M2 2l7.586 7.586\" />\n\t\t\t<path d=\"M11 4h4v4\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconBrush(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M9.06 11.9l8.07-8.06a2.85 2.85 0 0 1 4.03 4.03l-8.06 8.07\" />\n\t\t\t<path d=\"M7.5 15.5L3 21l5.5-4.5\" />\n\t\t\t<path d=\"M2 22l4-1\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconMarker(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M4 20h16\" />\n\t\t\t<path d=\"M6 16l6-12 6 12\" fill=\"currentColor\" fillOpacity={0.35} />\n\t\t\t<path d=\"M8 14h8\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconLaser(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"2.5\" />\n\t\t\t<path d=\"M12 4v4\" />\n\t\t\t<path d=\"M12 16v4\" />\n\t\t\t<path d=\"M4 12h4\" />\n\t\t\t<path d=\"M16 12h4\" />\n\t\t</svg>\n\t);\n}\n","import {\n\tArrowUpRight,\n\tCircle,\n\tEraser,\n\tHand,\n\tHighlighter,\n\tImage,\n\tMinus,\n\tMousePointer2,\n\tPenLine,\n\tSquare,\n\tType,\n} from \"lucide-react\";\nimport { IconArchitecturalCloud, IconLaser } from \"./icons\";\nimport type { VectorToolDefinition } from \"./types\";\n\n/** Match previous 20×20 toolbar glyphs; Lucide scales with `currentColor`. */\nconst ic = { size: 20, strokeWidth: 2 } as const;\n\n/**\n * Tool ids shown in the overflow menu at the end of the default toolbar (horizontal layout).\n * Order: shapes, marker, laser, image.\n */\nexport const DEFAULT_OVERFLOW_TOOL_IDS = [\n\t\"rect\",\n\t\"ellipse\",\n\t\"architectural-cloud\",\n\t\"line\",\n\t\"marker\",\n\t\"laser\",\n\t\"image\",\n] as const;\n\n/**\n * Opinionated default tool strip using [Lucide](https://lucide.dev) icons.\n * Pass a subset or your own list via {@link VectorToolbarProps.tools}.\n */\nexport const DEFAULT_VECTOR_TOOLS: VectorToolDefinition[] = [\n\t{\n\t\tid: \"hand\",\n\t\tlabel: \"Hand\",\n\t\ticon: <Hand {...ic} aria-hidden />,\n\t\tshortcutHint: \"H\",\n\t},\n\t{\n\t\tid: \"select\",\n\t\tlabel: \"Select\",\n\t\ticon: <MousePointer2 {...ic} aria-hidden />,\n\t\tshortcutHint: \"V\",\n\t},\n\t{\n\t\tid: \"rect\",\n\t\tlabel: \"Rectangle\",\n\t\ticon: <Square {...ic} aria-hidden />,\n\t\tshortcutHint: \"R\",\n\t},\n\t{\n\t\tid: \"ellipse\",\n\t\tlabel: \"Ellipse\",\n\t\ticon: <Circle {...ic} aria-hidden />,\n\t\tshortcutHint: \"O\",\n\t},\n\t{\n\t\tid: \"architectural-cloud\",\n\t\tlabel: \"Nuvem arquitetural\",\n\t\ttooltipLabel: \"Architectural cloud\",\n\t\ticon: <IconArchitecturalCloud aria-hidden />,\n\t\tshortcutHint: \"C\",\n\t},\n\t{\n\t\tid: \"line\",\n\t\tlabel: \"Line\",\n\t\ticon: <Minus {...ic} aria-hidden />,\n\t\tshortcutHint: \"L\",\n\t},\n\t{\n\t\tid: \"arrow\",\n\t\tlabel: \"Arrow\",\n\t\ticon: <ArrowUpRight {...ic} aria-hidden />,\n\t\tshortcutHint: \"A\",\n\t},\n\t{\n\t\tid: \"draw\",\n\t\tlabel: \"Desenhar\",\n\t\ttooltipLabel: \"Draw\",\n\t\ticon: <PenLine {...ic} aria-hidden />,\n\t\tshortcutHint: \"D\",\n\t},\n\t{\n\t\tid: \"marker\",\n\t\tlabel: \"Realce\",\n\t\ttooltipLabel: \"Highlighter\",\n\t\ticon: <Highlighter {...ic} aria-hidden />,\n\t\tshortcutHint: \"M\",\n\t},\n\t{\n\t\tid: \"laser\",\n\t\tlabel: \"Laser\",\n\t\ticon: <IconLaser aria-hidden />,\n\t\tshortcutHint: \"K\",\n\t},\n\t{\n\t\tid: \"eraser\",\n\t\tlabel: \"Borracha\",\n\t\ttooltipLabel: \"Eraser\",\n\t\ticon: <Eraser {...ic} aria-hidden />,\n\t\tshortcutHint: \"E\",\n\t},\n\t{\n\t\tid: \"text\",\n\t\tlabel: \"Text\",\n\t\ticon: <Type {...ic} aria-hidden />,\n\t\tshortcutHint: \"T\",\n\t},\n\t{\n\t\tid: \"image\",\n\t\tlabel: \"File\",\n\t\ticon: <Image {...ic} aria-hidden />,\n\t\tshortcutHint: \"I\",\n\t},\n];\n","import { MessageSquare, Sparkles } from \"lucide-react\";\nimport {\n\ttype CSSProperties,\n\ttype PointerEvent as ReactPointerEvent,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport type { Rect } from \"../../../math/rect\";\nimport { createCustomShapeItem } from \"../../../scene/custom-shape\";\nimport type { VectorSceneItem } from \"../../../scene/types\";\nimport type { VectorToolDefinition } from \"../../tools/types\";\nimport type { CanvasPlugin, CanvasPluginRenderContext } from \"../types\";\n\nconst iconProps = { size: 20, strokeWidth: 2 } as const;\nconst COMMENT_PLUGIN_DATA_KEY = \"realtimeComment\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport type RealtimeCommentData = {\n\tbody: string;\n\tcreatedAt: number;\n\tauthorPeerId: string;\n\tauthorDisplayName: string;\n\tauthorColor: string;\n\tauthorImage: string;\n};\n\ntype RealtimeCommentDraftData = {\n\tkind: \"draft\";\n\tseedColor?: string;\n};\n\ntype RealtimeCommentStoredData =\n\t| RealtimeCommentDraftData\n\t| ({ kind: \"comment\" } & RealtimeCommentData);\n\nexport type RealtimeCommentsOverlayProps = {\n\titems: readonly VectorSceneItem[];\n\tonItemsChange?: (items: VectorSceneItem[]) => void;\n\tisDragEnabled?: boolean;\n\tcameraVersion: number;\n\tviewportRef?: CanvasPluginRenderContext[\"viewportRef\"];\n};\n\nexport type RealtimeCommentsPluginOptions = Omit<\n\tRealtimeCommentsOverlayProps,\n\t\"viewportRef\"\n>;\n\ntype RealtimeCommentDragState = {\n\titemId: string;\n\tlastWorldX: number;\n\tlastWorldY: number;\n};\n\n/** Dedicated collaboration tool; unlike `text`, this opens a comment composer flow. */\nexport const REALTIME_COMMENT_TOOL: VectorToolDefinition = {\n\tid: \"comment\",\n\tlabel: \"Comentário\",\n\ttooltipLabel: \"Comment\",\n\tariaLabel: \"Adicionar comentário colaborativo\",\n\tshortcutHint: \"C\",\n\ticon: <MessageSquare {...iconProps} aria-hidden />,\n};\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction getString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction getNumber(value: unknown): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction initialsFromDisplayName(displayName: string): string {\n\tconst words = displayName.trim().split(/\\s+/).filter(Boolean).slice(0, 2);\n\tif (words.length === 0) return \"?\";\n\treturn words.map((part) => part[0]?.toUpperCase() ?? \"\").join(\"\") || \"?\";\n}\n\nfunction escapeSvgText(value: string): string {\n\treturn value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\n/**\n * Generates a tiny inline avatar so comments carry a portable visual identity even without a user photo API.\n */\nexport function createRealtimeCommentAvatarDataUrl(\n\tdisplayName: string,\n\tcolor: string,\n): string {\n\tconst initials = initialsFromDisplayName(displayName);\n\tconst svg = `\n\t\t<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"96\" height=\"96\" viewBox=\"0 0 96 96\">\n\t\t\t<defs>\n\t\t\t\t<linearGradient id=\"bg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n\t\t\t\t\t<stop offset=\"0%\" stop-color=\"${color}\" />\n\t\t\t\t\t<stop offset=\"100%\" stop-color=\"#0f172a\" />\n\t\t\t\t</linearGradient>\n\t\t\t\t<radialGradient id=\"shine\" cx=\"30%\" cy=\"24%\" r=\"70%\">\n\t\t\t\t\t<stop offset=\"0%\" stop-color=\"#ffffff\" stop-opacity=\"0.48\" />\n\t\t\t\t\t<stop offset=\"100%\" stop-color=\"#ffffff\" stop-opacity=\"0\" />\n\t\t\t\t</radialGradient>\n\t\t\t</defs>\n\t\t\t<rect width=\"96\" height=\"96\" rx=\"28\" fill=\"url(#bg)\" />\n\t\t\t<rect width=\"96\" height=\"96\" rx=\"28\" fill=\"url(#shine)\" />\n\t\t\t<circle cx=\"48\" cy=\"38\" r=\"18\" fill=\"rgba(255,255,255,0.2)\" />\n\t\t\t<path d=\"M20 84c5-16 17-24 28-24s23 8 28 24\" fill=\"rgba(255,255,255,0.16)\" />\n\t\t\t<text x=\"48\" y=\"56\" text-anchor=\"middle\" font-size=\"28\" font-weight=\"700\" font-family=\"system-ui, sans-serif\" fill=\"#ffffff\">${escapeSvgText(initials)}</text>\n\t\t</svg>\n\t`;\n\treturn `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;\n}\n\nfunction commentPlaceholderInnerSvg(color: string): string {\n\treturn `\n\t\t<circle cx=\"9\" cy=\"9\" r=\"7\" fill=\"rgba(255,255,255,0.94)\" stroke=\"${color}\" stroke-width=\"1.2\" stroke-dasharray=\"2 1.5\" />\n\t\t<circle cx=\"9\" cy=\"9\" r=\"3.1\" fill=\"${color}\" fill-opacity=\"0.18\" stroke=\"${color}\" stroke-width=\"1\" />\n\t\t<path d=\"M7.1 8.1h3.8c.8 0 1.4.5 1.4 1.2v1.1c0 .7-.6 1.2-1.4 1.2H9.3l-1.2 1v-1H7.1c-.8 0-1.4-.5-1.4-1.2V9.3c0-.7.6-1.2 1.4-1.2Z\" fill=\"#ffffff\" stroke=\"${color}\" stroke-width=\"0.9\" />\n\t`;\n}\n\nfunction commentAnchorInnerSvg(authorColor: string): string {\n\treturn `\n\t\t<circle cx=\"9\" cy=\"9\" r=\"7.2\" fill=\"rgba(255,255,255,0.96)\" stroke=\"rgba(15,23,42,0.1)\" stroke-width=\"0.9\" />\n\t\t<circle cx=\"9\" cy=\"9\" r=\"4.1\" fill=\"${authorColor}\" />\n\t\t<circle cx=\"13.2\" cy=\"13.2\" r=\"3.2\" fill=\"#ffffff\" stroke=\"rgba(15,23,42,0.12)\" stroke-width=\"0.9\" />\n\t\t<path d=\"M11.7 12.1h2.7c.6 0 1 .4 1 .9v.9c0 .5-.4.9-1 .9h-1.1l-1 .8v-.8h-.4c-.6 0-1-.4-1-.9V13c0-.5.4-.9 1-.9Z\" fill=\"#111827\" fill-opacity=\"0.08\" stroke=\"#111827\" stroke-width=\"0.75\" />\n\t`;\n}\n\nexport function createRealtimeCommentDraftItem(\n\tid: string,\n\tbounds: Rect,\n\tseedColor = \"#7c3aed\",\n): VectorSceneItem {\n\tconst base = createCustomShapeItem(id, bounds, {\n\t\trender: () => commentPlaceholderInnerSvg(seedColor),\n\t});\n\treturn {\n\t\t...base,\n\t\tpluginData: {\n\t\t\t...(base.pluginData ?? {}),\n\t\t\t[COMMENT_PLUGIN_DATA_KEY]: {\n\t\t\t\tkind: \"draft\",\n\t\t\t\tseedColor,\n\t\t\t} satisfies RealtimeCommentDraftData,\n\t\t},\n\t};\n}\n\nexport function createRealtimeCommentItem(\n\tid: string,\n\tbounds: Rect,\n\tcomment: RealtimeCommentData,\n): VectorSceneItem {\n\tconst base = createCustomShapeItem(id, bounds, {\n\t\trender: () => commentAnchorInnerSvg(comment.authorColor),\n\t});\n\treturn {\n\t\t...base,\n\t\tpluginData: {\n\t\t\t...(base.pluginData ?? {}),\n\t\t\t[COMMENT_PLUGIN_DATA_KEY]: {\n\t\t\t\tkind: \"comment\",\n\t\t\t\t...comment,\n\t\t\t} satisfies RealtimeCommentStoredData,\n\t\t},\n\t};\n}\n\nfunction getStoredRealtimeCommentData(\n\titem: VectorSceneItem,\n): RealtimeCommentStoredData | null {\n\tconst pluginData = item.pluginData?.[COMMENT_PLUGIN_DATA_KEY];\n\tif (!isRecord(pluginData)) return null;\n\tconst kind = getString(pluginData.kind);\n\tif (kind === \"draft\") {\n\t\treturn {\n\t\t\tkind,\n\t\t\t...(getString(pluginData.seedColor)\n\t\t\t\t? { seedColor: getString(pluginData.seedColor) }\n\t\t\t\t: {}),\n\t\t};\n\t}\n\tif (kind !== \"comment\") return null;\n\tconst body = getString(pluginData.body);\n\tconst createdAt = getNumber(pluginData.createdAt);\n\tconst authorPeerId = getString(pluginData.authorPeerId);\n\tconst authorDisplayName = getString(pluginData.authorDisplayName);\n\tconst authorColor = getString(pluginData.authorColor);\n\tconst authorImage = getString(pluginData.authorImage);\n\tif (\n\t\t!body ||\n\t\tcreatedAt == null ||\n\t\t!authorPeerId ||\n\t\t!authorDisplayName ||\n\t\t!authorColor ||\n\t\t!authorImage\n\t) {\n\t\treturn null;\n\t}\n\treturn {\n\t\tkind,\n\t\tbody,\n\t\tcreatedAt,\n\t\tauthorPeerId,\n\t\tauthorDisplayName,\n\t\tauthorColor,\n\t\tauthorImage,\n\t};\n}\n\nexport function isRealtimeCommentDraftItem(item: VectorSceneItem): boolean {\n\treturn getStoredRealtimeCommentData(item)?.kind === \"draft\";\n}\n\nexport function isRealtimeCommentItem(item: VectorSceneItem): boolean {\n\treturn getStoredRealtimeCommentData(item)?.kind === \"comment\";\n}\n\nexport function getRealtimeCommentData(\n\titem: VectorSceneItem,\n): RealtimeCommentData | null {\n\tconst data = getStoredRealtimeCommentData(item);\n\treturn data?.kind === \"comment\" ? data : null;\n}\n\n/**\n * Adds the comment tool without replacing the native text tool.\n * By default it is inserted right after `text`, or appended when `text` is absent.\n */\nexport function withRealtimeCommentTool(\n\ttools: readonly VectorToolDefinition[],\n): VectorToolDefinition[] {\n\tif (tools.some((tool) => tool.id === REALTIME_COMMENT_TOOL.id)) {\n\t\treturn tools.map((tool) =>\n\t\t\ttool.id === REALTIME_COMMENT_TOOL.id\n\t\t\t\t? { ...tool, ...REALTIME_COMMENT_TOOL }\n\t\t\t\t: tool,\n\t\t);\n\t}\n\tconst textIndex = tools.findIndex((tool) => tool.id === \"text\");\n\tif (textIndex < 0) return [...tools, REALTIME_COMMENT_TOOL];\n\treturn [\n\t\t...tools.slice(0, textIndex + 1),\n\t\tREALTIME_COMMENT_TOOL,\n\t\t...tools.slice(textIndex + 1),\n\t];\n}\n\nconst overlayShell: CSSProperties = {\n\tposition: \"absolute\",\n\tinset: 0,\n\tpointerEvents: \"none\",\n\tzIndex: 26,\n\toverflow: \"hidden\",\n};\n\nfunction formatCommentTimestamp(timestamp: number): string {\n\treturn new Intl.DateTimeFormat(\"pt-BR\", {\n\t\tdateStyle: \"short\",\n\t\ttimeStyle: \"short\",\n\t}).format(new Date(timestamp));\n}\n\nexport function RealtimeCommentsOverlay({\n\titems,\n\tonItemsChange,\n\tisDragEnabled = false,\n\tcameraVersion,\n\tviewportRef,\n}: RealtimeCommentsOverlayProps) {\n\tvoid cameraVersion;\n\tconst [hoveredId, setHoveredId] = useState<string | null>(null);\n\tconst [draggedId, setDraggedId] = useState<string | null>(null);\n\tconst dragStateRef = useRef<RealtimeCommentDragState | null>(null);\n\tconst itemsRef = useRef(items);\n\tuseEffect(() => {\n\t\titemsRef.current = items;\n\t}, [items]);\n\tconst camera = viewportRef?.current?.getCamera() ?? null;\n\tif (!camera) return null;\n\n\tfunction moveCommentItem(\n\t\titem: VectorSceneItem,\n\t\tdeltaX: number,\n\t\tdeltaY: number,\n\t): VectorSceneItem {\n\t\treturn {\n\t\t\t...item,\n\t\t\tx: item.x + deltaX,\n\t\t\ty: item.y + deltaY,\n\t\t\tbounds: {\n\t\t\t\t...item.bounds,\n\t\t\t\tx: item.bounds.x + deltaX,\n\t\t\t\ty: item.bounds.y + deltaY,\n\t\t\t},\n\t\t};\n\t}\n\n\tfunction handleCommentPointerDown(\n\t\titemId: string,\n\t\tevent: ReactPointerEvent<HTMLButtonElement>,\n\t): void {\n\t\tif (event.button !== 0 || !onItemsChange || !isDragEnabled) return;\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\tconst currentCamera = viewportRef?.current?.getCamera();\n\t\tif (!currentCamera) return;\n\t\tconst start = currentCamera.screenToWorld(event.clientX, event.clientY);\n\t\tdragStateRef.current = {\n\t\t\titemId,\n\t\t\tlastWorldX: start.worldX,\n\t\t\tlastWorldY: start.worldY,\n\t\t};\n\t\tsetDraggedId(itemId);\n\t\tsetHoveredId((current) => (current === itemId ? null : current));\n\n\t\tconst onPointerMove = (moveEvent: PointerEvent) => {\n\t\t\tconst drag = dragStateRef.current;\n\t\t\tconst liveCamera = viewportRef?.current?.getCamera();\n\t\t\tif (!drag || !liveCamera) return;\n\t\t\tconst next = liveCamera.screenToWorld(moveEvent.clientX, moveEvent.clientY);\n\t\t\tconst deltaX = next.worldX - drag.lastWorldX;\n\t\t\tconst deltaY = next.worldY - drag.lastWorldY;\n\t\t\tif (deltaX === 0 && deltaY === 0) return;\n\t\t\tdrag.lastWorldX = next.worldX;\n\t\t\tdrag.lastWorldY = next.worldY;\n\t\t\tconst nextItems = itemsRef.current.map((item) =>\n\t\t\t\titem.id === drag.itemId ? moveCommentItem(item, deltaX, deltaY) : item,\n\t\t\t);\n\t\t\titemsRef.current = nextItems;\n\t\t\tonItemsChange(nextItems);\n\t\t};\n\n\t\tconst onPointerUp = () => {\n\t\t\tdragStateRef.current = null;\n\t\t\tsetDraggedId((current) => (current === itemId ? null : current));\n\t\t\twindow.removeEventListener(\"pointermove\", onPointerMove);\n\t\t\twindow.removeEventListener(\"pointerup\", onPointerUp);\n\t\t\twindow.removeEventListener(\"pointercancel\", onPointerUp);\n\t\t};\n\n\t\twindow.addEventListener(\"pointermove\", onPointerMove);\n\t\twindow.addEventListener(\"pointerup\", onPointerUp);\n\t\twindow.addEventListener(\"pointercancel\", onPointerUp);\n\t}\n\n\tconst comments = items\n\t\t.map((item) => ({ item, data: getRealtimeCommentData(item) }))\n\t\t.filter(\n\t\t\t(entry): entry is { item: VectorSceneItem; data: RealtimeCommentData } =>\n\t\t\t\tentry.data != null,\n\t\t);\n\tif (comments.length === 0) return null;\n\n\treturn (\n\t\t<div style={overlayShell} data-slot=\"realtime-comments-overlay\">\n\t\t\t{comments.map(({ item, data }) => {\n\t\t\t\tconst anchor = camera.worldToScreen(\n\t\t\t\t\titem.bounds.x + item.bounds.width / 2,\n\t\t\t\t\titem.bounds.y + item.bounds.height / 2,\n\t\t\t\t);\n\t\t\t\tconst dragging = draggedId === item.id;\n\t\t\t\tconst expanded = hoveredId === item.id && !dragging;\n\t\t\t\treturn (\n\t\t\t\t\t<button\n\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\taria-label={`Comment by ${data.authorDisplayName}`}\n\t\t\t\t\t\tonMouseEnter={() => setHoveredId(item.id)}\n\t\t\t\t\t\tonMouseLeave={() =>\n\t\t\t\t\t\t\tsetHoveredId((current) => (current === item.id ? null : current))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tonPointerDown={(event) => handleCommentPointerDown(item.id, event)}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\tleft: anchor.screenX,\n\t\t\t\t\t\t\ttop: anchor.screenY,\n\t\t\t\t\t\t\ttransform: \"translate(-50%, -50%)\",\n\t\t\t\t\t\t\tpointerEvents: \"auto\",\n\t\t\t\t\t\t\tcursor:\n\t\t\t\t\t\t\t\tonItemsChange && isDragEnabled\n\t\t\t\t\t\t\t\t\t? dragging\n\t\t\t\t\t\t\t\t\t\t? \"grabbing\"\n\t\t\t\t\t\t\t\t\t\t: \"grab\"\n\t\t\t\t\t\t\t\t\t: \"default\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\t\t\talignItems: expanded ? \"flex-start\" : \"center\",\n\t\t\t\t\t\t\t\tgap: expanded ? 9 : 0,\n\t\t\t\t\t\t\t\twidth: expanded ? 228 : 44,\n\t\t\t\t\t\t\t\tminHeight: 44,\n\t\t\t\t\t\t\t\tpadding: expanded ? \"8px 10px 8px 8px\" : 3,\n\t\t\t\t\t\t\t\tborderRadius: expanded ? 18 : 999,\n\t\t\t\t\t\t\t\tbackground: expanded ? \"rgba(255,255,255,0.97)\" : \"transparent\",\n\t\t\t\t\t\t\t\tborder: expanded\n\t\t\t\t\t\t\t\t\t? \"1px solid rgba(148,163,184,0.28)\"\n\t\t\t\t\t\t\t\t\t: \"1px solid transparent\",\n\t\t\t\t\t\t\t\tboxShadow: expanded ? \"0 14px 32px rgba(15,23,42,0.18)\" : \"none\",\n\t\t\t\t\t\t\t\tbackdropFilter: \"blur(10px)\",\n\t\t\t\t\t\t\t\ttransition:\n\t\t\t\t\t\t\t\t\t\"width 160ms ease, border-radius 160ms ease, transform 160ms ease, box-shadow 160ms ease, padding 160ms ease\",\n\t\t\t\t\t\t\t\ttransform: dragging\n\t\t\t\t\t\t\t\t\t? \"scale(0.98)\"\n\t\t\t\t\t\t\t\t\t: expanded\n\t\t\t\t\t\t\t\t\t\t? \"translateY(-2px)\"\n\t\t\t\t\t\t\t\t\t\t: \"translateY(0)\",\n\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\t\t\t\t\twidth: 36,\n\t\t\t\t\t\t\t\t\theight: 36,\n\t\t\t\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t\t\t\tboxShadow: expanded\n\t\t\t\t\t\t\t\t\t\t? `0 0 0 2px ${data.authorColor}22`\n\t\t\t\t\t\t\t\t\t\t: \"0 10px 18px rgba(15,23,42,0.14)\",\n\t\t\t\t\t\t\t\t\tborder: expanded ? \"none\" : \"2px solid rgba(255,255,255,0.92)\",\n\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\tsrc={data.authorImage}\n\t\t\t\t\t\t\t\t\talt={data.authorDisplayName}\n\t\t\t\t\t\t\t\t\tstyle={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t\t\t\tright: expanded ? -1 : -2,\n\t\t\t\t\t\t\t\t\t\tbottom: expanded ? -1 : -2,\n\t\t\t\t\t\t\t\t\t\twidth: 14,\n\t\t\t\t\t\t\t\t\t\theight: 14,\n\t\t\t\t\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\t\t\t\t\tbackground: \"#111827\",\n\t\t\t\t\t\t\t\t\t\tcolor: \"#fff\",\n\t\t\t\t\t\t\t\t\t\tdisplay: \"grid\",\n\t\t\t\t\t\t\t\t\t\tplaceItems: \"center\",\n\t\t\t\t\t\t\t\t\t\tborder: \"1.5px solid rgba(255,255,255,0.98)\",\n\t\t\t\t\t\t\t\t\t\tboxShadow: \"0 4px 10px rgba(15,23,42,0.16)\",\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Sparkles size={8} strokeWidth={2.2} aria-hidden />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{expanded ? (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tdisplay: \"grid\",\n\t\t\t\t\t\t\t\t\t\tgap: 3,\n\t\t\t\t\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\t\t\t\t\tpaddingTop: 1,\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\t\t\t\t\t\tjustifyContent: \"space-between\",\n\t\t\t\t\t\t\t\t\t\t\tgap: 8,\n\t\t\t\t\t\t\t\t\t\t\talignItems: \"baseline\",\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\tfontSize: 12,\n\t\t\t\t\t\t\t\t\t\t\t\tfontWeight: 700,\n\t\t\t\t\t\t\t\t\t\t\t\tcolor: \"#0f172a\",\n\t\t\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{data.authorDisplayName}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\tfontSize: 10,\n\t\t\t\t\t\t\t\t\t\t\t\tcolor: \"#64748b\",\n\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{formatCommentTimestamp(data.createdAt)}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tfontSize: 11,\n\t\t\t\t\t\t\t\t\t\t\tlineHeight: 1.4,\n\t\t\t\t\t\t\t\t\t\t\tcolor: \"#334155\",\n\t\t\t\t\t\t\t\t\t\t\tdisplay: \"-webkit-box\",\n\t\t\t\t\t\t\t\t\t\t\tWebkitLineClamp: 3,\n\t\t\t\t\t\t\t\t\t\t\tWebkitBoxOrient: \"vertical\",\n\t\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{data.body}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</button>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n}\n\nexport function realtimeCommentsPlugin(\n\toptions: RealtimeCommentsPluginOptions,\n): CanvasPlugin {\n\treturn {\n\t\tid: \"trazo.plugin.realtime-comments\",\n\t\trender: (ctx) => (\n\t\t\t<RealtimeCommentsOverlay {...options} viewportRef={ctx.viewportRef} />\n\t\t),\n\t};\n}\n","\"use client\";\n\nimport {\n\ttype CSSProperties,\n\ttype KeyboardEvent,\n\ttype ReactNode,\n\ttype RefObject,\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport type { Rect } from \"../../../math/rect\";\nimport type { VectorSceneItem } from \"../../../scene/types\";\nimport { DEFAULT_VECTOR_TOOLS } from \"../../tools\";\nimport type { VectorToolDefinition } from \"../../tools/types\";\nimport type {\n\tCustomShapePlacementOptions,\n\tVectorViewportHandle,\n\tVectorViewportProps,\n} from \"../../VectorViewport\";\nimport {\n\tcreateRealtimeCommentAvatarDataUrl,\n\tcreateRealtimeCommentDraftItem,\n\tcreateRealtimeCommentItem,\n\tisRealtimeCommentDraftItem,\n\tRealtimeCommentsOverlay,\n\twithRealtimeCommentTool,\n} from \"./realtime-comment-tool\";\n\nconst COMMENT_BUBBLE_WORLD_SIZE = 18;\n\ntype PendingCommentComposer = {\n\tworldX: number;\n\tworldY: number;\n\tbody: string;\n};\n\nexport type RealtimeCommentsAuthor = {\n\tpeerId: string;\n\tdisplayName: string;\n\tcolor: string;\n\timage?: string;\n};\n\nexport type UseRealtimeCommentsOptions = {\n\titems: readonly VectorSceneItem[];\n\tonItemsChange: (items: VectorSceneItem[]) => void;\n\tauthor: RealtimeCommentsAuthor;\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n\tactiveToolId?: string;\n\troomId?: string;\n\tsetToolId?: (toolId: string) => void;\n\ttoolAfterDraft?: string;\n\ttools?: readonly VectorToolDefinition[];\n\tcomposerTitle?: string;\n\tcomposerDescription?: string;\n\tcomposerPlaceholder?: string;\n\tcancelLabel?: string;\n\tsubmitLabel?: string;\n\tsubmitHint?: string;\n};\n\nexport type RealtimeCommentsViewportBindings = Pick<\n\tVectorViewportProps,\n\t\"customPlacement\" | \"onItemsChange\" | \"onCameraChange\"\n>;\n\nexport type UseRealtimeCommentsResult = {\n\ttools: VectorToolDefinition[];\n\toverlay: ReactNode;\n\tviewport: RealtimeCommentsViewportBindings;\n\thandleViewportItemsChange: (\n\t\titems: VectorSceneItem[],\n\t\tonItemsChange?: (items: VectorSceneItem[]) => void,\n\t) => void;\n\tisComposerOpen: boolean;\n\tcloseComposer: () => void;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n\treturn Math.min(max, Math.max(min, value));\n}\n\nfunction createCommentId(): string {\n\tif (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n\t\treturn crypto.randomUUID();\n\t}\n\treturn `comment-${Math.random().toString(36).slice(2, 10)}`;\n}\n\ntype RealtimeCommentComposerProps = {\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n\tcameraVersion: number;\n\tcomposer: PendingCommentComposer | null;\n\tauthor: RealtimeCommentsAuthor;\n\tauthorImage: string;\n\troomId?: string;\n\ttitle: string;\n\tdescription: string;\n\tplaceholder: string;\n\tcancelLabel: string;\n\tsubmitLabel: string;\n\tsubmitHint: string;\n\tonBodyChange: (body: string) => void;\n\tonCommit: () => void;\n\tonCancel: () => void;\n};\n\nfunction RealtimeCommentComposer({\n\tviewportRef,\n\tcameraVersion,\n\tcomposer,\n\tauthor,\n\tauthorImage,\n\troomId,\n\ttitle,\n\tdescription,\n\tplaceholder,\n\tcancelLabel,\n\tsubmitLabel,\n\tsubmitHint,\n\tonBodyChange,\n\tonCommit,\n\tonCancel,\n}: RealtimeCommentComposerProps) {\n\tvoid cameraVersion;\n\tconst commentInputRef = useRef<HTMLTextAreaElement>(null);\n\tconst composerRef = useRef<HTMLDivElement>(null);\n\tconst [composerSize, setComposerSize] = useState({ width: 360, height: 320 });\n\n\tuseEffect(() => {\n\t\tif (!composer) return;\n\t\tcommentInputRef.current?.focus();\n\t}, [composer]);\n\n\tconst camera = viewportRef?.current?.getCamera();\n\tconst viewportSize = viewportRef?.current?.getViewportSize();\n\n\tuseLayoutEffect(() => {\n\t\tif (!composer || !viewportSize) return;\n\t\tconst el = composerRef.current;\n\t\tif (!el) return;\n\t\tconst updateSize = () => {\n\t\t\tconst next = {\n\t\t\t\twidth: el.offsetWidth,\n\t\t\t\theight: el.offsetHeight,\n\t\t\t};\n\t\t\tsetComposerSize((current) =>\n\t\t\t\tcurrent.width === next.width && current.height === next.height\n\t\t\t\t\t? current\n\t\t\t\t\t: next,\n\t\t\t);\n\t\t};\n\t\tupdateSize();\n\t\tif (typeof ResizeObserver === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\t\tconst observer = new ResizeObserver(updateSize);\n\t\tobserver.observe(el);\n\t\treturn () => observer.disconnect();\n\t}, [composer, viewportSize]);\n\n\tif (!composer) return null;\n\tif (!camera || !viewportSize) return null;\n\n\tconst anchor = camera.worldToScreen(composer.worldX, composer.worldY);\n\tconst composerWidth = Math.min(360, Math.max(220, viewportSize.width - 32));\n\tconst screenPosition = {\n\t\tleft: clamp(\n\t\t\tanchor.screenX + 20,\n\t\t\t16,\n\t\t\tMath.max(16, viewportSize.width - composerSize.width - 16),\n\t\t),\n\t\ttop: clamp(\n\t\t\tanchor.screenY - 22,\n\t\t\t16,\n\t\t\tMath.max(16, viewportSize.height - composerSize.height - 16),\n\t\t),\n\t};\n\n\tfunction handleKeyDown(event: KeyboardEvent<HTMLTextAreaElement>): void {\n\t\tif ((event.metaKey || event.ctrlKey) && event.key === \"Enter\") {\n\t\t\tevent.preventDefault();\n\t\t\tonCommit();\n\t\t\treturn;\n\t\t}\n\t\tif (event.key === \"Escape\") {\n\t\t\tevent.preventDefault();\n\t\t\tonCancel();\n\t\t}\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tref={composerRef}\n\t\t\tstyle={{\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tleft: screenPosition.left,\n\t\t\t\ttop: screenPosition.top,\n\t\t\t\tzIndex: 44,\n\t\t\t\twidth: composerWidth,\n\t\t\t\tmaxWidth: \"calc(100% - 32px)\",\n\t\t\t\tmaxHeight: \"calc(100% - 32px)\",\n\t\t\t\tpadding: 18,\n\t\t\t\tborderRadius: 22,\n\t\t\t\tbackground: \"rgba(255,255,255,0.98)\",\n\t\t\t\tborder: \"1px solid rgba(148,163,184,0.28)\",\n\t\t\t\tboxShadow: \"0 22px 48px rgba(15,23,42,0.18)\",\n\t\t\t\tbackdropFilter: \"blur(12px)\",\n\t\t\t\tpointerEvents: \"auto\",\n\t\t\t\tboxSizing: \"border-box\",\n\t\t\t\toverflow: \"auto\",\n\t\t\t}}\n\t\t>\n\t\t\t<div style={{ fontSize: 16, fontWeight: 700, color: \"#0f172a\" }}>{title}</div>\n\t\t\t<div style={{ marginTop: 6, color: \"#64748b\", fontSize: 13, lineHeight: 1.5 }}>\n\t\t\t\t{description}\n\t\t\t</div>\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\tgap: 10,\n\t\t\t\t\tmarginTop: 14,\n\t\t\t\t\tmarginBottom: 12,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<img\n\t\t\t\t\tsrc={authorImage}\n\t\t\t\t\talt={author.displayName}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\twidth: 38,\n\t\t\t\t\t\theight: 38,\n\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\tobjectFit: \"cover\",\n\t\t\t\t\t\tboxShadow: `0 0 0 2px ${author.color}22`,\n\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<div style={{ minWidth: 0 }}>\n\t\t\t\t\t<div style={{ fontWeight: 700, fontSize: 14, color: \"#0f172a\" }}>\n\t\t\t\t\t\t{author.displayName}\n\t\t\t\t\t</div>\n\t\t\t\t\t{roomId ? (\n\t\t\t\t\t\t<div style={{ color: \"#64748b\", fontSize: 12.5 }}>Sala {roomId}</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<textarea\n\t\t\t\tref={commentInputRef}\n\t\t\t\tvalue={composer.body}\n\t\t\t\tonChange={(event) => onBodyChange(event.target.value)}\n\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tstyle={{\n\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\tminHeight: 116,\n\t\t\t\t\tpadding: \"12px 14px\",\n\t\t\t\t\tborderRadius: 14,\n\t\t\t\t\tborder: \"1px solid #cbd5e1\",\n\t\t\t\t\tboxSizing: \"border-box\",\n\t\t\t\t\tfontFamily: \"inherit\",\n\t\t\t\t\tfontSize: 15,\n\t\t\t\t\tlineHeight: 1.5,\n\t\t\t\t\tcolor: \"#0f172a\",\n\t\t\t\t\tresize: \"vertical\",\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\tjustifyContent: \"space-between\",\n\t\t\t\t\talignItems: \"flex-end\",\n\t\t\t\t\tflexWrap: \"wrap\",\n\t\t\t\t\tgap: 10,\n\t\t\t\t\tmarginTop: 12,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"#64748b\",\n\t\t\t\t\t\tfontSize: 11.5,\n\t\t\t\t\t\tlineHeight: 1.4,\n\t\t\t\t\t\tflex: \"1 1 120px\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{submitHint}\n\t\t\t\t</div>\n\t\t\t\t<div style={{ display: \"flex\", gap: 8, flexShrink: 0 }}>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onCancel}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tpadding: \"10px 14px\",\n\t\t\t\t\t\t\tborderRadius: 12,\n\t\t\t\t\t\t\tborder: \"1px solid #cbd5e1\",\n\t\t\t\t\t\t\tbackground: \"#fff\",\n\t\t\t\t\t\t\tfontFamily: \"inherit\",\n\t\t\t\t\t\t\tfontSize: 14,\n\t\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{cancelLabel}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onCommit}\n\t\t\t\t\t\tdisabled={!composer.body.trim()}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tpadding: \"10px 14px\",\n\t\t\t\t\t\t\tborderRadius: 12,\n\t\t\t\t\t\t\tborder: \"1px solid #6d28d9\",\n\t\t\t\t\t\t\tbackground: composer.body.trim() ? \"#7c3aed\" : \"#c4b5fd\",\n\t\t\t\t\t\t\tcolor: \"#fff\",\n\t\t\t\t\t\t\tfontFamily: \"inherit\",\n\t\t\t\t\t\t\tfontSize: 14,\n\t\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\tcursor: composer.body.trim() ? \"pointer\" : \"not-allowed\",\n\t\t\t\t\t\t\topacity: composer.body.trim() ? 1 : 0.72,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{submitLabel}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nconst overlayShell: CSSProperties = {\n\tposition: \"absolute\",\n\tinset: 0,\n\tpointerEvents: \"none\",\n\tzIndex: 26,\n\toverflow: \"hidden\",\n};\n\ntype RealtimeCommentsOverlayNodeOptions = {\n\titems: readonly VectorSceneItem[];\n\tonItemsChange: (items: VectorSceneItem[]) => void;\n\tisDragEnabled: boolean;\n\tcameraVersion: number;\n\tcomposer: PendingCommentComposer | null;\n\tauthor: RealtimeCommentsAuthor;\n\tauthorImage: string;\n\troomId?: string;\n\ttitle: string;\n\tdescription: string;\n\tplaceholder: string;\n\tcancelLabel: string;\n\tsubmitLabel: string;\n\tsubmitHint: string;\n\tonBodyChange: (body: string) => void;\n\tonCommit: () => void;\n\tonCancel: () => void;\n};\n\nfunction renderRealtimeCommentsOverlayNode(\n\toptions: RealtimeCommentsOverlayNodeOptions,\n\tviewportRef?: RefObject<VectorViewportHandle | null>,\n): ReactNode {\n\treturn (\n\t\t<div style={overlayShell}>\n\t\t\t<RealtimeCommentsOverlay\n\t\t\t\titems={options.items}\n\t\t\t\tonItemsChange={options.onItemsChange}\n\t\t\t\tisDragEnabled={options.isDragEnabled}\n\t\t\t\tcameraVersion={options.cameraVersion}\n\t\t\t\tviewportRef={viewportRef}\n\t\t\t/>\n\t\t\t<RealtimeCommentComposer\n\t\t\t\tviewportRef={viewportRef}\n\t\t\t\tcameraVersion={options.cameraVersion}\n\t\t\t\tcomposer={options.composer}\n\t\t\t\tauthor={options.author}\n\t\t\t\tauthorImage={options.authorImage}\n\t\t\t\troomId={options.roomId}\n\t\t\t\ttitle={options.title}\n\t\t\t\tdescription={options.description}\n\t\t\t\tplaceholder={options.placeholder}\n\t\t\t\tcancelLabel={options.cancelLabel}\n\t\t\t\tsubmitLabel={options.submitLabel}\n\t\t\t\tsubmitHint={options.submitHint}\n\t\t\t\tonBodyChange={options.onBodyChange}\n\t\t\t\tonCommit={options.onCommit}\n\t\t\t\tonCancel={options.onCancel}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\nexport function useRealtimeComments({\n\titems,\n\tonItemsChange,\n\tauthor,\n\tviewportRef,\n\tactiveToolId,\n\troomId,\n\tsetToolId,\n\ttoolAfterDraft = \"select\",\n\ttools: providedTools = DEFAULT_VECTOR_TOOLS,\n\tcomposerTitle = \"Novo comentário\",\n\tcomposerDescription = \"Escreva algo para a equipe. Ao enviar, a bolha sincroniza na sala.\",\n\tcomposerPlaceholder = \"Contexto, decisao, duvida, feedback...\",\n\tcancelLabel = \"Cancelar\",\n\tsubmitLabel = \"Publicar comentário\",\n\tsubmitHint = \"`Ctrl/Cmd + Enter` envia\",\n}: UseRealtimeCommentsOptions): UseRealtimeCommentsResult {\n\tconst [cameraVersion, setCameraVersion] = useState(0);\n\tconst [commentComposer, setCommentComposer] =\n\t\tuseState<PendingCommentComposer | null>(null);\n\n\tconst authorImage = useMemo(\n\t\t() =>\n\t\t\tauthor.image ??\n\t\t\tcreateRealtimeCommentAvatarDataUrl(author.displayName, author.color),\n\t\t[author.color, author.displayName, author.image],\n\t);\n\n\tconst tools = useMemo(\n\t\t() => withRealtimeCommentTool(providedTools),\n\t\t[providedTools],\n\t);\n\n\tconst customPlacement = useMemo<CustomShapePlacementOptions>(\n\t\t() => ({\n\t\t\ttoolId: \"comment\",\n\t\t\tcreateItem: ({ id, bounds }: { id: string; bounds: Rect }) =>\n\t\t\t\tcreateRealtimeCommentDraftItem(id, bounds, author.color),\n\t\t}),\n\t\t[author.color],\n\t);\n\n\tconst handleViewportItemsChange = useCallback(\n\t\t(\n\t\t\tnextItems: VectorSceneItem[],\n\t\t\toverrideOnItemsChange?: (items: VectorSceneItem[]) => void,\n\t\t) => {\n\t\t\tconst applyItemsChange = overrideOnItemsChange ?? onItemsChange;\n\t\t\tconst currentIds = new Set(items.map((item) => item.id));\n\t\t\tconst draftItem = nextItems.find(\n\t\t\t\t(item) => !currentIds.has(item.id) && isRealtimeCommentDraftItem(item),\n\t\t\t);\n\t\t\tif (!draftItem) {\n\t\t\t\tapplyItemsChange(nextItems);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst filteredItems = nextItems.filter((item) => item.id !== draftItem.id);\n\t\t\tconst shouldPersistFiltered =\n\t\t\t\tfilteredItems.length !== items.length ||\n\t\t\t\tfilteredItems.some((item, index) => items[index]?.id !== item.id);\n\t\t\tif (shouldPersistFiltered) {\n\t\t\t\tapplyItemsChange(filteredItems);\n\t\t\t}\n\n\t\t\tsetCommentComposer({\n\t\t\t\tworldX: draftItem.bounds.x + draftItem.bounds.width / 2,\n\t\t\t\tworldY: draftItem.bounds.y + draftItem.bounds.height / 2,\n\t\t\t\tbody: \"\",\n\t\t\t});\n\t\t\tsetToolId?.(toolAfterDraft);\n\t\t},\n\t\t[items, onItemsChange, setToolId, toolAfterDraft],\n\t);\n\n\tconst onCameraChange = useCallback(() => {\n\t\tsetCameraVersion((value) => value + 1);\n\t}, []);\n\n\tconst closeComposer = useCallback(() => {\n\t\tsetCommentComposer(null);\n\t}, []);\n\n\tconst onComposerBodyChange = useCallback((body: string) => {\n\t\tsetCommentComposer((current) => (current ? { ...current, body } : current));\n\t}, []);\n\n\tconst onComposerCommit = useCallback(() => {\n\t\tif (!commentComposer) return;\n\t\tconst body = commentComposer.body.trim();\n\t\tif (!body) return;\n\n\t\tconst half = COMMENT_BUBBLE_WORLD_SIZE / 2;\n\t\tconst nextItem = createRealtimeCommentItem(\n\t\t\tcreateCommentId(),\n\t\t\t{\n\t\t\t\tx: commentComposer.worldX - half,\n\t\t\t\ty: commentComposer.worldY - half,\n\t\t\t\twidth: COMMENT_BUBBLE_WORLD_SIZE,\n\t\t\t\theight: COMMENT_BUBBLE_WORLD_SIZE,\n\t\t\t},\n\t\t\t{\n\t\t\t\tbody,\n\t\t\t\tcreatedAt: Date.now(),\n\t\t\t\tauthorPeerId: author.peerId,\n\t\t\t\tauthorDisplayName: author.displayName,\n\t\t\t\tauthorColor: author.color,\n\t\t\t\tauthorImage: authorImage,\n\t\t\t},\n\t\t);\n\n\t\tonItemsChange(items.concat(nextItem));\n\t\tsetCommentComposer(null);\n\t}, [\n\t\tauthor.color,\n\t\tauthor.displayName,\n\t\tauthor.peerId,\n\t\tauthorImage,\n\t\tcommentComposer,\n\t\titems,\n\t\tonItemsChange,\n\t]);\n\n\tconst overlay = useMemo(\n\t\t() =>\n\t\t\trenderRealtimeCommentsOverlayNode(\n\t\t\t\t{\n\t\t\t\t\titems,\n\t\t\t\t\tonItemsChange,\n\t\t\t\t\tisDragEnabled: activeToolId === \"select\",\n\t\t\t\t\tcameraVersion,\n\t\t\t\t\tcomposer: commentComposer,\n\t\t\t\t\tauthor,\n\t\t\t\t\tauthorImage,\n\t\t\t\t\troomId,\n\t\t\t\t\ttitle: composerTitle,\n\t\t\t\t\tdescription: composerDescription,\n\t\t\t\t\tplaceholder: composerPlaceholder,\n\t\t\t\t\tcancelLabel,\n\t\t\t\t\tsubmitLabel,\n\t\t\t\t\tsubmitHint,\n\t\t\t\t\tonBodyChange: onComposerBodyChange,\n\t\t\t\t\tonCommit: onComposerCommit,\n\t\t\t\t\tonCancel: closeComposer,\n\t\t\t\t},\n\t\t\t\tviewportRef,\n\t\t\t),\n\t\t[\n\t\t\tauthor,\n\t\t\tauthorImage,\n\t\t\tcameraVersion,\n\t\t\tcancelLabel,\n\t\t\tcloseComposer,\n\t\t\tcommentComposer,\n\t\t\tcomposerDescription,\n\t\t\tcomposerPlaceholder,\n\t\t\tcomposerTitle,\n\t\t\titems,\n\t\t\tactiveToolId,\n\t\t\tonItemsChange,\n\t\t\tonComposerBodyChange,\n\t\t\tonComposerCommit,\n\t\t\troomId,\n\t\t\tsubmitHint,\n\t\t\tsubmitLabel,\n\t\t\tviewportRef,\n\t\t],\n\t);\n\n\tconst viewport = useMemo(\n\t\t() => ({\n\t\t\tcustomPlacement,\n\t\t\tonItemsChange: (nextItems: VectorSceneItem[]) =>\n\t\t\t\thandleViewportItemsChange(nextItems),\n\t\t\tonCameraChange,\n\t\t}),\n\t\t[customPlacement, handleViewportItemsChange, onCameraChange],\n\t);\n\n\treturn useMemo(\n\t\t() => ({\n\t\t\ttools,\n\t\t\toverlay,\n\t\t\tviewport,\n\t\t\thandleViewportItemsChange,\n\t\t\tisComposerOpen: commentComposer != null,\n\t\t\tcloseComposer,\n\t\t}),\n\t\t[\n\t\t\tcloseComposer,\n\t\t\tcommentComposer,\n\t\t\thandleViewportItemsChange,\n\t\t\toverlay,\n\t\t\ttools,\n\t\t\tviewport,\n\t\t],\n\t);\n}\n","\"use client\";\n\nimport type { RefObject } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type { VectorViewportHandle } from \"../../VectorViewport\";\nimport type { RealtimeSessionPeer } from \"./protocol\";\n\nexport type UseRealtimePeerFollowOptions = {\n\tviewportRef: RefObject<VectorViewportHandle | null>;\n\tsessionPeers: RealtimeSessionPeer[];\n\tfollowedPeerId: string | null | undefined;\n\tonFollowEnd?: () => void;\n};\n\ntype ViewportCameraSnapshot = {\n\tx: number;\n\ty: number;\n\tzoom: number;\n\tviewportWidth: number;\n\tviewportHeight: number;\n};\n\nconst viewportFollowSyncSnapshots = new WeakMap<\n\tVectorViewportHandle,\n\tViewportCameraSnapshot\n>();\n\nfunction getFollowedPeer(\n\tsessionPeers: RealtimeSessionPeer[],\n\tfollowedPeerId: string,\n): RealtimeSessionPeer | undefined {\n\treturn sessionPeers.find(\n\t\t(peerState) =>\n\t\t\tpeerState.peerId === followedPeerId || peerState.id === followedPeerId,\n\t);\n}\n\nfunction getCameraKey(peer: RealtimeSessionPeer): string | null {\n\tif (!peer.camera) return null;\n\treturn [\n\t\tpeer.peerId,\n\t\tpeer.camera.x,\n\t\tpeer.camera.y,\n\t\tpeer.camera.zoom,\n\t\tpeer.camera.viewportWidth,\n\t\tpeer.camera.viewportHeight,\n\t].join(\":\");\n}\n\nfunction getViewportSizeKey(viewport: VectorViewportHandle | null): string | null {\n\tif (!viewport) return null;\n\tconst viewportSize = viewport.getViewportSize();\n\treturn [viewportSize.width, viewportSize.height].join(\":\");\n}\n\nfunction getFollowedCameraPosition(\n\tviewport: VectorViewportHandle,\n\tpeer: RealtimeSessionPeer,\n): { x: number; y: number; zoom: number } | null {\n\tif (!peer.camera) return null;\n\tconst viewportSize = viewport.getViewportSize();\n\treturn {\n\t\tx: peer.camera.x + (viewportSize.width - peer.camera.viewportWidth) / 2,\n\t\ty: peer.camera.y + (viewportSize.height - peer.camera.viewportHeight) / 2,\n\t\tzoom: peer.camera.zoom,\n\t};\n}\n\nfunction applyPeerCamera(\n\tviewport: VectorViewportHandle,\n\tpeer: RealtimeSessionPeer,\n): boolean {\n\tconst camera = viewport.getCamera();\n\tconst nextCamera = getFollowedCameraPosition(viewport, peer);\n\tconst viewportSize = viewport.getViewportSize();\n\tif (!camera || !nextCamera) return false;\n\tif (\n\t\tcamera.x === nextCamera.x &&\n\t\tcamera.y === nextCamera.y &&\n\t\tcamera.zoom === nextCamera.zoom\n\t) {\n\t\treturn true;\n\t}\n\tmarkViewportFollowSync(viewport, {\n\t\tx: nextCamera.x,\n\t\ty: nextCamera.y,\n\t\tzoom: nextCamera.zoom,\n\t\tviewportWidth: viewportSize.width,\n\t\tviewportHeight: viewportSize.height,\n\t});\n\tcamera.x = nextCamera.x;\n\tcamera.y = nextCamera.y;\n\tcamera.zoom = nextCamera.zoom;\n\tviewport.requestRender();\n\treturn true;\n}\n\nexport function markViewportFollowSync(\n\tviewport: VectorViewportHandle,\n\tsnapshot: ViewportCameraSnapshot,\n): void {\n\tviewportFollowSyncSnapshots.set(viewport, snapshot);\n}\n\nexport function consumeViewportFollowSync(\n\tviewport: VectorViewportHandle,\n\tsnapshot: ViewportCameraSnapshot,\n): boolean {\n\tconst currentSnapshot = viewportFollowSyncSnapshots.get(viewport);\n\tif (\n\t\t!currentSnapshot ||\n\t\tcurrentSnapshot.x !== snapshot.x ||\n\t\tcurrentSnapshot.y !== snapshot.y ||\n\t\tcurrentSnapshot.zoom !== snapshot.zoom ||\n\t\tcurrentSnapshot.viewportWidth !== snapshot.viewportWidth ||\n\t\tcurrentSnapshot.viewportHeight !== snapshot.viewportHeight\n\t) {\n\t\treturn false;\n\t}\n\tviewportFollowSyncSnapshots.delete(viewport);\n\treturn true;\n}\n\nexport function useRealtimePeerFollow(options: UseRealtimePeerFollowOptions): void {\n\tconst { viewportRef, sessionPeers, followedPeerId, onFollowEnd } = options;\n\tconst endedPeerIdRef = useRef<string | null>(null);\n\tconst lastAppliedCameraKeyRef = useRef<string | null>(null);\n\tconst [, setViewportSizeVersion] = useState(0);\n\n\tuseEffect(() => {\n\t\tif (!followedPeerId) return;\n\t\tlet animationFrameId = 0;\n\t\tlet lastViewportSizeKey = getViewportSizeKey(viewportRef.current ?? null);\n\n\t\tconst checkViewportSize = () => {\n\t\t\tconst nextViewportSizeKey = getViewportSizeKey(viewportRef.current ?? null);\n\t\t\tif (nextViewportSizeKey !== lastViewportSizeKey) {\n\t\t\t\tlastViewportSizeKey = nextViewportSizeKey;\n\t\t\t\tsetViewportSizeVersion((value) => value + 1);\n\t\t\t}\n\t\t\tanimationFrameId = window.requestAnimationFrame(checkViewportSize);\n\t\t};\n\n\t\tanimationFrameId = window.requestAnimationFrame(checkViewportSize);\n\t\treturn () => {\n\t\t\twindow.cancelAnimationFrame(animationFrameId);\n\t\t};\n\t}, [followedPeerId, viewportRef]);\n\n\tuseEffect(() => {\n\t\tif (!followedPeerId) {\n\t\t\tendedPeerIdRef.current = null;\n\t\t\tlastAppliedCameraKeyRef.current = null;\n\t\t\treturn;\n\t\t}\n\n\t\tconst followedPeer = getFollowedPeer(sessionPeers, followedPeerId);\n\t\tif (!followedPeer) {\n\t\t\tlastAppliedCameraKeyRef.current = null;\n\t\t\tif (endedPeerIdRef.current === followedPeerId) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tendedPeerIdRef.current = followedPeerId;\n\t\t\tonFollowEnd?.();\n\t\t\treturn;\n\t\t}\n\t\tif (!followedPeer.camera) {\n\t\t\tendedPeerIdRef.current = null;\n\t\t\tlastAppliedCameraKeyRef.current = null;\n\t\t\treturn;\n\t\t}\n\n\t\tendedPeerIdRef.current = null;\n\t\tconst viewport = viewportRef.current;\n\t\tconst nextCameraKey = [\n\t\t\tgetCameraKey(followedPeer),\n\t\t\tgetViewportSizeKey(viewport ?? null),\n\t\t].join(\":\");\n\t\tif (nextCameraKey && nextCameraKey === lastAppliedCameraKeyRef.current) {\n\t\t\treturn;\n\t\t}\n\t\tif (!viewport || !applyPeerCamera(viewport, followedPeer)) {\n\t\t\treturn;\n\t\t}\n\t\tlastAppliedCameraKeyRef.current = nextCameraKey;\n\t}, [followedPeerId, onFollowEnd, sessionPeers, viewportRef]);\n}\n","import * as Y from \"yjs\";\nimport type { VectorSceneItem } from \"../../../scene/types\";\n\n// Phase 1 design: Yjs is the local source of truth for items, but the wire\n// protocol remains items-array snapshots (so legacy boards and unchanged\n// server work). The CRDT semantics buy us per-field merge on the client side\n// and accurate distinction between \"deleted by another user\" vs \"added\n// locally and not yet synced\".\n//\n// Y.Doc shape:\n// doc.getArray<Y.Map>(\"items\") → ordered list of items\n// each Y.Map has the VectorSceneItem fields (id, toolKind, bounds, etc.)\n//\n// We never put blob handles or rasterized image refs into the Y.Doc — those\n// are local-only and would not survive sync. sanitizeRealtimeItem upstream\n// already strips them before items reach this layer for outbound.\n\nconst ITEMS_KEY = \"items\";\n\n// Window during which a freshly server-added id is protected from being\n// deleted by a local-items update. Necessary because the React consumer that\n// drives applyLocalItemsToYDoc cannot have rendered the just-received server\n// item yet, so its \"current local view\" legitimately lacks it. Without this\n// guard, a user drawing at 60fps while another peer adds items causes those\n// inbound items to vanish from the Y.Doc the next time the consumer's\n// onItemsChange fires.\nconst SERVER_ADD_RACE_WINDOW_MS = 2000;\n\nexport type YjsBoardDoc = {\n\treadonly doc: Y.Doc;\n\treadonly yItems: Y.Array<Y.Map<unknown>>;\n\t/**\n\t * Set of item ids that the server has confirmed in its latest snapshot.\n\t * Items present in the Y.Doc whose id is NOT in this set are considered\n\t * locally-pending — they have not yet been seen by the server. When a\n\t * server snapshot arrives lacking an id that IS in this set, we know the\n\t * server deleted it (rather than simply not having seen our local copy).\n\t */\n\tlastServerConfirmedIds: Set<string>;\n\tlastServerConfirmedItemSerializations: Map<string, string>;\n\t/**\n\t * Map of id → timestamp (ms) recording when the server most recently\n\t * surfaced an item. Used to protect freshly added remote items from being\n\t * deleted by a stale local-items update during the React-render race\n\t * window. Entries older than SERVER_ADD_RACE_WINDOW_MS are eligible for\n\t * pruning during deletion checks.\n\t */\n\tserverItemSeenAt: Map<string, number>;\n};\n\nexport function createYjsBoardDoc(): YjsBoardDoc {\n\tconst doc = new Y.Doc();\n\tconst yItems = doc.getArray<Y.Map<unknown>>(ITEMS_KEY);\n\treturn {\n\t\tdoc,\n\t\tyItems,\n\t\tlastServerConfirmedIds: new Set(),\n\t\tlastServerConfirmedItemSerializations: new Map(),\n\t\tserverItemSeenAt: new Map(),\n\t};\n}\n\nfunction getItemId(item: VectorSceneItem | Y.Map<unknown>): string | null {\n\tif (item instanceof Y.Map) {\n\t\tconst id = item.get(\"id\");\n\t\treturn typeof id === \"string\" ? id : null;\n\t}\n\tconst id = (item as { id?: unknown }).id;\n\treturn typeof id === \"string\" ? id : null;\n}\n\nfunction vectorItemToYMap(item: VectorSceneItem): Y.Map<unknown> {\n\tconst yMap = new Y.Map<unknown>();\n\tfor (const [key, value] of Object.entries(item)) {\n\t\tif (value === undefined) continue;\n\t\tyMap.set(key, value);\n\t}\n\treturn yMap;\n}\n\nfunction yMapToVectorItem(yMap: Y.Map<unknown>): VectorSceneItem {\n\tconst obj: Record<string, unknown> = {};\n\tfor (const [key, value] of yMap.entries()) {\n\t\tobj[key] = value;\n\t}\n\treturn obj as VectorSceneItem;\n}\n\n/**\n * Project the current Y.Doc state to a plain items array for the React\n * consumer (canvu's VectorCanvas).\n */\nexport function readVectorItems(yItems: Y.Array<Y.Map<unknown>>): VectorSceneItem[] {\n\tconst result: VectorSceneItem[] = [];\n\tfor (let i = 0; i < yItems.length; i++) {\n\t\tconst yMap = yItems.get(i);\n\t\tif (yMap) result.push(yMapToVectorItem(yMap));\n\t}\n\treturn result;\n}\n\n/**\n * Build an index of the current Y.Doc items by id for fast lookups during\n * merge. Items without an id are skipped — they cannot be reconciled by id\n * and stay as-is.\n */\nfunction indexYItemsById(\n\tyItems: Y.Array<Y.Map<unknown>>,\n): Map<string, { yMap: Y.Map<unknown>; index: number }> {\n\tconst result = new Map<string, { yMap: Y.Map<unknown>; index: number }>();\n\tfor (let i = 0; i < yItems.length; i++) {\n\t\tconst yMap = yItems.get(i);\n\t\tif (!yMap) continue;\n\t\tconst id = getItemId(yMap);\n\t\tif (!id) continue;\n\t\tresult.set(id, { yMap, index: i });\n\t}\n\treturn result;\n}\n\nfunction valuesEqual(left: unknown, right: unknown): boolean {\n\tif (left === right) return true;\n\tif (typeof left !== typeof right) return false;\n\tif (left === null || right === null) return false;\n\tif (typeof left !== \"object\") return false;\n\ttry {\n\t\treturn JSON.stringify(left) === JSON.stringify(right);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction serializeItem(value: VectorSceneItem | Y.Map<unknown>): string {\n\tconst item = value instanceof Y.Map ? yMapToVectorItem(value) : value;\n\treturn JSON.stringify(item);\n}\n\n/**\n * Update a Y.Map in place to match a target VectorSceneItem, touching only\n * the fields that actually changed. This keeps Yjs ops minimal and avoids\n * triggering observers for no-op updates.\n */\nfunction updateYMapInPlace(yMap: Y.Map<unknown>, next: VectorSceneItem): void {\n\tconst nextKeys = new Set<string>();\n\tfor (const [key, value] of Object.entries(next)) {\n\t\tif (value === undefined) continue;\n\t\tnextKeys.add(key);\n\t\tconst current = yMap.get(key);\n\t\tif (!valuesEqual(current, value)) {\n\t\t\tyMap.set(key, value);\n\t\t}\n\t}\n\tfor (const key of Array.from(yMap.keys())) {\n\t\tif (!nextKeys.has(key)) yMap.delete(key);\n\t}\n}\n\nexport type ApplyLocalItemsOptions = {\n\t/**\n\t * Items provided by the local consumer (canvu's VectorCanvas onItemsChange).\n\t * The Y.Doc is mutated to match this set: new ids are added (in the order\n\t * they appear), changed ids have their Y.Map fields updated, and ids\n\t * missing from the new list are removed.\n\t *\n\t * All mutations happen inside a single Y transaction so observers see one\n\t * coherent change.\n\t */\n\titems: readonly VectorSceneItem[];\n\t/**\n\t * Optional origin tag for the transaction. Useful to distinguish local\n\t * edits from remote applies when observing the doc.\n\t */\n\torigin?: unknown;\n};\n\n/**\n * Apply a complete items array from the local consumer as a set of minimal\n * Yjs operations. Order of the next array becomes the order in the Y.Array.\n *\n * Returns the list of item ids that are newly introduced (not present before\n * this call), so the caller can track them as \"locally-pending until server\n * confirms\".\n */\nexport function applyLocalItemsToYDoc(\n\tboard: YjsBoardDoc,\n\toptions: ApplyLocalItemsOptions,\n): { addedIds: string[]; removedIds: string[] } {\n\tconst { items, origin } = options;\n\tconst addedIds: string[] = [];\n\tconst removedIds: string[] = [];\n\tconst now = Date.now();\n\tboard.doc.transact(() => {\n\t\tconst currentIndex = indexYItemsById(board.yItems);\n\t\tconst nextIds = new Set<string>();\n\t\tfor (const item of items) {\n\t\t\tconst id = getItemId(item);\n\t\t\tif (!id) continue;\n\t\t\tnextIds.add(id);\n\t\t}\n\t\t// Walk deletes in descending index order so removals don't shift the\n\t\t// indices of items still pending deletion.\n\t\tconst toDelete: Array<{ id: string; index: number }> = [];\n\t\tfor (const [id, entry] of currentIndex) {\n\t\t\tif (nextIds.has(id)) continue;\n\t\t\t// Race guard: an id that the server surfaced within the last race\n\t\t\t// window may simply not have been rendered by the React consumer\n\t\t\t// yet, so its absence from `items` is not a real user delete.\n\t\t\t// Preserve it; the next local update after the consumer re-renders\n\t\t\t// will include it (no-op) or genuinely omit it (after the window\n\t\t\t// elapses, deletion will then go through).\n\t\t\tconst serverSeenAt = board.serverItemSeenAt.get(id);\n\t\t\tif (serverSeenAt != null && now - serverSeenAt < SERVER_ADD_RACE_WINDOW_MS) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttoDelete.push({ id, index: entry.index });\n\t\t}\n\t\ttoDelete.sort((a, b) => b.index - a.index);\n\t\tfor (const { id, index } of toDelete) {\n\t\t\tboard.yItems.delete(index, 1);\n\t\t\tboard.serverItemSeenAt.delete(id);\n\t\t\tremovedIds.push(id);\n\t\t}\n\t\tconst refreshedIndex = indexYItemsById(board.yItems);\n\t\tfor (let nextOrder = 0; nextOrder < items.length; nextOrder++) {\n\t\t\tconst item = items[nextOrder];\n\t\t\tif (!item) continue;\n\t\t\tconst id = getItemId(item);\n\t\t\tif (!id) continue;\n\t\t\tconst existing = refreshedIndex.get(id);\n\t\t\tif (existing) {\n\t\t\t\tupdateYMapInPlace(existing.yMap, item);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst yMap = vectorItemToYMap(item);\n\t\t\tboard.yItems.push([yMap]);\n\t\t\taddedIds.push(id);\n\t\t}\n\t}, origin);\n\treturn { addedIds, removedIds };\n}\n\nexport type ApplyServerSnapshotOptions = {\n\t/**\n\t * Server-confirmed items snapshot. Ordering of the snapshot is treated as\n\t * authoritative for items the server knows about.\n\t */\n\titems: readonly VectorSceneItem[];\n\t/**\n\t * Optional origin tag for the transaction.\n\t */\n\torigin?: unknown;\n};\n\n/**\n * Reconcile a server snapshot into the Y.Doc, additively.\n *\n * Rules:\n * - id present in snapshot AND in Y.Doc → update Y.Map fields in place.\n * - id present in snapshot AND NOT in Y.Doc → add to Y.Doc.\n * - id present in Y.Doc, NOT in snapshot → **keep**. We intentionally do\n * not delete based on server absence. With a snapshot wire protocol and\n * a store-and-broadcast server that does not merge, we cannot tell\n * \"another peer deleted this id\" apart from \"another peer sent a stale\n * snapshot that didn't include this id yet\". Treating absence as delete\n * caused a cascading wipe: each peer's update removed the others'\n * unsynced items, peer A's next snapshot then removed peer B's items\n * again, until everything converged to empty.\n *\n * The cost of being conservative: deletes performed by other peers do\n * not propagate visually. Local user deletes still work via\n * applyLocalItemsToYDoc (their Y.Doc loses the item, the next flush\n * pushes the new state up). Fixing cross-peer deletes properly requires\n * an explicit delete signal on the wire — that is Phase 2 (ops-based\n * protocol with server-side merge).\n *\n * `board.lastServerConfirmedIds` is still updated to the snapshot id set so\n * the local delete path's race guard remains accurate.\n */\nexport function applyServerSnapshotToYDoc(\n\tboard: YjsBoardDoc,\n\toptions: ApplyServerSnapshotOptions,\n): void {\n\tconst { items: snapshotItems, origin } = options;\n\tconst now = Date.now();\n\tboard.doc.transact(() => {\n\t\tfor (const item of snapshotItems) {\n\t\t\tconst id = getItemId(item);\n\t\t\tif (!id) continue;\n\t\t\tconst existing = indexYItemsById(board.yItems).get(id);\n\t\t\tif (existing) {\n\t\t\t\tconst currentSerialized = serializeItem(existing.yMap);\n\t\t\t\tconst incomingSerialized = serializeItem(item);\n\t\t\t\tconst confirmedSerialized =\n\t\t\t\t\tboard.lastServerConfirmedItemSerializations.get(id);\n\t\t\t\tconst hasPendingLocalChange =\n\t\t\t\t\tconfirmedSerialized === undefined\n\t\t\t\t\t\t? currentSerialized !== incomingSerialized\n\t\t\t\t\t\t: currentSerialized !== confirmedSerialized &&\n\t\t\t\t\t\t\tcurrentSerialized !== incomingSerialized;\n\t\t\t\tif (hasPendingLocalChange) {\n\t\t\t\t\tboard.serverItemSeenAt.set(id, now);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tupdateYMapInPlace(existing.yMap, item);\n\t\t\t\tboard.serverItemSeenAt.set(id, now);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst yMap = vectorItemToYMap(item);\n\t\t\tboard.yItems.push([yMap]);\n\t\t\tboard.serverItemSeenAt.set(id, now);\n\t\t}\n\t}, origin);\n\n\tboard.lastServerConfirmedIds = new Set();\n\tboard.lastServerConfirmedItemSerializations = new Map();\n\tfor (const item of snapshotItems) {\n\t\tconst id = getItemId(item);\n\t\tif (id) {\n\t\t\tboard.lastServerConfirmedIds.add(id);\n\t\t\tboard.lastServerConfirmedItemSerializations.set(id, serializeItem(item));\n\t\t}\n\t}\n}\n\n/**\n * Replace the entire Y.Doc state with a snapshot, discarding any local\n * changes. Used on initial load when no local draft exists and we just want\n * the server's view.\n */\nexport function replaceYDocWithSnapshot(\n\tboard: YjsBoardDoc,\n\toptions: ApplyServerSnapshotOptions,\n): void {\n\tconst { items: snapshotItems, origin } = options;\n\tconst now = Date.now();\n\tboard.doc.transact(() => {\n\t\tif (board.yItems.length > 0) {\n\t\t\tboard.yItems.delete(0, board.yItems.length);\n\t\t}\n\t\tfor (const item of snapshotItems) {\n\t\t\tboard.yItems.push([vectorItemToYMap(item)]);\n\t\t}\n\t}, origin);\n\tboard.lastServerConfirmedIds = new Set();\n\tboard.lastServerConfirmedItemSerializations = new Map();\n\tboard.serverItemSeenAt = new Map();\n\tfor (const item of snapshotItems) {\n\t\tconst id = getItemId(item);\n\t\tif (id) {\n\t\t\tboard.lastServerConfirmedIds.add(id);\n\t\t\tboard.lastServerConfirmedItemSerializations.set(id, serializeItem(item));\n\t\t\tboard.serverItemSeenAt.set(id, now);\n\t\t}\n\t}\n}\n\n/**\n * Return ids of items currently in the Y.Doc that have not yet been\n * confirmed in a server snapshot. These are the user's local additions still\n * waiting for the server to round-trip.\n */\nexport function getLocallyPendingItemIds(board: YjsBoardDoc): Set<string> {\n\tconst pending = new Set<string>();\n\tfor (let i = 0; i < board.yItems.length; i++) {\n\t\tconst yMap = board.yItems.get(i);\n\t\tif (!yMap) continue;\n\t\tconst id = getItemId(yMap);\n\t\tif (!id) continue;\n\t\tconst confirmedSerialized = board.lastServerConfirmedItemSerializations.get(id);\n\t\tif (!confirmedSerialized || serializeItem(yMap) !== confirmedSerialized) {\n\t\t\tpending.add(id);\n\t\t}\n\t}\n\treturn pending;\n}\n\n/**\n * Encode the Y.Doc state for persistence (localStorage offline draft).\n * Returns a base64-ish string suitable for JSON storage.\n */\nexport function encodeYDocState(board: YjsBoardDoc): string {\n\tconst update = Y.encodeStateAsUpdate(board.doc);\n\tlet binary = \"\";\n\tfor (let i = 0; i < update.length; i++) {\n\t\tbinary += String.fromCharCode(update[i] as number);\n\t}\n\treturn btoa(binary);\n}\n\n/**\n * Decode and apply a previously-encoded Y.Doc state. Returns true if the\n * state was applied successfully.\n */\nexport function decodeYDocState(board: YjsBoardDoc, encoded: string): boolean {\n\ttry {\n\t\tconst binary = atob(encoded);\n\t\tconst update = new Uint8Array(binary.length);\n\t\tfor (let i = 0; i < binary.length; i++) {\n\t\t\tupdate[i] = binary.charCodeAt(i);\n\t\t}\n\t\tY.applyUpdate(board.doc, update);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","\"use client\";\n\nimport type { RefObject } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { VectorSceneItem } from \"../../../scene/types\";\nimport type { PlacementPreview } from \"../../InteractionOverlay\";\nimport type { VectorCanvasRemoteAdapter } from \"../../persistence\";\nimport { remoteMarkupStrokeFromPlacementPreview } from \"../../presence\";\nimport type {\n\tVectorViewportHandle,\n\tVectorViewportProps,\n} from \"../../VectorViewport\";\nimport {\n\tparseRealtimeServerMessage,\n\ttype RealtimeClientMessage,\n\ttype RealtimeConnectionInfo,\n\ttype RealtimeDocumentSnapshot,\n\ttype RealtimeSessionPeer,\n} from \"./protocol\";\nimport { consumeViewportFollowSync } from \"./use-realtime-peer-follow\";\nimport {\n\tapplyLocalItemsToYDoc,\n\tapplyServerSnapshotToYDoc,\n\tcreateYjsBoardDoc,\n\tdecodeYDocState,\n\tencodeYDocState,\n\tgetLocallyPendingItemIds,\n\treadVectorItems,\n\treplaceYDocWithSnapshot,\n\ttype YjsBoardDoc,\n} from \"./yjs-document\";\n\n// Origin tags for Y.Doc transactions. Used to distinguish local edits from\n// remote applies when observing the doc so we can avoid feedback loops.\nconst ORIGIN_LOCAL = Symbol(\"canvu/realtime/local\");\nconst ORIGIN_REMOTE = Symbol(\"canvu/realtime/remote\");\nconst ORIGIN_BOOTSTRAP = Symbol(\"canvu/realtime/bootstrap\");\n\ntype RealtimeSessionPeerInput = {\n\tid: string;\n\tdisplayName?: string;\n\tcolor?: string;\n\timage?: string;\n\tclientId?: string;\n};\n\nexport type UseRealtimeSessionOptions = {\n\turl: string;\n\troomId: string;\n\tpeer: RealtimeSessionPeerInput;\n\tenabled?: boolean;\n\treconnect?: boolean;\n\theartbeatMs?: number;\n\tmaxReconnectDelayMs?: number;\n\tinitialReconnectDelayMs?: number;\n\tconnectTimeoutMs?: number;\n\tonError?: (message: string) => void;\n};\n\nexport type RealtimeViewportPresenceBindings = Pick<\n\tVectorViewportProps,\n\t| \"remotePresence\"\n\t| \"onWorldPointerMove\"\n\t| \"onWorldPointerLeave\"\n\t| \"onPlacementPreviewChange\"\n\t| \"onCameraChange\"\n>;\n\ntype BindViewportPresenceOptions = {\n\tactiveTool?: string;\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n};\n\nexport type RealtimeSyncState =\n\t| \"connected\"\n\t| \"reconnecting\"\n\t| \"offline\"\n\t| \"conflicted\";\n\nexport type RealtimeDocumentConflict = {\n\treadonly serverRevision: number;\n\treadonly serverItems: VectorSceneItem[];\n\treadonly localItems: VectorSceneItem[];\n};\n\ntype RealtimeOfflineDraft = {\n\treadonly roomId: string;\n\treadonly baseRevision: number;\n\treadonly items: VectorSceneItem[];\n\treadonly updatedAt: number;\n\t/**\n\t * Optional encoded Y.Doc state. When present, applying the draft on\n\t * reconnect uses the binary state (CRDT-preserving). Older drafts may\n\t * only have `items` (legacy format) — in that case we bootstrap a fresh\n\t * Y.Doc from the items array.\n\t */\n\treadonly yDocState?: string;\n\t/**\n\t * Optional list of ids that were not yet server-confirmed when the draft\n\t * was written. Lets us continue treating them as locally-pending after\n\t * reload.\n\t */\n\treadonly pendingIds?: string[];\n};\n\nexport type UseRealtimeSessionResult = {\n\tconnection: RealtimeConnectionInfo;\n\tsessionPeers: RealtimeSessionPeer[];\n\tremotePresence: RealtimeSessionPeer[];\n\tremoteAdapter: VectorCanvasRemoteAdapter;\n\tdocument: RealtimeDocumentSnapshot | null;\n\thasLocalOfflineDraft: boolean;\n\thasPendingDocumentSync: boolean;\n\tsyncState: RealtimeSyncState;\n\tconflict: RealtimeDocumentConflict | null;\n\tbindViewportPresence: (\n\t\toptions?: BindViewportPresenceOptions,\n\t) => RealtimeViewportPresenceBindings;\n\tsyncViewportPresence: (options?: BindViewportPresenceOptions) => boolean;\n\tresolveConflict: (action: \"keep-local\" | \"use-server\") => void;\n\tclearLocalDraft: () => void;\n\tflushDocumentSync: () => Promise<void>;\n\tdisconnect: () => void;\n\treconnectNow: () => void;\n};\n\nconst DRAFT_STORAGE_PREFIX = \"canvu-realtime-draft:\";\nconst DOCUMENT_FLUSH_DEBOUNCE_MS = 120;\nconst DRAFT_PERSIST_DEBOUNCE_MS = 420;\n\ntype IdleCallbackHandle = number;\n\nfunction requestWindowIdleCallback(\n\tcallback: () => void,\n\ttimeout: number,\n): IdleCallbackHandle {\n\tif (typeof window.requestIdleCallback === \"function\") {\n\t\treturn window.requestIdleCallback(callback, { timeout });\n\t}\n\treturn window.setTimeout(callback, timeout);\n}\n\nfunction cancelWindowIdleCallback(handle: IdleCallbackHandle | null): void {\n\tif (handle == null) return;\n\tif (typeof window.cancelIdleCallback === \"function\") {\n\t\twindow.cancelIdleCallback(handle);\n\t\treturn;\n\t}\n\twindow.clearTimeout(handle);\n}\n\nfunction createClientId(): string {\n\tif (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n\t\treturn crypto.randomUUID();\n\t}\n\treturn `client-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction normalizeSocketUrl(input: string): string {\n\tif (!input) return \"\";\n\tif (input.startsWith(\"ws://\") || input.startsWith(\"wss://\")) return input;\n\tif (input.startsWith(\"http://\")) return `ws://${input.slice(\"http://\".length)}`;\n\tif (input.startsWith(\"https://\")) return `wss://${input.slice(\"https://\".length)}`;\n\tif (input.startsWith(\"/\")) {\n\t\tconst protocol = window.location.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n\t\treturn `${protocol}//${window.location.host}${input}`;\n\t}\n\treturn input;\n}\n\nfunction isValidSocketUrl(input: string): boolean {\n\tif (!input || input.includes(\"<\") || input.includes(\">\")) return false;\n\ttry {\n\t\tconst parsed = new URL(input);\n\t\treturn parsed.protocol === \"ws:\" || parsed.protocol === \"wss:\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction sanitizeRealtimeItem(item: VectorSceneItem): VectorSceneItem {\n\tif (item.toolKind !== \"image\") return item;\n\treturn {\n\t\t...item,\n\t\timageBlobId: undefined,\n\t\timageThumbnailBlobId: undefined,\n\t\timageRasterHref: undefined,\n\t\timageThumbnailHref: undefined,\n\t\tchildrenSvg: \"\",\n\t};\n}\n\nfunction sanitizeRealtimeItems(\n\titems: readonly VectorSceneItem[],\n): VectorSceneItem[] {\n\treturn items.map(sanitizeRealtimeItem);\n}\n\nfunction sanitizeRealtimeSnapshot(\n\tsnapshot: RealtimeDocumentSnapshot,\n): RealtimeDocumentSnapshot {\n\treturn {\n\t\t...snapshot,\n\t\titems: sanitizeRealtimeItems(snapshot.items),\n\t};\n}\n\nfunction serializeItems(items: VectorSceneItem[]): string | null {\n\ttry {\n\t\treturn JSON.stringify(sanitizeRealtimeItems(items));\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction sameSerializedItems(\n\tleft: VectorSceneItem[] | null | undefined,\n\tright: VectorSceneItem[] | null | undefined,\n): boolean {\n\tif (left === right) return true;\n\tif (!left || !right) return false;\n\tconst leftJson = serializeItems(left);\n\tconst rightJson = serializeItems(right);\n\treturn leftJson != null && leftJson === rightJson;\n}\n\nfunction nowMs(): number {\n\treturn Date.now();\n}\n\nfunction draftStorageKey(roomId: string): string {\n\treturn `${DRAFT_STORAGE_PREFIX}${roomId}`;\n}\n\nfunction isRealtimeOfflineDraft(value: unknown): value is RealtimeOfflineDraft {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst record = value as Record<string, unknown>;\n\tif (\n\t\ttypeof record.roomId !== \"string\" ||\n\t\ttypeof record.baseRevision !== \"number\" ||\n\t\ttypeof record.updatedAt !== \"number\" ||\n\t\t!Array.isArray(record.items)\n\t) {\n\t\treturn false;\n\t}\n\tif (record.yDocState != null && typeof record.yDocState !== \"string\") {\n\t\treturn false;\n\t}\n\tif (record.pendingIds != null && !Array.isArray(record.pendingIds)) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nfunction readRealtimeOfflineDraft(roomId: string): RealtimeOfflineDraft | null {\n\tif (typeof window === \"undefined\" || !roomId) return null;\n\ttry {\n\t\tconst raw = window.localStorage.getItem(draftStorageKey(roomId));\n\t\tif (!raw) return null;\n\t\tconst parsed = JSON.parse(raw) as unknown;\n\t\tif (!isRealtimeOfflineDraft(parsed)) return null;\n\t\treturn {\n\t\t\t...parsed,\n\t\t\titems: sanitizeRealtimeItems(parsed.items),\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction writeRealtimeOfflineDraft(draft: RealtimeOfflineDraft | null): void {\n\tif (typeof window === \"undefined\") return;\n\tif (!draft) return;\n\ttry {\n\t\twindow.localStorage.setItem(\n\t\t\tdraftStorageKey(draft.roomId),\n\t\t\tJSON.stringify({\n\t\t\t\t...draft,\n\t\t\t\titems: sanitizeRealtimeItems(draft.items),\n\t\t\t}),\n\t\t);\n\t} catch {}\n}\n\nfunction removeRealtimeOfflineDraft(roomId: string): void {\n\tif (typeof window === \"undefined\" || !roomId) return;\n\ttry {\n\t\twindow.localStorage.removeItem(draftStorageKey(roomId));\n\t} catch {}\n}\n\nfunction getViewportCameraSnapshot(\n\tviewport: VectorViewportHandle | null | undefined,\n): RealtimeSessionPeer[\"camera\"] | null {\n\tif (!viewport) return null;\n\tconst camera = viewport.getCamera();\n\tif (!camera) return null;\n\tconst viewportSize = viewport.getViewportSize();\n\treturn {\n\t\tx: camera.x,\n\t\ty: camera.y,\n\t\tzoom: camera.zoom,\n\t\tviewportWidth: viewportSize.width,\n\t\tviewportHeight: viewportSize.height,\n\t};\n}\n\nfunction prepareRealtimeItems(\n\titems: readonly VectorSceneItem[],\n): { items: VectorSceneItem[]; serialized: string } | null {\n\ttry {\n\t\tconst sanitizedItems = sanitizeRealtimeItems(items);\n\t\treturn {\n\t\t\titems: sanitizedItems,\n\t\t\tserialized: JSON.stringify(sanitizedItems),\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport function useRealtimeSession(\n\toptions: UseRealtimeSessionOptions,\n): UseRealtimeSessionResult {\n\tconst {\n\t\turl,\n\t\troomId,\n\t\tpeer,\n\t\tenabled = true,\n\t\treconnect = true,\n\t\theartbeatMs = 10_000,\n\t\tmaxReconnectDelayMs = 12_000,\n\t\tinitialReconnectDelayMs = 800,\n\t\tconnectTimeoutMs = 10_000,\n\t\tonError,\n\t} = options;\n\n\tconst clientIdRef = useRef(peer.clientId ?? createClientId());\n\tconst wsRef = useRef<WebSocket | null>(null);\n\tconst reconnectTimerRef = useRef<number | null>(null);\n\tconst heartbeatTimerRef = useRef<number | null>(null);\n\tconst connectTimeoutRef = useRef<number | null>(null);\n\tconst documentFlushTimerRef = useRef<number | null>(null);\n\tconst documentFlushIdleRef = useRef<IdleCallbackHandle | null>(null);\n\tconst draftPersistTimerRef = useRef<number | null>(null);\n\tconst draftPersistIdleRef = useRef<IdleCallbackHandle | null>(null);\n\tconst manualDisconnectRef = useRef(false);\n\tconst retryCountRef = useRef(0);\n\tconst currentRevisionRef = useRef(0);\n\tconst outboundInFlightRef = useRef<{\n\t\tbaseRevision: number;\n\t\titems: VectorSceneItem[];\n\t\tserialized: string | null;\n\t} | null>(null);\n\tconst queuedDirtyRef = useRef(false);\n\t// Latest items snapshot the consumer wants to push, captured by\n\t// queueDocumentSend at potentially 60fps. The expensive merge into the\n\t// Y.Doc, projection, encoding and React state updates are all deferred\n\t// to flushQueuedDocument so the input thread on iPad isn't saturated\n\t// during continuous drawing.\n\tconst pendingLocalItemsRef = useRef<VectorSceneItem[] | null>(null);\n\tconst subscriberRefs = useRef(new Set<(items: VectorSceneItem[]) => void>());\n\tconst boardRef = useRef<YjsBoardDoc | null>(null);\n\tif (boardRef.current == null) {\n\t\tboardRef.current = createYjsBoardDoc();\n\t}\n\tconst lastCursorRef = useRef<{ x: number; y: number } | null>(null);\n\tconst lastMarkupStrokeRef = useRef<\n\t\tRealtimeSessionPeer[\"markupStroke\"] | null | undefined\n\t>(null);\n\tconst lastCameraRef = useRef<RealtimeSessionPeer[\"camera\"] | null | undefined>(\n\t\tnull,\n\t);\n\tconst lastActiveToolRef = useRef<string | undefined>(undefined);\n\tconst latestDocumentRef = useRef<RealtimeDocumentSnapshot | null>(null);\n\tconst connectionStateRef = useRef<RealtimeConnectionInfo[\"state\"]>(\n\t\tenabled ? \"connecting\" : \"offline\",\n\t);\n\tconst localDraftRef = useRef<RealtimeOfflineDraft | null>(null);\n\tconst conflictRef = useRef<RealtimeDocumentConflict | null>(null);\n\tconst onErrorRef = useRef(onError);\n\tonErrorRef.current = onError;\n\n\tconst [connectSequence, setConnectSequence] = useState(0);\n\tconst [connection, setConnection] = useState<RealtimeConnectionInfo>({\n\t\tstate: enabled ? \"connecting\" : \"offline\",\n\t\tconnected: false,\n\t\troomId,\n\t\tclientId: null,\n\t\tretryCount: 0,\n\t\tlastConnectedAt: null,\n\t\tlastMessageAt: null,\n\t\tlastPongAt: null,\n\t\tlastError: null,\n\t});\n\tconst [sessionPeers, setSessionPeers] = useState<RealtimeSessionPeer[]>([]);\n\tconst [document, setDocument] = useState<RealtimeDocumentSnapshot | null>(null);\n\tconst [hasLocalOfflineDraft, setHasLocalOfflineDraft] = useState(false);\n\tconst [hasPendingDocumentSync, setHasPendingDocumentSync] = useState(false);\n\tconst [conflict, setConflict] = useState<RealtimeDocumentConflict | null>(null);\n\tconnectionStateRef.current = connection.state;\n\n\tconst syncState = useMemo<RealtimeSyncState>(() => {\n\t\tif (conflict != null) return \"conflicted\";\n\t\tif (connection.connected) return \"connected\";\n\t\tif (connection.state === \"reconnecting\" || connection.state === \"connecting\") {\n\t\t\treturn \"reconnecting\";\n\t\t}\n\t\treturn \"offline\";\n\t}, [conflict, connection.connected, connection.state]);\n\n\tconst clearReconnectTimer = useCallback(() => {\n\t\tif (reconnectTimerRef.current != null) {\n\t\t\twindow.clearTimeout(reconnectTimerRef.current);\n\t\t\treconnectTimerRef.current = null;\n\t\t}\n\t}, []);\n\n\tconst clearHeartbeatTimer = useCallback(() => {\n\t\tif (heartbeatTimerRef.current != null) {\n\t\t\twindow.clearInterval(heartbeatTimerRef.current);\n\t\t\theartbeatTimerRef.current = null;\n\t\t}\n\t}, []);\n\n\tconst clearConnectTimeout = useCallback(() => {\n\t\tif (connectTimeoutRef.current != null) {\n\t\t\twindow.clearTimeout(connectTimeoutRef.current);\n\t\t\tconnectTimeoutRef.current = null;\n\t\t}\n\t}, []);\n\n\tconst clearDocumentFlushSchedule = useCallback(() => {\n\t\tif (documentFlushTimerRef.current != null) {\n\t\t\twindow.clearTimeout(documentFlushTimerRef.current);\n\t\t\tdocumentFlushTimerRef.current = null;\n\t\t}\n\t\tcancelWindowIdleCallback(documentFlushIdleRef.current);\n\t\tdocumentFlushIdleRef.current = null;\n\t}, []);\n\n\tconst clearDraftPersistSchedule = useCallback(() => {\n\t\tif (draftPersistTimerRef.current != null) {\n\t\t\twindow.clearTimeout(draftPersistTimerRef.current);\n\t\t\tdraftPersistTimerRef.current = null;\n\t\t}\n\t\tcancelWindowIdleCallback(draftPersistIdleRef.current);\n\t\tdraftPersistIdleRef.current = null;\n\t}, []);\n\n\tconst updateConnection = useCallback(\n\t\t(\n\t\t\tpatch:\n\t\t\t\t| Partial<RealtimeConnectionInfo>\n\t\t\t\t| ((prev: RealtimeConnectionInfo) => RealtimeConnectionInfo),\n\t\t) => {\n\t\t\tsetConnection((prev) => {\n\t\t\t\tif (typeof patch === \"function\") return patch(prev);\n\t\t\t\treturn { ...prev, ...patch };\n\t\t\t});\n\t\t},\n\t\t[],\n\t);\n\n\tconst notifySubscribers = useCallback((items: VectorSceneItem[]) => {\n\t\tfor (const subscriber of subscriberRefs.current) {\n\t\t\tsubscriber(items);\n\t\t}\n\t}, []);\n\n\t// applyDocument merges a snapshot into the local Y.Doc. When `replace` is\n\t// true (used for the very first bootstrap when we have no local items), the\n\t// Y.Doc is reset to exactly the snapshot. Otherwise applyServerSnapshotToYDoc\n\t// runs the smart merge that preserves locally-pending items and respects\n\t// server-side deletes.\n\tconst applyDocument = useCallback(\n\t\t(\n\t\t\tsnapshot: RealtimeDocumentSnapshot,\n\t\t\toptions?: { suppressSubscriberNotify?: boolean; replace?: boolean },\n\t\t) => {\n\t\t\tconst currentSnapshot = latestDocumentRef.current;\n\t\t\tif (\n\t\t\t\tcurrentSnapshot &&\n\t\t\t\tcurrentSnapshot.revision === snapshot.revision &&\n\t\t\t\tcurrentSnapshot.updatedByClientId === snapshot.updatedByClientId &&\n\t\t\t\tsameSerializedItems(currentSnapshot.items, snapshot.items)\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst board = boardRef.current;\n\t\t\tif (board) {\n\t\t\t\t// Drain any pending local items into the Y.Doc *before* applying\n\t\t\t\t// the server snapshot. queueDocumentSend only stashes the latest\n\t\t\t\t// items in pendingLocalItemsRef so the canvas hot path stays\n\t\t\t\t// cheap, but that means items the user just drew may not be in\n\t\t\t\t// the Y.Doc yet. If we merge the server snapshot first, the\n\t\t\t\t// projected items would be missing those local strokes and\n\t\t\t\t// trazo would receive a snapshot that wipes them from view\n\t\t\t\t// until the next flush round-trip echoes them back.\n\t\t\t\tif (!options?.replace) {\n\t\t\t\t\tconst pendingLocal = pendingLocalItemsRef.current;\n\t\t\t\t\tif (pendingLocal) {\n\t\t\t\t\t\tpendingLocalItemsRef.current = null;\n\t\t\t\t\t\tapplyLocalItemsToYDoc(board, {\n\t\t\t\t\t\t\titems: pendingLocal,\n\t\t\t\t\t\t\torigin: ORIGIN_LOCAL,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tqueuedDirtyRef.current = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (options?.replace) {\n\t\t\t\t\treplaceYDocWithSnapshot(board, {\n\t\t\t\t\t\titems: snapshot.items,\n\t\t\t\t\t\torigin: ORIGIN_REMOTE,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tapplyServerSnapshotToYDoc(board, {\n\t\t\t\t\t\titems: snapshot.items,\n\t\t\t\t\t\torigin: ORIGIN_REMOTE,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst mergedItems = board ? readVectorItems(board.yItems) : snapshot.items;\n\t\t\tconst mergedSnapshot: RealtimeDocumentSnapshot = {\n\t\t\t\t...snapshot,\n\t\t\t\titems: mergedItems,\n\t\t\t};\n\t\t\tcurrentRevisionRef.current = snapshot.revision;\n\t\t\tlatestDocumentRef.current = mergedSnapshot;\n\t\t\tsetDocument(mergedSnapshot);\n\t\t\tif (!options?.suppressSubscriberNotify) {\n\t\t\t\tnotifySubscribers(mergedItems);\n\t\t\t}\n\t\t},\n\t\t[notifySubscribers],\n\t);\n\n\tconst setConflictState = useCallback(\n\t\t(nextConflict: RealtimeDocumentConflict | null) => {\n\t\t\tconflictRef.current = nextConflict;\n\t\t\tsetConflict(nextConflict);\n\t\t},\n\t\t[],\n\t);\n\n\tconst setLocalDraft = useCallback(\n\t\t(nextDraft: RealtimeOfflineDraft | null) => {\n\t\t\tlocalDraftRef.current = nextDraft;\n\t\t\tsetHasLocalOfflineDraft(nextDraft != null);\n\t\t\tif (nextDraft) return;\n\t\t\tremoveRealtimeOfflineDraft(roomId);\n\t\t},\n\t\t[roomId],\n\t);\n\n\tconst persistLocalDraft = useCallback(() => {\n\t\tclearDraftPersistSchedule();\n\t\tif (!localDraftRef.current) {\n\t\t\tremoveRealtimeOfflineDraft(roomId);\n\t\t\treturn;\n\t\t}\n\t\t// Encode the Y.Doc state lazily, right before writing to localStorage,\n\t\t// so the expensive Y.encodeStateAsUpdate + base64 work stays out of\n\t\t// the per-flush hot path. flushQueuedDocument only updates the\n\t\t// in-memory draft (items + meta + pendingIds); the binary CRDT state\n\t\t// is materialised here on the debounced persistence schedule.\n\t\tconst board = boardRef.current;\n\t\tconst draft = localDraftRef.current;\n\t\tconst draftToWrite =\n\t\t\tboard && draft.yDocState == null\n\t\t\t\t? { ...draft, yDocState: encodeYDocState(board) }\n\t\t\t\t: draft;\n\t\twriteRealtimeOfflineDraft(draftToWrite);\n\t}, [clearDraftPersistSchedule, roomId]);\n\n\tconst scheduleDraftPersistence = useCallback(() => {\n\t\tclearDraftPersistSchedule();\n\t\tdraftPersistTimerRef.current = window.setTimeout(() => {\n\t\t\tdraftPersistTimerRef.current = null;\n\t\t\tdraftPersistIdleRef.current = requestWindowIdleCallback(() => {\n\t\t\t\tdraftPersistIdleRef.current = null;\n\t\t\t\tpersistLocalDraft();\n\t\t\t}, DRAFT_PERSIST_DEBOUNCE_MS);\n\t\t}, DRAFT_PERSIST_DEBOUNCE_MS);\n\t}, [clearDraftPersistSchedule, persistLocalDraft]);\n\n\tconst clearLocalDraft = useCallback(() => {\n\t\tsetLocalDraft(null);\n\t\tclearDraftPersistSchedule();\n\t}, [clearDraftPersistSchedule, setLocalDraft]);\n\n\tconst createSelfPeer = useCallback(\n\t\t(state: RealtimeConnectionInfo[\"state\"]): RealtimeSessionPeer => ({\n\t\t\tid: peer.id,\n\t\t\tclientId: clientIdRef.current,\n\t\t\tpeerId: peer.id,\n\t\t\troomId,\n\t\t\tjoinedAt: connection.lastConnectedAt ?? nowMs(),\n\t\t\tlastSeenAt: nowMs(),\n\t\t\tcursor: lastCursorRef.current,\n\t\t\tisSelf: true,\n\t\t\tconnectionState: state,\n\t\t\t...(peer.displayName ? { displayName: peer.displayName } : {}),\n\t\t\t...(peer.color ? { color: peer.color } : {}),\n\t\t\t...(peer.image ? { image: peer.image } : {}),\n\t\t\t...(lastMarkupStrokeRef.current !== undefined\n\t\t\t\t? { markupStroke: lastMarkupStrokeRef.current ?? null }\n\t\t\t\t: {}),\n\t\t\t...(lastCameraRef.current !== undefined\n\t\t\t\t? { camera: lastCameraRef.current ?? null }\n\t\t\t\t: {}),\n\t\t\t...(lastActiveToolRef.current\n\t\t\t\t? { activeTool: lastActiveToolRef.current }\n\t\t\t\t: {}),\n\t\t}),\n\t\t[\n\t\t\tconnection.lastConnectedAt,\n\t\t\tpeer.color,\n\t\t\tpeer.displayName,\n\t\t\tpeer.id,\n\t\t\tpeer.image,\n\t\t\troomId,\n\t\t],\n\t);\n\n\tconst collapsePeersToSelf = useCallback(\n\t\t(state: RealtimeConnectionInfo[\"state\"]) => {\n\t\t\tsetSessionPeers((prev) => {\n\t\t\t\tconst selfPeer = prev.find(\n\t\t\t\t\t(peerState) => peerState.clientId === clientIdRef.current,\n\t\t\t\t);\n\t\t\t\treturn [\n\t\t\t\t\tselfPeer\n\t\t\t\t\t\t? { ...selfPeer, isSelf: true, connectionState: state }\n\t\t\t\t\t\t: createSelfPeer(state),\n\t\t\t\t];\n\t\t\t});\n\t\t},\n\t\t[createSelfPeer],\n\t);\n\n\tconst applyPeers = useCallback((peers: RealtimeSessionPeer[]) => {\n\t\tconst selfClientId = clientIdRef.current;\n\t\tsetSessionPeers(\n\t\t\tpeers.map((peerState) =>\n\t\t\t\tpeerState.clientId === selfClientId\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...peerState,\n\t\t\t\t\t\t\tisSelf: true,\n\t\t\t\t\t\t\tconnectionState: connectionStateRef.current,\n\t\t\t\t\t\t}\n\t\t\t\t\t: peerState,\n\t\t\t),\n\t\t);\n\t}, []);\n\n\tconst buildClientMessage = useCallback(\n\t\t(message: RealtimeClientMessage): string => JSON.stringify(message),\n\t\t[],\n\t);\n\n\tconst sendRaw = useCallback(\n\t\t(message: RealtimeClientMessage): boolean => {\n\t\t\tconst ws = wsRef.current;\n\t\t\tif (!ws || ws.readyState !== WebSocket.OPEN) return false;\n\t\t\tws.send(buildClientMessage(message));\n\t\t\treturn true;\n\t\t},\n\t\t[buildClientMessage],\n\t);\n\n\tconst flushQueuedDocument = useCallback(() => {\n\t\tclearDocumentFlushSchedule();\n\t\tconst board = boardRef.current;\n\t\tif (!board) return;\n\t\tif (!queuedDirtyRef.current && pendingLocalItemsRef.current == null) return;\n\t\tif (outboundInFlightRef.current) return;\n\t\t// Heavy work deferred from queueDocumentSend: apply the latest local\n\t\t// items snapshot the consumer pushed (possibly accumulated over many\n\t\t// 60fps onItemsChange firings) into the Y.Doc once.\n\t\tconst pendingLocal = pendingLocalItemsRef.current;\n\t\tif (pendingLocal) {\n\t\t\tpendingLocalItemsRef.current = null;\n\t\t\tapplyLocalItemsToYDoc(board, {\n\t\t\t\titems: pendingLocal,\n\t\t\t\torigin: ORIGIN_LOCAL,\n\t\t\t});\n\t\t}\n\t\tconst baseRevision = currentRevisionRef.current;\n\t\tconst mergedItems = readVectorItems(board.yItems);\n\t\tconst preparedItems = prepareRealtimeItems(mergedItems);\n\t\tif (!preparedItems) return;\n\t\tqueuedDirtyRef.current = false;\n\t\toutboundInFlightRef.current = {\n\t\t\tbaseRevision,\n\t\t\titems: preparedItems.items,\n\t\t\tserialized: preparedItems.serialized,\n\t\t};\n\t\tconst didSend = sendRawRef.current({\n\t\t\ttype: \"document:update\",\n\t\t\troomId,\n\t\t\tclientId: clientIdRef.current,\n\t\t\tbaseRevision,\n\t\t\titems: preparedItems.items,\n\t\t});\n\t\t// Refresh the offline draft with the post-merge state. Doing this\n\t\t// here (~8x/sec at flush rate) instead of on every queueDocumentSend\n\t\t// avoids encoding the full Y.Doc and triggering React state churn at\n\t\t// 60fps during drawing.\n\t\tconst pendingIds = getLocallyPendingItemIds(board);\n\t\tif (pendingIds.size > 0) {\n\t\t\t// Don't encode the Y.Doc here — persistLocalDraft materialises it\n\t\t\t// lazily so this hot path stays cheap during 60fps drawing.\n\t\t\tsetLocalDraftRef.current({\n\t\t\t\troomId,\n\t\t\t\tbaseRevision,\n\t\t\t\titems: mergedItems,\n\t\t\t\tupdatedAt: nowMs(),\n\t\t\t\tpendingIds: Array.from(pendingIds),\n\t\t\t});\n\t\t\tscheduleDraftPersistenceRef.current?.();\n\t\t}\n\t\tif (!didSend) {\n\t\t\tqueuedDirtyRef.current = true;\n\t\t\toutboundInFlightRef.current = null;\n\t\t\tsetHasPendingDocumentSync(true);\n\t\t}\n\t}, [clearDocumentFlushSchedule, roomId]);\n\n\tconst scheduleDocumentFlush = useCallback(() => {\n\t\tclearDocumentFlushSchedule();\n\t\tdocumentFlushTimerRef.current = window.setTimeout(() => {\n\t\t\tdocumentFlushTimerRef.current = null;\n\t\t\tdocumentFlushIdleRef.current = requestWindowIdleCallback(() => {\n\t\t\t\tdocumentFlushIdleRef.current = null;\n\t\t\t\tflushQueuedDocument();\n\t\t\t}, DOCUMENT_FLUSH_DEBOUNCE_MS);\n\t\t}, DOCUMENT_FLUSH_DEBOUNCE_MS);\n\t}, [clearDocumentFlushSchedule, flushQueuedDocument]);\n\n\t// queueDocumentSend is on the canvas hot path — invoked at up to 60fps\n\t// during continuous drawing. Keep it O(1): just stash the latest items\n\t// snapshot and schedule a flush. All Y.Doc mutations, projection,\n\t// encoding and React state updates are amortised across the flush\n\t// window (DOCUMENT_FLUSH_DEBOUNCE_MS) inside flushQueuedDocument.\n\tconst queueDocumentSend = useCallback((items: VectorSceneItem[]) => {\n\t\tpendingLocalItemsRef.current = items;\n\t\tqueuedDirtyRef.current = true;\n\t\tsetHasPendingDocumentSync(true);\n\t\tsetHasLocalOfflineDraft(true);\n\t\tscheduleDocumentFlushRef.current();\n\t}, []);\n\n\t// Bootstrap the Y.Doc from a persisted draft. When the draft has a binary\n\t// yDocState (new format), we decode it directly to preserve CRDT history\n\t// and pending-id tracking. For legacy drafts (items only), we replace the\n\t// Y.Doc with the items array and conservatively mark every item as still\n\t// \"pending server confirmation\" — the next server snapshot will reconcile.\n\tconst applyDraftSnapshot = useCallback(\n\t\t(\n\t\t\tdraft: RealtimeOfflineDraft,\n\t\t\toptions?: { suppressSubscriberNotify?: boolean },\n\t\t) => {\n\t\t\tconst board = boardRef.current;\n\t\t\tif (board) {\n\t\t\t\tlet restoredFromBinary = false;\n\t\t\t\tif (draft.yDocState) {\n\t\t\t\t\tif (board.yItems.length > 0) {\n\t\t\t\t\t\tboard.doc.transact(() => {\n\t\t\t\t\t\t\tboard.yItems.delete(0, board.yItems.length);\n\t\t\t\t\t\t}, ORIGIN_BOOTSTRAP);\n\t\t\t\t\t}\n\t\t\t\t\trestoredFromBinary = decodeYDocState(board, draft.yDocState);\n\t\t\t\t\tif (restoredFromBinary) {\n\t\t\t\t\t\tconst allIds = new Set<string>();\n\t\t\t\t\t\tconst allItems = readVectorItems(board.yItems);\n\t\t\t\t\t\tfor (let i = 0; i < board.yItems.length; i++) {\n\t\t\t\t\t\t\tconst yMap = board.yItems.get(i);\n\t\t\t\t\t\t\tif (!yMap) continue;\n\t\t\t\t\t\t\tconst id = yMap.get(\"id\");\n\t\t\t\t\t\t\tif (typeof id === \"string\") allIds.add(id);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst pendingIds = new Set(draft.pendingIds ?? []);\n\t\t\t\t\t\tboard.lastServerConfirmedIds = new Set();\n\t\t\t\t\t\tboard.lastServerConfirmedItemSerializations = new Map();\n\t\t\t\t\t\tfor (const id of allIds) {\n\t\t\t\t\t\t\tif (!pendingIds.has(id)) {\n\t\t\t\t\t\t\t\tboard.lastServerConfirmedIds.add(id);\n\t\t\t\t\t\t\t\tconst item = allItems.find((candidate) => candidate.id === id);\n\t\t\t\t\t\t\t\tif (item) {\n\t\t\t\t\t\t\t\t\tboard.lastServerConfirmedItemSerializations.set(\n\t\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\t\tJSON.stringify(item),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!restoredFromBinary) {\n\t\t\t\t\treplaceYDocWithSnapshot(board, {\n\t\t\t\t\t\titems: draft.items,\n\t\t\t\t\t\torigin: ORIGIN_BOOTSTRAP,\n\t\t\t\t\t});\n\t\t\t\t\t// Legacy draft: no record of which ids were already confirmed by the\n\t\t\t\t\t// server. Mark all as pending so the next server snapshot can\n\t\t\t\t\t// reconcile correctly (additive merge will preserve them, and any\n\t\t\t\t\t// server-deleted ids will simply not be in lastServerConfirmedIds\n\t\t\t\t\t// to be re-added).\n\t\t\t\t\tboard.lastServerConfirmedIds = new Set();\n\t\t\t\t\tboard.lastServerConfirmedItemSerializations = new Map();\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst items = board ? readVectorItems(board.yItems) : draft.items;\n\t\t\tconst snapshot: RealtimeDocumentSnapshot = {\n\t\t\t\trevision: draft.baseRevision,\n\t\t\t\titems,\n\t\t\t\tupdatedAt: draft.updatedAt,\n\t\t\t\tupdatedByClientId: clientIdRef.current,\n\t\t\t};\n\t\t\tcurrentRevisionRef.current = snapshot.revision;\n\t\t\tlatestDocumentRef.current = snapshot;\n\t\t\tsetDocument(snapshot);\n\t\t\tif (!options?.suppressSubscriberNotify) {\n\t\t\t\tnotifySubscribers(items);\n\t\t\t}\n\t\t},\n\t\t[notifySubscribers],\n\t);\n\n\t// With Yjs as the source of truth, conflicts no longer exist as a concept.\n\t// Every server snapshot is merged into the Y.Doc; locally-added items that\n\t// the server has not yet seen are preserved, and items the server deleted\n\t// (i.e. id was in the previous server snapshot but is absent now) are\n\t// removed. The legacy \"keep-local vs use-server\" choice is gone.\n\t//\n\t// Returns true when the local Y.Doc still has pending items the server\n\t// hasn't seen after the merge (so the caller knows to re-schedule a flush).\n\tconst resolveAuthoritativeDocument = useCallback(\n\t\t(\n\t\t\tserverDocument: RealtimeDocumentSnapshot,\n\t\t\toptions?: { suppressSubscriberNotify?: boolean },\n\t\t): boolean => {\n\t\t\tconst board = boardRef.current;\n\t\t\tconst hadLocalContent =\n\t\t\t\tlocalDraftRef.current != null || (board != null && board.yItems.length > 0);\n\n\t\t\tapplyDocument(serverDocument, {\n\t\t\t\t...options,\n\t\t\t\treplace: !hadLocalContent,\n\t\t\t});\n\n\t\t\tif (!board) {\n\t\t\t\tsetHasPendingDocumentSync(false);\n\t\t\t\tclearLocalDraftRef.current();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst pendingIds = getLocallyPendingItemIds(board);\n\t\t\tif (pendingIds.size === 0) {\n\t\t\t\tclearLocalDraftRef.current();\n\t\t\t\tsetHasPendingDocumentSync(false);\n\t\t\t\toutboundInFlightRef.current = null;\n\t\t\t\tqueuedDirtyRef.current = false;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst mergedItems = readVectorItems(board.yItems);\n\t\t\tsetLocalDraft({\n\t\t\t\troomId,\n\t\t\t\tbaseRevision: serverDocument.revision,\n\t\t\t\titems: mergedItems,\n\t\t\t\tupdatedAt: nowMs(),\n\t\t\t\tpendingIds: Array.from(pendingIds),\n\t\t\t});\n\t\t\toutboundInFlightRef.current = null;\n\t\t\tqueuedDirtyRef.current = true;\n\t\t\tsetHasPendingDocumentSync(true);\n\t\t\tscheduleDocumentFlush();\n\t\t\treturn true;\n\t\t},\n\t\t[applyDocument, roomId, scheduleDocumentFlush, setLocalDraft],\n\t);\n\n\tconst sendPresenceUpdate = useCallback(() => {\n\t\tsendRaw({\n\t\t\ttype: \"presence:update\",\n\t\t\troomId,\n\t\t\tclientId: clientIdRef.current,\n\t\t\tpresence: {\n\t\t\t\tcursor: lastCursorRef.current,\n\t\t\t\tmarkupStroke: lastMarkupStrokeRef.current ?? null,\n\t\t\t\tcamera: lastCameraRef.current ?? null,\n\t\t\t\t...(lastActiveToolRef.current\n\t\t\t\t\t? { activeTool: lastActiveToolRef.current }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t});\n\t}, [roomId, sendRaw]);\n\n\tconst scheduleReconnect = useCallback(() => {\n\t\tif (!reconnect || manualDisconnectRef.current) return;\n\t\tclearReconnectTimer();\n\t\tretryCountRef.current += 1;\n\t\tconst delay = Math.min(\n\t\t\tmaxReconnectDelayMs,\n\t\t\tinitialReconnectDelayMs * 2 ** Math.max(0, retryCountRef.current - 1),\n\t\t);\n\t\tupdateConnection((prev) => ({\n\t\t\t...prev,\n\t\t\tstate: \"reconnecting\",\n\t\t\tconnected: false,\n\t\t\tretryCount: retryCountRef.current,\n\t\t}));\n\t\treconnectTimerRef.current = window.setTimeout(() => {\n\t\t\tsetConnectSequence((value) => value + 1);\n\t\t}, delay);\n\t}, [\n\t\tclearReconnectTimer,\n\t\tinitialReconnectDelayMs,\n\t\tmaxReconnectDelayMs,\n\t\treconnect,\n\t\tupdateConnection,\n\t]);\n\n\t// Kept for API back-compat with consumers that still call resolveConflict.\n\t// Yjs handles merge automatically inside resolveAuthoritativeDocument, so\n\t// `conflict` is always null and this becomes a no-op. We accept the action\n\t// argument silently so callers don't break.\n\tconst resolveConflict = useCallback((_action: \"keep-local\" | \"use-server\") => {\n\t\tvoid _action;\n\t}, []);\n\n\tconst setConflictStateRef = useRef(setConflictState);\n\tsetConflictStateRef.current = setConflictState;\n\tconst updateConnectionRef = useRef(updateConnection);\n\tupdateConnectionRef.current = updateConnection;\n\tconst applyDocumentRef = useRef(applyDocument);\n\tapplyDocumentRef.current = applyDocument;\n\tconst clearLocalDraftRef = useRef(clearLocalDraft);\n\tclearLocalDraftRef.current = clearLocalDraft;\n\tconst collapsePeersToSelfRef = useRef(collapsePeersToSelf);\n\tcollapsePeersToSelfRef.current = collapsePeersToSelf;\n\tconst applyPeersRef = useRef(applyPeers);\n\tapplyPeersRef.current = applyPeers;\n\tconst resolveAuthoritativeDocumentRef = useRef(resolveAuthoritativeDocument);\n\tresolveAuthoritativeDocumentRef.current = resolveAuthoritativeDocument;\n\tconst scheduleDocumentFlushRef = useRef(scheduleDocumentFlush);\n\tscheduleDocumentFlushRef.current = scheduleDocumentFlush;\n\tconst scheduleReconnectRef = useRef(scheduleReconnect);\n\tscheduleReconnectRef.current = scheduleReconnect;\n\tconst sendRawRef = useRef(sendRaw);\n\tsendRawRef.current = sendRaw;\n\tconst setLocalDraftRef = useRef(setLocalDraft);\n\tsetLocalDraftRef.current = setLocalDraft;\n\tconst scheduleDraftPersistenceRef = useRef(scheduleDraftPersistence);\n\tscheduleDraftPersistenceRef.current = scheduleDraftPersistence;\n\n\tuseEffect(() => {\n\t\t// Fresh Y.Doc per roomId — destroy the previous one to release CRDT\n\t\t// state and observers, then start clean. This keeps memory bounded\n\t\t// when navigating between boards.\n\t\tif (boardRef.current) {\n\t\t\tboardRef.current.doc.destroy();\n\t\t}\n\t\tboardRef.current = createYjsBoardDoc();\n\t\tif (!roomId) {\n\t\t\tclearDocumentFlushSchedule();\n\t\t\tclearDraftPersistSchedule();\n\t\t\tlocalDraftRef.current = null;\n\t\t\tsetHasLocalOfflineDraft(false);\n\t\t\tsetHasPendingDocumentSync(false);\n\t\t\tsetConflictState(null);\n\t\t\tqueuedDirtyRef.current = false;\n\t\t\tpendingLocalItemsRef.current = null;\n\t\t\toutboundInFlightRef.current = null;\n\t\t\tlatestDocumentRef.current = null;\n\t\t\tsetDocument(null);\n\t\t\tcurrentRevisionRef.current = 0;\n\t\t\treturn;\n\t\t}\n\t\tconst localDraft = readRealtimeOfflineDraft(roomId);\n\t\tsetLocalDraft(localDraft);\n\t\tsetHasPendingDocumentSync(localDraft != null);\n\t\tsetConflictState(null);\n\t\tqueuedDirtyRef.current = localDraft != null;\n\t\tpendingLocalItemsRef.current = null;\n\t\toutboundInFlightRef.current = null;\n\t\tif (localDraft) {\n\t\t\tapplyDraftSnapshot(localDraft, {\n\t\t\t\tsuppressSubscriberNotify: sameSerializedItems(\n\t\t\t\t\tlatestDocumentRef.current?.items,\n\t\t\t\t\tlocalDraft.items,\n\t\t\t\t),\n\t\t\t});\n\t\t} else {\n\t\t\tlatestDocumentRef.current = null;\n\t\t\tsetDocument(null);\n\t\t\tcurrentRevisionRef.current = 0;\n\t\t}\n\t}, [\n\t\tapplyDraftSnapshot,\n\t\tclearDocumentFlushSchedule,\n\t\tclearDraftPersistSchedule,\n\t\troomId,\n\t\tsetConflictState,\n\t\tsetLocalDraft,\n\t]);\n\n\tuseEffect(() => {\n\t\tvoid connectSequence;\n\t\tif (!enabled) {\n\t\t\tmanualDisconnectRef.current = true;\n\t\t\tclearReconnectTimer();\n\t\t\tclearHeartbeatTimer();\n\t\t\tclearConnectTimeout();\n\t\t\tclearDocumentFlushSchedule();\n\t\t\twsRef.current?.close();\n\t\t\twsRef.current = null;\n\t\t\tqueuedDirtyRef.current = localDraftRef.current != null;\n\t\t\toutboundInFlightRef.current = null;\n\t\t\tsetHasPendingDocumentSync(localDraftRef.current != null);\n\t\t\tcollapsePeersToSelfRef.current(\"offline\");\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tstate: \"offline\",\n\t\t\t\tconnected: false,\n\t\t\t\troomId,\n\t\t\t\tclientId: null,\n\t\t\t}));\n\t\t\treturn;\n\t\t}\n\n\t\tmanualDisconnectRef.current = false;\n\t\tconst socketUrl = normalizeSocketUrl(url);\n\t\tif (!socketUrl) {\n\t\t\tcollapsePeersToSelfRef.current(\"offline\");\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tstate: \"offline\",\n\t\t\t\tconnected: false,\n\t\t\t\troomId,\n\t\t\t\tlastError: null,\n\t\t\t}));\n\t\t\treturn;\n\t\t}\n\t\tif (!isValidSocketUrl(socketUrl)) {\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tstate: \"error\",\n\t\t\t\tconnected: false,\n\t\t\t\troomId,\n\t\t\t\tlastError: \"URL de websocket invalida.\",\n\t\t\t}));\n\t\t\tonErrorRef.current?.(\"URL de websocket invalida.\");\n\t\t\treturn;\n\t\t}\n\t\tlet disposed = false;\n\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t...prev,\n\t\t\tstate: retryCountRef.current > 0 ? \"reconnecting\" : \"connecting\",\n\t\t\tconnected: false,\n\t\t\troomId,\n\t\t\tlastError: null,\n\t\t}));\n\n\t\tconst socket = new WebSocket(socketUrl);\n\t\twsRef.current = socket;\n\t\tclearConnectTimeout();\n\t\tconnectTimeoutRef.current = window.setTimeout(() => {\n\t\t\tif (socket.readyState === WebSocket.CONNECTING) {\n\t\t\t\tsocket.close();\n\t\t\t}\n\t\t}, connectTimeoutMs);\n\n\t\tsocket.addEventListener(\"open\", () => {\n\t\t\tif (disposed) return;\n\t\t\tclearConnectTimeout();\n\t\t\tsendRawRef.current({\n\t\t\t\ttype: \"session:join\",\n\t\t\t\troomId,\n\t\t\t\tpeer: {\n\t\t\t\t\tclientId: clientIdRef.current,\n\t\t\t\t\tpeerId: peer.id,\n\t\t\t\t\t...(peer.displayName ? { displayName: peer.displayName } : {}),\n\t\t\t\t\t...(peer.color ? { color: peer.color } : {}),\n\t\t\t\t\t...(peer.image ? { image: peer.image } : {}),\n\t\t\t\t},\n\t\t\t});\n\t\t\tclearHeartbeatTimer();\n\t\t\theartbeatTimerRef.current = window.setInterval(() => {\n\t\t\t\tsendRawRef.current({\n\t\t\t\t\ttype: \"session:ping\",\n\t\t\t\t\troomId,\n\t\t\t\t\tclientId: clientIdRef.current,\n\t\t\t\t\tsentAt: nowMs(),\n\t\t\t\t});\n\t\t\t}, heartbeatMs);\n\t\t});\n\n\t\tsocket.addEventListener(\"message\", (event) => {\n\t\t\tif (disposed) return;\n\t\t\tlet payload: unknown = event.data;\n\t\t\tif (typeof event.data === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tpayload = JSON.parse(event.data);\n\t\t\t\t} catch {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst parsed = parseRealtimeServerMessage(payload);\n\t\t\tif (!parsed) return;\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tlastMessageAt: nowMs(),\n\t\t\t}));\n\n\t\t\tif (parsed.type === \"session:welcome\") {\n\t\t\t\tretryCountRef.current = 0;\n\t\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tstate: \"connected\",\n\t\t\t\t\tconnected: true,\n\t\t\t\t\tclientId: parsed.clientId,\n\t\t\t\t\tretryCount: 0,\n\t\t\t\t\tlastConnectedAt: nowMs(),\n\t\t\t\t\tlastError: null,\n\t\t\t\t}));\n\t\t\t\tapplyPeersRef.current(parsed.peers);\n\t\t\t\tconst handledByDraft = resolveAuthoritativeDocumentRef.current(\n\t\t\t\t\tsanitizeRealtimeSnapshot(parsed.document),\n\t\t\t\t\t{\n\t\t\t\t\t\tsuppressSubscriberNotify:\n\t\t\t\t\t\t\tlocalDraftRef.current != null &&\n\t\t\t\t\t\t\tsameSerializedItems(\n\t\t\t\t\t\t\t\tlatestDocumentRef.current?.items,\n\t\t\t\t\t\t\t\tlocalDraftRef.current.items,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tif (!handledByDraft) {\n\t\t\t\t\tqueuedDirtyRef.current = false;\n\t\t\t\t\toutboundInFlightRef.current = null;\n\t\t\t\t\tsetHasPendingDocumentSync(false);\n\t\t\t\t}\n\t\t\t\tscheduleDocumentFlushRef.current();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"presence:sync\") {\n\t\t\t\tapplyPeersRef.current(parsed.peers);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"session:peer-joined\") {\n\t\t\t\tsetSessionPeers((prev) => {\n\t\t\t\t\tconst next = prev.filter(\n\t\t\t\t\t\t(peerState) => peerState.clientId !== parsed.peer.clientId,\n\t\t\t\t\t);\n\t\t\t\t\tnext.push(\n\t\t\t\t\t\tparsed.peer.clientId === clientIdRef.current\n\t\t\t\t\t\t\t? { ...parsed.peer, isSelf: true }\n\t\t\t\t\t\t\t: parsed.peer,\n\t\t\t\t\t);\n\t\t\t\t\treturn next;\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"session:peer-left\") {\n\t\t\t\tsetSessionPeers((prev) =>\n\t\t\t\t\tprev.filter((peerState) => peerState.clientId !== parsed.clientId),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"session:pong\") {\n\t\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tlastPongAt: parsed.serverTime,\n\t\t\t\t}));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"session:error\") {\n\t\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tstate: prev.connected ? prev.state : \"error\",\n\t\t\t\t\tlastError: parsed.message,\n\t\t\t\t}));\n\t\t\t\tonErrorRef.current?.(parsed.message);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"document:sync\") {\n\t\t\t\tconst selfClientId = clientIdRef.current;\n\t\t\t\tconst inFlight = outboundInFlightRef.current;\n\t\t\t\tconst isSelfAck = parsed.document.updatedByClientId === selfClientId;\n\t\t\t\tif (!isSelfAck) {\n\t\t\t\t\t// Update from another peer. Clear in-flight (server moved on, our\n\t\t\t\t\t// pending send will be re-flushed against the new revision) and\n\t\t\t\t\t// run the smart merge.\n\t\t\t\t\toutboundInFlightRef.current = null;\n\t\t\t\t\tresolveAuthoritativeDocumentRef.current(\n\t\t\t\t\t\tsanitizeRealtimeSnapshot(parsed.document),\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Our own update was acked. Apply the canonical server view (with\n\t\t\t\t// any normalisation the server might have done) into the Y.Doc as\n\t\t\t\t// a smart merge — if we already drew more strokes during the round\n\t\t\t\t// trip, they survive as locally-pending.\n\t\t\t\tconst shouldSuppress =\n\t\t\t\t\tinFlight != null &&\n\t\t\t\t\tsameSerializedItems(inFlight.items, parsed.document.items);\n\t\t\t\toutboundInFlightRef.current = null;\n\t\t\t\tapplyDocumentRef.current(sanitizeRealtimeSnapshot(parsed.document), {\n\t\t\t\t\tsuppressSubscriberNotify: shouldSuppress,\n\t\t\t\t});\n\t\t\t\tconst board = boardRef.current;\n\t\t\t\tconst stillPending = board\n\t\t\t\t\t? getLocallyPendingItemIds(board).size > 0\n\t\t\t\t\t: false;\n\t\t\t\tif (stillPending) {\n\t\t\t\t\tconst mergedItems = board ? readVectorItems(board.yItems) : [];\n\t\t\t\t\tsetLocalDraftRef.current({\n\t\t\t\t\t\troomId,\n\t\t\t\t\t\tbaseRevision: currentRevisionRef.current,\n\t\t\t\t\t\titems: mergedItems,\n\t\t\t\t\t\tupdatedAt: nowMs(),\n\t\t\t\t\t\tpendingIds: board\n\t\t\t\t\t\t\t? Array.from(getLocallyPendingItemIds(board))\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t});\n\t\t\t\t\tqueuedDirtyRef.current = true;\n\t\t\t\t\tsetHasPendingDocumentSync(true);\n\t\t\t\t\tscheduleDocumentFlushRef.current();\n\t\t\t\t} else {\n\t\t\t\t\tqueuedDirtyRef.current = false;\n\t\t\t\t\tclearLocalDraftRef.current();\n\t\t\t\t\tsetHasPendingDocumentSync(false);\n\t\t\t\t}\n\t\t\t\tsetConflictStateRef.current(null);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"document:resync-required\") {\n\t\t\t\toutboundInFlightRef.current = null;\n\t\t\t\tqueuedDirtyRef.current = localDraftRef.current != null;\n\t\t\t\tsetHasPendingDocumentSync(queuedDirtyRef.current);\n\t\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tlastError: parsed.reason,\n\t\t\t\t}));\n\t\t\t\tresolveAuthoritativeDocumentRef.current(\n\t\t\t\t\tsanitizeRealtimeSnapshot(parsed.document),\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tsocket.addEventListener(\"error\", () => {\n\t\t\tif (disposed) return;\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tstate: prev.connected ? prev.state : \"error\",\n\t\t\t\tlastError: \"Falha de conexão websocket.\",\n\t\t\t}));\n\t\t});\n\n\t\tsocket.addEventListener(\"close\", () => {\n\t\t\tif (disposed) return;\n\t\t\tclearHeartbeatTimer();\n\t\t\tclearConnectTimeout();\n\t\t\twsRef.current = null;\n\t\t\tcollapsePeersToSelfRef.current(\n\t\t\t\tmanualDisconnectRef.current || !enabled ? \"offline\" : \"reconnecting\",\n\t\t\t);\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tconnected: false,\n\t\t\t\tclientId: prev.clientId,\n\t\t\t\tstate: manualDisconnectRef.current || !enabled ? \"offline\" : prev.state,\n\t\t\t}));\n\t\t\tif (!manualDisconnectRef.current && enabled) {\n\t\t\t\tscheduleReconnectRef.current();\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tdisposed = true;\n\t\t\tclearReconnectTimer();\n\t\t\tclearHeartbeatTimer();\n\t\t\tclearConnectTimeout();\n\t\t\tclearDocumentFlushSchedule();\n\t\t\tsocket.close();\n\t\t};\n\t}, [\n\t\tclearConnectTimeout,\n\t\tclearDocumentFlushSchedule,\n\t\tclearHeartbeatTimer,\n\t\tclearReconnectTimer,\n\t\tconnectSequence,\n\t\tconnectTimeoutMs,\n\t\tenabled,\n\t\theartbeatMs,\n\t\tpeer.color,\n\t\tpeer.displayName,\n\t\tpeer.id,\n\t\tpeer.image,\n\t\troomId,\n\t\turl,\n\t]);\n\n\tuseEffect(() => {\n\t\tsetSessionPeers((prev) =>\n\t\t\tprev.map((peerState) =>\n\t\t\t\tpeerState.clientId === clientIdRef.current\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...peerState,\n\t\t\t\t\t\t\tisSelf: true,\n\t\t\t\t\t\t\tconnectionState: connection.state,\n\t\t\t\t\t\t}\n\t\t\t\t\t: peerState,\n\t\t\t),\n\t\t);\n\t}, [connection.state]);\n\n\tuseEffect(\n\t\t() => () => {\n\t\t\tclearDocumentFlushSchedule();\n\t\t\tclearDraftPersistSchedule();\n\t\t\tif (boardRef.current) {\n\t\t\t\tboardRef.current.doc.destroy();\n\t\t\t\tboardRef.current = null;\n\t\t\t}\n\t\t},\n\t\t[clearDocumentFlushSchedule, clearDraftPersistSchedule],\n\t);\n\n\tconst flushDocumentSync = useCallback(async () => {\n\t\t// Manual flush (saveCurrentCanvas in trazo): drain pendingLocalItemsRef\n\t\t// into the Y.Doc and update the draft synchronously before persisting,\n\t\t// so the localStorage snapshot reflects the latest local changes even\n\t\t// when called while a previous send is still in-flight.\n\t\tconst board = boardRef.current;\n\t\tconst pendingLocal = pendingLocalItemsRef.current;\n\t\tif (board && pendingLocal) {\n\t\t\tpendingLocalItemsRef.current = null;\n\t\t\tapplyLocalItemsToYDoc(board, {\n\t\t\t\titems: pendingLocal,\n\t\t\t\torigin: ORIGIN_LOCAL,\n\t\t\t});\n\t\t\tconst mergedItems = readVectorItems(board.yItems);\n\t\t\tconst pendingIds = getLocallyPendingItemIds(board);\n\t\t\tif (pendingIds.size > 0) {\n\t\t\t\tsetLocalDraftRef.current({\n\t\t\t\t\troomId,\n\t\t\t\t\tbaseRevision: currentRevisionRef.current,\n\t\t\t\t\titems: mergedItems,\n\t\t\t\t\tupdatedAt: nowMs(),\n\t\t\t\t\tpendingIds: Array.from(pendingIds),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tpersistLocalDraft();\n\t\tif (!connection.connected) return;\n\t\tflushQueuedDocument();\n\t}, [connection.connected, flushQueuedDocument, persistLocalDraft, roomId]);\n\n\tconst remoteAdapter = useMemo<VectorCanvasRemoteAdapter>(\n\t\t() => ({\n\t\t\tsubscribe(onItems) {\n\t\t\t\tsubscriberRefs.current.add(onItems);\n\t\t\t\tif (latestDocumentRef.current) {\n\t\t\t\t\tonItems(latestDocumentRef.current.items);\n\t\t\t\t}\n\t\t\t\treturn () => {\n\t\t\t\t\tsubscriberRefs.current.delete(onItems);\n\t\t\t\t};\n\t\t\t},\n\t\t\tsend(items) {\n\t\t\t\tqueueDocumentSend(items);\n\t\t\t},\n\t\t\tflush() {\n\t\t\t\treturn flushDocumentSync();\n\t\t\t},\n\t\t}),\n\t\t[flushDocumentSync, queueDocumentSend],\n\t);\n\n\tconst disconnect = useCallback(() => {\n\t\tmanualDisconnectRef.current = true;\n\t\tclearReconnectTimer();\n\t\tclearHeartbeatTimer();\n\t\tclearConnectTimeout();\n\t\tsendRaw({\n\t\t\ttype: \"session:leave\",\n\t\t\troomId,\n\t\t\tclientId: clientIdRef.current,\n\t\t});\n\t\twsRef.current?.close();\n\t\twsRef.current = null;\n\t\tcollapsePeersToSelf(\"offline\");\n\t\tupdateConnection((prev) => ({\n\t\t\t...prev,\n\t\t\tstate: \"offline\",\n\t\t\tconnected: false,\n\t\t}));\n\t}, [\n\t\tclearConnectTimeout,\n\t\tclearHeartbeatTimer,\n\t\tclearReconnectTimer,\n\t\tcollapsePeersToSelf,\n\t\troomId,\n\t\tsendRaw,\n\t\tupdateConnection,\n\t]);\n\n\tconst reconnectNow = useCallback(() => {\n\t\tdisconnect();\n\t\tmanualDisconnectRef.current = false;\n\t\tretryCountRef.current = 0;\n\t\tsetConnectSequence((value) => value + 1);\n\t}, [disconnect]);\n\n\tconst remotePresence = useMemo(\n\t\t() => sessionPeers.filter((peerState) => !peerState.isSelf),\n\t\t[sessionPeers],\n\t);\n\n\tconst syncViewportPresence = useCallback(\n\t\t(bindingOptions?: BindViewportPresenceOptions) => {\n\t\t\tconst viewport = bindingOptions?.viewportRef?.current;\n\t\t\tconst cameraSnapshot = getViewportCameraSnapshot(viewport);\n\t\t\tif (!cameraSnapshot) return false;\n\t\t\tlastCameraRef.current = cameraSnapshot;\n\t\t\tlastActiveToolRef.current = bindingOptions?.activeTool;\n\t\t\tsendPresenceUpdate();\n\t\t\treturn true;\n\t\t},\n\t\t[sendPresenceUpdate],\n\t);\n\n\tconst bindViewportPresence = useCallback(\n\t\t(\n\t\t\tbindingOptions?: BindViewportPresenceOptions,\n\t\t): RealtimeViewportPresenceBindings => ({\n\t\t\tremotePresence,\n\t\t\tonWorldPointerMove(world) {\n\t\t\t\tlastCursorRef.current = world;\n\t\t\t\tlastActiveToolRef.current = bindingOptions?.activeTool;\n\t\t\t\tsendPresenceUpdate();\n\t\t\t},\n\t\t\tonWorldPointerLeave() {\n\t\t\t\tlastCursorRef.current = null;\n\t\t\t\tlastActiveToolRef.current = bindingOptions?.activeTool;\n\t\t\t\tsendPresenceUpdate();\n\t\t\t},\n\t\t\tonPlacementPreviewChange(preview: PlacementPreview | null) {\n\t\t\t\tlastMarkupStrokeRef.current =\n\t\t\t\t\tremoteMarkupStrokeFromPlacementPreview(preview);\n\t\t\t\tlastActiveToolRef.current = bindingOptions?.activeTool;\n\t\t\t\tsendPresenceUpdate();\n\t\t\t},\n\t\t\tonCameraChange() {\n\t\t\t\tconst viewport = bindingOptions?.viewportRef?.current;\n\t\t\t\tconst cameraSnapshot = getViewportCameraSnapshot(viewport);\n\t\t\t\tif (!cameraSnapshot) return;\n\t\t\t\tif (viewport && consumeViewportFollowSync(viewport, cameraSnapshot)) {\n\t\t\t\t\tlastCameraRef.current = cameraSnapshot;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlastCameraRef.current = cameraSnapshot;\n\t\t\t\tlastActiveToolRef.current = bindingOptions?.activeTool;\n\t\t\t\tsendPresenceUpdate();\n\t\t\t},\n\t\t}),\n\t\t[remotePresence, sendPresenceUpdate],\n\t);\n\n\treturn {\n\t\tconnection,\n\t\tsessionPeers,\n\t\tremotePresence,\n\t\tremoteAdapter,\n\t\tdocument,\n\t\thasLocalOfflineDraft,\n\t\thasPendingDocumentSync,\n\t\tsyncState,\n\t\tconflict,\n\t\tbindViewportPresence,\n\t\tsyncViewportPresence,\n\t\tresolveConflict,\n\t\tclearLocalDraft,\n\t\tflushDocumentSync,\n\t\tdisconnect,\n\t\treconnectNow,\n\t};\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo } from \"react\";\nimport { defaultPresenceColorForId } from \"../../presence\";\nimport {\n\ttype CanvasPlugin,\n\ttype CanvasPluginContribution,\n\ttype CanvasPluginItemsChangeMiddlewareContext,\n\tcreateCanvuPlugin,\n\tuseCanvuDocumentContext,\n\tuseCanvuPluginContribution,\n\tuseCanvuViewportContext,\n} from \"../types\";\nimport {\n\tRealtimeSessionPanel,\n\ttype RealtimeSessionPanelProps,\n} from \"./RealtimeSessionPanel\";\nimport {\n\ttype RealtimeCommentsAuthor,\n\ttype UseRealtimeCommentsOptions,\n\tuseRealtimeComments,\n} from \"./use-realtime-comments\";\nimport {\n\ttype UseRealtimeSessionOptions,\n\tuseRealtimeSession,\n} from \"./use-realtime-session\";\n\nexport type RealtimeCollaborationPluginOptions = UseRealtimeSessionOptions & {\n\t/** Enable or disable the built-in session panel. Default: `true`. */\n\tshowSessionPanel?: boolean;\n\t/** Optional visual customization for the built-in session panel. */\n\tsessionPanel?: Partial<\n\t\tOmit<\n\t\t\tRealtimeSessionPanelProps,\n\t\t\t\"peers\" | \"connected\" | \"connectionState\" | \"roomId\"\n\t\t>\n\t>;\n\t/**\n\t * Enable or configure the built-in collaborative comments experience.\n\t *\n\t * Pass `false` to disable comments entirely. When omitted, comments are enabled.\n\t */\n\tcomments?:\n\t\t| false\n\t\t| Omit<\n\t\t\t\tUseRealtimeCommentsOptions,\n\t\t\t\t\"items\" | \"onItemsChange\" | \"author\" | \"viewportRef\" | \"roomId\" | \"setToolId\"\n\t\t >;\n};\n\nfunction RealtimeCollaborationPluginComponent({\n\tpluginId,\n\toptions,\n}: {\n\tpluginId: string;\n\toptions: RealtimeCollaborationPluginOptions;\n}) {\n\tconst { viewportRef, viewport } = useCanvuViewportContext();\n\tconst { items, onItemsChange } = useCanvuDocumentContext();\n\tconst session = useRealtimeSession(options);\n\tconst peerDisplayName = options.peer.displayName ?? options.peer.id;\n\tconst peerColor = options.peer.color ?? defaultPresenceColorForId(options.peer.id);\n\tconst peerAuthor = useMemo<RealtimeCommentsAuthor>(\n\t\t() => ({\n\t\t\tpeerId: options.peer.id,\n\t\t\tdisplayName: peerDisplayName,\n\t\t\tcolor: peerColor,\n\t\t\t...(options.peer.image ? { image: options.peer.image } : {}),\n\t\t}),\n\t\t[options.peer.id, options.peer.image, peerColor, peerDisplayName],\n\t);\n\tconst commentOptions = useMemo(\n\t\t() => (options.comments === false ? null : (options.comments ?? {})),\n\t\t[options.comments],\n\t);\n\tconst handleCommentItemsChange = useCallback(\n\t\t(nextItems: typeof items) => {\n\t\t\tonItemsChange?.([...nextItems]);\n\t\t\tsession.remoteAdapter.send?.([...nextItems]);\n\t\t},\n\t\t[onItemsChange, session.remoteAdapter],\n\t);\n\tconst comments = useRealtimeComments({\n\t\titems,\n\t\tonItemsChange: handleCommentItemsChange,\n\t\tauthor: peerAuthor,\n\t\tviewportRef,\n\t\tactiveToolId: viewport.toolId,\n\t\troomId: options.roomId,\n\t\tsetToolId: viewport.onToolChangeRequest,\n\t\t...(commentOptions ?? {}),\n\t});\n\tconst presenceBindings = useMemo(\n\t\t() =>\n\t\t\tsession.bindViewportPresence({\n\t\t\t\tactiveTool: viewport.toolId,\n\t\t\t\tviewportRef,\n\t\t\t}),\n\t\t[session.bindViewportPresence, viewport.toolId, viewportRef],\n\t);\n\tconst onViewportCameraChange = useCallback(() => {\n\t\tpresenceBindings.onCameraChange?.();\n\t\tcomments.viewport.onCameraChange?.();\n\t}, [comments.viewport, presenceBindings]);\n\n\tuseEffect(() => {\n\t\tif (!session.connection.connected) return;\n\t\tlet animationFrameId = 0;\n\t\tconst syncViewportPresence = () => {\n\t\t\tconst didSync = session.syncViewportPresence({\n\t\t\t\tactiveTool: viewport.toolId,\n\t\t\t\tviewportRef,\n\t\t\t});\n\t\t\tif (didSync) return;\n\t\t\tanimationFrameId = window.requestAnimationFrame(syncViewportPresence);\n\t\t};\n\t\tsyncViewportPresence();\n\t\treturn () => {\n\t\t\twindow.cancelAnimationFrame(animationFrameId);\n\t\t};\n\t}, [\n\t\tsession.connection.connected,\n\t\tsession.syncViewportPresence,\n\t\tviewport.toolId,\n\t\tviewportRef,\n\t]);\n\n\tuseEffect(() => {\n\t\tif (!onItemsChange || !session.document) return;\n\t\tif (session.document.updatedByClientId === session.connection.clientId) return;\n\t\tonItemsChange(session.document.items);\n\t}, [onItemsChange, session.connection.clientId, session.document]);\n\n\tconst contribution = useMemo<CanvasPluginContribution>(\n\t\t() => ({\n\t\t\ttoolTransform: commentOptions ? () => comments.tools : undefined,\n\t\t\tcustomPlacements: commentOptions\n\t\t\t\t? comments.viewport.customPlacement\n\t\t\t\t\t? [comments.viewport.customPlacement]\n\t\t\t\t\t: undefined\n\t\t\t\t: undefined,\n\t\t\tviewportProps: {\n\t\t\t\tremotePresence: presenceBindings.remotePresence,\n\t\t\t},\n\t\t\tcallbacks: {\n\t\t\t\tonWorldPointerMove: presenceBindings.onWorldPointerMove,\n\t\t\t\tonWorldPointerLeave: presenceBindings.onWorldPointerLeave,\n\t\t\t\tonPlacementPreviewChange: presenceBindings.onPlacementPreviewChange,\n\t\t\t\tonCameraChange: onViewportCameraChange,\n\t\t\t},\n\t\t\twrapOnItemsChange: (\n\t\t\t\tnextItems,\n\t\t\t\tctx: CanvasPluginItemsChangeMiddlewareContext,\n\t\t\t) => {\n\t\t\t\tif (commentOptions) {\n\t\t\t\t\tcomments.handleViewportItemsChange(nextItems, (processedItems) => {\n\t\t\t\t\t\tctx.next(processedItems);\n\t\t\t\t\t\tsession.remoteAdapter.send?.([...processedItems]);\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tctx.next(nextItems);\n\t\t\t\tsession.remoteAdapter.send?.(nextItems);\n\t\t\t},\n\t\t}),\n\t\t[\n\t\t\tcommentOptions,\n\t\t\tcomments.tools,\n\t\t\tcomments.viewport,\n\t\t\tcomments.handleViewportItemsChange,\n\t\t\tonViewportCameraChange,\n\t\t\tpresenceBindings,\n\t\t\tsession.remoteAdapter,\n\t\t],\n\t);\n\tuseCanvuPluginContribution(pluginId, contribution);\n\n\treturn (\n\t\t<>\n\t\t\t{options.showSessionPanel === false ? null : (\n\t\t\t\t<RealtimeSessionPanel\n\t\t\t\t\ttitle={options.sessionPanel?.title ?? \"Sessão realtime\"}\n\t\t\t\t\tpeers={session.sessionPeers}\n\t\t\t\t\tconnected={session.connection.connected}\n\t\t\t\t\tconnectionState={session.connection.state}\n\t\t\t\t\troomId={options.roomId}\n\t\t\t\t>\n\t\t\t\t\t{options.sessionPanel?.children}\n\t\t\t\t</RealtimeSessionPanel>\n\t\t\t)}\n\t\t\t{commentOptions ? comments.overlay : null}\n\t\t</>\n\t);\n}\n\n/**\n * High-level plug and play collaboration plugin for `VectorViewport`.\n *\n * Use this when you want realtime presence, session UI, collaborative comments, and document sync\n * without manually wiring `useRealtimeSession`, `useRealtimeComments`, or extra viewport props.\n *\n * For advanced customizations and bespoke UIs, use `useRealtimeSession(...)` and\n * `useRealtimeComments(...)` directly.\n */\nexport function realtimeCollaborationPlugin(\n\toptions: RealtimeCollaborationPluginOptions,\n): CanvasPlugin {\n\tconst pluginId = `canvu.plugin.realtime-collaboration:${options.roomId}:${options.peer.clientId ?? options.peer.id}`;\n\treturn createCanvuPlugin({\n\t\tid: pluginId,\n\t\tComponent() {\n\t\t\treturn (\n\t\t\t\t<RealtimeCollaborationPluginComponent\n\t\t\t\t\tpluginId={pluginId}\n\t\t\t\t\toptions={options}\n\t\t\t\t/>\n\t\t\t);\n\t\t},\n\t});\n}\n","import type { CanvasPlugin } from \"../types\";\nimport {\n\tRealtimeSessionPanel,\n\ttype RealtimeSessionPanelProps,\n} from \"./RealtimeSessionPanel\";\n\nexport type RealtimeSessionPluginOptions = RealtimeSessionPanelProps;\n\n/**\n * Optional UI roster for who is in the session (your WebSocket layer fills `peers`).\n * World-space cursors and strokes use {@link VectorViewport} `remotePresence` and\n * `onWorldPointerMove` — this plugin only renders a small panel in the viewport plugin layer.\n *\n * @example\n * ```tsx\n * <VectorViewport\n * items={doc.items}\n * onItemsChange={doc.onItemsChange}\n * plugins={[\n * realtimeSessionPlugin({ peers: presenceRoster, connected: wsOpen }),\n * ]}\n * />\n * ```\n */\nexport function realtimeSessionPlugin(\n\toptions: RealtimeSessionPluginOptions,\n): CanvasPlugin {\n\treturn {\n\t\tid: \"trazo.plugin.realtime-session\",\n\t\trender: () => <RealtimeSessionPanel {...options} />,\n\t};\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { VectorSceneItem } from \"../../../scene/types\";\nimport type {\n\tRealtimeDocumentConflict,\n\tRealtimeSyncState,\n\tUseRealtimeSessionResult,\n} from \"./use-realtime-session\";\n\ntype UseRealtimeCanvasDocumentOptions = {\n\tsession: Pick<\n\t\tUseRealtimeSessionResult,\n\t\t| \"connection\"\n\t\t| \"document\"\n\t\t| \"remoteAdapter\"\n\t\t| \"hasLocalOfflineDraft\"\n\t\t| \"hasPendingDocumentSync\"\n\t\t| \"syncState\"\n\t\t| \"conflict\"\n\t\t| \"resolveConflict\"\n\t\t| \"clearLocalDraft\"\n\t\t| \"flushDocumentSync\"\n\t> | null;\n\titems: readonly VectorSceneItem[];\n\tonItemsChange?: (nextItems: VectorSceneItem[]) => void;\n\tnormalizeItems?: (nextItems: readonly VectorSceneItem[]) => VectorSceneItem[];\n\thydrateItems?: (\n\t\tnextItems: readonly VectorSceneItem[],\n\t) => Promise<VectorSceneItem[]>;\n\tenabled?: boolean;\n};\n\nexport type UseRealtimeCanvasDocumentResult = {\n\titems: readonly VectorSceneItem[];\n\tonItemsChange?: (nextItems: VectorSceneItem[]) => void;\n\tloading: boolean;\n\tsaving: boolean;\n\thasLocalOfflineDraft: boolean;\n\tsyncState: RealtimeSyncState;\n\tconflict: RealtimeDocumentConflict | null;\n\tresolveConflict: (action: \"keep-local\" | \"use-server\") => void;\n\tclearLocalDraft: () => void;\n\tflush: () => Promise<void>;\n};\n\nexport function useRealtimeCanvasDocument(\n\toptions: UseRealtimeCanvasDocumentOptions,\n): UseRealtimeCanvasDocumentResult {\n\tconst {\n\t\tsession,\n\t\titems,\n\t\tonItemsChange,\n\t\tnormalizeItems,\n\t\thydrateItems,\n\t\tenabled = true,\n\t} = options;\n\tconst [loading, setLoading] = useState(false);\n\tconst lastAppliedRevisionRef = useRef<number | null>(null);\n\tconst inFlightRevisionRef = useRef<number | null>(null);\n\t// Once we've ever propagated a non-empty items set to the consumer, treat\n\t// a subsequent inbound empty document as suspicious and skip it. This\n\t// guards against rare races (tab killed before localStorage debounce\n\t// flushed, Y.Doc reset, stale snapshot) that would otherwise wipe the\n\t// consumer's view to []. Genuine empty boards on first load still work\n\t// because hasEverPropagatedItemsRef starts false.\n\tconst hasEverPropagatedItemsRef = useRef(false);\n\tconst realtimeEnabled = enabled && session != null;\n\tconst documentRevision = session?.document?.revision ?? null;\n\tconst documentItems = session?.document?.items;\n\tconst documentUpdatedByClientId = session?.document?.updatedByClientId ?? null;\n\tconst connectionClientId = session?.connection.clientId ?? null;\n\n\tconst applyIncomingItems = useCallback(\n\t\tasync (nextItems: readonly VectorSceneItem[]) => {\n\t\t\tconst normalizedItems = normalizeItems\n\t\t\t\t? normalizeItems(nextItems)\n\t\t\t\t: [...nextItems];\n\t\t\tif (!hydrateItems) return normalizedItems;\n\t\t\treturn await hydrateItems(normalizedItems);\n\t\t},\n\t\t[hydrateItems, normalizeItems],\n\t);\n\n\tconst handleItemsChange = useCallback(\n\t\t(nextItems: VectorSceneItem[]) => {\n\t\t\tif (!enabled) {\n\t\t\t\tonItemsChange?.(normalizeItems ? normalizeItems(nextItems) : nextItems);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst normalizedItems = normalizeItems ? normalizeItems(nextItems) : nextItems;\n\t\t\tonItemsChange?.(normalizedItems);\n\t\t\tsession?.remoteAdapter.send?.(normalizedItems);\n\t\t},\n\t\t[enabled, normalizeItems, onItemsChange, session],\n\t);\n\n\tuseEffect(() => {\n\t\tif (!realtimeEnabled || !onItemsChange || !session?.document) return;\n\t\tif (documentUpdatedByClientId === connectionClientId) return;\n\t\tif (documentRevision == null) return;\n\t\tif (lastAppliedRevisionRef.current === documentRevision) return;\n\t\tif (inFlightRevisionRef.current === documentRevision) return;\n\t\tinFlightRevisionRef.current = documentRevision;\n\t\tlet cancelled = false;\n\t\tsetLoading(true);\n\t\tvoid applyIncomingItems(documentItems ?? [])\n\t\t\t.then((resolvedItems) => {\n\t\t\t\tif (cancelled) return;\n\t\t\t\tif (inFlightRevisionRef.current !== documentRevision) return;\n\t\t\t\tlastAppliedRevisionRef.current = documentRevision;\n\t\t\t\tif (resolvedItems.length === 0 && hasEverPropagatedItemsRef.current) {\n\t\t\t\t\t// Defensive: a previously non-empty document is now empty.\n\t\t\t\t\t// Almost always a stale or buggy snapshot — skip rather\n\t\t\t\t\t// than wipe the consumer's view. The next snapshot will\n\t\t\t\t\t// reconcile if the emptiness was real.\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (resolvedItems.length > 0) {\n\t\t\t\t\thasEverPropagatedItemsRef.current = true;\n\t\t\t\t}\n\t\t\t\tonItemsChange(resolvedItems);\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (inFlightRevisionRef.current === documentRevision) {\n\t\t\t\t\tinFlightRevisionRef.current = null;\n\t\t\t\t}\n\t\t\t\tif (cancelled) return;\n\t\t\t\tsetLoading(false);\n\t\t\t});\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [\n\t\tapplyIncomingItems,\n\t\tconnectionClientId,\n\t\tdocumentItems,\n\t\tdocumentRevision,\n\t\tdocumentUpdatedByClientId,\n\t\tonItemsChange,\n\t\trealtimeEnabled,\n\t\tsession?.document,\n\t]);\n\n\treturn useMemo(\n\t\t() => ({\n\t\t\titems,\n\t\t\tonItemsChange: onItemsChange ? handleItemsChange : undefined,\n\t\t\tloading,\n\t\t\tsaving: session?.hasPendingDocumentSync ?? false,\n\t\t\thasLocalOfflineDraft: session?.hasLocalOfflineDraft ?? false,\n\t\t\tsyncState: session?.syncState ?? \"offline\",\n\t\t\tconflict: session?.conflict ?? null,\n\t\t\tresolveConflict: session?.resolveConflict ?? (() => {}),\n\t\t\tclearLocalDraft: session?.clearLocalDraft ?? (() => {}),\n\t\t\tflush: session?.flushDocumentSync ?? (async () => {}),\n\t\t}),\n\t\t[handleItemsChange, items, loading, onItemsChange, session],\n\t);\n}\n"]}
1
+ {"version":3,"sources":["../src/react/presence/map-placement-preview.ts","../src/math/rect.ts","../src/renderer/svg-vector-renderer.ts","../src/scene/freehand-path.ts","../src/scene/custom-shape.ts","../src/scene/shape-builders.ts","../src/react/presence/peer-color.ts","../src/react/presence/PresenceRemoteLayer.tsx","../src/react/plugins/realtime/protocol.ts","../src/react/plugins/realtime/RealtimeSessionPanel.tsx","../src/react/plugins/types.ts","../src/react/tools/icons.tsx","../src/react/tools/default-tools.tsx","../src/react/plugins/realtime/realtime-comment-tool.tsx","../src/react/plugins/realtime/use-realtime-comments.tsx","../src/react/plugins/realtime/use-realtime-peer-follow.ts","../src/react/plugins/realtime/yjs-document.ts","../src/react/plugins/realtime/use-realtime-session.ts","../src/react/plugins/realtime/realtime-collaboration-plugin.tsx","../src/react/plugins/realtime/realtime-session-plugin.tsx","../src/react/plugins/realtime/use-realtime-canvas-document.ts"],"names":["base","d","getStroke","jsx","MousePointer2","document","jsxs","Fragment","createContext","useContext","useLayoutEffect","Hand","Square","Circle","Minus","ArrowUpRight","PenLine","Highlighter","Eraser","Type","Image","MessageSquare","isRecord","getString","getNumber","useState","useRef","useEffect","Sparkles","overlayShell","useMemo","useCallback","Y","id","options"],"mappings":"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","file":"realtime.cjs","sourcesContent":["import type { PlacementPreview } from \"../InteractionOverlay\";\nimport type { RemotePresenceMarkupStroke } from \"./types\";\n\n/**\n * Maps a local {@link PlacementPreview} stroke to {@link RemotePresenceMarkupStroke} for broadcasting.\n * Returns `null` when there is no in-progress stroke.\n */\nexport function remoteMarkupStrokeFromPlacementPreview(\n\tpreview: PlacementPreview | null,\n): RemotePresenceMarkupStroke | null {\n\tif (!preview || preview.kind !== \"stroke\" || preview.points.length === 0) {\n\t\treturn null;\n\t}\n\tconst tool = preview.tool;\n\tconst mapped: RemotePresenceMarkupStroke[\"tool\"] =\n\t\ttool === \"laser\" || tool === \"marker\" || tool === \"draw\" ? tool : \"draw\";\n\tconst style = preview.style;\n\treturn {\n\t\tpoints: preview.points,\n\t\ttool: mapped,\n\t\t...(style?.strokeWidth != null ? { strokeWidth: style.strokeWidth } : {}),\n\t\t...(style?.stroke ? { stroke: style.stroke } : {}),\n\t\t...(style?.strokeOpacity != null ? { strokeOpacity: style.strokeOpacity } : {}),\n\t};\n}\n","/**\n * Axis-aligned rectangle in 2D (world or screen space).\n */\nexport type Rect = {\n\treadonly x: number;\n\treadonly y: number;\n\treadonly width: number;\n\treadonly height: number;\n};\n\n/**\n * Returns whether two axis-aligned rectangles intersect (edges touching count).\n */\nexport function rectsIntersect(a: Rect, b: Rect): boolean {\n\treturn (\n\t\ta.x < b.x + b.width &&\n\t\ta.x + a.width > b.x &&\n\t\ta.y < b.y + b.height &&\n\t\ta.y + a.height > b.y\n\t);\n}\n\n/**\n * Normalizes a rect so width and height are non-negative.\n */\nexport function normalizeRect(r: Rect): Rect {\n\tconst x0 = r.width >= 0 ? r.x : r.x + r.width;\n\tconst y0 = r.height >= 0 ? r.y : r.y + r.height;\n\treturn {\n\t\tx: x0,\n\t\ty: y0,\n\t\twidth: Math.abs(r.width),\n\t\theight: Math.abs(r.height),\n\t};\n}\n","import type { Camera2D } from \"../camera/camera\";\nimport { normalizeRect } from \"../math/rect\";\nimport { cullItemsByViewport } from \"../scene/cull\";\nimport type { VectorScene } from \"../scene/scene\";\nimport type { VectorSceneItem } from \"../scene/types\";\n\n/**\n * Builds the SVG `transform` attribute for mapping world coordinates to viewport CSS pixels.\n */\nexport function formatCameraTransform(camera: Camera2D): string {\n\tconst z = camera.zoom;\n\treturn `matrix(${z}, 0, 0, ${z}, ${camera.x}, ${camera.y})`;\n}\n\n/**\n * Transform for item `<g>`: `translate(x,y)` plus optional rotation around the bounds center.\n * SVG `rotate` uses degrees.\n */\nexport function formatItemPlacementTransform(item: VectorSceneItem): string {\n\tconst r = normalizeRect(item.bounds);\n\tconst rot = item.rotation ?? 0;\n\tif (Math.abs(rot) < 1e-12) {\n\t\treturn `translate(${item.x}, ${item.y})`;\n\t}\n\tconst deg = (rot * 180) / Math.PI;\n\tconst cx = r.width / 2;\n\tconst cy = r.height / 2;\n\treturn `translate(${item.x}, ${item.y}) translate(${cx}, ${cy}) rotate(${deg}) translate(${-cx}, ${-cy})`;\n}\n\nexport type SvgVectorRendererOptions = {\n\t/** Root element (typically `position: relative` and fixed size). */\n\tcontainer: HTMLElement;\n\tscene: VectorScene;\n\tcamera: Camera2D;\n\t/**\n\t * When true, the scene SVG ignores pointer events so an overlay can own hit-testing\n\t * (interactive selection / resize / placement).\n\t */\n\tpointerEventsNone?: boolean;\n};\n\ntype CachedItemG = {\n\treadonly g: SVGGElement;\n\tlastChildrenSvg: string;\n\tlastTransform: string;\n};\n\n/**\n * Renders vector scene items into a single SVG: camera as an outer `<g>` transform,\n * so geometry stays sharp at any zoom (no fixed-resolution raster).\n *\n * Uses incremental DOM updates: keeps a stable `<g>` per visible item id, updates\n * `innerHTML` only when `childrenSvg` changes, and only adjusts the camera transform\n * when pan/zoom changes without content edits.\n */\nexport class SvgVectorRenderer {\n\tprivate readonly container: HTMLElement;\n\tprivate readonly scene: VectorScene;\n\tprivate readonly camera: Camera2D;\n\tprivate readonly svg: SVGSVGElement;\n\tprivate readonly rootG: SVGGElement;\n\tprivate readonly itemNodeCache = new Map<string, CachedItemG>();\n\tprivate liveOverlay: CachedItemG | null = null;\n\tprivate readonly resizeObserver: ResizeObserver;\n\n\tconstructor(options: SvgVectorRendererOptions) {\n\t\tthis.container = options.container;\n\t\tthis.scene = options.scene;\n\t\tthis.camera = options.camera;\n\n\t\tthis.svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n\t\tthis.svg.setAttribute(\"width\", \"100%\");\n\t\tthis.svg.setAttribute(\"height\", \"100%\");\n\t\tthis.svg.setAttribute(\"shape-rendering\", \"geometricPrecision\");\n\t\tthis.svg.style.display = \"block\";\n\t\tthis.svg.setAttribute(\"role\", \"presentation\");\n\t\tthis.svg.setAttribute(\"focusable\", \"false\");\n\t\tthis.setPointerEventsNone(options.pointerEventsNone ?? false);\n\n\t\tthis.rootG = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n\t\tthis.svg.appendChild(this.rootG);\n\n\t\tthis.container.appendChild(this.svg);\n\n\t\tthis.resizeObserver = new ResizeObserver(() => this.render());\n\t\tthis.resizeObserver.observe(this.container);\n\t}\n\n\t/**\n\t * Reads container size, culls items, and updates the SVG (incrementally when possible).\n\t */\n\trender(): void {\n\t\tconst w = this.container.clientWidth;\n\t\tconst h = this.container.clientHeight;\n\t\tif (w <= 0 || h <= 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.svg.setAttribute(\"viewBox\", `0 0 ${w} ${h}`);\n\t\tthis.svg.setAttribute(\"preserveAspectRatio\", \"xMidYMid slice\");\n\n\t\tconst visible = this.camera.getVisibleWorldRect(w, h);\n\t\tconst items = cullItemsByViewport(this.scene.getItems(), visible);\n\n\t\tthis.syncVisibleItems(items);\n\t\tthis.rootG.setAttribute(\"transform\", formatCameraTransform(this.camera));\n\t\tthis.keepLiveOverlayOnTop();\n\t}\n\n\t/**\n\t * Updates only the in-progress (live) stroke node without re-culling or\n\t * re-syncing the committed scene items. Drawing tools call this on every\n\t * pointer move, so it must stay O(1) regardless of how many items the\n\t * board already contains.\n\t *\n\t * Pass `null` to remove the live overlay (e.g. when the stroke is committed).\n\t */\n\trenderLiveItem(item: VectorSceneItem | null): void {\n\t\tif (!item) {\n\t\t\tif (this.liveOverlay) {\n\t\t\t\tthis.liveOverlay.g.remove();\n\t\t\t\tthis.liveOverlay = null;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.liveOverlay) {\n\t\t\tconst g = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n\t\t\tg.setAttribute(\"data-live-overlay\", \"true\");\n\t\t\tthis.liveOverlay = {\n\t\t\t\tg,\n\t\t\t\tlastChildrenSvg: \"\",\n\t\t\t\tlastTransform: \"\",\n\t\t\t};\n\t\t\tthis.rootG.appendChild(g);\n\t\t}\n\n\t\tconst cached = this.liveOverlay;\n\t\tconst t = formatItemPlacementTransform(item);\n\t\tif (cached.lastTransform !== t) {\n\t\t\tcached.g.setAttribute(\"transform\", t);\n\t\t\tcached.lastTransform = t;\n\t\t}\n\t\tif (cached.lastChildrenSvg !== item.childrenSvg) {\n\t\t\t// Trusted SVG fragments only — sanitize untrusted strings in your app.\n\t\t\tcached.g.innerHTML = item.childrenSvg;\n\t\t\tcached.lastChildrenSvg = item.childrenSvg;\n\t\t}\n\t\tthis.keepLiveOverlayOnTop();\n\t}\n\n\tprivate keepLiveOverlayOnTop(): void {\n\t\tif (this.liveOverlay && this.rootG.lastChild !== this.liveOverlay.g) {\n\t\t\tthis.rootG.appendChild(this.liveOverlay.g);\n\t\t}\n\t}\n\n\tprivate syncVisibleItems(items: readonly VectorSceneItem[]): void {\n\t\tconst visibleIds = new Set<string>();\n\t\tfor (const item of items) {\n\t\t\tvisibleIds.add(item.id);\n\t\t}\n\n\t\tfor (const [id, cached] of this.itemNodeCache) {\n\t\t\tif (!visibleIds.has(id)) {\n\t\t\t\tcached.g.remove();\n\t\t\t}\n\t\t}\n\n\t\tlet previousNode: ChildNode | null = null;\n\t\tfor (const item of items) {\n\t\t\tlet cached = this.itemNodeCache.get(item.id);\n\t\t\tif (!cached) {\n\t\t\t\tconst g = document.createElementNS(\"http://www.w3.org/2000/svg\", \"g\");\n\t\t\t\tg.setAttribute(\"data-item-id\", item.id);\n\t\t\t\tcached = {\n\t\t\t\t\tg,\n\t\t\t\t\tlastChildrenSvg: \"\",\n\t\t\t\t\tlastTransform: \"\",\n\t\t\t\t};\n\t\t\t\tthis.itemNodeCache.set(item.id, cached);\n\t\t\t}\n\n\t\t\tconst { g } = cached;\n\t\t\tconst t = formatItemPlacementTransform(item);\n\t\t\tif (cached.lastTransform !== t) {\n\t\t\t\tg.setAttribute(\"transform\", t);\n\t\t\t\tcached.lastTransform = t;\n\t\t\t}\n\n\t\t\tif (cached.lastChildrenSvg !== item.childrenSvg) {\n\t\t\t\t// Trusted SVG fragments only — sanitize untrusted strings in your app.\n\t\t\t\tg.innerHTML = item.childrenSvg;\n\t\t\t\tcached.lastChildrenSvg = item.childrenSvg;\n\t\t\t}\n\n\t\t\tconst expectedPosition: ChildNode | null = previousNode\n\t\t\t\t? previousNode.nextSibling\n\t\t\t\t: this.rootG.firstChild;\n\t\t\tif (expectedPosition !== g) {\n\t\t\t\tthis.rootG.insertBefore(g, expectedPosition);\n\t\t\t}\n\t\t\tpreviousNode = g;\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.resizeObserver.disconnect();\n\t\tthis.itemNodeCache.clear();\n\t\tthis.liveOverlay = null;\n\t\tthis.svg.remove();\n\t}\n\n\t/** Toggle whether the scene SVG receives pointer events (vs overlay handling them). */\n\tsetPointerEventsNone(value: boolean): void {\n\t\tthis.svg.style.pointerEvents = value ? \"none\" : \"auto\";\n\t}\n}\n","/**\n * Freehand stroke helpers: dedupe noisy samples and build smooth SVG path `d` values\n * (quadratic Béziers) so strokes don't look jagged / \"pixelated\" from many short L segments.\n */\n\n/** Drop intermediate samples closer than `minDist` (local/world units) to reduce jitter. */\nexport function dedupeFreehandPoints<T extends { x: number; y: number }>(\n\tpoints: readonly T[],\n\tminDist: number,\n): T[] {\n\tif (points.length <= 2) {\n\t\treturn points.map((p) => ({ ...p }));\n\t}\n\tconst minSq = minDist * minDist;\n\tconst first = points[0];\n\tif (!first) return [];\n\tconst out: T[] = [{ ...first }];\n\tfor (let i = 1; i < points.length - 1; i++) {\n\t\tconst p = points[i];\n\t\tconst last = out[out.length - 1];\n\t\tif (!p || !last) continue;\n\t\tconst dx = p.x - last.x;\n\t\tconst dy = p.y - last.y;\n\t\tif (dx * dx + dy * dy >= minSq) {\n\t\t\tout.push({ ...p });\n\t\t}\n\t}\n\tconst end = points[points.length - 1];\n\tconst lastKept = out[out.length - 1];\n\tif (!end || !lastKept) return out;\n\tif ((end.x - lastKept.x) ** 2 + (end.y - lastKept.y) ** 2 > 1e-12) {\n\t\tout.push({ ...end });\n\t}\n\treturn out;\n}\n\n/**\n * Smooth polyline → SVG path `d` using quadratic curves (canvas quadraticCurveTo midpoint pattern).\n * Avoids faceted \"broken\" lines from chaining many `L` commands.\n */\nexport function smoothFreehandPointsToPathD(\n\tpoints: readonly { x: number; y: number }[],\n): string {\n\tconst n = points.length;\n\tif (n === 0) return \"\";\n\tif (n === 1) {\n\t\tconst p = points[0];\n\t\tif (!p) return \"\";\n\t\treturn `M ${p.x} ${p.y}`;\n\t}\n\tif (n === 2) {\n\t\tconst a = points[0];\n\t\tconst b = points[1];\n\t\tif (!a || !b) return \"\";\n\t\treturn `M ${a.x} ${a.y} L ${b.x} ${b.y}`;\n\t}\n\tconst p0 = points[0];\n\tif (!p0) return \"\";\n\tlet d = `M ${p0.x} ${p0.y}`;\n\tlet i = 1;\n\tfor (; i < n - 2; i++) {\n\t\tconst pi = points[i];\n\t\tconst pi1 = points[i + 1];\n\t\tif (!pi || !pi1) continue;\n\t\tconst xc = (pi.x + pi1.x) / 2;\n\t\tconst yc = (pi.y + pi1.y) / 2;\n\t\td += ` Q ${pi.x} ${pi.y} ${xc} ${yc}`;\n\t}\n\tconst pLast = points[i];\n\tconst pEnd = points[i + 1];\n\tif (!pLast || !pEnd) return d;\n\td += ` Q ${pLast.x} ${pLast.y} ${pEnd.x} ${pEnd.y}`;\n\treturn d;\n}\n\n/**\n * Closed path from `perfect-freehand` outline → SVG `d` for fill.\n *\n * Uses the algorithm from the perfect-freehand README (`getSvgPathFromStroke`):\n * each outline point is a quadratic control point and the midpoint between\n * consecutive outline points is the curve endpoint. This produces\n * C1-continuous curves without the kinks that chained `T` or short `L` segments cause.\n */\nexport function outlineStrokeToClosedPathD(\n\toutline: readonly [number, number][],\n): string {\n\tconst len = outline.length;\n\tif (len === 0) return \"\";\n\tconst first = outline[0];\n\tif (!first) return \"\";\n\tif (len < 3) {\n\t\tlet d = `M ${first[0]} ${first[1]}`;\n\t\tfor (let i = 1; i < len; i++) {\n\t\t\tconst pt = outline[i];\n\t\t\tif (!pt) continue;\n\t\t\td += ` L ${pt[0]} ${pt[1]}`;\n\t\t}\n\t\treturn `${d} Z`;\n\t}\n\n\tlet d = `M ${first[0]} ${first[1]} Q`;\n\tfor (let i = 0; i < len; i++) {\n\t\tconst p0 = outline[i];\n\t\tconst p1 = outline[(i + 1) % len];\n\t\tif (!p0 || !p1) continue;\n\t\td += ` ${p0[0]} ${p0[1]} ${(p0[0] + p1[0]) / 2} ${(p0[1] + p1[1]) / 2}`;\n\t}\n\treturn `${d} Z`;\n}\n","import type { Rect } from \"../math/rect\";\nimport { normalizeRect } from \"../math/rect\";\nimport type { VectorSceneItem } from \"./types\";\n\n/** Width/height of the shape’s local drawing box (same as `bounds` at creation). */\nexport type CustomShapeSize = { width: number; height: number };\n\n/**\n * How to build the inner SVG (inside the item’s bounding box).\n *\n * - **`svg`**: paste-friendly markup. Use `{{w}}`, `{{h}}`, `{{width}}`, or `{{height}}` where the size should go.\n * - **`render`**: a small function when you prefer code over a string template.\n */\nexport type CreateCustomShapeContent =\n\t| {\n\t\t\t/**\n\t\t\t * SVG fragment for `<g>` contents (no outer `<svg>`). Placeholders are replaced with numeric sizes:\n\t\t\t * `{{w}}`, `{{h}}`, `{{width}}`, `{{height}}`.\n\t\t\t */\n\t\t\tsvg: string;\n\t }\n\t| {\n\t\t\t/** Returns inner SVG for the given box size (same coordinate range as `bounds`). */\n\t\t\trender: (size: CustomShapeSize) => string;\n\t };\n\n/**\n * Replaces `{{w}}`, `{{h}}`, `{{width}}`, and `{{height}}` in a string with the given dimensions.\n * Use this if you build SVG strings yourself and want the same rules as {@link createCustomShapeItem}.\n */\nexport function expandCustomShapeTemplate(\n\ttemplate: string,\n\twidth: number,\n\theight: number,\n): string {\n\treturn template\n\t\t.replace(/\\{\\{w\\}\\}/g, String(width))\n\t\t.replace(/\\{\\{h\\}\\}/g, String(height))\n\t\t.replace(/\\{\\{width\\}\\}/g, String(width))\n\t\t.replace(/\\{\\{height\\}\\}/g, String(height));\n}\n\nfunction resolveCustomInner(\n\tcontent: CreateCustomShapeContent,\n\tsize: CustomShapeSize,\n): string {\n\tif (\"render\" in content) {\n\t\treturn content.render(size);\n\t}\n\treturn expandCustomShapeTemplate(content.svg, size.width, size.height);\n}\n\n/**\n * Builds the scaled `<g>` wrapper used for `childrenSvg` on custom shapes that support resize.\n */\nexport function buildCustomShapeChildrenSvg(\n\tinner: string,\n\tintrinsic: CustomShapeSize,\n\tbounds: Rect,\n): string {\n\tconst b = normalizeRect(bounds);\n\tconst sx = b.width / intrinsic.width;\n\tconst sy = b.height / intrinsic.height;\n\treturn `<g transform=\"scale(${sx},${sy})\">${inner}</g>`;\n}\n\n/**\n * Creates a user-defined shape from SVG markup or a `render` callback.\n *\n * Coordinates are **local**: draw from `(0,0)` to `(width, height)` of `bounds`. The library stores an\n * intrinsic copy so resize handles (when interactive) scale the drawing uniformly.\n *\n * @example\n * ```ts\n * const star = createCustomShapeItem(createShapeId(), rect, {\n * svg: `<polygon points=\"...\" fill=\"gold\" stroke=\"#b45309\" stroke-width=\"2\" />`,\n * });\n * ```\n *\n * @example Template (good for copy-paste from design tools)\n * ```ts\n * createCustomShapeItem(id, rect, {\n * svg: `<rect width=\"{{w}}\" height=\"{{h}}\" rx=\"8\" fill=\"#e0e7ff\" stroke=\"#6366f1\" />`,\n * });\n * ```\n */\nexport function createCustomShapeItem(\n\tid: string,\n\tbounds: Rect,\n\tcontent: CreateCustomShapeContent,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst intrinsic: CustomShapeSize = { width: r.width, height: r.height };\n\tconst inner = resolveCustomInner(content, intrinsic);\n\treturn {\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"custom\",\n\t\tcustomIntrinsicSize: intrinsic,\n\t\tcustomInnerSvg: inner,\n\t\tchildrenSvg: buildCustomShapeChildrenSvg(inner, intrinsic, r),\n\t};\n}\n","import type { StrokeOptions } from \"perfect-freehand\";\nimport getStroke from \"perfect-freehand\";\nimport type { Rect } from \"../math/rect\";\nimport { normalizeRect } from \"../math/rect\";\nimport { buildCustomShapeChildrenSvg } from \"./custom-shape\";\nimport {\n\tbuildTextFixedBoundsSvg,\n\tbuildTextSvg,\n\tDEFAULT_TEXT_FONT_SIZE,\n\tmeasureTextBoundsLocal,\n} from \"./text-svg\";\nimport type {\n\tArrowBindings,\n\tLineEndpointsLocal,\n\tVectorPathPoint,\n\tVectorSceneItem,\n} from \"./types\";\n\nexport {\n\tbuildTextFixedBoundsSvg,\n\tbuildTextSvg,\n\tDEFAULT_TEXT_FONT_SIZE,\n\tmeasureTextBoundsLocal,\n};\n\n/**\n * While inline-editing: sync bounds to draft width/height and hide SVG so only the textarea shows text.\n */\nexport function applyTextDraftWhileEditing(\n\titem: VectorSceneItem,\n\tdraft: string,\n): VectorSceneItem {\n\tif (item.toolKind !== \"text\") return item;\n\tconst fs = item.textFontSize ?? DEFAULT_TEXT_FONT_SIZE;\n\tif (item.textFixedBounds) {\n\t\treturn {\n\t\t\t...item,\n\t\t\ttext: draft,\n\t\t\tchildrenSvg: \"\",\n\t\t};\n\t}\n\tconst m = measureTextBoundsLocal(draft, fs);\n\treturn {\n\t\t...item,\n\t\ttext: draft,\n\t\tbounds: {\n\t\t\tx: item.x,\n\t\t\ty: item.y,\n\t\t\twidth: m.width,\n\t\t\theight: m.height,\n\t\t},\n\t\tchildrenSvg: \"\",\n\t};\n}\n\n/** Stroke dash pattern for freehand drawings. `solid` = perfect-freehand fill; `dashed` = centerline stroke with dashes. */\nexport type StrokeDash = \"solid\" | \"dashed\";\n\n/** Resolved stroke for SVG generation. */\nexport type StrokeStyle = {\n\tstroke: string;\n\tstrokeWidth: number;\n\tstrokeOpacity?: number;\n\tstrokeDash?: StrokeDash;\n};\n\nexport const DEFAULT_STROKE_STYLE: StrokeStyle = {\n\tstroke: \"#1d1d1d\",\n\tstrokeWidth: 2,\n};\n\nconst TOOL_FREEHAND_DEFAULTS: Record<\n\t\"draw\" | \"pencil\" | \"brush\" | \"marker\",\n\tPartial<StrokeStyle>\n> = {\n\tdraw: { strokeWidth: 10 },\n\tpencil: { strokeWidth: 3 },\n\tbrush: { strokeWidth: 10 },\n\tmarker: { stroke: \"#fde047\", strokeWidth: 16, strokeOpacity: 0.5 },\n};\n\nfunction perfectFreehandOptions(\n\ttoolKind: \"draw\" | \"pencil\" | \"brush\" | \"marker\",\n\tstyle: StrokeStyle,\n\tstrokeComplete: boolean,\n\tpressureAware = false,\n): StrokeOptions {\n\tconst sw = style.strokeWidth;\n\tconst base: StrokeOptions = {\n\t\tlast: strokeComplete,\n\t\tsimulatePressure: true,\n\t};\n\tif (toolKind === \"draw\" || toolKind === \"pencil\") {\n\t\tif (pressureAware && toolKind === \"draw\") {\n\t\t\treturn {\n\t\t\t\t...base,\n\t\t\t\tsize: Math.max(2, sw * 1.05),\n\t\t\t\tthinning: 0.42,\n\t\t\t\tsmoothing: 0.78,\n\t\t\t\tstreamline: 0.62,\n\t\t\t\tsimulatePressure: true,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\t...base,\n\t\t\tsize: Math.max(2, sw * 1.18),\n\t\t\tthinning: 0.12,\n\t\t\tsmoothing: 0.85,\n\t\t\tstreamline: 0.78,\n\t\t\tsimulatePressure: true,\n\t\t};\n\t}\n\tif (toolKind === \"brush\") {\n\t\treturn {\n\t\t\t...base,\n\t\t\tsize: Math.max(4, sw * 1.22),\n\t\t\tthinning: 0.52,\n\t\t\tsmoothing: 0.64,\n\t\t\tstreamline: 0.68,\n\t\t};\n\t}\n\treturn {\n\t\t...base,\n\t\tsize: Math.max(6, sw * 1.08),\n\t\tthinning: 0.08,\n\t\tsmoothing: 0.88,\n\t\tstreamline: 0.84,\n\t\tsimulatePressure: true,\n\t};\n}\n\nexport function resolveStrokeStyle(item: VectorSceneItem): StrokeStyle {\n\treturn {\n\t\tstroke: item.stroke ?? DEFAULT_STROKE_STYLE.stroke,\n\t\tstrokeWidth: item.strokeWidth ?? DEFAULT_STROKE_STYLE.strokeWidth,\n\t\tstrokeOpacity: item.strokeOpacity,\n\t\tstrokeDash: item.strokeDash,\n\t};\n}\n\nfunction strokeOpacityAttr(style: StrokeStyle): string {\n\treturn style.strokeOpacity != null\n\t\t? ` stroke-opacity=\"${style.strokeOpacity}\"`\n\t\t: \"\";\n}\n\nfunction svgNumber(value: number): string {\n\tif (!Number.isFinite(value)) return \"0\";\n\tconst rounded = Math.round(value * 100) / 100;\n\treturn Number.isInteger(rounded) ? String(rounded) : String(rounded);\n}\n\nconst ARCHITECTURAL_CLOUD_RADIUS = 38;\nconst ARCHITECTURAL_CLOUD_TARGET_SPACING = 50;\nconst ARCHITECTURAL_CLOUD_FLAT_RADIUS_RATIO = 0.38;\nconst ARCHITECTURAL_CLOUD_ROUNDED_RADIUS = 72;\nconst ARCHITECTURAL_CLOUD_ROUNDED_MIN_RADIUS = 44;\nconst ARCHITECTURAL_CLOUD_ROUNDED_TARGET_SPACING = 98;\n\ntype CloudPoint = readonly [number, number];\n\ntype CloudPathSegment = {\n\tlength: number;\n\tpointAt: (t: number) => CloudPoint;\n};\n\nfunction architecturalCloudCenterCount(edgeLength: number, radius: number): number {\n\tconst targetSpacing = Math.min(\n\t\tARCHITECTURAL_CLOUD_TARGET_SPACING,\n\t\tMath.max(1, radius * 1.3),\n\t);\n\treturn Math.max(2, Math.round(edgeLength / targetSpacing) + 1);\n}\n\nfunction distributeRange(start: number, end: number, count: number): number[] {\n\tif (count <= 1) return [start];\n\tconst step = (end - start) / (count - 1);\n\treturn Array.from({ length: count }, (_, index) => start + step * index);\n}\n\nfunction lineCloudPathSegment(start: CloudPoint, end: CloudPoint): CloudPathSegment {\n\tconst dx = end[0] - start[0];\n\tconst dy = end[1] - start[1];\n\tconst length = Math.hypot(dx, dy);\n\treturn {\n\t\tlength,\n\t\tpointAt: (t) => [start[0] + dx * t, start[1] + dy * t],\n\t};\n}\n\nfunction ellipsePoint(\n\tcenterX: number,\n\tcenterY: number,\n\tradiusX: number,\n\tradiusY: number,\n\tangle: number,\n): CloudPoint {\n\treturn [centerX + Math.cos(angle) * radiusX, centerY + Math.sin(angle) * radiusY];\n}\n\nfunction approximateEllipseArcLength(\n\tradiusX: number,\n\tradiusY: number,\n\tstartAngle: number,\n\tendAngle: number,\n): number {\n\tconst steps = Math.max(\n\t\t4,\n\t\tMath.ceil(Math.abs(endAngle - startAngle) / (Math.PI / 16)),\n\t);\n\tlet length = 0;\n\tlet previous = ellipsePoint(0, 0, radiusX, radiusY, startAngle);\n\tfor (let index = 1; index <= steps; index += 1) {\n\t\tconst angle = startAngle + ((endAngle - startAngle) * index) / steps;\n\t\tconst next = ellipsePoint(0, 0, radiusX, radiusY, angle);\n\t\tlength += Math.hypot(next[0] - previous[0], next[1] - previous[1]);\n\t\tprevious = next;\n\t}\n\treturn length;\n}\n\nfunction ellipseCloudPathSegment(\n\tcenterX: number,\n\tcenterY: number,\n\tradiusX: number,\n\tradiusY: number,\n\tstartAngle: number,\n\tendAngle: number,\n): CloudPathSegment {\n\treturn {\n\t\tlength: approximateEllipseArcLength(radiusX, radiusY, startAngle, endAngle),\n\t\tpointAt: (t) =>\n\t\t\tellipsePoint(\n\t\t\t\tcenterX,\n\t\t\t\tcenterY,\n\t\t\t\tradiusX,\n\t\t\t\tradiusY,\n\t\t\t\tstartAngle + (endAngle - startAngle) * t,\n\t\t\t),\n\t};\n}\n\nfunction cloudPathPerimeter(segments: CloudPathSegment[]): number {\n\tconst usableSegments = segments.filter((segment) => segment.length > 1e-9);\n\treturn usableSegments.reduce((sum, segment) => sum + segment.length, 0);\n}\n\nfunction pointOnCloudPath(\n\tsegments: CloudPathSegment[],\n\tdistance: number,\n): CloudPoint {\n\tconst perimeter = cloudPathPerimeter(segments);\n\tif (perimeter <= 0) return [0, 0];\n\n\tlet remaining = ((distance % perimeter) + perimeter) % perimeter;\n\tfor (const segment of segments) {\n\t\tif (segment.length <= 1e-9) continue;\n\t\tif (remaining <= segment.length) {\n\t\t\tconst t = remaining / segment.length;\n\t\t\treturn segment.pointAt(t);\n\t\t}\n\t\tremaining -= segment.length;\n\t}\n\n\tconst fallback = segments.find((segment) => segment.length > 1e-9);\n\treturn fallback?.pointAt(0) ?? [0, 0];\n}\n\nfunction buildRoundedCapsulePathSegments(\n\twidth: number,\n\theight: number,\n\tinset: number,\n): CloudPathSegment[] {\n\tconst left = inset;\n\tconst top = inset;\n\tconst right = width - inset;\n\tconst bottom = height - inset;\n\tconst capsuleWidth = Math.max(0, right - left);\n\tconst capsuleHeight = Math.max(0, bottom - top);\n\tconst radius = Math.min(capsuleWidth, capsuleHeight) / 2;\n\tif (radius <= 0) return [];\n\n\tconst leftCenterX = left + radius;\n\tconst rightCenterX = right - radius;\n\tconst topCenterY = top + radius;\n\tconst bottomCenterY = bottom - radius;\n\n\treturn [\n\t\tlineCloudPathSegment([leftCenterX, top], [rightCenterX, top]),\n\t\tellipseCloudPathSegment(\n\t\t\trightCenterX,\n\t\t\ttopCenterY,\n\t\t\tradius,\n\t\t\tradius,\n\t\t\t-Math.PI / 2,\n\t\t\t0,\n\t\t),\n\t\tlineCloudPathSegment([right, topCenterY], [right, bottomCenterY]),\n\t\tellipseCloudPathSegment(\n\t\t\trightCenterX,\n\t\t\tbottomCenterY,\n\t\t\tradius,\n\t\t\tradius,\n\t\t\t0,\n\t\t\tMath.PI / 2,\n\t\t),\n\t\tlineCloudPathSegment([rightCenterX, bottom], [leftCenterX, bottom]),\n\t\tellipseCloudPathSegment(\n\t\t\tleftCenterX,\n\t\t\tbottomCenterY,\n\t\t\tradius,\n\t\t\tradius,\n\t\t\tMath.PI / 2,\n\t\t\tMath.PI,\n\t\t),\n\t\tlineCloudPathSegment([left, bottomCenterY], [left, topCenterY]),\n\t\tellipseCloudPathSegment(\n\t\t\tleftCenterX,\n\t\t\ttopCenterY,\n\t\t\tradius,\n\t\t\tradius,\n\t\t\tMath.PI,\n\t\t\tMath.PI * 1.5,\n\t\t),\n\t];\n}\n\nfunction buildRoundedArcCloudPathD(\n\tcloudWidth: number,\n\tcloudHeight: number,\n\tcenter: CloudPoint,\n): string {\n\tconst minDimension = Math.min(cloudWidth, cloudHeight);\n\tconst radius = Math.min(\n\t\tARCHITECTURAL_CLOUD_ROUNDED_RADIUS,\n\t\tMath.max(ARCHITECTURAL_CLOUD_ROUNDED_MIN_RADIUS, minDimension * 0.16),\n\t);\n\tconst centerPath = buildRoundedCapsulePathSegments(\n\t\tcloudWidth,\n\t\tcloudHeight,\n\t\tradius,\n\t);\n\tconst centerPerimeter = cloudPathPerimeter(centerPath);\n\tif (centerPerimeter <= 0) return \"\";\n\n\tconst lobeCount = Math.max(\n\t\t8,\n\t\tMath.round(centerPerimeter / ARCHITECTURAL_CLOUD_ROUNDED_TARGET_SPACING),\n\t);\n\tconst centers = Array.from({ length: lobeCount }, (_, index) =>\n\t\tpointOnCloudPath(centerPath, (centerPerimeter * index) / lobeCount),\n\t);\n\tconst points = centers.map((point, index) => {\n\t\tconst previous = centers[(index - 1 + centers.length) % centers.length] ?? point;\n\t\treturn cloudCircleIntersection(previous, point, radius, center);\n\t});\n\tconst [startX, startY] = points[0] ?? [0, 0];\n\tconst segments = [`M${svgNumber(startX)} ${svgNumber(startY)}`];\n\n\tfor (const [endX, endY] of points.slice(1)) {\n\t\tsegments.push(\n\t\t\t`A ${svgNumber(radius)} ${svgNumber(radius)} 0 0 1 ${svgNumber(endX)} ${svgNumber(endY)}`,\n\t\t);\n\t}\n\tsegments.push(\n\t\t`A ${svgNumber(radius)} ${svgNumber(radius)} 0 0 1 ${svgNumber(startX)} ${svgNumber(startY)}`,\n\t);\n\n\tsegments.push(\"Z\");\n\treturn segments.join(\" \");\n}\n\nfunction cloudCircleIntersection(\n\ta: CloudPoint,\n\tb: CloudPoint,\n\tradius: number,\n\tcenter: CloudPoint,\n): [number, number] {\n\tconst midX = (a[0] + b[0]) / 2;\n\tconst midY = (a[1] + b[1]) / 2;\n\tconst dx = b[0] - a[0];\n\tconst dy = b[1] - a[1];\n\tconst distance = Math.hypot(dx, dy);\n\tif (distance <= 1e-9) return [midX, midY];\n\n\tconst halfDistance = distance / 2;\n\tconst offset = Math.sqrt(\n\t\tMath.max(0, radius * radius - halfDistance * halfDistance),\n\t);\n\tconst normalX = -dy / distance;\n\tconst normalY = dx / distance;\n\tconst first: [number, number] = [midX + normalX * offset, midY + normalY * offset];\n\tconst second: [number, number] = [\n\t\tmidX - normalX * offset,\n\t\tmidY - normalY * offset,\n\t];\n\tconst firstDistance =\n\t\t(first[0] - center[0]) * (first[0] - center[0]) +\n\t\t(first[1] - center[1]) * (first[1] - center[1]);\n\tconst secondDistance =\n\t\t(second[0] - center[0]) * (second[0] - center[0]) +\n\t\t(second[1] - center[1]) * (second[1] - center[1]);\n\treturn firstDistance >= secondDistance ? first : second;\n}\n\nfunction cloudEllipseIntersection(\n\ta: CloudPoint,\n\tb: CloudPoint,\n\tradiusX: number,\n\tradiusY: number,\n\tcenter: CloudPoint,\n): [number, number] {\n\tconst scaleY = radiusX / radiusY;\n\tconst [x, y] = cloudCircleIntersection(\n\t\t[a[0], a[1] * scaleY],\n\t\t[b[0], b[1] * scaleY],\n\t\tradiusX,\n\t\t[center[0], center[1] * scaleY],\n\t);\n\treturn [x, y / scaleY];\n}\n\nexport function buildRectSvg(\n\twidth: number,\n\theight: number,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\treturn `<rect width=\"${width}\" height=\"${height}\" fill=\"none\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\" rx=\"4\"${strokeOpacityAttr(style)} />`;\n}\n\nexport function buildEllipseSvg(\n\twidth: number,\n\theight: number,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\tconst rx = width / 2;\n\tconst ry = height / 2;\n\treturn `<ellipse cx=\"${rx}\" cy=\"${ry}\" rx=\"${rx}\" ry=\"${ry}\" fill=\"none\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\"${strokeOpacityAttr(style)} />`;\n}\n\n/**\n * Returns the local SVG path for a scalable architectural revision cloud.\n *\n * Use this low-level helper when you need to preview or inspect the shape without\n * creating a full scene item. Prefer {@link createArchitecturalCloudItem} when\n * adding a cloud to a `VectorSceneItem[]`, because it keeps `toolKind`, bounds,\n * stroke fields, and `childrenSvg` synchronized for editing.\n *\n * @example\n * ```ts\n * const d = buildArchitecturalCloudPathD(180, 90);\n * ```\n */\nexport function buildArchitecturalCloudPathD(\n\twidth: number,\n\theight: number,\n\tstrokeWidth = DEFAULT_STROKE_STYLE.strokeWidth,\n): string {\n\tconst w = Math.max(0, width);\n\tconst h = Math.max(0, height);\n\tif (w <= 0 || h <= 0) return \"\";\n\n\tconst padding = Math.max(0, strokeWidth * 2);\n\tconst cloudWidth = Math.max(0, w - padding);\n\tconst cloudHeight = Math.max(0, h - padding);\n\tif (cloudWidth <= 0 || cloudHeight <= 0) return \"\";\n\n\tconst radiusX = Math.min(\n\t\tARCHITECTURAL_CLOUD_RADIUS,\n\t\tcloudWidth * ARCHITECTURAL_CLOUD_FLAT_RADIUS_RATIO,\n\t);\n\tconst radiusY = Math.min(\n\t\tARCHITECTURAL_CLOUD_RADIUS,\n\t\tcloudHeight * ARCHITECTURAL_CLOUD_FLAT_RADIUS_RATIO,\n\t);\n\tif (radiusX <= 0 || radiusY <= 0) return \"\";\n\n\tconst center: CloudPoint = [cloudWidth / 2, cloudHeight / 2];\n\tconst leftCenterX = radiusX;\n\tconst rightCenterX = cloudWidth - radiusX;\n\tconst topCenterY = radiusY;\n\tconst bottomCenterY = cloudHeight - radiusY;\n\tconst horizontalCenters = distributeRange(\n\t\tleftCenterX,\n\t\trightCenterX,\n\t\tarchitecturalCloudCenterCount(Math.max(0, rightCenterX - leftCenterX), radiusX),\n\t);\n\tconst verticalCenters = distributeRange(\n\t\ttopCenterY,\n\t\tbottomCenterY,\n\t\tarchitecturalCloudCenterCount(Math.max(0, bottomCenterY - topCenterY), radiusY),\n\t);\n\tif (horizontalCenters.length > 3 && verticalCenters.length > 3) {\n\t\tconst roundedArcCloudPath = buildRoundedArcCloudPathD(\n\t\t\tcloudWidth,\n\t\t\tcloudHeight,\n\t\t\tcenter,\n\t\t);\n\t\tif (roundedArcCloudPath !== \"\") return roundedArcCloudPath;\n\t}\n\tconst rectangularCenters: CloudPoint[] = [\n\t\t...horizontalCenters.map((x) => [x, topCenterY] as const),\n\t\t...verticalCenters.slice(1).map((y) => [rightCenterX, y] as const),\n\t\t...horizontalCenters\n\t\t\t.slice(0, -1)\n\t\t\t.reverse()\n\t\t\t.map((x) => [x, bottomCenterY] as const),\n\t\t...verticalCenters\n\t\t\t.slice(1, -1)\n\t\t\t.reverse()\n\t\t\t.map((y) => [leftCenterX, y] as const),\n\t];\n\tconst centers = rectangularCenters;\n\tconst points = centers.map((point, index) => {\n\t\tconst previous = centers[(index - 1 + centers.length) % centers.length] ?? point;\n\t\treturn cloudEllipseIntersection(previous, point, radiusX, radiusY, center);\n\t});\n\tconst [startX, startY] = points[0] ?? [0, 0];\n\tconst segments = [`M${svgNumber(startX)} ${svgNumber(startY)}`];\n\n\tfor (const [endX, endY] of points.slice(1)) {\n\t\tsegments.push(\n\t\t\t`A ${svgNumber(radiusX)} ${svgNumber(radiusY)} 0 0 1 ${svgNumber(endX)} ${svgNumber(endY)}`,\n\t\t);\n\t}\n\tsegments.push(\n\t\t`A ${svgNumber(radiusX)} ${svgNumber(radiusY)} 0 0 1 ${svgNumber(startX)} ${svgNumber(startY)}`,\n\t);\n\n\tsegments.push(\"Z\");\n\treturn segments.join(\" \");\n}\n\n/**\n * Builds an SVG fragment for an architectural revision cloud outline.\n *\n * This is the renderer-level primitive behind the built-in `\"architectural-cloud\"`\n * tool. Prefer {@link createArchitecturalCloudItem} for app code that inserts a\n * normal editable scene item.\n */\nexport function buildArchitecturalCloudSvg(\n\twidth: number,\n\theight: number,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\tconst d = buildArchitecturalCloudPathD(width, height, style.strokeWidth);\n\treturn `<path d=\"${d}\" fill=\"none\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\"${strokeOpacityAttr(style)} />`;\n}\n\nexport function buildLineSvg(\n\tline: LineEndpointsLocal,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\treturn `<line x1=\"${line.x1}\" y1=\"${line.y1}\" x2=\"${line.x2}\" y2=\"${line.y2}\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\"${strokeOpacityAttr(style)} />`;\n}\n\nexport type StraightArrowGeometry = {\n\tshaftEndX: number;\n\tshaftEndY: number;\n\theadTipX: number;\n\theadTipY: number;\n\theadLeftX: number;\n\theadLeftY: number;\n\theadRightX: number;\n\theadRightY: number;\n};\n\nexport function computeStraightArrowGeometry(\n\tline: LineEndpointsLocal,\n\tstrokeWidth: number,\n): StraightArrowGeometry | null {\n\tconst dx = line.x2 - line.x1;\n\tconst dy = line.y2 - line.y1;\n\tconst len = Math.hypot(dx, dy);\n\tif (len < 1e-6) return null;\n\tconst ux = dx / len;\n\tconst uy = dy / len;\n\tconst headLength = Math.min(Math.max(strokeWidth * 4.2, 12), len * 0.38);\n\tconst headAngle = Math.PI / 6;\n\tconst cos = Math.cos(headAngle);\n\tconst sin = Math.sin(headAngle);\n\tconst rx1 = ux * cos - uy * sin;\n\tconst ry1 = ux * sin + uy * cos;\n\tconst rx2 = ux * cos + uy * sin;\n\tconst ry2 = -ux * sin + uy * cos;\n\treturn {\n\t\tshaftEndX: line.x2,\n\t\tshaftEndY: line.y2,\n\t\theadTipX: line.x2,\n\t\theadTipY: line.y2,\n\t\theadLeftX: line.x2 - rx1 * headLength,\n\t\theadLeftY: line.y2 - ry1 * headLength,\n\t\theadRightX: line.x2 - rx2 * headLength,\n\t\theadRightY: line.y2 - ry2 * headLength,\n\t};\n}\n\nexport function buildArrowSvg(\n\titemId: string,\n\tline: LineEndpointsLocal,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\tvoid itemId;\n\tconst geometry = computeStraightArrowGeometry(line, style.strokeWidth);\n\tif (!geometry) {\n\t\treturn buildLineSvg(line, style);\n\t}\n\tconst op = strokeOpacityAttr(style);\n\treturn `\n\t\t<line x1=\"${line.x1}\" y1=\"${line.y1}\" x2=\"${geometry.shaftEndX}\" y2=\"${geometry.shaftEndY}\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\" stroke-linecap=\"round\"${op} />\n\t\t<path d=\"M ${geometry.headLeftX} ${geometry.headLeftY} L ${geometry.headTipX} ${geometry.headTipY} L ${geometry.headRightX} ${geometry.headRightY}\" fill=\"none\" stroke=\"${style.stroke}\" stroke-width=\"${style.strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" shape-rendering=\"geometricPrecision\"${op} />\n\t`;\n}\n\nexport function buildDrawDotSvg(\n\tr: number,\n\tstyle: StrokeStyle = DEFAULT_STROKE_STYLE,\n): string {\n\tconst op =\n\t\tstyle.strokeOpacity != null ? ` fill-opacity=\"${style.strokeOpacity}\"` : \"\";\n\treturn `<circle cx=\"${r}\" cy=\"${r}\" r=\"${r}\" fill=\"${style.stroke}\" shape-rendering=\"geometricPrecision\"${op} />`;\n}\n\n/** Structured result for React overlays; scene uses {@link buildFreehandPathSvg} string. */\nexport type FreehandSvgPayload =\n\t| {\n\t\t\tkind: \"circle\";\n\t\t\tcx: number;\n\t\t\tcy: number;\n\t\t\tr: number;\n\t\t\tfill: string;\n\t\t\tfillOpacity?: number;\n\t }\n\t| {\n\t\t\tkind: \"fillPath\";\n\t\t\td: string;\n\t\t\tfill: string;\n\t\t\tfillOpacity?: number;\n\t }\n\t| {\n\t\t\tkind: \"strokePath\";\n\t\t\td: string;\n\t\t\tstroke: string;\n\t\t\tstrokeWidth: number;\n\t\t\tstrokeOpacity?: number;\n\t\t\tstrokeDasharray?: string;\n\t };\n\nfunction dashArrayForDrawStroke(strokeWidth: number): string {\n\tconst dash = Math.max(strokeWidth * 1.8, 4);\n\tconst gap = Math.max(strokeWidth * 1.4, 3);\n\treturn `${dash} ${gap}`;\n}\n\nfunction buildSmoothedCenterlinePath(\n\tpoints: readonly { x: number; y: number }[],\n): string | null {\n\tif (points.length < 2) return null;\n\tconst first = points[0];\n\tif (!first) return null;\n\tlet d = `M ${first.x} ${first.y}`;\n\tfor (let i = 1; i < points.length - 1; i++) {\n\t\tconst a = points[i];\n\t\tconst b = points[i + 1];\n\t\tif (!a || !b) continue;\n\t\tconst midX = (a.x + b.x) / 2;\n\t\tconst midY = (a.y + b.y) / 2;\n\t\td += ` Q ${a.x} ${a.y} ${midX} ${midY}`;\n\t}\n\tconst last = points[points.length - 1];\n\tif (last) {\n\t\td += ` L ${last.x} ${last.y}`;\n\t}\n\treturn d;\n}\n\n/**\n * Computes freehand geometry (perfect-freehand + fallback). Used by {@link buildFreehandPathSvg}\n * and React overlays without `dangerouslySetInnerHTML`.\n */\nexport function computeFreehandSvgPayload(\n\tpathPointsLocal: readonly VectorPathPoint[],\n\tstyle: StrokeStyle,\n\ttoolKind: \"draw\" | \"pencil\" | \"brush\" | \"marker\",\n\tstrokeComplete = true,\n): FreehandSvgPayload | null {\n\tif (pathPointsLocal.length === 0) return null;\n\tif (pathPointsLocal.length === 1) {\n\t\tconst p = pathPointsLocal[0];\n\t\tif (!p) return null;\n\t\treturn {\n\t\t\tkind: \"circle\",\n\t\t\tcx: p.x,\n\t\t\tcy: p.y,\n\t\t\tr: Math.max(0.5, style.strokeWidth / 2),\n\t\t\tfill: style.stroke,\n\t\t\tfillOpacity: style.strokeOpacity,\n\t\t};\n\t}\n\tif (\n\t\tstyle.strokeDash === \"dashed\" &&\n\t\t(toolKind === \"draw\" || toolKind === \"pencil\")\n\t) {\n\t\tconst d = buildSmoothedCenterlinePath(pathPointsLocal);\n\t\tif (!d) return null;\n\t\treturn {\n\t\t\tkind: \"strokePath\",\n\t\t\td,\n\t\t\tstroke: style.stroke,\n\t\t\tstrokeWidth: style.strokeWidth,\n\t\t\tstrokeOpacity: style.strokeOpacity,\n\t\t\tstrokeDasharray: dashArrayForDrawStroke(style.strokeWidth),\n\t\t};\n\t}\n\tconst hasPressure = pathPointsLocal.some(\n\t\t(p) => p.pressure != null && Number.isFinite(p.pressure),\n\t);\n\tconst input = hasPressure\n\t\t? pathPointsLocal.map(\n\t\t\t\t(p) =>\n\t\t\t\t\t[p.x, p.y, Math.min(1, Math.max(0, p.pressure ?? 0.5))] as [\n\t\t\t\t\t\tnumber,\n\t\t\t\t\t\tnumber,\n\t\t\t\t\t\tnumber,\n\t\t\t\t\t],\n\t\t\t)\n\t\t: pathPointsLocal.map((p) => [p.x, p.y] as [number, number]);\n\tconst stroke = getStroke(\n\t\tinput,\n\t\tperfectFreehandOptions(toolKind, style, strokeComplete, hasPressure),\n\t);\n\tif (stroke.length < 3) return null;\n\tconst first = stroke[0];\n\tif (!first) return null;\n\tlet d = `M ${first[0]} ${first[1]} Q`;\n\tfor (let i = 0; i < stroke.length; i++) {\n\t\tconst a = stroke[i];\n\t\tconst b = stroke[(i + 1) % stroke.length];\n\t\tif (!a || !b) continue;\n\t\td += ` ${a[0]} ${a[1]} ${(a[0] + b[0]) / 2} ${(a[1] + b[1]) / 2}`;\n\t}\n\td += \" Z\";\n\treturn {\n\t\tkind: \"fillPath\",\n\t\td,\n\t\tfill: style.stroke,\n\t\tfillOpacity: style.strokeOpacity,\n\t};\n}\n\nfunction freehandPayloadToSvgString(payload: FreehandSvgPayload): string {\n\tif (payload.kind === \"circle\") {\n\t\tconst op =\n\t\t\tpayload.fillOpacity != null ? ` fill-opacity=\"${payload.fillOpacity}\"` : \"\";\n\t\treturn `<circle cx=\"${payload.cx}\" cy=\"${payload.cy}\" r=\"${payload.r}\" fill=\"${payload.fill}\" shape-rendering=\"geometricPrecision\"${op} />`;\n\t}\n\tif (payload.kind === \"fillPath\") {\n\t\tconst op =\n\t\t\tpayload.fillOpacity != null ? ` fill-opacity=\"${payload.fillOpacity}\"` : \"\";\n\t\treturn `<path d=\"${payload.d}\" fill=\"${payload.fill}\" fill-rule=\"nonzero\" stroke=\"none\"${op} shape-rendering=\"geometricPrecision\" />`;\n\t}\n\tconst op = strokeOpacityAttr({\n\t\tstroke: payload.stroke,\n\t\tstrokeWidth: payload.strokeWidth,\n\t\tstrokeOpacity: payload.strokeOpacity,\n\t});\n\tconst dash = payload.strokeDasharray\n\t\t? ` stroke-dasharray=\"${payload.strokeDasharray}\"`\n\t\t: \"\";\n\treturn `<path d=\"${payload.d}\" fill=\"none\" stroke=\"${payload.stroke}\" stroke-width=\"${payload.strokeWidth}\" stroke-linecap=\"round\" stroke-linejoin=\"round\" shape-rendering=\"geometricPrecision\"${op}${dash} />`;\n}\n\n/**\n * Freehand stroke in local coordinates using [perfect-freehand](https://github.com/steveruizok/perfect-freehand)\n * (filled outline, tapered caps — similar spirit to tldraw / Excalidraw ink).\n */\nexport function buildFreehandPathSvg(\n\tpathPointsLocal: readonly { x: number; y: number }[],\n\tstyle: StrokeStyle,\n\ttoolKind: \"draw\" | \"pencil\" | \"brush\" | \"marker\",\n\tstrokeComplete = true,\n): string {\n\tconst payload = computeFreehandSvgPayload(\n\t\tpathPointsLocal,\n\t\tstyle,\n\t\ttoolKind,\n\t\tstrokeComplete,\n\t);\n\tif (!payload) return \"\";\n\treturn freehandPayloadToSvgString(payload);\n}\n\n/**\n * Creates a new unique id for a shape (for `VectorSceneItem.id` when adding from code or API).\n */\nexport function createShapeId(): string {\n\tconst uid =\n\t\ttypeof crypto !== \"undefined\" && crypto.randomUUID\n\t\t\t? crypto.randomUUID()\n\t\t\t: String(Date.now());\n\treturn `user-shape-${uid}`;\n}\n\n/**\n * Converts line segment endpoints from **world** coordinates to **local** coordinates\n * (origin = top-left of `bounds`). Use with {@link createLineItem}.\n */\nexport function lineEndpointsToLocal(\n\tbounds: Rect,\n\tworldEndA: { x: number; y: number },\n\tworldEndB: { x: number; y: number },\n): LineEndpointsLocal {\n\tconst b = normalizeRect(bounds);\n\treturn {\n\t\tx1: worldEndA.x - b.x,\n\t\ty1: worldEndA.y - b.y,\n\t\tx2: worldEndB.x - b.x,\n\t\ty2: worldEndB.y - b.y,\n\t};\n}\n\n/**\n * Rebuilds the SVG fragment (`childrenSvg`) from geometry + stroke fields (after edits or resize).\n */\nexport function rebuildItemSvg(item: VectorSceneItem): VectorSceneItem {\n\tconst style = resolveStrokeStyle(item);\n\tconst k = item.toolKind;\n\n\tif (k === \"rect\") {\n\t\tconst b = normalizeRect(item.bounds);\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildRectSvg(b.width, b.height, style),\n\t\t};\n\t}\n\tif (k === \"ellipse\") {\n\t\tconst b = normalizeRect(item.bounds);\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildEllipseSvg(b.width, b.height, style),\n\t\t};\n\t}\n\tif (k === \"architectural-cloud\") {\n\t\tconst b = normalizeRect(item.bounds);\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildArchitecturalCloudSvg(b.width, b.height, style),\n\t\t};\n\t}\n\tif ((k === \"line\" || k === \"arrow\") && item.line) {\n\t\tconst line = item.line;\n\t\tconst childrenSvg =\n\t\t\tk === \"arrow\"\n\t\t\t\t? buildArrowSvg(item.id, line, style)\n\t\t\t\t: buildLineSvg(line, style);\n\t\treturn { ...item, childrenSvg };\n\t}\n\tif (k === \"text\" && item.text !== undefined) {\n\t\tconst fs = item.textFontSize ?? DEFAULT_TEXT_FONT_SIZE;\n\t\tif (item.textFixedBounds) {\n\t\t\tconst b = normalizeRect(item.bounds);\n\t\t\treturn {\n\t\t\t\t...item,\n\t\t\t\tx: b.x,\n\t\t\t\ty: b.y,\n\t\t\t\tbounds: b,\n\t\t\t\tchildrenSvg: buildTextFixedBoundsSvg(\n\t\t\t\t\titem.text,\n\t\t\t\t\tb.width,\n\t\t\t\t\tb.height,\n\t\t\t\t\tstyle.stroke,\n\t\t\t\t\tfs,\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t\tconst m = measureTextBoundsLocal(item.text, fs);\n\t\tconst b = normalizeRect({\n\t\t\tx: item.x,\n\t\t\ty: item.y,\n\t\t\twidth: m.width,\n\t\t\theight: m.height,\n\t\t});\n\t\treturn {\n\t\t\t...item,\n\t\t\tx: b.x,\n\t\t\ty: b.y,\n\t\t\tbounds: b,\n\t\t\tchildrenSvg: buildTextSvg(item.text, b.width, b.height, style.stroke, fs),\n\t\t};\n\t}\n\tif (\n\t\t(k === \"draw\" || k === \"pencil\" || k === \"brush\" || k === \"marker\") &&\n\t\titem.pathPointsLocal &&\n\t\titem.pathPointsLocal.length > 0\n\t) {\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildFreehandPathSvg(item.pathPointsLocal, style, k),\n\t\t};\n\t}\n\tif (k === \"draw\") {\n\t\tconst b = normalizeRect(item.bounds);\n\t\tconst r = Math.min(b.width, b.height) / 2;\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildDrawDotSvg(r, style),\n\t\t};\n\t}\n\tif (k === \"image\" && item.imageRasterHref && item.imageIntrinsicSize) {\n\t\tconst b = normalizeRect(item.bounds);\n\t\treturn {\n\t\t\t...item,\n\t\t\tchildrenSvg: buildRasterImageChildrenSvg(\n\t\t\t\titem.imageRasterHref,\n\t\t\t\titem.imageIntrinsicSize,\n\t\t\t\tb,\n\t\t\t),\n\t\t};\n\t}\n\tif (k === \"custom\" && item.customIntrinsicSize && item.customInnerSvg) {\n\t\tconst b = normalizeRect(item.bounds);\n\t\treturn {\n\t\t\t...item,\n\t\t\tx: b.x,\n\t\t\ty: b.y,\n\t\t\tbounds: b,\n\t\t\tchildrenSvg: buildCustomShapeChildrenSvg(\n\t\t\t\titem.customInnerSvg,\n\t\t\t\titem.customIntrinsicSize,\n\t\t\t\tb,\n\t\t\t),\n\t\t};\n\t}\n\n\treturn item;\n}\n\n/** Updates stroke color / width / opacity and refreshes the item’s SVG. */\nexport function applyStrokeToItem(\n\titem: VectorSceneItem,\n\tpatch: Partial<\n\t\tPick<\n\t\t\tVectorSceneItem,\n\t\t\t\"stroke\" | \"strokeWidth\" | \"strokeOpacity\" | \"strokeDash\" | \"textFontSize\"\n\t\t>\n\t>,\n): VectorSceneItem {\n\treturn rebuildItemSvg({ ...item, ...patch });\n}\n\n/** Creates a rectangle shape ready to append to your scene `items` array. */\nexport function createRectangleItem(\n\tid: string,\n\tbounds: Rect,\n\tstyle?: Partial<StrokeStyle>,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"rect\",\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/** Creates an ellipse shape. */\nexport function createEllipseItem(\n\tid: string,\n\tbounds: Rect,\n\tstyle?: Partial<StrokeStyle>,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"ellipse\",\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/**\n * Creates an architectural revision cloud shape.\n *\n * Use this high-level builder when adding the built-in cloud shape from code or\n * from custom integrations. It creates an editable `VectorSceneItem` with\n * `toolKind: \"architectural-cloud\"`, so resize, stroke styling, selection, and\n * serialization continue to work like the built-in rectangle and ellipse tools.\n *\n * @example\n * ```ts\n * const cloud = createArchitecturalCloudItem(createShapeId(), {\n * x: 40,\n * y: 30,\n * width: 180,\n * height: 90,\n * });\n * ```\n */\nexport function createArchitecturalCloudItem(\n\tid: string,\n\tbounds: Rect,\n\tstyle?: Partial<StrokeStyle>,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"architectural-cloud\",\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/** Creates a straight line or arrow; `line` is usually from {@link lineEndpointsToLocal}. */\nexport function createLineItem(\n\tid: string,\n\tbounds: Rect,\n\tline: LineEndpointsLocal,\n\ttoolKind: \"line\" | \"arrow\",\n\tstyle?: Partial<StrokeStyle>,\n\tarrowBind?: ArrowBindings,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind,\n\t\tline: { ...line },\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\t...(arrowBind ? { arrowBind } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/** “Draw dot” tool: a small filled circle at (`worldX`, `worldY`). */\nexport function createDrawDotItem(\n\tid: string,\n\tworldX: number,\n\tworldY: number,\n\tradius: number,\n\tstyle?: Partial<StrokeStyle>,\n): VectorSceneItem {\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: worldX - radius,\n\t\ty: worldY - radius,\n\t\tbounds: {\n\t\t\tx: worldX - radius,\n\t\t\ty: worldY - radius,\n\t\t\twidth: radius * 2,\n\t\t\theight: radius * 2,\n\t\t},\n\t\ttoolKind: \"draw\",\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/** Creates an editable text box (`stroke` is used as text fill). */\nexport function createTextItem(\n\tid: string,\n\tbounds: Rect,\n\ttext = \"\",\n\tstyle?: Partial<StrokeStyle>,\n\ttextFontSize?: number,\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst s = { ...DEFAULT_STROKE_STYLE, ...style };\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"text\",\n\t\ttext,\n\t\tstroke: s.stroke,\n\t\tstrokeWidth: s.strokeWidth,\n\t\t...(s.strokeOpacity != null ? { strokeOpacity: s.strokeOpacity } : {}),\n\t\t...(textFontSize != null ? { textFontSize } : {}),\n\t\tchildrenSvg: \"\",\n\t});\n}\n\n/** Freehand stroke from world-space points (main pen or marker highlight). */\nexport function createFreehandStrokeItem(\n\tid: string,\n\tpointsWorld: readonly VectorPathPoint[],\n\ttoolKind: \"draw\" | \"marker\",\n\tstyle?: Partial<StrokeStyle>,\n): VectorSceneItem | null {\n\tif (pointsWorld.length === 0) return null;\n\n\tconst merged: StrokeStyle = {\n\t\t...DEFAULT_STROKE_STYLE,\n\t\t...TOOL_FREEHAND_DEFAULTS[toolKind],\n\t\t...style,\n\t};\n\n\tconst sw = merged.strokeWidth;\n\t/** Filled outline extends ~size/2 past the polyline; keep generous padding to avoid clipping. */\n\tconst pad = Math.max(sw * 0.75 + 4, sw / 2 + 6);\n\tconst xs = pointsWorld.map((p) => p.x);\n\tconst ys = pointsWorld.map((p) => p.y);\n\tconst minX = Math.min(...xs);\n\tconst maxX = Math.max(...xs);\n\tconst minY = Math.min(...ys);\n\tconst maxY = Math.max(...ys);\n\n\tconst x = minX - pad;\n\tconst y = minY - pad;\n\tconst w = Math.max(maxX - minX + 2 * pad, sw);\n\tconst h = Math.max(maxY - minY + 2 * pad, sw);\n\n\tconst pathPointsLocal = pointsWorld.map((p) => ({\n\t\tx: p.x - x,\n\t\ty: p.y - y,\n\t\t...(p.pressure != null ? { pressure: p.pressure } : {}),\n\t}));\n\n\treturn rebuildItemSvg({\n\t\tid,\n\t\tx,\n\t\ty,\n\t\tbounds: { x, y, width: w, height: h },\n\t\ttoolKind,\n\t\tstroke: merged.stroke,\n\t\tstrokeWidth: merged.strokeWidth,\n\t\t...(merged.strokeOpacity != null ? { strokeOpacity: merged.strokeOpacity } : {}),\n\t\t...(merged.strokeDash != null ? { strokeDash: merged.strokeDash } : {}),\n\t\tpathPointsLocal,\n\t\tchildrenSvg: \"\",\n\t});\n}\n\nfunction escapeSvgAttr(s: string): string {\n\treturn s.replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\").replace(/</g, \"&lt;\");\n}\n\n/**\n * Builds `<g><image href=\"data:...\"/></g>` inside `bounds` from intrinsic pixel dimensions.\n * When bounds match intrinsic aspect (normal after aspect-locked resize), uses a uniform **fill** scale.\n * Otherwise uses **contain** + center for legacy or pasted rects with wrong proportion.\n */\nexport function buildRasterImageChildrenSvg(\n\tdataUrl: string,\n\tintrinsic: { width: number; height: number },\n\tbounds: Rect,\n): string {\n\tconst r = normalizeRect(bounds);\n\tconst iw = Math.max(1e-6, intrinsic.width);\n\tconst ih = Math.max(1e-6, intrinsic.height);\n\tconst href = escapeSvgAttr(dataUrl);\n\tconst arB = r.width / Math.max(1e-9, r.height);\n\tconst arI = iw / ih;\n\tif (Math.abs(arB - arI) < 1e-3) {\n\t\tconst s = r.width / iw;\n\t\treturn `<g transform=\"scale(${s})\"><image href=\"${href}\" x=\"0\" y=\"0\" width=\"${iw}\" height=\"${ih}\" /></g>`;\n\t}\n\tconst s = Math.min(r.width / iw, r.height / ih);\n\tconst tx = (r.width - iw * s) / 2;\n\tconst ty = (r.height - ih * s) / 2;\n\treturn `<g transform=\"translate(${tx}, ${ty}) scale(${s})\"><image href=\"${href}\" x=\"0\" y=\"0\" width=\"${iw}\" height=\"${ih}\" /></g>`;\n}\n\n/** Places a bitmap (e.g. `data:image/png;base64,...`) inside `bounds`. */\nexport function createImageItem(\n\tid: string,\n\tbounds: Rect,\n\timageRasterHref: string,\n\timageIntrinsicSize: { width: number; height: number },\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst iw = Math.max(1e-6, imageIntrinsicSize.width);\n\tconst ih = Math.max(1e-6, imageIntrinsicSize.height);\n\treturn {\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"image\",\n\t\timageRasterHref,\n\t\timageIntrinsicSize: { width: iw, height: ih },\n\t\tchildrenSvg: buildRasterImageChildrenSvg(\n\t\t\timageRasterHref,\n\t\t\t{ width: iw, height: ih },\n\t\t\tr,\n\t\t),\n\t};\n}\n\n/** @internal Legacy traced path content — prefer {@link createImageItem} with a raster data URL. */\nexport function createImageFromVectorTrace(\n\tid: string,\n\tbounds: Rect,\n\timageVectorInnerSvg: string,\n\timageVectorLocalSize: { width: number; height: number },\n): VectorSceneItem {\n\tconst r = normalizeRect(bounds);\n\tconst lw = Math.max(1e-6, imageVectorLocalSize.width);\n\tconst lh = Math.max(1e-6, imageVectorLocalSize.height);\n\tconst arB = r.width / Math.max(1e-9, r.height);\n\tconst arI = lw / lh;\n\tlet childrenSvg: string;\n\tif (Math.abs(arB - arI) < 1e-3) {\n\t\tconst s = r.width / lw;\n\t\tchildrenSvg = `<g transform=\"scale(${s})\">${imageVectorInnerSvg}</g>`;\n\t} else {\n\t\tconst s = Math.min(r.width / lw, r.height / lh);\n\t\tconst tx = (r.width - lw * s) / 2;\n\t\tconst ty = (r.height - lh * s) / 2;\n\t\tchildrenSvg = `<g transform=\"translate(${tx}, ${ty}) scale(${s})\">${imageVectorInnerSvg}</g>`;\n\t}\n\treturn {\n\t\tid,\n\t\tx: r.x,\n\t\ty: r.y,\n\t\tbounds: { ...r },\n\t\ttoolKind: \"image\",\n\t\timageVectorInnerSvg,\n\t\timageVectorLocalSize: { width: lw, height: lh },\n\t\tchildrenSvg,\n\t};\n}\n","/**\n * Deterministic accent from a peer id when `color` is not provided.\n */\nexport function defaultPresenceColorForId(id: string): string {\n\tlet h = 2166136261;\n\tfor (let i = 0; i < id.length; i++) {\n\t\th ^= id.charCodeAt(i);\n\t\th = Math.imul(h, 16777619);\n\t}\n\tconst hue = (h >>> 0) % 360;\n\treturn `hsl(${hue} 72% 42%)`;\n}\n","\"use client\";\n\nimport { MousePointer2 } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport type { Camera2D } from \"../../camera/camera\";\nimport { formatCameraTransform } from \"../../renderer/svg-vector-renderer\";\nimport { smoothFreehandPointsToPathD } from \"../../scene/freehand-path\";\nimport {\n\tcomputeFreehandSvgPayload,\n\ttype StrokeStyle,\n} from \"../../scene/shape-builders\";\nimport { defaultPresenceColorForId } from \"./peer-color\";\nimport type { RemotePresenceMarkupStroke, RemotePresencePeer } from \"./types\";\n\nfunction strokePaint(\n\ttool: RemotePresenceMarkupStroke[\"tool\"],\n\tfallback: string,\n): { stroke: string; strokeOpacity: number; widthWorld: number } {\n\tswitch (tool) {\n\t\tcase \"laser\":\n\t\t\treturn { stroke: \"#f43f5e\", strokeOpacity: 0.92, widthWorld: 4 };\n\t\tcase \"marker\":\n\t\t\treturn { stroke: fallback, strokeOpacity: 0.45, widthWorld: 14 };\n\t\tcase \"brush\":\n\t\t\treturn { stroke: fallback, strokeOpacity: 0.85, widthWorld: 5 };\n\t\tcase \"pencil\":\n\t\t\treturn { stroke: fallback, strokeOpacity: 0.9, widthWorld: 2.5 };\n\t\tdefault:\n\t\t\treturn { stroke: fallback, strokeOpacity: 0.95, widthWorld: 3.5 };\n\t}\n}\n\nfunction isFreehandTool(\n\ttool: RemotePresenceMarkupStroke[\"tool\"],\n): tool is \"draw\" | \"marker\" | \"pencil\" | \"brush\" {\n\treturn (\n\t\ttool === \"draw\" || tool === \"marker\" || tool === \"pencil\" || tool === \"brush\"\n\t);\n}\n\nexport type PresenceRemoteLayerProps = {\n\tcamera: Camera2D;\n\t/** Bump when camera changes (same as {@link InteractionOverlay}). */\n\tcameraVersion: number;\n\tpeers: readonly RemotePresencePeer[];\n};\n\n/**\n * World-space SVG overlay: remote cursors + in-progress markup strokes.\n * Usually passed via {@link VectorViewport} `remotePresence` or `presenceOverlay`.\n */\nexport function PresenceRemoteLayer({\n\tcamera,\n\tcameraVersion: _cameraVersion,\n\tpeers,\n}: PresenceRemoteLayerProps) {\n\tvoid _cameraVersion;\n\tconst z = camera.zoom;\n\tconst rootTransform = formatCameraTransform(camera);\n\tconst overlayStrokePx = 1.25;\n\t/** Lucide `MousePointer2` viewBox; tip ≈ this point in icon space (see lucide `mouse-pointer-2`). */\n\tconst LUCIDE_POINTER_VIEWBOX = 24;\n\tconst LUCIDE_POINTER_TIP_X = 4.037;\n\tconst LUCIDE_POINTER_TIP_Y = 4.688;\n\t/** Target on-screen size (~px); scale in world space so it stays constant when zooming. */\n\tconst remoteCursorScreenPx = 22;\n\tconst iconWorldScale = remoteCursorScreenPx / (LUCIDE_POINTER_VIEWBOX * z);\n\n\treturn (\n\t\t<svg\n\t\t\tstyle={{\n\t\t\t\tposition: \"absolute\",\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\tright: 0,\n\t\t\t\tbottom: 0,\n\t\t\t\tzIndex: 9,\n\t\t\t\twidth: \"100%\",\n\t\t\t\theight: \"100%\",\n\t\t\t\ttouchAction: \"none\",\n\t\t\t\tpointerEvents: \"none\",\n\t\t\t}}\n\t\t\trole=\"presentation\"\n\t\t\taria-hidden\n\t\t\twidth=\"100%\"\n\t\t\theight=\"100%\"\n\t\t>\n\t\t\t<g transform={rootTransform}>\n\t\t\t\t{peers.map((peer) => {\n\t\t\t\t\tconst color = peer.color ?? defaultPresenceColorForId(peer.id);\n\t\t\t\t\tconst markup = peer.markupStroke;\n\t\t\t\t\tlet strokeNode: ReactNode = null;\n\t\t\t\t\tif (markup && markup.points.length > 0) {\n\t\t\t\t\t\tconst fallbackPaint = strokePaint(markup.tool, color);\n\t\t\t\t\t\tconst paint = {\n\t\t\t\t\t\t\tstroke: markup.stroke ?? fallbackPaint.stroke,\n\t\t\t\t\t\t\tstrokeOpacity: markup.strokeOpacity ?? fallbackPaint.strokeOpacity,\n\t\t\t\t\t\t\twidthWorld: markup.strokeWidth ?? fallbackPaint.widthWorld,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (markup.tool === \"laser\") {\n\t\t\t\t\t\t\tconst d =\n\t\t\t\t\t\t\t\tmarkup.points.length >= 2\n\t\t\t\t\t\t\t\t\t? smoothFreehandPointsToPathD([...markup.points])\n\t\t\t\t\t\t\t\t\t: null;\n\t\t\t\t\t\t\tif (d) {\n\t\t\t\t\t\t\t\tstrokeNode = (\n\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\td={d}\n\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\tstroke={paint.stroke}\n\t\t\t\t\t\t\t\t\t\tstrokeOpacity={paint.strokeOpacity}\n\t\t\t\t\t\t\t\t\t\tstrokeWidth={Math.max(paint.widthWorld / z, overlayStrokePx)}\n\t\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\tshapeRendering=\"geometricPrecision\"\n\t\t\t\t\t\t\t\t\t\tvectorEffect=\"non-scaling-stroke\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (isFreehandTool(markup.tool)) {\n\t\t\t\t\t\t\tconst style: StrokeStyle = {\n\t\t\t\t\t\t\t\tstroke: paint.stroke,\n\t\t\t\t\t\t\t\tstrokeWidth: paint.widthWorld,\n\t\t\t\t\t\t\t\t...(paint.strokeOpacity != null\n\t\t\t\t\t\t\t\t\t? { strokeOpacity: paint.strokeOpacity }\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tconst payload = computeFreehandSvgPayload(\n\t\t\t\t\t\t\t\tmarkup.points.map((p) => ({ x: p.x, y: p.y })),\n\t\t\t\t\t\t\t\tstyle,\n\t\t\t\t\t\t\t\tmarkup.tool,\n\t\t\t\t\t\t\t\tmarkup.points.length === 2,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (payload?.kind === \"circle\") {\n\t\t\t\t\t\t\t\tstrokeNode = (\n\t\t\t\t\t\t\t\t\t<circle\n\t\t\t\t\t\t\t\t\t\tcx={payload.cx}\n\t\t\t\t\t\t\t\t\t\tcy={payload.cy}\n\t\t\t\t\t\t\t\t\t\tr={payload.r}\n\t\t\t\t\t\t\t\t\t\tfill={payload.fill}\n\t\t\t\t\t\t\t\t\t\t{...(payload.fillOpacity != null\n\t\t\t\t\t\t\t\t\t\t\t? { fillOpacity: payload.fillOpacity }\n\t\t\t\t\t\t\t\t\t\t\t: {})}\n\t\t\t\t\t\t\t\t\t\tshapeRendering=\"geometricPrecision\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else if (payload?.kind === \"fillPath\") {\n\t\t\t\t\t\t\t\tstrokeNode = (\n\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\td={payload.d}\n\t\t\t\t\t\t\t\t\t\tfill={payload.fill}\n\t\t\t\t\t\t\t\t\t\tfillRule=\"nonzero\"\n\t\t\t\t\t\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t\t\t\t\t\t{...(payload.fillOpacity != null\n\t\t\t\t\t\t\t\t\t\t\t? { fillOpacity: payload.fillOpacity }\n\t\t\t\t\t\t\t\t\t\t\t: {})}\n\t\t\t\t\t\t\t\t\t\tshapeRendering=\"geometricPrecision\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} else if (payload?.kind === \"strokePath\") {\n\t\t\t\t\t\t\t\tstrokeNode = (\n\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\td={payload.d}\n\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\tstroke={payload.stroke}\n\t\t\t\t\t\t\t\t\t\tstrokeWidth={payload.strokeWidth}\n\t\t\t\t\t\t\t\t\t\t{...(payload.strokeOpacity != null\n\t\t\t\t\t\t\t\t\t\t\t? { strokeOpacity: payload.strokeOpacity }\n\t\t\t\t\t\t\t\t\t\t\t: {})}\n\t\t\t\t\t\t\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\t\t\t\t\t\t\tstrokeLinejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\tshapeRendering=\"geometricPrecision\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst cur = peer.cursor;\n\t\t\t\t\tlet cursorNode: ReactNode = null;\n\t\t\t\t\tif (cur) {\n\t\t\t\t\t\tconst displayName = peer.displayName;\n\t\t\t\t\t\tconst labelOffsetX = 14 / z;\n\t\t\t\t\t\tconst labelOffsetY = 14 / z;\n\t\t\t\t\t\tconst labelFont = 12 / z;\n\t\t\t\t\t\tcursorNode = (\n\t\t\t\t\t\t\t<g>\n\t\t\t\t\t\t\t\t<g\n\t\t\t\t\t\t\t\t\ttransform={`translate(${cur.x}, ${cur.y}) scale(${iconWorldScale}) translate(${-LUCIDE_POINTER_TIP_X}, ${-LUCIDE_POINTER_TIP_Y})`}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<MousePointer2\n\t\t\t\t\t\t\t\t\t\tsize={LUCIDE_POINTER_VIEWBOX}\n\t\t\t\t\t\t\t\t\t\tcolor={color}\n\t\t\t\t\t\t\t\t\t\tfill={color}\n\t\t\t\t\t\t\t\t\t\tstroke=\"none\"\n\t\t\t\t\t\t\t\t\t\taria-hidden\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t\t\t{displayName ? (\n\t\t\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t\t\tx={cur.x + labelOffsetX}\n\t\t\t\t\t\t\t\t\t\ty={cur.y + labelOffsetY}\n\t\t\t\t\t\t\t\t\t\tfill={color}\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tfontSize: labelFont,\n\t\t\t\t\t\t\t\t\t\t\tfontFamily: \"system-ui, sans-serif\",\n\t\t\t\t\t\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tvectorEffect=\"non-scaling-stroke\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{displayName}\n\t\t\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<g key={peer.id}>\n\t\t\t\t\t\t\t{strokeNode}\n\t\t\t\t\t\t\t{cursorNode}\n\t\t\t\t\t\t</g>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</g>\n\t\t</svg>\n\t);\n}\n","import type { VectorSceneItem } from \"../../../scene/types\";\nimport type {\n\tRealtimeConnectionState,\n\tRemotePresenceCamera,\n\tRemotePresenceMarkupStroke,\n\tRemotePresencePeer,\n} from \"../../presence/types\";\n\nexport type RealtimeSessionPeer = RemotePresencePeer & {\n\treadonly clientId: string;\n\treadonly peerId: string;\n\treadonly roomId: string;\n\treadonly joinedAt: number;\n\treadonly lastSeenAt: number;\n\treadonly isSelf: boolean;\n\treadonly connectionState?: RealtimeConnectionState;\n};\n\nexport type RealtimeDocumentSnapshot = {\n\treadonly revision: number;\n\treadonly items: VectorSceneItem[];\n\treadonly updatedAt: number;\n\treadonly updatedByClientId?: string;\n};\n\nexport type RealtimeConnectionInfo = {\n\treadonly state: RealtimeConnectionState;\n\treadonly connected: boolean;\n\treadonly roomId: string;\n\treadonly clientId: string | null;\n\treadonly retryCount: number;\n\treadonly lastConnectedAt: number | null;\n\treadonly lastMessageAt: number | null;\n\treadonly lastPongAt: number | null;\n\treadonly lastError: string | null;\n};\n\nexport type RealtimePresencePayload = {\n\treadonly cursor: { readonly x: number; readonly y: number } | null;\n\treadonly markupStroke?: RemotePresenceMarkupStroke | null;\n\treadonly camera?: RemotePresenceCamera | null;\n\treadonly activeTool?: string;\n};\n\nexport type RealtimeClientPeer = {\n\treadonly clientId: string;\n\treadonly peerId: string;\n\treadonly displayName?: string;\n\treadonly color?: string;\n\treadonly image?: string;\n};\n\nexport type RealtimeClientMessage =\n\t| {\n\t\t\treadonly type: \"session:join\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly peer: RealtimeClientPeer;\n\t }\n\t| {\n\t\t\treadonly type: \"session:leave\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t }\n\t| {\n\t\t\treadonly type: \"session:ping\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t\t\treadonly sentAt: number;\n\t }\n\t| {\n\t\t\treadonly type: \"presence:update\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t\t\treadonly presence: RealtimePresencePayload;\n\t }\n\t| {\n\t\t\treadonly type: \"document:update\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t\t\treadonly baseRevision: number;\n\t\t\treadonly items: VectorSceneItem[];\n\t };\n\nexport type RealtimeServerMessage =\n\t| {\n\t\t\treadonly type: \"session:welcome\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t\t\treadonly serverTime: number;\n\t\t\treadonly document: RealtimeDocumentSnapshot;\n\t\t\treadonly peers: RealtimeSessionPeer[];\n\t }\n\t| {\n\t\t\treadonly type: \"session:peer-joined\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly peer: RealtimeSessionPeer;\n\t }\n\t| {\n\t\t\treadonly type: \"session:peer-left\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t }\n\t| {\n\t\t\treadonly type: \"session:pong\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly clientId: string;\n\t\t\treadonly sentAt: number;\n\t\t\treadonly serverTime: number;\n\t }\n\t| {\n\t\t\treadonly type: \"session:error\";\n\t\t\treadonly roomId?: string;\n\t\t\treadonly code: string;\n\t\t\treadonly message: string;\n\t }\n\t| {\n\t\t\treadonly type: \"presence:sync\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly peers: RealtimeSessionPeer[];\n\t\t\treadonly serverTime: number;\n\t }\n\t| {\n\t\t\treadonly type: \"document:sync\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly document: RealtimeDocumentSnapshot;\n\t }\n\t| {\n\t\t\treadonly type: \"document:resync-required\";\n\t\t\treadonly roomId: string;\n\t\t\treadonly reason: string;\n\t\t\treadonly document: RealtimeDocumentSnapshot;\n\t };\n\ntype UnknownRecord = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction getString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction getNumber(value: unknown): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction parseCursor(value: unknown): { x: number; y: number } | null | undefined {\n\tif (value === null) return null;\n\tif (!isRecord(value)) return undefined;\n\tconst x = getNumber(value.x);\n\tconst y = getNumber(value.y);\n\tif (x == null || y == null) return undefined;\n\treturn { x, y };\n}\n\nfunction parseCamera(value: unknown): RemotePresenceCamera | null | undefined {\n\tif (value === null) return null;\n\tif (!isRecord(value)) return undefined;\n\tconst x = getNumber(value.x);\n\tconst y = getNumber(value.y);\n\tconst zoom = getNumber(value.zoom);\n\tconst viewportWidth = getNumber(value.viewportWidth);\n\tconst viewportHeight = getNumber(value.viewportHeight);\n\tif (\n\t\tx == null ||\n\t\ty == null ||\n\t\tzoom == null ||\n\t\tviewportWidth == null ||\n\t\tviewportHeight == null\n\t) {\n\t\treturn undefined;\n\t}\n\treturn { x, y, zoom, viewportWidth, viewportHeight };\n}\n\nfunction parseMarkupStroke(\n\tvalue: unknown,\n): RemotePresenceMarkupStroke | null | undefined {\n\tif (value === null) return null;\n\tif (!isRecord(value) || !Array.isArray(value.points)) return undefined;\n\tconst tool = getString(value.tool);\n\tif (\n\t\ttool !== \"draw\" &&\n\t\ttool !== \"pencil\" &&\n\t\ttool !== \"brush\" &&\n\t\ttool !== \"marker\" &&\n\t\ttool !== \"laser\"\n\t) {\n\t\treturn undefined;\n\t}\n\tconst points = value.points\n\t\t.map((point) => {\n\t\t\tif (!isRecord(point)) return null;\n\t\t\tconst x = getNumber(point.x);\n\t\t\tconst y = getNumber(point.y);\n\t\t\tif (x == null || y == null) return null;\n\t\t\treturn { x, y };\n\t\t})\n\t\t.filter((point): point is { x: number; y: number } => point != null);\n\tconst strokeWidth = getNumber(value.strokeWidth);\n\tconst stroke = getString(value.stroke);\n\tconst strokeOpacity = getNumber(value.strokeOpacity);\n\treturn {\n\t\tpoints,\n\t\ttool,\n\t\t...(strokeWidth != null ? { strokeWidth } : {}),\n\t\t...(stroke ? { stroke } : {}),\n\t\t...(strokeOpacity != null ? { strokeOpacity } : {}),\n\t};\n}\n\nfunction parsePresencePayload(value: unknown): RealtimePresencePayload | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst cursor = parseCursor(value.cursor);\n\tif (cursor === undefined) return undefined;\n\tconst markupStroke = parseMarkupStroke(value.markupStroke);\n\tif (markupStroke === undefined && value.markupStroke !== undefined)\n\t\treturn undefined;\n\tconst camera = parseCamera(value.camera);\n\tif (camera === undefined && value.camera !== undefined) return undefined;\n\treturn {\n\t\tcursor,\n\t\t...(markupStroke !== undefined ? { markupStroke } : {}),\n\t\t...(camera !== undefined ? { camera } : {}),\n\t\t...(getString(value.activeTool)\n\t\t\t? { activeTool: getString(value.activeTool) }\n\t\t\t: {}),\n\t};\n}\n\nfunction parseItems(value: unknown): VectorSceneItem[] | undefined {\n\treturn Array.isArray(value) ? (value as VectorSceneItem[]) : undefined;\n}\n\nfunction parseDocumentSnapshot(\n\tvalue: unknown,\n): RealtimeDocumentSnapshot | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst revision = getNumber(value.revision);\n\tconst updatedAt = getNumber(value.updatedAt);\n\tconst items = parseItems(value.items);\n\tif (revision == null || updatedAt == null || items == null) return undefined;\n\treturn {\n\t\trevision,\n\t\tupdatedAt,\n\t\titems,\n\t\t...(getString(value.updatedByClientId)\n\t\t\t? { updatedByClientId: getString(value.updatedByClientId) }\n\t\t\t: {}),\n\t};\n}\n\nexport function parseRealtimeSessionPeer(\n\tvalue: unknown,\n): RealtimeSessionPeer | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst clientId = getString(value.clientId);\n\tconst peerId = getString(value.peerId);\n\tconst roomId = getString(value.roomId);\n\tconst joinedAt = getNumber(value.joinedAt);\n\tconst lastSeenAt = getNumber(value.lastSeenAt);\n\tconst cursor = parseCursor(value.cursor);\n\tif (\n\t\tclientId == null ||\n\t\tpeerId == null ||\n\t\troomId == null ||\n\t\tjoinedAt == null ||\n\t\tlastSeenAt == null ||\n\t\tcursor === undefined\n\t) {\n\t\treturn undefined;\n\t}\n\tconst markupStroke = parseMarkupStroke(value.markupStroke);\n\tif (markupStroke === undefined && value.markupStroke !== undefined)\n\t\treturn undefined;\n\tconst camera = parseCamera(value.camera);\n\tif (camera === undefined && value.camera !== undefined) return undefined;\n\tconst isSelf = value.isSelf === true;\n\tconst connectionState = getString(value.connectionState) as\n\t\t| RealtimeConnectionState\n\t\t| undefined;\n\treturn {\n\t\tid: clientId,\n\t\tclientId,\n\t\tpeerId,\n\t\troomId,\n\t\tjoinedAt,\n\t\tlastSeenAt,\n\t\tisSelf,\n\t\tcursor,\n\t\t...(getString(value.displayName)\n\t\t\t? { displayName: getString(value.displayName) }\n\t\t\t: {}),\n\t\t...(getString(value.color) ? { color: getString(value.color) } : {}),\n\t\t...(getString(value.image) ? { image: getString(value.image) } : {}),\n\t\t...(markupStroke !== undefined ? { markupStroke } : {}),\n\t\t...(camera !== undefined ? { camera } : {}),\n\t\t...(getString(value.activeTool)\n\t\t\t? { activeTool: getString(value.activeTool) }\n\t\t\t: {}),\n\t\t...(connectionState ? { connectionState } : {}),\n\t};\n}\n\nfunction parsePeers(value: unknown): RealtimeSessionPeer[] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst peers = value\n\t\t.map((peer) => parseRealtimeSessionPeer(peer))\n\t\t.filter((peer): peer is RealtimeSessionPeer => peer != null);\n\treturn peers.length === value.length ? peers : undefined;\n}\n\nexport function parseRealtimeClientMessage(\n\tvalue: unknown,\n): RealtimeClientMessage | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst type = getString(value.type);\n\tif (type === \"session:join\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst peer = isRecord(value.peer) ? value.peer : undefined;\n\t\tconst clientId = peer ? getString(peer.clientId) : undefined;\n\t\tconst peerId = peer ? getString(peer.peerId) : undefined;\n\t\tif (!roomId || !peer || !clientId || !peerId) return undefined;\n\t\treturn {\n\t\t\ttype,\n\t\t\troomId,\n\t\t\tpeer: {\n\t\t\t\tclientId,\n\t\t\t\tpeerId,\n\t\t\t\t...(getString(peer.displayName)\n\t\t\t\t\t? { displayName: getString(peer.displayName) }\n\t\t\t\t\t: {}),\n\t\t\t\t...(getString(peer.color) ? { color: getString(peer.color) } : {}),\n\t\t\t\t...(getString(peer.image) ? { image: getString(peer.image) } : {}),\n\t\t\t},\n\t\t};\n\t}\n\tif (type === \"session:leave\" || type === \"session:ping\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tif (!roomId || !clientId) return undefined;\n\t\tif (type === \"session:leave\") {\n\t\t\treturn { type, roomId, clientId };\n\t\t}\n\t\tconst sentAt = getNumber(value.sentAt);\n\t\tif (sentAt == null) return undefined;\n\t\treturn { type, roomId, clientId, sentAt };\n\t}\n\tif (type === \"presence:update\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tconst presence = parsePresencePayload(value.presence);\n\t\tif (!roomId || !clientId || !presence) return undefined;\n\t\treturn { type, roomId, clientId, presence };\n\t}\n\tif (type === \"document:update\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tconst baseRevision = getNumber(value.baseRevision);\n\t\tconst items = parseItems(value.items);\n\t\tif (!roomId || !clientId || baseRevision == null || !items) return undefined;\n\t\treturn { type, roomId, clientId, baseRevision, items };\n\t}\n\treturn undefined;\n}\n\nexport function parseRealtimeServerMessage(\n\tvalue: unknown,\n): RealtimeServerMessage | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst type = getString(value.type);\n\tif (type === \"session:welcome\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tconst serverTime = getNumber(value.serverTime);\n\t\tconst document = parseDocumentSnapshot(value.document);\n\t\tconst peers = parsePeers(value.peers);\n\t\tif (!roomId || !clientId || serverTime == null || !document || !peers) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn { type, roomId, clientId, serverTime, document, peers };\n\t}\n\tif (type === \"session:peer-joined\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst peer = parseRealtimeSessionPeer(value.peer);\n\t\tif (!roomId || !peer) return undefined;\n\t\treturn { type, roomId, peer };\n\t}\n\tif (type === \"session:peer-left\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tif (!roomId || !clientId) return undefined;\n\t\treturn { type, roomId, clientId };\n\t}\n\tif (type === \"session:pong\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst clientId = getString(value.clientId);\n\t\tconst sentAt = getNumber(value.sentAt);\n\t\tconst serverTime = getNumber(value.serverTime);\n\t\tif (!roomId || !clientId || sentAt == null || serverTime == null) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn { type, roomId, clientId, sentAt, serverTime };\n\t}\n\tif (type === \"session:error\") {\n\t\tconst code = getString(value.code);\n\t\tconst message = getString(value.message);\n\t\tif (!code || !message) return undefined;\n\t\treturn {\n\t\t\ttype,\n\t\t\tcode,\n\t\t\tmessage,\n\t\t\t...(getString(value.roomId) ? { roomId: getString(value.roomId) } : {}),\n\t\t};\n\t}\n\tif (type === \"presence:sync\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst peers = parsePeers(value.peers);\n\t\tconst serverTime = getNumber(value.serverTime);\n\t\tif (!roomId || !peers || serverTime == null) return undefined;\n\t\treturn { type, roomId, peers, serverTime };\n\t}\n\tif (type === \"document:sync\" || type === \"document:resync-required\") {\n\t\tconst roomId = getString(value.roomId);\n\t\tconst document = parseDocumentSnapshot(value.document);\n\t\tif (!roomId || !document) return undefined;\n\t\tif (type === \"document:sync\") {\n\t\t\treturn { type, roomId, document };\n\t\t}\n\t\tconst reason = getString(value.reason);\n\t\tif (!reason) return undefined;\n\t\treturn { type, roomId, reason, document };\n\t}\n\treturn undefined;\n}\n","\"use client\";\n\nimport type { CSSProperties, ReactNode } from \"react\";\nimport type { RealtimeConnectionState } from \"../../presence/types\";\nimport type { RealtimeSessionPeer } from \"./protocol\";\n\nconst shell: CSSProperties = {\n\tposition: \"absolute\",\n\ttop: 12,\n\tleft: \"50%\",\n\ttransform: \"translateX(-50%)\",\n\tdisplay: \"flex\",\n\tflexDirection: \"row\",\n\talignItems: \"center\",\n\tflexWrap: \"wrap\",\n\tjustifyContent: \"center\",\n\tgap: \"0 14px\",\n\tmaxWidth: \"min(100% - 24px, 520px)\",\n\tpadding: \"6px 14px\",\n\tborderRadius: 9999,\n\tborder: \"1px solid rgba(15, 23, 42, 0.08)\",\n\tbackground: \"rgba(255, 255, 255, 0.78)\",\n\tbackdropFilter: \"blur(12px)\",\n\tWebkitBackdropFilter: \"blur(12px)\",\n\tboxShadow: \"0 1px 2px rgba(15, 23, 42, 0.04), 0 4px 16px rgba(15, 23, 42, 0.06)\",\n\tpointerEvents: \"auto\",\n\tuserSelect: \"none\",\n\tWebkitUserSelect: \"none\",\n\tWebkitTouchCallout: \"none\",\n\tfontSize: \"0.6875rem\",\n\tfontWeight: 500,\n\tletterSpacing: \"0.01em\",\n\tcolor: \"#334155\",\n};\n\nconst titleStyle: CSSProperties = {\n\tfontWeight: 600,\n\tcolor: \"#64748b\",\n\tletterSpacing: \"0.06em\",\n\ttextTransform: \"uppercase\",\n\tfontSize: \"0.625rem\",\n\twhiteSpace: \"nowrap\",\n};\n\nconst statusRow: CSSProperties = {\n\tdisplay: \"inline-flex\",\n\talignItems: \"center\",\n\tgap: 6,\n\tflexShrink: 0,\n};\n\nconst peerList: CSSProperties = {\n\tdisplay: \"flex\",\n\talignItems: \"center\",\n\tflexWrap: \"wrap\",\n\tgap: \"4px 10px\",\n\tmargin: 0,\n\tpadding: 0,\n\tlistStyle: \"none\",\n\tjustifyContent: \"center\",\n};\n\nconst peerItem: CSSProperties = {\n\tdisplay: \"inline-flex\",\n\talignItems: \"center\",\n\tgap: 5,\n\tmaxWidth: 140,\n};\n\nconst dot: CSSProperties = {\n\twidth: 6,\n\theight: 6,\n\tborderRadius: 999,\n\tflexShrink: 0,\n};\n\nconst avatarStyle: CSSProperties = {\n\twidth: 18,\n\theight: 18,\n\tborderRadius: 999,\n\tobjectFit: \"cover\",\n\tflexShrink: 0,\n\tborder: \"1px solid rgba(15, 23, 42, 0.08)\",\n};\n\nconst nameStyle: CSSProperties = {\n\toverflow: \"hidden\",\n\ttextOverflow: \"ellipsis\",\n\twhiteSpace: \"nowrap\",\n};\n\nexport type RealtimeSessionPanelProps = {\n\t/** @default \"Session\" */\n\ttitle?: string;\n\t/** Shown in the participant list (ids + optional display names from your presence layer). */\n\tpeers: readonly (\n\t\t| RealtimeSessionPeer\n\t\t| {\n\t\t\t\tid: string;\n\t\t\t\tdisplayName?: string;\n\t\t\t\tcolor?: string;\n\t\t\t\timage?: string;\n\t\t\t\tisSelf?: boolean;\n\t\t }\n\t)[];\n\t/** @default true */\n\tconnected?: boolean;\n\tconnectionState?: RealtimeConnectionState;\n\troomId?: string;\n\tchildren?: ReactNode;\n};\n\nfunction connectionAppearance(connectionState: RealtimeConnectionState): {\n\tcolor: string;\n\tlabel: string;\n\tshadow: string;\n} {\n\tif (connectionState === \"connected\") {\n\t\treturn {\n\t\t\tcolor: \"#16a34a\",\n\t\t\tlabel: \"Live\",\n\t\t\tshadow: \"0 0 0 2px rgba(22, 163, 74, 0.25)\",\n\t\t};\n\t}\n\tif (connectionState === \"connecting\") {\n\t\treturn {\n\t\t\tcolor: \"#2563eb\",\n\t\t\tlabel: \"Conectando\",\n\t\t\tshadow: \"0 0 0 2px rgba(37, 99, 235, 0.18)\",\n\t\t};\n\t}\n\tif (connectionState === \"reconnecting\") {\n\t\treturn {\n\t\t\tcolor: \"#d97706\",\n\t\t\tlabel: \"Reconectando\",\n\t\t\tshadow: \"0 0 0 2px rgba(217, 119, 6, 0.2)\",\n\t\t};\n\t}\n\tif (connectionState === \"error\") {\n\t\treturn {\n\t\t\tcolor: \"#dc2626\",\n\t\t\tlabel: \"Erro\",\n\t\t\tshadow: \"none\",\n\t\t};\n\t}\n\treturn {\n\t\tcolor: \"#64748b\",\n\t\tlabel: \"Offline\",\n\t\tshadow: \"none\",\n\t};\n}\n\n/**\n * Minimal roster + connection status, top-center above the viewport.\n * Pair with {@link realtimeSessionPlugin} and {@link VectorViewport} presence props.\n */\nexport function RealtimeSessionPanel({\n\ttitle = \"Session\",\n\tpeers,\n\tconnected = true,\n\tconnectionState,\n\troomId,\n\tchildren,\n}: RealtimeSessionPanelProps) {\n\tconst resolvedConnectionState =\n\t\tconnectionState ?? (connected ? \"connected\" : \"reconnecting\");\n\tconst status = connectionAppearance(resolvedConnectionState);\n\n\treturn (\n\t\t<div style={shell} data-slot=\"realtime-session-panel\">\n\t\t\t<span style={titleStyle}>{title}</span>\n\t\t\t{roomId ? (\n\t\t\t\t<>\n\t\t\t\t\t<span\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\twidth: 1,\n\t\t\t\t\t\t\theight: 14,\n\t\t\t\t\t\t\tbackground: \"rgba(15, 23, 42, 0.12)\",\n\t\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t}}\n\t\t\t\t\t\taria-hidden\n\t\t\t\t\t/>\n\t\t\t\t\t<span style={{ ...titleStyle, textTransform: \"none\", letterSpacing: 0 }}>\n\t\t\t\t\t\tSala {roomId}\n\t\t\t\t\t</span>\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t\t<span\n\t\t\t\tstyle={{\n\t\t\t\t\twidth: 1,\n\t\t\t\t\theight: 14,\n\t\t\t\t\tbackground: \"rgba(15, 23, 42, 0.12)\",\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t}}\n\t\t\t\taria-hidden\n\t\t\t/>\n\t\t\t<span style={statusRow}>\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\t...dot,\n\t\t\t\t\t\tbackground: status.color,\n\t\t\t\t\t\tboxShadow: status.shadow,\n\t\t\t\t\t}}\n\t\t\t\t\taria-hidden\n\t\t\t\t/>\n\t\t\t\t<span style={{ color: status.color, fontWeight: 600 }}>{status.label}</span>\n\t\t\t</span>\n\t\t\t{peers.length > 0 ? (\n\t\t\t\t<>\n\t\t\t\t\t<span\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\twidth: 1,\n\t\t\t\t\t\t\theight: 14,\n\t\t\t\t\t\t\tbackground: \"rgba(15, 23, 42, 0.12)\",\n\t\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t}}\n\t\t\t\t\t\taria-hidden\n\t\t\t\t\t/>\n\t\t\t\t\t<ul style={peerList}>\n\t\t\t\t\t\t{peers.map((p) => (\n\t\t\t\t\t\t\t<li key={p.id} style={peerItem}>\n\t\t\t\t\t\t\t\t{\"image\" in p && p.image ? (\n\t\t\t\t\t\t\t\t\t<img src={p.image} alt=\"\" aria-hidden style={avatarStyle} />\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\taria-hidden\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t...dot,\n\t\t\t\t\t\t\t\t\t\t\tbackground: p.color ?? \"#94a3b8\",\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t<span style={nameStyle}>\n\t\t\t\t\t\t\t\t\t{p.displayName ?? p.id}\n\t\t\t\t\t\t\t\t\t{\"isSelf\" in p && p.isSelf ? \" (você)\" : \"\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t\t{children}\n\t\t</div>\n\t);\n}\n","\"use client\";\n\nimport {\n\tcreateContext,\n\ttype ReactNode,\n\ttype RefObject,\n\tuseContext,\n\tuseLayoutEffect,\n} from \"react\";\nimport type { VectorSceneItem } from \"../../scene/types\";\nimport type { VectorToolDefinition } from \"../tools/types\";\nimport type {\n\tCustomShapePlacementOptions,\n\tVectorViewportHandle,\n\tVectorViewportProps,\n} from \"../VectorViewport\";\n\nexport type CanvasPluginRenderContext = {\n\t/** Live viewport handle when the plugin needs camera or viewport size. */\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n};\n\nexport type CanvasPluginItemsChangeMiddlewareContext = {\n\t/** Current board items before the pending change is applied. */\n\tcurrentItems: readonly VectorSceneItem[];\n\t/** Continue the item change pipeline. */\n\tnext: NonNullable<VectorViewportProps[\"onItemsChange\"]>;\n\t/** Original consumer callback passed to `VectorViewport`. */\n\tconsumerOnItemsChange?: VectorViewportProps[\"onItemsChange\"];\n\t/** Live viewport handle for advanced integrations. */\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n};\n\nexport type CanvasPluginContribution = {\n\t/** Additional tools injected into the board toolbar/runtime. */\n\ttools?: readonly VectorToolDefinition[];\n\t/** Transform the resolved tool list (reorder, replace, or filter existing tools). */\n\ttoolTransform?: (tools: VectorToolDefinition[]) => VectorToolDefinition[];\n\t/** Multiple custom placements contributed by plugins; the active one is resolved by `toolId`. */\n\tcustomPlacements?: readonly CustomShapePlacementOptions[];\n\t/** Simple viewport prop overrides owned by the plugin runtime. */\n\tviewportProps?: Partial<\n\t\tPick<VectorViewportProps, \"remotePresence\" | \"presenceOverlay\">\n\t>;\n\t/** Event callbacks chained into the viewport without manual wiring in app code. */\n\tcallbacks?: Partial<\n\t\tPick<\n\t\t\tVectorViewportProps,\n\t\t\t| \"onWorldPointerDown\"\n\t\t\t| \"onWorldPointerMove\"\n\t\t\t| \"onWorldPointerLeave\"\n\t\t\t| \"onPlacementPreviewChange\"\n\t\t\t| \"onCameraChange\"\n\t\t>\n\t>;\n\t/** Middleware around `onItemsChange` for collaboration, comments, persistence, etc. */\n\twrapOnItemsChange?: (\n\t\tnextItems: VectorSceneItem[],\n\t\tctx: CanvasPluginItemsChangeMiddlewareContext,\n\t) => void;\n};\n\nexport type CanvasPluginComponentProps = {\n\t/** Stable plugin id so the component can register contributions. */\n\tpluginId: string;\n};\n\nexport type CanvasPlugin = {\n\t/** Stable id, e.g. `canvu.plugin.chatbot`. */\n\tid: string;\n\t/**\n\t * Legacy/simple rendering path for purely visual plugins.\n\t *\n\t * Prefer `Component` for plugins that need hooks, document integration, tools, or runtime contributions.\n\t */\n\trender?: (ctx: CanvasPluginRenderContext) => ReactNode;\n\t/**\n\t * Preferred plugin entrypoint for first-party and advanced plugins.\n\t *\n\t * The component can use hooks and register contributions through `useCanvuPluginContribution`.\n\t */\n\tComponent?: (props: CanvasPluginComponentProps) => ReactNode;\n};\n\nexport type CanvuPluginViewportSnapshot = Pick<\n\tVectorViewportProps,\n\t| \"items\"\n\t| \"onItemsChange\"\n\t| \"toolId\"\n\t| \"interactive\"\n\t| \"toolLocked\"\n\t| \"onToolChangeRequest\"\n>;\n\nexport type CanvuPluginContextValue = {\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n\tviewport: CanvuPluginViewportSnapshot;\n\tresolvedTools: VectorToolDefinition[];\n\tregisterContribution: (\n\t\tpluginId: string,\n\t\tcontribution: CanvasPluginContribution,\n\t) => void;\n\tunregisterContribution: (pluginId: string) => void;\n};\n\nexport const CanvuPluginContext = createContext<CanvuPluginContextValue | null>(\n\tnull,\n);\n\n/**\n * Creates a typed canvu plugin descriptor.\n *\n * Use this helper when authoring custom plugins so your editor can infer the plugin shape\n * and surface better hover documentation for the returned object.\n */\nexport function createCanvuPlugin(plugin: CanvasPlugin): CanvasPlugin {\n\treturn plugin;\n}\n\n/**\n * Returns the low-level canvu plugin runtime context.\n *\n * This is an advanced API for custom plugin authors. Prefer first-party plugin factories such as\n * `chatbotPlugin(...)` and `realtimeCollaborationPlugin(...)` for the common path.\n */\nexport function useCanvuPluginContext(): CanvuPluginContextValue {\n\tconst ctx = useContext(CanvuPluginContext);\n\tif (!ctx) {\n\t\tthrow new Error(\n\t\t\t\"useCanvuPluginContext must be used inside a VectorViewport plugin runtime.\",\n\t\t);\n\t}\n\treturn ctx;\n}\n\n/**\n * Returns the current viewport-facing board state exposed to plugins.\n *\n * Use this when a custom plugin needs access to items, the active tool, or the consumer's\n * `onToolChangeRequest` callback.\n */\nexport function useCanvuViewportContext(): {\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n\tviewport: CanvuPluginViewportSnapshot;\n} {\n\tconst { viewportRef, viewport } = useCanvuPluginContext();\n\treturn { viewportRef, viewport };\n}\n\n/**\n * Returns the board document context exposed to plugins.\n *\n * This hook is intended for advanced plugins that need to read items or integrate with the board's\n * `onItemsChange` lifecycle.\n */\nexport function useCanvuDocumentContext(): {\n\titems: readonly VectorSceneItem[];\n\tonItemsChange?: VectorViewportProps[\"onItemsChange\"];\n} {\n\tconst { viewport } = useCanvuPluginContext();\n\treturn {\n\t\titems: viewport.items,\n\t\tonItemsChange: viewport.onItemsChange,\n\t};\n}\n\n/**\n * Returns the tool list already resolved by the plugin runtime.\n *\n * `VectorToolbar` consumes this automatically when you omit its `tools` prop, so most apps do not\n * need this hook directly.\n */\nexport function useCanvuResolvedTools(): VectorToolDefinition[] {\n\treturn useCanvuPluginContext().resolvedTools;\n}\n\n/**\n * Registers non-visual plugin contributions with the current `VectorViewport` runtime.\n *\n * Use this inside `plugin.Component` when you want to inject tools, pointer/camera behavior, or\n * document middleware without requiring the consumer to wire hooks manually.\n */\nexport function useCanvuPluginContribution(\n\tpluginId: string,\n\tcontribution: CanvasPluginContribution,\n): void {\n\tconst { registerContribution, unregisterContribution } = useCanvuPluginContext();\n\tuseLayoutEffect(() => {\n\t\tregisterContribution(pluginId, contribution);\n\t\treturn () => unregisterContribution(pluginId);\n\t}, [contribution, pluginId, registerContribution, unregisterContribution]);\n}\n","import type { SVGProps } from \"react\";\n\ntype IconProps = SVGProps<SVGSVGElement>;\n\nconst architecturalCloudIconPath =\n\t\"M1.5 12 A 4.94 5.23 0 0 1 9.07 6 A 4.94 5.23 0 0 1 14.93 6 A 4.94 5.23 0 0 1 22.5 12 A 4.94 5.23 0 0 1 14.93 18 A 4.94 5.23 0 0 1 9.07 18 A 4.94 5.23 0 0 1 1.5 12 Z\";\n\nconst base = {\n\twidth: 20,\n\theight: 20,\n\tviewBox: \"0 0 24 24\",\n\tfill: \"none\",\n\tstroke: \"currentColor\",\n\tstrokeWidth: 2,\n\tstrokeLinecap: \"round\" as const,\n\tstrokeLinejoin: \"round\" as const,\n};\n\nexport function IconHand(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M18 11V6a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2v0\" />\n\t\t\t<path d=\"M14 10V4a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2v2\" />\n\t\t\t<path d=\"M10 10.5V6a2 2 0 0 0-2-2v0a2 2 0 0 0-2 2v8\" />\n\t\t\t<path d=\"M18 8a2 2 0 1 1 4 0v5a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconSelect(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z\" />\n\t\t\t<path d=\"M13 13l6 6\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconRect(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconEllipse(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<ellipse cx=\"12\" cy=\"12\" rx=\"9\" ry=\"6\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconArchitecturalCloud(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d={architecturalCloudIconPath} />\n\t\t</svg>\n\t);\n}\n\nexport function IconLine(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<line x1=\"5\" y1=\"19\" x2=\"19\" y2=\"5\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconArrow(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<line x1=\"5\" y1=\"19\" x2=\"19\" y2=\"5\" />\n\t\t\t<polyline points=\"12 5 19 5 19 12\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconDraw(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M12 19l7-7 3 3-7 7-3-3z\" />\n\t\t\t<path d=\"M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z\" />\n\t\t\t<path d=\"M2 2l7.586 7.586\" />\n\t\t\t<circle cx=\"11\" cy=\"11\" r=\"2\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconText(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2\" />\n\t\t\t<path d=\"M9 21h6\" />\n\t\t\t<path d=\"M12 3v18\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconImage(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n\t\t\t<circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\" />\n\t\t\t<polyline points=\"21 15 16 10 5 21\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconPencil(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M12 19l7-7 3 3-7 7-3-3z\" />\n\t\t\t<path d=\"M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z\" />\n\t\t\t<path d=\"M2 2l7.586 7.586\" />\n\t\t\t<path d=\"M11 4h4v4\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconBrush(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M9.06 11.9l8.07-8.06a2.85 2.85 0 0 1 4.03 4.03l-8.06 8.07\" />\n\t\t\t<path d=\"M7.5 15.5L3 21l5.5-4.5\" />\n\t\t\t<path d=\"M2 22l4-1\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconMarker(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<path d=\"M4 20h16\" />\n\t\t\t<path d=\"M6 16l6-12 6 12\" fill=\"currentColor\" fillOpacity={0.35} />\n\t\t\t<path d=\"M8 14h8\" />\n\t\t</svg>\n\t);\n}\n\nexport function IconLaser(props: IconProps) {\n\treturn (\n\t\t<svg {...base} {...props} aria-hidden>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"2.5\" />\n\t\t\t<path d=\"M12 4v4\" />\n\t\t\t<path d=\"M12 16v4\" />\n\t\t\t<path d=\"M4 12h4\" />\n\t\t\t<path d=\"M16 12h4\" />\n\t\t</svg>\n\t);\n}\n","import {\n\tArrowUpRight,\n\tCircle,\n\tEraser,\n\tHand,\n\tHighlighter,\n\tImage,\n\tMinus,\n\tMousePointer2,\n\tPenLine,\n\tSquare,\n\tType,\n} from \"lucide-react\";\nimport { IconArchitecturalCloud, IconLaser } from \"./icons\";\nimport type { VectorToolDefinition } from \"./types\";\n\n/** Match previous 20×20 toolbar glyphs; Lucide scales with `currentColor`. */\nconst ic = { size: 20, strokeWidth: 2 } as const;\n\n/**\n * Tool ids shown in the overflow menu at the end of the default toolbar (horizontal layout).\n * Order: shapes, marker, laser, image.\n */\nexport const DEFAULT_OVERFLOW_TOOL_IDS = [\n\t\"rect\",\n\t\"ellipse\",\n\t\"architectural-cloud\",\n\t\"line\",\n\t\"marker\",\n\t\"laser\",\n\t\"image\",\n] as const;\n\n/**\n * Opinionated default tool strip using [Lucide](https://lucide.dev) icons.\n * Pass a subset or your own list via {@link VectorToolbarProps.tools}.\n */\nexport const DEFAULT_VECTOR_TOOLS: VectorToolDefinition[] = [\n\t{\n\t\tid: \"hand\",\n\t\tlabel: \"Hand\",\n\t\ticon: <Hand {...ic} aria-hidden />,\n\t\tshortcutHint: \"H\",\n\t},\n\t{\n\t\tid: \"select\",\n\t\tlabel: \"Select\",\n\t\ticon: <MousePointer2 {...ic} aria-hidden />,\n\t\tshortcutHint: \"V\",\n\t},\n\t{\n\t\tid: \"rect\",\n\t\tlabel: \"Rectangle\",\n\t\ticon: <Square {...ic} aria-hidden />,\n\t\tshortcutHint: \"R\",\n\t},\n\t{\n\t\tid: \"ellipse\",\n\t\tlabel: \"Ellipse\",\n\t\ticon: <Circle {...ic} aria-hidden />,\n\t\tshortcutHint: \"O\",\n\t},\n\t{\n\t\tid: \"architectural-cloud\",\n\t\tlabel: \"Nuvem arquitetural\",\n\t\ttooltipLabel: \"Architectural cloud\",\n\t\ticon: <IconArchitecturalCloud aria-hidden />,\n\t\tshortcutHint: \"C\",\n\t},\n\t{\n\t\tid: \"line\",\n\t\tlabel: \"Line\",\n\t\ticon: <Minus {...ic} aria-hidden />,\n\t\tshortcutHint: \"L\",\n\t},\n\t{\n\t\tid: \"arrow\",\n\t\tlabel: \"Arrow\",\n\t\ticon: <ArrowUpRight {...ic} aria-hidden />,\n\t\tshortcutHint: \"A\",\n\t},\n\t{\n\t\tid: \"draw\",\n\t\tlabel: \"Desenhar\",\n\t\ttooltipLabel: \"Draw\",\n\t\ticon: <PenLine {...ic} aria-hidden />,\n\t\tshortcutHint: \"D\",\n\t},\n\t{\n\t\tid: \"marker\",\n\t\tlabel: \"Realce\",\n\t\ttooltipLabel: \"Highlighter\",\n\t\ticon: <Highlighter {...ic} aria-hidden />,\n\t\tshortcutHint: \"M\",\n\t},\n\t{\n\t\tid: \"laser\",\n\t\tlabel: \"Laser\",\n\t\ticon: <IconLaser aria-hidden />,\n\t\tshortcutHint: \"K\",\n\t},\n\t{\n\t\tid: \"eraser\",\n\t\tlabel: \"Borracha\",\n\t\ttooltipLabel: \"Eraser\",\n\t\ticon: <Eraser {...ic} aria-hidden />,\n\t\tshortcutHint: \"E\",\n\t},\n\t{\n\t\tid: \"text\",\n\t\tlabel: \"Text\",\n\t\ticon: <Type {...ic} aria-hidden />,\n\t\tshortcutHint: \"T\",\n\t},\n\t{\n\t\tid: \"image\",\n\t\tlabel: \"File\",\n\t\ticon: <Image {...ic} aria-hidden />,\n\t\tshortcutHint: \"I\",\n\t},\n];\n","import { MessageSquare, Sparkles } from \"lucide-react\";\nimport {\n\ttype CSSProperties,\n\ttype PointerEvent as ReactPointerEvent,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport type { Rect } from \"../../../math/rect\";\nimport { createCustomShapeItem } from \"../../../scene/custom-shape\";\nimport type { VectorSceneItem } from \"../../../scene/types\";\nimport type { VectorToolDefinition } from \"../../tools/types\";\nimport type { CanvasPlugin, CanvasPluginRenderContext } from \"../types\";\n\nconst iconProps = { size: 20, strokeWidth: 2 } as const;\nconst COMMENT_PLUGIN_DATA_KEY = \"realtimeComment\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport type RealtimeCommentData = {\n\tbody: string;\n\tcreatedAt: number;\n\tauthorPeerId: string;\n\tauthorDisplayName: string;\n\tauthorColor: string;\n\tauthorImage: string;\n};\n\ntype RealtimeCommentDraftData = {\n\tkind: \"draft\";\n\tseedColor?: string;\n};\n\ntype RealtimeCommentStoredData =\n\t| RealtimeCommentDraftData\n\t| ({ kind: \"comment\" } & RealtimeCommentData);\n\nexport type RealtimeCommentsOverlayProps = {\n\titems: readonly VectorSceneItem[];\n\tonItemsChange?: (items: VectorSceneItem[]) => void;\n\tisDragEnabled?: boolean;\n\tcameraVersion: number;\n\tviewportRef?: CanvasPluginRenderContext[\"viewportRef\"];\n};\n\nexport type RealtimeCommentsPluginOptions = Omit<\n\tRealtimeCommentsOverlayProps,\n\t\"viewportRef\"\n>;\n\ntype RealtimeCommentDragState = {\n\titemId: string;\n\tlastWorldX: number;\n\tlastWorldY: number;\n};\n\n/** Dedicated collaboration tool; unlike `text`, this opens a comment composer flow. */\nexport const REALTIME_COMMENT_TOOL: VectorToolDefinition = {\n\tid: \"comment\",\n\tlabel: \"Comentário\",\n\ttooltipLabel: \"Comment\",\n\tariaLabel: \"Adicionar comentário colaborativo\",\n\tshortcutHint: \"C\",\n\ticon: <MessageSquare {...iconProps} aria-hidden />,\n};\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction getString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction getNumber(value: unknown): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction initialsFromDisplayName(displayName: string): string {\n\tconst words = displayName.trim().split(/\\s+/).filter(Boolean).slice(0, 2);\n\tif (words.length === 0) return \"?\";\n\treturn words.map((part) => part[0]?.toUpperCase() ?? \"\").join(\"\") || \"?\";\n}\n\nfunction escapeSvgText(value: string): string {\n\treturn value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\n/**\n * Generates a tiny inline avatar so comments carry a portable visual identity even without a user photo API.\n */\nexport function createRealtimeCommentAvatarDataUrl(\n\tdisplayName: string,\n\tcolor: string,\n): string {\n\tconst initials = initialsFromDisplayName(displayName);\n\tconst svg = `\n\t\t<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"96\" height=\"96\" viewBox=\"0 0 96 96\">\n\t\t\t<defs>\n\t\t\t\t<linearGradient id=\"bg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n\t\t\t\t\t<stop offset=\"0%\" stop-color=\"${color}\" />\n\t\t\t\t\t<stop offset=\"100%\" stop-color=\"#0f172a\" />\n\t\t\t\t</linearGradient>\n\t\t\t\t<radialGradient id=\"shine\" cx=\"30%\" cy=\"24%\" r=\"70%\">\n\t\t\t\t\t<stop offset=\"0%\" stop-color=\"#ffffff\" stop-opacity=\"0.48\" />\n\t\t\t\t\t<stop offset=\"100%\" stop-color=\"#ffffff\" stop-opacity=\"0\" />\n\t\t\t\t</radialGradient>\n\t\t\t</defs>\n\t\t\t<rect width=\"96\" height=\"96\" rx=\"28\" fill=\"url(#bg)\" />\n\t\t\t<rect width=\"96\" height=\"96\" rx=\"28\" fill=\"url(#shine)\" />\n\t\t\t<circle cx=\"48\" cy=\"38\" r=\"18\" fill=\"rgba(255,255,255,0.2)\" />\n\t\t\t<path d=\"M20 84c5-16 17-24 28-24s23 8 28 24\" fill=\"rgba(255,255,255,0.16)\" />\n\t\t\t<text x=\"48\" y=\"56\" text-anchor=\"middle\" font-size=\"28\" font-weight=\"700\" font-family=\"system-ui, sans-serif\" fill=\"#ffffff\">${escapeSvgText(initials)}</text>\n\t\t</svg>\n\t`;\n\treturn `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;\n}\n\nfunction commentPlaceholderInnerSvg(color: string): string {\n\treturn `\n\t\t<circle cx=\"9\" cy=\"9\" r=\"7\" fill=\"rgba(255,255,255,0.94)\" stroke=\"${color}\" stroke-width=\"1.2\" stroke-dasharray=\"2 1.5\" />\n\t\t<circle cx=\"9\" cy=\"9\" r=\"3.1\" fill=\"${color}\" fill-opacity=\"0.18\" stroke=\"${color}\" stroke-width=\"1\" />\n\t\t<path d=\"M7.1 8.1h3.8c.8 0 1.4.5 1.4 1.2v1.1c0 .7-.6 1.2-1.4 1.2H9.3l-1.2 1v-1H7.1c-.8 0-1.4-.5-1.4-1.2V9.3c0-.7.6-1.2 1.4-1.2Z\" fill=\"#ffffff\" stroke=\"${color}\" stroke-width=\"0.9\" />\n\t`;\n}\n\nfunction commentAnchorInnerSvg(authorColor: string): string {\n\treturn `\n\t\t<circle cx=\"9\" cy=\"9\" r=\"7.2\" fill=\"rgba(255,255,255,0.96)\" stroke=\"rgba(15,23,42,0.1)\" stroke-width=\"0.9\" />\n\t\t<circle cx=\"9\" cy=\"9\" r=\"4.1\" fill=\"${authorColor}\" />\n\t\t<circle cx=\"13.2\" cy=\"13.2\" r=\"3.2\" fill=\"#ffffff\" stroke=\"rgba(15,23,42,0.12)\" stroke-width=\"0.9\" />\n\t\t<path d=\"M11.7 12.1h2.7c.6 0 1 .4 1 .9v.9c0 .5-.4.9-1 .9h-1.1l-1 .8v-.8h-.4c-.6 0-1-.4-1-.9V13c0-.5.4-.9 1-.9Z\" fill=\"#111827\" fill-opacity=\"0.08\" stroke=\"#111827\" stroke-width=\"0.75\" />\n\t`;\n}\n\nexport function createRealtimeCommentDraftItem(\n\tid: string,\n\tbounds: Rect,\n\tseedColor = \"#7c3aed\",\n): VectorSceneItem {\n\tconst base = createCustomShapeItem(id, bounds, {\n\t\trender: () => commentPlaceholderInnerSvg(seedColor),\n\t});\n\treturn {\n\t\t...base,\n\t\tpluginData: {\n\t\t\t...(base.pluginData ?? {}),\n\t\t\t[COMMENT_PLUGIN_DATA_KEY]: {\n\t\t\t\tkind: \"draft\",\n\t\t\t\tseedColor,\n\t\t\t} satisfies RealtimeCommentDraftData,\n\t\t},\n\t};\n}\n\nexport function createRealtimeCommentItem(\n\tid: string,\n\tbounds: Rect,\n\tcomment: RealtimeCommentData,\n): VectorSceneItem {\n\tconst base = createCustomShapeItem(id, bounds, {\n\t\trender: () => commentAnchorInnerSvg(comment.authorColor),\n\t});\n\treturn {\n\t\t...base,\n\t\tpluginData: {\n\t\t\t...(base.pluginData ?? {}),\n\t\t\t[COMMENT_PLUGIN_DATA_KEY]: {\n\t\t\t\tkind: \"comment\",\n\t\t\t\t...comment,\n\t\t\t} satisfies RealtimeCommentStoredData,\n\t\t},\n\t};\n}\n\nfunction getStoredRealtimeCommentData(\n\titem: VectorSceneItem,\n): RealtimeCommentStoredData | null {\n\tconst pluginData = item.pluginData?.[COMMENT_PLUGIN_DATA_KEY];\n\tif (!isRecord(pluginData)) return null;\n\tconst kind = getString(pluginData.kind);\n\tif (kind === \"draft\") {\n\t\treturn {\n\t\t\tkind,\n\t\t\t...(getString(pluginData.seedColor)\n\t\t\t\t? { seedColor: getString(pluginData.seedColor) }\n\t\t\t\t: {}),\n\t\t};\n\t}\n\tif (kind !== \"comment\") return null;\n\tconst body = getString(pluginData.body);\n\tconst createdAt = getNumber(pluginData.createdAt);\n\tconst authorPeerId = getString(pluginData.authorPeerId);\n\tconst authorDisplayName = getString(pluginData.authorDisplayName);\n\tconst authorColor = getString(pluginData.authorColor);\n\tconst authorImage = getString(pluginData.authorImage);\n\tif (\n\t\t!body ||\n\t\tcreatedAt == null ||\n\t\t!authorPeerId ||\n\t\t!authorDisplayName ||\n\t\t!authorColor ||\n\t\t!authorImage\n\t) {\n\t\treturn null;\n\t}\n\treturn {\n\t\tkind,\n\t\tbody,\n\t\tcreatedAt,\n\t\tauthorPeerId,\n\t\tauthorDisplayName,\n\t\tauthorColor,\n\t\tauthorImage,\n\t};\n}\n\nexport function isRealtimeCommentDraftItem(item: VectorSceneItem): boolean {\n\treturn getStoredRealtimeCommentData(item)?.kind === \"draft\";\n}\n\nexport function isRealtimeCommentItem(item: VectorSceneItem): boolean {\n\treturn getStoredRealtimeCommentData(item)?.kind === \"comment\";\n}\n\nexport function getRealtimeCommentData(\n\titem: VectorSceneItem,\n): RealtimeCommentData | null {\n\tconst data = getStoredRealtimeCommentData(item);\n\treturn data?.kind === \"comment\" ? data : null;\n}\n\n/**\n * Adds the comment tool without replacing the native text tool.\n * By default it is inserted right after `text`, or appended when `text` is absent.\n */\nexport function withRealtimeCommentTool(\n\ttools: readonly VectorToolDefinition[],\n): VectorToolDefinition[] {\n\tif (tools.some((tool) => tool.id === REALTIME_COMMENT_TOOL.id)) {\n\t\treturn tools.map((tool) =>\n\t\t\ttool.id === REALTIME_COMMENT_TOOL.id\n\t\t\t\t? { ...tool, ...REALTIME_COMMENT_TOOL }\n\t\t\t\t: tool,\n\t\t);\n\t}\n\tconst textIndex = tools.findIndex((tool) => tool.id === \"text\");\n\tif (textIndex < 0) return [...tools, REALTIME_COMMENT_TOOL];\n\treturn [\n\t\t...tools.slice(0, textIndex + 1),\n\t\tREALTIME_COMMENT_TOOL,\n\t\t...tools.slice(textIndex + 1),\n\t];\n}\n\nconst overlayShell: CSSProperties = {\n\tposition: \"absolute\",\n\tinset: 0,\n\tpointerEvents: \"none\",\n\tzIndex: 26,\n\toverflow: \"hidden\",\n};\n\nfunction formatCommentTimestamp(timestamp: number): string {\n\treturn new Intl.DateTimeFormat(\"pt-BR\", {\n\t\tdateStyle: \"short\",\n\t\ttimeStyle: \"short\",\n\t}).format(new Date(timestamp));\n}\n\nexport function RealtimeCommentsOverlay({\n\titems,\n\tonItemsChange,\n\tisDragEnabled = false,\n\tcameraVersion,\n\tviewportRef,\n}: RealtimeCommentsOverlayProps) {\n\tvoid cameraVersion;\n\tconst [hoveredId, setHoveredId] = useState<string | null>(null);\n\tconst [draggedId, setDraggedId] = useState<string | null>(null);\n\tconst dragStateRef = useRef<RealtimeCommentDragState | null>(null);\n\tconst itemsRef = useRef(items);\n\tuseEffect(() => {\n\t\titemsRef.current = items;\n\t}, [items]);\n\tconst camera = viewportRef?.current?.getCamera() ?? null;\n\tif (!camera) return null;\n\n\tfunction moveCommentItem(\n\t\titem: VectorSceneItem,\n\t\tdeltaX: number,\n\t\tdeltaY: number,\n\t): VectorSceneItem {\n\t\treturn {\n\t\t\t...item,\n\t\t\tx: item.x + deltaX,\n\t\t\ty: item.y + deltaY,\n\t\t\tbounds: {\n\t\t\t\t...item.bounds,\n\t\t\t\tx: item.bounds.x + deltaX,\n\t\t\t\ty: item.bounds.y + deltaY,\n\t\t\t},\n\t\t};\n\t}\n\n\tfunction handleCommentPointerDown(\n\t\titemId: string,\n\t\tevent: ReactPointerEvent<HTMLButtonElement>,\n\t): void {\n\t\tif (event.button !== 0 || !onItemsChange || !isDragEnabled) return;\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\t\tconst currentCamera = viewportRef?.current?.getCamera();\n\t\tif (!currentCamera) return;\n\t\tconst start = currentCamera.screenToWorld(event.clientX, event.clientY);\n\t\tdragStateRef.current = {\n\t\t\titemId,\n\t\t\tlastWorldX: start.worldX,\n\t\t\tlastWorldY: start.worldY,\n\t\t};\n\t\tsetDraggedId(itemId);\n\t\tsetHoveredId((current) => (current === itemId ? null : current));\n\n\t\tconst onPointerMove = (moveEvent: PointerEvent) => {\n\t\t\tconst drag = dragStateRef.current;\n\t\t\tconst liveCamera = viewportRef?.current?.getCamera();\n\t\t\tif (!drag || !liveCamera) return;\n\t\t\tconst next = liveCamera.screenToWorld(moveEvent.clientX, moveEvent.clientY);\n\t\t\tconst deltaX = next.worldX - drag.lastWorldX;\n\t\t\tconst deltaY = next.worldY - drag.lastWorldY;\n\t\t\tif (deltaX === 0 && deltaY === 0) return;\n\t\t\tdrag.lastWorldX = next.worldX;\n\t\t\tdrag.lastWorldY = next.worldY;\n\t\t\tconst nextItems = itemsRef.current.map((item) =>\n\t\t\t\titem.id === drag.itemId ? moveCommentItem(item, deltaX, deltaY) : item,\n\t\t\t);\n\t\t\titemsRef.current = nextItems;\n\t\t\tonItemsChange(nextItems);\n\t\t};\n\n\t\tconst onPointerUp = () => {\n\t\t\tdragStateRef.current = null;\n\t\t\tsetDraggedId((current) => (current === itemId ? null : current));\n\t\t\twindow.removeEventListener(\"pointermove\", onPointerMove);\n\t\t\twindow.removeEventListener(\"pointerup\", onPointerUp);\n\t\t\twindow.removeEventListener(\"pointercancel\", onPointerUp);\n\t\t};\n\n\t\twindow.addEventListener(\"pointermove\", onPointerMove);\n\t\twindow.addEventListener(\"pointerup\", onPointerUp);\n\t\twindow.addEventListener(\"pointercancel\", onPointerUp);\n\t}\n\n\tconst comments = items\n\t\t.map((item) => ({ item, data: getRealtimeCommentData(item) }))\n\t\t.filter(\n\t\t\t(entry): entry is { item: VectorSceneItem; data: RealtimeCommentData } =>\n\t\t\t\tentry.data != null,\n\t\t);\n\tif (comments.length === 0) return null;\n\n\treturn (\n\t\t<div style={overlayShell} data-slot=\"realtime-comments-overlay\">\n\t\t\t{comments.map(({ item, data }) => {\n\t\t\t\tconst anchor = camera.worldToScreen(\n\t\t\t\t\titem.bounds.x + item.bounds.width / 2,\n\t\t\t\t\titem.bounds.y + item.bounds.height / 2,\n\t\t\t\t);\n\t\t\t\tconst dragging = draggedId === item.id;\n\t\t\t\tconst expanded = hoveredId === item.id && !dragging;\n\t\t\t\treturn (\n\t\t\t\t\t<button\n\t\t\t\t\t\tkey={item.id}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\taria-label={`Comment by ${data.authorDisplayName}`}\n\t\t\t\t\t\tonMouseEnter={() => setHoveredId(item.id)}\n\t\t\t\t\t\tonMouseLeave={() =>\n\t\t\t\t\t\t\tsetHoveredId((current) => (current === item.id ? null : current))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tonPointerDown={(event) => handleCommentPointerDown(item.id, event)}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\t\tpadding: 0,\n\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\tleft: anchor.screenX,\n\t\t\t\t\t\t\ttop: anchor.screenY,\n\t\t\t\t\t\t\ttransform: \"translate(-50%, -50%)\",\n\t\t\t\t\t\t\tpointerEvents: \"auto\",\n\t\t\t\t\t\t\tcursor:\n\t\t\t\t\t\t\t\tonItemsChange && isDragEnabled\n\t\t\t\t\t\t\t\t\t? dragging\n\t\t\t\t\t\t\t\t\t\t? \"grabbing\"\n\t\t\t\t\t\t\t\t\t\t: \"grab\"\n\t\t\t\t\t\t\t\t\t: \"default\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\t\t\talignItems: expanded ? \"flex-start\" : \"center\",\n\t\t\t\t\t\t\t\tgap: expanded ? 9 : 0,\n\t\t\t\t\t\t\t\twidth: expanded ? 228 : 44,\n\t\t\t\t\t\t\t\tminHeight: 44,\n\t\t\t\t\t\t\t\tpadding: expanded ? \"8px 10px 8px 8px\" : 3,\n\t\t\t\t\t\t\t\tborderRadius: expanded ? 18 : 999,\n\t\t\t\t\t\t\t\tbackground: expanded ? \"rgba(255,255,255,0.97)\" : \"transparent\",\n\t\t\t\t\t\t\t\tborder: expanded\n\t\t\t\t\t\t\t\t\t? \"1px solid rgba(148,163,184,0.28)\"\n\t\t\t\t\t\t\t\t\t: \"1px solid transparent\",\n\t\t\t\t\t\t\t\tboxShadow: expanded ? \"0 14px 32px rgba(15,23,42,0.18)\" : \"none\",\n\t\t\t\t\t\t\t\tbackdropFilter: \"blur(10px)\",\n\t\t\t\t\t\t\t\ttransition:\n\t\t\t\t\t\t\t\t\t\"width 160ms ease, border-radius 160ms ease, transform 160ms ease, box-shadow 160ms ease, padding 160ms ease\",\n\t\t\t\t\t\t\t\ttransform: dragging\n\t\t\t\t\t\t\t\t\t? \"scale(0.98)\"\n\t\t\t\t\t\t\t\t\t: expanded\n\t\t\t\t\t\t\t\t\t\t? \"translateY(-2px)\"\n\t\t\t\t\t\t\t\t\t\t: \"translateY(0)\",\n\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\t\t\t\t\twidth: 36,\n\t\t\t\t\t\t\t\t\theight: 36,\n\t\t\t\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t\t\t\tboxShadow: expanded\n\t\t\t\t\t\t\t\t\t\t? `0 0 0 2px ${data.authorColor}22`\n\t\t\t\t\t\t\t\t\t\t: \"0 10px 18px rgba(15,23,42,0.14)\",\n\t\t\t\t\t\t\t\t\tborder: expanded ? \"none\" : \"2px solid rgba(255,255,255,0.92)\",\n\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\tsrc={data.authorImage}\n\t\t\t\t\t\t\t\t\talt={data.authorDisplayName}\n\t\t\t\t\t\t\t\t\tstyle={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t\t\t\tright: expanded ? -1 : -2,\n\t\t\t\t\t\t\t\t\t\tbottom: expanded ? -1 : -2,\n\t\t\t\t\t\t\t\t\t\twidth: 14,\n\t\t\t\t\t\t\t\t\t\theight: 14,\n\t\t\t\t\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\t\t\t\t\tbackground: \"#111827\",\n\t\t\t\t\t\t\t\t\t\tcolor: \"#fff\",\n\t\t\t\t\t\t\t\t\t\tdisplay: \"grid\",\n\t\t\t\t\t\t\t\t\t\tplaceItems: \"center\",\n\t\t\t\t\t\t\t\t\t\tborder: \"1.5px solid rgba(255,255,255,0.98)\",\n\t\t\t\t\t\t\t\t\t\tboxShadow: \"0 4px 10px rgba(15,23,42,0.16)\",\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Sparkles size={8} strokeWidth={2.2} aria-hidden />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{expanded ? (\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tdisplay: \"grid\",\n\t\t\t\t\t\t\t\t\t\tgap: 3,\n\t\t\t\t\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\t\t\t\t\tpaddingTop: 1,\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\t\t\t\t\t\tjustifyContent: \"space-between\",\n\t\t\t\t\t\t\t\t\t\t\tgap: 8,\n\t\t\t\t\t\t\t\t\t\t\talignItems: \"baseline\",\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\tfontSize: 12,\n\t\t\t\t\t\t\t\t\t\t\t\tfontWeight: 700,\n\t\t\t\t\t\t\t\t\t\t\t\tcolor: \"#0f172a\",\n\t\t\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{data.authorDisplayName}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\t\tfontSize: 10,\n\t\t\t\t\t\t\t\t\t\t\t\tcolor: \"#64748b\",\n\t\t\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{formatCommentTimestamp(data.createdAt)}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\t\tfontSize: 11,\n\t\t\t\t\t\t\t\t\t\t\tlineHeight: 1.4,\n\t\t\t\t\t\t\t\t\t\t\tcolor: \"#334155\",\n\t\t\t\t\t\t\t\t\t\t\tdisplay: \"-webkit-box\",\n\t\t\t\t\t\t\t\t\t\t\tWebkitLineClamp: 3,\n\t\t\t\t\t\t\t\t\t\t\tWebkitBoxOrient: \"vertical\",\n\t\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{data.body}\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</button>\n\t\t\t\t);\n\t\t\t})}\n\t\t</div>\n\t);\n}\n\nexport function realtimeCommentsPlugin(\n\toptions: RealtimeCommentsPluginOptions,\n): CanvasPlugin {\n\treturn {\n\t\tid: \"trazo.plugin.realtime-comments\",\n\t\trender: (ctx) => (\n\t\t\t<RealtimeCommentsOverlay {...options} viewportRef={ctx.viewportRef} />\n\t\t),\n\t};\n}\n","\"use client\";\n\nimport {\n\ttype CSSProperties,\n\ttype KeyboardEvent,\n\ttype ReactNode,\n\ttype RefObject,\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from \"react\";\nimport type { Rect } from \"../../../math/rect\";\nimport type { VectorSceneItem } from \"../../../scene/types\";\nimport { DEFAULT_VECTOR_TOOLS } from \"../../tools\";\nimport type { VectorToolDefinition } from \"../../tools/types\";\nimport type {\n\tCustomShapePlacementOptions,\n\tVectorViewportHandle,\n\tVectorViewportProps,\n} from \"../../VectorViewport\";\nimport {\n\tcreateRealtimeCommentAvatarDataUrl,\n\tcreateRealtimeCommentDraftItem,\n\tcreateRealtimeCommentItem,\n\tisRealtimeCommentDraftItem,\n\tRealtimeCommentsOverlay,\n\twithRealtimeCommentTool,\n} from \"./realtime-comment-tool\";\n\nconst COMMENT_BUBBLE_WORLD_SIZE = 18;\n\ntype PendingCommentComposer = {\n\tworldX: number;\n\tworldY: number;\n\tbody: string;\n};\n\nexport type RealtimeCommentsAuthor = {\n\tpeerId: string;\n\tdisplayName: string;\n\tcolor: string;\n\timage?: string;\n};\n\nexport type UseRealtimeCommentsOptions = {\n\titems: readonly VectorSceneItem[];\n\tonItemsChange: (items: VectorSceneItem[]) => void;\n\tauthor: RealtimeCommentsAuthor;\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n\tactiveToolId?: string;\n\troomId?: string;\n\tsetToolId?: (toolId: string) => void;\n\ttoolAfterDraft?: string;\n\ttools?: readonly VectorToolDefinition[];\n\tcomposerTitle?: string;\n\tcomposerDescription?: string;\n\tcomposerPlaceholder?: string;\n\tcancelLabel?: string;\n\tsubmitLabel?: string;\n\tsubmitHint?: string;\n};\n\nexport type RealtimeCommentsViewportBindings = Pick<\n\tVectorViewportProps,\n\t\"customPlacement\" | \"onItemsChange\" | \"onCameraChange\"\n>;\n\nexport type UseRealtimeCommentsResult = {\n\ttools: VectorToolDefinition[];\n\toverlay: ReactNode;\n\tviewport: RealtimeCommentsViewportBindings;\n\thandleViewportItemsChange: (\n\t\titems: VectorSceneItem[],\n\t\tonItemsChange?: (items: VectorSceneItem[]) => void,\n\t) => void;\n\tisComposerOpen: boolean;\n\tcloseComposer: () => void;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n\treturn Math.min(max, Math.max(min, value));\n}\n\nfunction createCommentId(): string {\n\tif (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n\t\treturn crypto.randomUUID();\n\t}\n\treturn `comment-${Math.random().toString(36).slice(2, 10)}`;\n}\n\ntype RealtimeCommentComposerProps = {\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n\tcameraVersion: number;\n\tcomposer: PendingCommentComposer | null;\n\tauthor: RealtimeCommentsAuthor;\n\tauthorImage: string;\n\troomId?: string;\n\ttitle: string;\n\tdescription: string;\n\tplaceholder: string;\n\tcancelLabel: string;\n\tsubmitLabel: string;\n\tsubmitHint: string;\n\tonBodyChange: (body: string) => void;\n\tonCommit: () => void;\n\tonCancel: () => void;\n};\n\nfunction RealtimeCommentComposer({\n\tviewportRef,\n\tcameraVersion,\n\tcomposer,\n\tauthor,\n\tauthorImage,\n\troomId,\n\ttitle,\n\tdescription,\n\tplaceholder,\n\tcancelLabel,\n\tsubmitLabel,\n\tsubmitHint,\n\tonBodyChange,\n\tonCommit,\n\tonCancel,\n}: RealtimeCommentComposerProps) {\n\tvoid cameraVersion;\n\tconst commentInputRef = useRef<HTMLTextAreaElement>(null);\n\tconst composerRef = useRef<HTMLDivElement>(null);\n\tconst [composerSize, setComposerSize] = useState({ width: 360, height: 320 });\n\n\tuseEffect(() => {\n\t\tif (!composer) return;\n\t\tcommentInputRef.current?.focus();\n\t}, [composer]);\n\n\tconst camera = viewportRef?.current?.getCamera();\n\tconst viewportSize = viewportRef?.current?.getViewportSize();\n\n\tuseLayoutEffect(() => {\n\t\tif (!composer || !viewportSize) return;\n\t\tconst el = composerRef.current;\n\t\tif (!el) return;\n\t\tconst updateSize = () => {\n\t\t\tconst next = {\n\t\t\t\twidth: el.offsetWidth,\n\t\t\t\theight: el.offsetHeight,\n\t\t\t};\n\t\t\tsetComposerSize((current) =>\n\t\t\t\tcurrent.width === next.width && current.height === next.height\n\t\t\t\t\t? current\n\t\t\t\t\t: next,\n\t\t\t);\n\t\t};\n\t\tupdateSize();\n\t\tif (typeof ResizeObserver === \"undefined\") {\n\t\t\treturn;\n\t\t}\n\t\tconst observer = new ResizeObserver(updateSize);\n\t\tobserver.observe(el);\n\t\treturn () => observer.disconnect();\n\t}, [composer, viewportSize]);\n\n\tif (!composer) return null;\n\tif (!camera || !viewportSize) return null;\n\n\tconst anchor = camera.worldToScreen(composer.worldX, composer.worldY);\n\tconst composerWidth = Math.min(360, Math.max(220, viewportSize.width - 32));\n\tconst screenPosition = {\n\t\tleft: clamp(\n\t\t\tanchor.screenX + 20,\n\t\t\t16,\n\t\t\tMath.max(16, viewportSize.width - composerSize.width - 16),\n\t\t),\n\t\ttop: clamp(\n\t\t\tanchor.screenY - 22,\n\t\t\t16,\n\t\t\tMath.max(16, viewportSize.height - composerSize.height - 16),\n\t\t),\n\t};\n\n\tfunction handleKeyDown(event: KeyboardEvent<HTMLTextAreaElement>): void {\n\t\tif ((event.metaKey || event.ctrlKey) && event.key === \"Enter\") {\n\t\t\tevent.preventDefault();\n\t\t\tonCommit();\n\t\t\treturn;\n\t\t}\n\t\tif (event.key === \"Escape\") {\n\t\t\tevent.preventDefault();\n\t\t\tonCancel();\n\t\t}\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tref={composerRef}\n\t\t\tstyle={{\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tleft: screenPosition.left,\n\t\t\t\ttop: screenPosition.top,\n\t\t\t\tzIndex: 44,\n\t\t\t\twidth: composerWidth,\n\t\t\t\tmaxWidth: \"calc(100% - 32px)\",\n\t\t\t\tmaxHeight: \"calc(100% - 32px)\",\n\t\t\t\tpadding: 18,\n\t\t\t\tborderRadius: 22,\n\t\t\t\tbackground: \"rgba(255,255,255,0.98)\",\n\t\t\t\tborder: \"1px solid rgba(148,163,184,0.28)\",\n\t\t\t\tboxShadow: \"0 22px 48px rgba(15,23,42,0.18)\",\n\t\t\t\tbackdropFilter: \"blur(12px)\",\n\t\t\t\tpointerEvents: \"auto\",\n\t\t\t\tboxSizing: \"border-box\",\n\t\t\t\toverflow: \"auto\",\n\t\t\t}}\n\t\t>\n\t\t\t<div style={{ fontSize: 16, fontWeight: 700, color: \"#0f172a\" }}>{title}</div>\n\t\t\t<div style={{ marginTop: 6, color: \"#64748b\", fontSize: 13, lineHeight: 1.5 }}>\n\t\t\t\t{description}\n\t\t\t</div>\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\tgap: 10,\n\t\t\t\t\tmarginTop: 14,\n\t\t\t\t\tmarginBottom: 12,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<img\n\t\t\t\t\tsrc={authorImage}\n\t\t\t\t\talt={author.displayName}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\twidth: 38,\n\t\t\t\t\t\theight: 38,\n\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\tobjectFit: \"cover\",\n\t\t\t\t\t\tboxShadow: `0 0 0 2px ${author.color}22`,\n\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<div style={{ minWidth: 0 }}>\n\t\t\t\t\t<div style={{ fontWeight: 700, fontSize: 14, color: \"#0f172a\" }}>\n\t\t\t\t\t\t{author.displayName}\n\t\t\t\t\t</div>\n\t\t\t\t\t{roomId ? (\n\t\t\t\t\t\t<div style={{ color: \"#64748b\", fontSize: 12.5 }}>Sala {roomId}</div>\n\t\t\t\t\t) : null}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<textarea\n\t\t\t\tref={commentInputRef}\n\t\t\t\tvalue={composer.body}\n\t\t\t\tonChange={(event) => onBodyChange(event.target.value)}\n\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tstyle={{\n\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\tminHeight: 116,\n\t\t\t\t\tpadding: \"12px 14px\",\n\t\t\t\t\tborderRadius: 14,\n\t\t\t\t\tborder: \"1px solid #cbd5e1\",\n\t\t\t\t\tboxSizing: \"border-box\",\n\t\t\t\t\tfontFamily: \"inherit\",\n\t\t\t\t\tfontSize: 15,\n\t\t\t\t\tlineHeight: 1.5,\n\t\t\t\t\tcolor: \"#0f172a\",\n\t\t\t\t\tresize: \"vertical\",\n\t\t\t\t}}\n\t\t\t/>\n\t\t\t<div\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\tjustifyContent: \"space-between\",\n\t\t\t\t\talignItems: \"flex-end\",\n\t\t\t\t\tflexWrap: \"wrap\",\n\t\t\t\t\tgap: 10,\n\t\t\t\t\tmarginTop: 12,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"#64748b\",\n\t\t\t\t\t\tfontSize: 11.5,\n\t\t\t\t\t\tlineHeight: 1.4,\n\t\t\t\t\t\tflex: \"1 1 120px\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{submitHint}\n\t\t\t\t</div>\n\t\t\t\t<div style={{ display: \"flex\", gap: 8, flexShrink: 0 }}>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onCancel}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tpadding: \"10px 14px\",\n\t\t\t\t\t\t\tborderRadius: 12,\n\t\t\t\t\t\t\tborder: \"1px solid #cbd5e1\",\n\t\t\t\t\t\t\tbackground: \"#fff\",\n\t\t\t\t\t\t\tfontFamily: \"inherit\",\n\t\t\t\t\t\t\tfontSize: 14,\n\t\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\tcursor: \"pointer\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{cancelLabel}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={onCommit}\n\t\t\t\t\t\tdisabled={!composer.body.trim()}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\tpadding: \"10px 14px\",\n\t\t\t\t\t\t\tborderRadius: 12,\n\t\t\t\t\t\t\tborder: \"1px solid #6d28d9\",\n\t\t\t\t\t\t\tbackground: composer.body.trim() ? \"#7c3aed\" : \"#c4b5fd\",\n\t\t\t\t\t\t\tcolor: \"#fff\",\n\t\t\t\t\t\t\tfontFamily: \"inherit\",\n\t\t\t\t\t\t\tfontSize: 14,\n\t\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\tcursor: composer.body.trim() ? \"pointer\" : \"not-allowed\",\n\t\t\t\t\t\t\topacity: composer.body.trim() ? 1 : 0.72,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t{submitLabel}\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nconst overlayShell: CSSProperties = {\n\tposition: \"absolute\",\n\tinset: 0,\n\tpointerEvents: \"none\",\n\tzIndex: 26,\n\toverflow: \"hidden\",\n};\n\ntype RealtimeCommentsOverlayNodeOptions = {\n\titems: readonly VectorSceneItem[];\n\tonItemsChange: (items: VectorSceneItem[]) => void;\n\tisDragEnabled: boolean;\n\tcameraVersion: number;\n\tcomposer: PendingCommentComposer | null;\n\tauthor: RealtimeCommentsAuthor;\n\tauthorImage: string;\n\troomId?: string;\n\ttitle: string;\n\tdescription: string;\n\tplaceholder: string;\n\tcancelLabel: string;\n\tsubmitLabel: string;\n\tsubmitHint: string;\n\tonBodyChange: (body: string) => void;\n\tonCommit: () => void;\n\tonCancel: () => void;\n};\n\nfunction renderRealtimeCommentsOverlayNode(\n\toptions: RealtimeCommentsOverlayNodeOptions,\n\tviewportRef?: RefObject<VectorViewportHandle | null>,\n): ReactNode {\n\treturn (\n\t\t<div style={overlayShell}>\n\t\t\t<RealtimeCommentsOverlay\n\t\t\t\titems={options.items}\n\t\t\t\tonItemsChange={options.onItemsChange}\n\t\t\t\tisDragEnabled={options.isDragEnabled}\n\t\t\t\tcameraVersion={options.cameraVersion}\n\t\t\t\tviewportRef={viewportRef}\n\t\t\t/>\n\t\t\t<RealtimeCommentComposer\n\t\t\t\tviewportRef={viewportRef}\n\t\t\t\tcameraVersion={options.cameraVersion}\n\t\t\t\tcomposer={options.composer}\n\t\t\t\tauthor={options.author}\n\t\t\t\tauthorImage={options.authorImage}\n\t\t\t\troomId={options.roomId}\n\t\t\t\ttitle={options.title}\n\t\t\t\tdescription={options.description}\n\t\t\t\tplaceholder={options.placeholder}\n\t\t\t\tcancelLabel={options.cancelLabel}\n\t\t\t\tsubmitLabel={options.submitLabel}\n\t\t\t\tsubmitHint={options.submitHint}\n\t\t\t\tonBodyChange={options.onBodyChange}\n\t\t\t\tonCommit={options.onCommit}\n\t\t\t\tonCancel={options.onCancel}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\nexport function useRealtimeComments({\n\titems,\n\tonItemsChange,\n\tauthor,\n\tviewportRef,\n\tactiveToolId,\n\troomId,\n\tsetToolId,\n\ttoolAfterDraft = \"select\",\n\ttools: providedTools = DEFAULT_VECTOR_TOOLS,\n\tcomposerTitle = \"Novo comentário\",\n\tcomposerDescription = \"Escreva algo para a equipe. Ao enviar, a bolha sincroniza na sala.\",\n\tcomposerPlaceholder = \"Contexto, decisao, duvida, feedback...\",\n\tcancelLabel = \"Cancelar\",\n\tsubmitLabel = \"Publicar comentário\",\n\tsubmitHint = \"`Ctrl/Cmd + Enter` envia\",\n}: UseRealtimeCommentsOptions): UseRealtimeCommentsResult {\n\tconst [cameraVersion, setCameraVersion] = useState(0);\n\tconst [commentComposer, setCommentComposer] =\n\t\tuseState<PendingCommentComposer | null>(null);\n\n\tconst authorImage = useMemo(\n\t\t() =>\n\t\t\tauthor.image ??\n\t\t\tcreateRealtimeCommentAvatarDataUrl(author.displayName, author.color),\n\t\t[author.color, author.displayName, author.image],\n\t);\n\n\tconst tools = useMemo(\n\t\t() => withRealtimeCommentTool(providedTools),\n\t\t[providedTools],\n\t);\n\n\tconst customPlacement = useMemo<CustomShapePlacementOptions>(\n\t\t() => ({\n\t\t\ttoolId: \"comment\",\n\t\t\tcreateItem: ({ id, bounds }: { id: string; bounds: Rect }) =>\n\t\t\t\tcreateRealtimeCommentDraftItem(id, bounds, author.color),\n\t\t}),\n\t\t[author.color],\n\t);\n\n\tconst handleViewportItemsChange = useCallback(\n\t\t(\n\t\t\tnextItems: VectorSceneItem[],\n\t\t\toverrideOnItemsChange?: (items: VectorSceneItem[]) => void,\n\t\t) => {\n\t\t\tconst applyItemsChange = overrideOnItemsChange ?? onItemsChange;\n\t\t\tconst currentIds = new Set(items.map((item) => item.id));\n\t\t\tconst draftItem = nextItems.find(\n\t\t\t\t(item) => !currentIds.has(item.id) && isRealtimeCommentDraftItem(item),\n\t\t\t);\n\t\t\tif (!draftItem) {\n\t\t\t\tapplyItemsChange(nextItems);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst filteredItems = nextItems.filter((item) => item.id !== draftItem.id);\n\t\t\tconst shouldPersistFiltered =\n\t\t\t\tfilteredItems.length !== items.length ||\n\t\t\t\tfilteredItems.some((item, index) => items[index]?.id !== item.id);\n\t\t\tif (shouldPersistFiltered) {\n\t\t\t\tapplyItemsChange(filteredItems);\n\t\t\t}\n\n\t\t\tsetCommentComposer({\n\t\t\t\tworldX: draftItem.bounds.x + draftItem.bounds.width / 2,\n\t\t\t\tworldY: draftItem.bounds.y + draftItem.bounds.height / 2,\n\t\t\t\tbody: \"\",\n\t\t\t});\n\t\t\tsetToolId?.(toolAfterDraft);\n\t\t},\n\t\t[items, onItemsChange, setToolId, toolAfterDraft],\n\t);\n\n\tconst onCameraChange = useCallback(() => {\n\t\tsetCameraVersion((value) => value + 1);\n\t}, []);\n\n\tconst closeComposer = useCallback(() => {\n\t\tsetCommentComposer(null);\n\t}, []);\n\n\tconst onComposerBodyChange = useCallback((body: string) => {\n\t\tsetCommentComposer((current) => (current ? { ...current, body } : current));\n\t}, []);\n\n\tconst onComposerCommit = useCallback(() => {\n\t\tif (!commentComposer) return;\n\t\tconst body = commentComposer.body.trim();\n\t\tif (!body) return;\n\n\t\tconst half = COMMENT_BUBBLE_WORLD_SIZE / 2;\n\t\tconst nextItem = createRealtimeCommentItem(\n\t\t\tcreateCommentId(),\n\t\t\t{\n\t\t\t\tx: commentComposer.worldX - half,\n\t\t\t\ty: commentComposer.worldY - half,\n\t\t\t\twidth: COMMENT_BUBBLE_WORLD_SIZE,\n\t\t\t\theight: COMMENT_BUBBLE_WORLD_SIZE,\n\t\t\t},\n\t\t\t{\n\t\t\t\tbody,\n\t\t\t\tcreatedAt: Date.now(),\n\t\t\t\tauthorPeerId: author.peerId,\n\t\t\t\tauthorDisplayName: author.displayName,\n\t\t\t\tauthorColor: author.color,\n\t\t\t\tauthorImage: authorImage,\n\t\t\t},\n\t\t);\n\n\t\tonItemsChange(items.concat(nextItem));\n\t\tsetCommentComposer(null);\n\t}, [\n\t\tauthor.color,\n\t\tauthor.displayName,\n\t\tauthor.peerId,\n\t\tauthorImage,\n\t\tcommentComposer,\n\t\titems,\n\t\tonItemsChange,\n\t]);\n\n\tconst overlay = useMemo(\n\t\t() =>\n\t\t\trenderRealtimeCommentsOverlayNode(\n\t\t\t\t{\n\t\t\t\t\titems,\n\t\t\t\t\tonItemsChange,\n\t\t\t\t\tisDragEnabled: activeToolId === \"select\",\n\t\t\t\t\tcameraVersion,\n\t\t\t\t\tcomposer: commentComposer,\n\t\t\t\t\tauthor,\n\t\t\t\t\tauthorImage,\n\t\t\t\t\troomId,\n\t\t\t\t\ttitle: composerTitle,\n\t\t\t\t\tdescription: composerDescription,\n\t\t\t\t\tplaceholder: composerPlaceholder,\n\t\t\t\t\tcancelLabel,\n\t\t\t\t\tsubmitLabel,\n\t\t\t\t\tsubmitHint,\n\t\t\t\t\tonBodyChange: onComposerBodyChange,\n\t\t\t\t\tonCommit: onComposerCommit,\n\t\t\t\t\tonCancel: closeComposer,\n\t\t\t\t},\n\t\t\t\tviewportRef,\n\t\t\t),\n\t\t[\n\t\t\tauthor,\n\t\t\tauthorImage,\n\t\t\tcameraVersion,\n\t\t\tcancelLabel,\n\t\t\tcloseComposer,\n\t\t\tcommentComposer,\n\t\t\tcomposerDescription,\n\t\t\tcomposerPlaceholder,\n\t\t\tcomposerTitle,\n\t\t\titems,\n\t\t\tactiveToolId,\n\t\t\tonItemsChange,\n\t\t\tonComposerBodyChange,\n\t\t\tonComposerCommit,\n\t\t\troomId,\n\t\t\tsubmitHint,\n\t\t\tsubmitLabel,\n\t\t\tviewportRef,\n\t\t],\n\t);\n\n\tconst viewport = useMemo(\n\t\t() => ({\n\t\t\tcustomPlacement,\n\t\t\tonItemsChange: (nextItems: VectorSceneItem[]) =>\n\t\t\t\thandleViewportItemsChange(nextItems),\n\t\t\tonCameraChange,\n\t\t}),\n\t\t[customPlacement, handleViewportItemsChange, onCameraChange],\n\t);\n\n\treturn useMemo(\n\t\t() => ({\n\t\t\ttools,\n\t\t\toverlay,\n\t\t\tviewport,\n\t\t\thandleViewportItemsChange,\n\t\t\tisComposerOpen: commentComposer != null,\n\t\t\tcloseComposer,\n\t\t}),\n\t\t[\n\t\t\tcloseComposer,\n\t\t\tcommentComposer,\n\t\t\thandleViewportItemsChange,\n\t\t\toverlay,\n\t\t\ttools,\n\t\t\tviewport,\n\t\t],\n\t);\n}\n","\"use client\";\n\nimport type { RefObject } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\nimport type { VectorViewportHandle } from \"../../VectorViewport\";\nimport type { RealtimeSessionPeer } from \"./protocol\";\n\nexport type UseRealtimePeerFollowOptions = {\n\tviewportRef: RefObject<VectorViewportHandle | null>;\n\tsessionPeers: RealtimeSessionPeer[];\n\tfollowedPeerId: string | null | undefined;\n\tonFollowEnd?: () => void;\n};\n\ntype ViewportCameraSnapshot = {\n\tx: number;\n\ty: number;\n\tzoom: number;\n\tviewportWidth: number;\n\tviewportHeight: number;\n};\n\nconst viewportFollowSyncSnapshots = new WeakMap<\n\tVectorViewportHandle,\n\tViewportCameraSnapshot\n>();\n\nfunction getFollowedPeer(\n\tsessionPeers: RealtimeSessionPeer[],\n\tfollowedPeerId: string,\n): RealtimeSessionPeer | undefined {\n\treturn sessionPeers.find(\n\t\t(peerState) =>\n\t\t\tpeerState.peerId === followedPeerId || peerState.id === followedPeerId,\n\t);\n}\n\nfunction getCameraKey(peer: RealtimeSessionPeer): string | null {\n\tif (!peer.camera) return null;\n\treturn [\n\t\tpeer.peerId,\n\t\tpeer.camera.x,\n\t\tpeer.camera.y,\n\t\tpeer.camera.zoom,\n\t\tpeer.camera.viewportWidth,\n\t\tpeer.camera.viewportHeight,\n\t].join(\":\");\n}\n\nfunction getViewportSizeKey(viewport: VectorViewportHandle | null): string | null {\n\tif (!viewport) return null;\n\tconst viewportSize = viewport.getViewportSize();\n\treturn [viewportSize.width, viewportSize.height].join(\":\");\n}\n\nfunction getFollowedCameraPosition(\n\tviewport: VectorViewportHandle,\n\tpeer: RealtimeSessionPeer,\n): { x: number; y: number; zoom: number } | null {\n\tif (!peer.camera) return null;\n\tconst viewportSize = viewport.getViewportSize();\n\treturn {\n\t\tx: peer.camera.x + (viewportSize.width - peer.camera.viewportWidth) / 2,\n\t\ty: peer.camera.y + (viewportSize.height - peer.camera.viewportHeight) / 2,\n\t\tzoom: peer.camera.zoom,\n\t};\n}\n\nfunction applyPeerCamera(\n\tviewport: VectorViewportHandle,\n\tpeer: RealtimeSessionPeer,\n): boolean {\n\tconst camera = viewport.getCamera();\n\tconst nextCamera = getFollowedCameraPosition(viewport, peer);\n\tconst viewportSize = viewport.getViewportSize();\n\tif (!camera || !nextCamera) return false;\n\tif (\n\t\tcamera.x === nextCamera.x &&\n\t\tcamera.y === nextCamera.y &&\n\t\tcamera.zoom === nextCamera.zoom\n\t) {\n\t\treturn true;\n\t}\n\tmarkViewportFollowSync(viewport, {\n\t\tx: nextCamera.x,\n\t\ty: nextCamera.y,\n\t\tzoom: nextCamera.zoom,\n\t\tviewportWidth: viewportSize.width,\n\t\tviewportHeight: viewportSize.height,\n\t});\n\tcamera.x = nextCamera.x;\n\tcamera.y = nextCamera.y;\n\tcamera.zoom = nextCamera.zoom;\n\tviewport.requestRender();\n\treturn true;\n}\n\nexport function markViewportFollowSync(\n\tviewport: VectorViewportHandle,\n\tsnapshot: ViewportCameraSnapshot,\n): void {\n\tviewportFollowSyncSnapshots.set(viewport, snapshot);\n}\n\nexport function consumeViewportFollowSync(\n\tviewport: VectorViewportHandle,\n\tsnapshot: ViewportCameraSnapshot,\n): boolean {\n\tconst currentSnapshot = viewportFollowSyncSnapshots.get(viewport);\n\tif (\n\t\t!currentSnapshot ||\n\t\tcurrentSnapshot.x !== snapshot.x ||\n\t\tcurrentSnapshot.y !== snapshot.y ||\n\t\tcurrentSnapshot.zoom !== snapshot.zoom ||\n\t\tcurrentSnapshot.viewportWidth !== snapshot.viewportWidth ||\n\t\tcurrentSnapshot.viewportHeight !== snapshot.viewportHeight\n\t) {\n\t\treturn false;\n\t}\n\tviewportFollowSyncSnapshots.delete(viewport);\n\treturn true;\n}\n\nexport function useRealtimePeerFollow(options: UseRealtimePeerFollowOptions): void {\n\tconst { viewportRef, sessionPeers, followedPeerId, onFollowEnd } = options;\n\tconst endedPeerIdRef = useRef<string | null>(null);\n\tconst lastAppliedCameraKeyRef = useRef<string | null>(null);\n\tconst [, setViewportSizeVersion] = useState(0);\n\n\tuseEffect(() => {\n\t\tif (!followedPeerId) return;\n\t\tlet animationFrameId = 0;\n\t\tlet lastViewportSizeKey = getViewportSizeKey(viewportRef.current ?? null);\n\n\t\tconst checkViewportSize = () => {\n\t\t\tconst nextViewportSizeKey = getViewportSizeKey(viewportRef.current ?? null);\n\t\t\tif (nextViewportSizeKey !== lastViewportSizeKey) {\n\t\t\t\tlastViewportSizeKey = nextViewportSizeKey;\n\t\t\t\tsetViewportSizeVersion((value) => value + 1);\n\t\t\t}\n\t\t\tanimationFrameId = window.requestAnimationFrame(checkViewportSize);\n\t\t};\n\n\t\tanimationFrameId = window.requestAnimationFrame(checkViewportSize);\n\t\treturn () => {\n\t\t\twindow.cancelAnimationFrame(animationFrameId);\n\t\t};\n\t}, [followedPeerId, viewportRef]);\n\n\tuseEffect(() => {\n\t\tif (!followedPeerId) {\n\t\t\tendedPeerIdRef.current = null;\n\t\t\tlastAppliedCameraKeyRef.current = null;\n\t\t\treturn;\n\t\t}\n\n\t\tconst followedPeer = getFollowedPeer(sessionPeers, followedPeerId);\n\t\tif (!followedPeer) {\n\t\t\tlastAppliedCameraKeyRef.current = null;\n\t\t\tif (endedPeerIdRef.current === followedPeerId) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tendedPeerIdRef.current = followedPeerId;\n\t\t\tonFollowEnd?.();\n\t\t\treturn;\n\t\t}\n\t\tif (!followedPeer.camera) {\n\t\t\tendedPeerIdRef.current = null;\n\t\t\tlastAppliedCameraKeyRef.current = null;\n\t\t\treturn;\n\t\t}\n\n\t\tendedPeerIdRef.current = null;\n\t\tconst viewport = viewportRef.current;\n\t\tconst nextCameraKey = [\n\t\t\tgetCameraKey(followedPeer),\n\t\t\tgetViewportSizeKey(viewport ?? null),\n\t\t].join(\":\");\n\t\tif (nextCameraKey && nextCameraKey === lastAppliedCameraKeyRef.current) {\n\t\t\treturn;\n\t\t}\n\t\tif (!viewport || !applyPeerCamera(viewport, followedPeer)) {\n\t\t\treturn;\n\t\t}\n\t\tlastAppliedCameraKeyRef.current = nextCameraKey;\n\t}, [followedPeerId, onFollowEnd, sessionPeers, viewportRef]);\n}\n","import * as Y from \"yjs\";\nimport type { VectorSceneItem } from \"../../../scene/types\";\n\n// Phase 1 design: Yjs is the local source of truth for items, but the wire\n// protocol remains items-array snapshots (so legacy boards and unchanged\n// server work). The CRDT semantics buy us per-field merge on the client side\n// and accurate distinction between \"deleted by another user\" vs \"added\n// locally and not yet synced\".\n//\n// Y.Doc shape:\n// doc.getArray<Y.Map>(\"items\") → ordered list of items\n// each Y.Map has the VectorSceneItem fields (id, toolKind, bounds, etc.)\n//\n// We never put blob handles or rasterized image refs into the Y.Doc — those\n// are local-only and would not survive sync. sanitizeRealtimeItem upstream\n// already strips them before items reach this layer for outbound.\n\nconst ITEMS_KEY = \"items\";\n\n// Window during which a freshly server-added id is protected from being\n// deleted by a local-items update. Necessary because the React consumer that\n// drives applyLocalItemsToYDoc cannot have rendered the just-received server\n// item yet, so its \"current local view\" legitimately lacks it. Without this\n// guard, a user drawing at 60fps while another peer adds items causes those\n// inbound items to vanish from the Y.Doc the next time the consumer's\n// onItemsChange fires.\nconst SERVER_ADD_RACE_WINDOW_MS = 2000;\n\nexport type YjsBoardDoc = {\n\treadonly doc: Y.Doc;\n\treadonly yItems: Y.Array<Y.Map<unknown>>;\n\t/**\n\t * Set of item ids that the server has confirmed in its latest snapshot.\n\t * Items present in the Y.Doc whose id is NOT in this set are considered\n\t * locally-pending — they have not yet been seen by the server. When a\n\t * server snapshot arrives lacking an id that IS in this set, we know the\n\t * server deleted it (rather than simply not having seen our local copy).\n\t */\n\tlastServerConfirmedIds: Set<string>;\n\tlastServerConfirmedItemSerializations: Map<string, string>;\n\t/**\n\t * Map of id → timestamp (ms) recording when the server most recently\n\t * surfaced an item. Used to protect freshly added remote items from being\n\t * deleted by a stale local-items update during the React-render race\n\t * window. Entries older than SERVER_ADD_RACE_WINDOW_MS are eligible for\n\t * pruning during deletion checks.\n\t */\n\tserverItemSeenAt: Map<string, number>;\n};\n\nexport function createYjsBoardDoc(): YjsBoardDoc {\n\tconst doc = new Y.Doc();\n\tconst yItems = doc.getArray<Y.Map<unknown>>(ITEMS_KEY);\n\treturn {\n\t\tdoc,\n\t\tyItems,\n\t\tlastServerConfirmedIds: new Set(),\n\t\tlastServerConfirmedItemSerializations: new Map(),\n\t\tserverItemSeenAt: new Map(),\n\t};\n}\n\nfunction getItemId(item: VectorSceneItem | Y.Map<unknown>): string | null {\n\tif (item instanceof Y.Map) {\n\t\tconst id = item.get(\"id\");\n\t\treturn typeof id === \"string\" ? id : null;\n\t}\n\tconst id = (item as { id?: unknown }).id;\n\treturn typeof id === \"string\" ? id : null;\n}\n\nfunction vectorItemToYMap(item: VectorSceneItem): Y.Map<unknown> {\n\tconst yMap = new Y.Map<unknown>();\n\tfor (const [key, value] of Object.entries(item)) {\n\t\tif (value === undefined) continue;\n\t\tyMap.set(key, value);\n\t}\n\treturn yMap;\n}\n\nfunction yMapToVectorItem(yMap: Y.Map<unknown>): VectorSceneItem {\n\tconst obj: Record<string, unknown> = {};\n\tfor (const [key, value] of yMap.entries()) {\n\t\tobj[key] = value;\n\t}\n\treturn obj as VectorSceneItem;\n}\n\n/**\n * Project the current Y.Doc state to a plain items array for the React\n * consumer (canvu's VectorCanvas).\n */\nexport function readVectorItems(yItems: Y.Array<Y.Map<unknown>>): VectorSceneItem[] {\n\tconst result: VectorSceneItem[] = [];\n\tfor (let i = 0; i < yItems.length; i++) {\n\t\tconst yMap = yItems.get(i);\n\t\tif (yMap) result.push(yMapToVectorItem(yMap));\n\t}\n\treturn result;\n}\n\n/**\n * Build an index of the current Y.Doc items by id for fast lookups during\n * merge. Items without an id are skipped — they cannot be reconciled by id\n * and stay as-is.\n */\nfunction indexYItemsById(\n\tyItems: Y.Array<Y.Map<unknown>>,\n): Map<string, { yMap: Y.Map<unknown>; index: number }> {\n\tconst result = new Map<string, { yMap: Y.Map<unknown>; index: number }>();\n\tfor (let i = 0; i < yItems.length; i++) {\n\t\tconst yMap = yItems.get(i);\n\t\tif (!yMap) continue;\n\t\tconst id = getItemId(yMap);\n\t\tif (!id) continue;\n\t\tresult.set(id, { yMap, index: i });\n\t}\n\treturn result;\n}\n\nfunction valuesEqual(left: unknown, right: unknown): boolean {\n\tif (left === right) return true;\n\tif (typeof left !== typeof right) return false;\n\tif (left === null || right === null) return false;\n\tif (typeof left !== \"object\") return false;\n\ttry {\n\t\treturn JSON.stringify(left) === JSON.stringify(right);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction serializeItem(value: VectorSceneItem | Y.Map<unknown>): string {\n\tconst item = value instanceof Y.Map ? yMapToVectorItem(value) : value;\n\treturn JSON.stringify(item);\n}\n\n/**\n * Update a Y.Map in place to match a target VectorSceneItem, touching only\n * the fields that actually changed. This keeps Yjs ops minimal and avoids\n * triggering observers for no-op updates.\n */\nfunction updateYMapInPlace(yMap: Y.Map<unknown>, next: VectorSceneItem): void {\n\tconst nextKeys = new Set<string>();\n\tfor (const [key, value] of Object.entries(next)) {\n\t\tif (value === undefined) continue;\n\t\tnextKeys.add(key);\n\t\tconst current = yMap.get(key);\n\t\tif (!valuesEqual(current, value)) {\n\t\t\tyMap.set(key, value);\n\t\t}\n\t}\n\tfor (const key of Array.from(yMap.keys())) {\n\t\tif (!nextKeys.has(key)) yMap.delete(key);\n\t}\n}\n\nexport type ApplyLocalItemsOptions = {\n\t/**\n\t * Items provided by the local consumer (canvu's VectorCanvas onItemsChange).\n\t * The Y.Doc is mutated to match this set: new ids are added (in the order\n\t * they appear), changed ids have their Y.Map fields updated, and ids\n\t * missing from the new list are removed.\n\t *\n\t * All mutations happen inside a single Y transaction so observers see one\n\t * coherent change.\n\t */\n\titems: readonly VectorSceneItem[];\n\t/**\n\t * Optional origin tag for the transaction. Useful to distinguish local\n\t * edits from remote applies when observing the doc.\n\t */\n\torigin?: unknown;\n};\n\n/**\n * Apply a complete items array from the local consumer as a set of minimal\n * Yjs operations. Order of the next array becomes the order in the Y.Array.\n *\n * Returns the list of item ids that are newly introduced (not present before\n * this call), so the caller can track them as \"locally-pending until server\n * confirms\".\n */\nexport function applyLocalItemsToYDoc(\n\tboard: YjsBoardDoc,\n\toptions: ApplyLocalItemsOptions,\n): { addedIds: string[]; removedIds: string[] } {\n\tconst { items, origin } = options;\n\tconst addedIds: string[] = [];\n\tconst removedIds: string[] = [];\n\tconst now = Date.now();\n\tboard.doc.transact(() => {\n\t\tconst currentIndex = indexYItemsById(board.yItems);\n\t\tconst nextIds = new Set<string>();\n\t\tfor (const item of items) {\n\t\t\tconst id = getItemId(item);\n\t\t\tif (!id) continue;\n\t\t\tnextIds.add(id);\n\t\t}\n\t\t// Walk deletes in descending index order so removals don't shift the\n\t\t// indices of items still pending deletion.\n\t\tconst toDelete: Array<{ id: string; index: number }> = [];\n\t\tfor (const [id, entry] of currentIndex) {\n\t\t\tif (nextIds.has(id)) continue;\n\t\t\t// Race guard: an id that the server surfaced within the last race\n\t\t\t// window may simply not have been rendered by the React consumer\n\t\t\t// yet, so its absence from `items` is not a real user delete.\n\t\t\t// Preserve it; the next local update after the consumer re-renders\n\t\t\t// will include it (no-op) or genuinely omit it (after the window\n\t\t\t// elapses, deletion will then go through).\n\t\t\tconst serverSeenAt = board.serverItemSeenAt.get(id);\n\t\t\tif (serverSeenAt != null && now - serverSeenAt < SERVER_ADD_RACE_WINDOW_MS) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttoDelete.push({ id, index: entry.index });\n\t\t}\n\t\ttoDelete.sort((a, b) => b.index - a.index);\n\t\tfor (const { id, index } of toDelete) {\n\t\t\tboard.yItems.delete(index, 1);\n\t\t\tboard.serverItemSeenAt.delete(id);\n\t\t\tremovedIds.push(id);\n\t\t}\n\t\tconst refreshedIndex = indexYItemsById(board.yItems);\n\t\tfor (let nextOrder = 0; nextOrder < items.length; nextOrder++) {\n\t\t\tconst item = items[nextOrder];\n\t\t\tif (!item) continue;\n\t\t\tconst id = getItemId(item);\n\t\t\tif (!id) continue;\n\t\t\tconst existing = refreshedIndex.get(id);\n\t\t\tif (existing) {\n\t\t\t\tupdateYMapInPlace(existing.yMap, item);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst yMap = vectorItemToYMap(item);\n\t\t\tboard.yItems.push([yMap]);\n\t\t\taddedIds.push(id);\n\t\t}\n\t}, origin);\n\treturn { addedIds, removedIds };\n}\n\nexport type ApplyServerSnapshotOptions = {\n\t/**\n\t * Server-confirmed items snapshot. Ordering of the snapshot is treated as\n\t * authoritative for items the server knows about.\n\t */\n\titems: readonly VectorSceneItem[];\n\t/**\n\t * Optional origin tag for the transaction.\n\t */\n\torigin?: unknown;\n};\n\n/**\n * Reconcile a server snapshot into the Y.Doc, additively.\n *\n * Rules:\n * - id present in snapshot AND in Y.Doc → update Y.Map fields in place.\n * - id present in snapshot AND NOT in Y.Doc → add to Y.Doc.\n * - id present in Y.Doc, NOT in snapshot → **keep**. We intentionally do\n * not delete based on server absence. With a snapshot wire protocol and\n * a store-and-broadcast server that does not merge, we cannot tell\n * \"another peer deleted this id\" apart from \"another peer sent a stale\n * snapshot that didn't include this id yet\". Treating absence as delete\n * caused a cascading wipe: each peer's update removed the others'\n * unsynced items, peer A's next snapshot then removed peer B's items\n * again, until everything converged to empty.\n *\n * The cost of being conservative: deletes performed by other peers do\n * not propagate visually. Local user deletes still work via\n * applyLocalItemsToYDoc (their Y.Doc loses the item, the next flush\n * pushes the new state up). Fixing cross-peer deletes properly requires\n * an explicit delete signal on the wire — that is Phase 2 (ops-based\n * protocol with server-side merge).\n *\n * `board.lastServerConfirmedIds` is still updated to the snapshot id set so\n * the local delete path's race guard remains accurate.\n */\nexport function applyServerSnapshotToYDoc(\n\tboard: YjsBoardDoc,\n\toptions: ApplyServerSnapshotOptions,\n): void {\n\tconst { items: snapshotItems, origin } = options;\n\tconst now = Date.now();\n\tboard.doc.transact(() => {\n\t\tfor (const item of snapshotItems) {\n\t\t\tconst id = getItemId(item);\n\t\t\tif (!id) continue;\n\t\t\tconst existing = indexYItemsById(board.yItems).get(id);\n\t\t\tif (existing) {\n\t\t\t\tconst currentSerialized = serializeItem(existing.yMap);\n\t\t\t\tconst incomingSerialized = serializeItem(item);\n\t\t\t\tconst confirmedSerialized =\n\t\t\t\t\tboard.lastServerConfirmedItemSerializations.get(id);\n\t\t\t\tconst hasPendingLocalChange =\n\t\t\t\t\tconfirmedSerialized === undefined\n\t\t\t\t\t\t? currentSerialized !== incomingSerialized\n\t\t\t\t\t\t: currentSerialized !== confirmedSerialized &&\n\t\t\t\t\t\t\tcurrentSerialized !== incomingSerialized;\n\t\t\t\tif (hasPendingLocalChange) {\n\t\t\t\t\tboard.serverItemSeenAt.set(id, now);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tupdateYMapInPlace(existing.yMap, item);\n\t\t\t\tboard.serverItemSeenAt.set(id, now);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst yMap = vectorItemToYMap(item);\n\t\t\tboard.yItems.push([yMap]);\n\t\t\tboard.serverItemSeenAt.set(id, now);\n\t\t}\n\t}, origin);\n\n\tboard.lastServerConfirmedIds = new Set();\n\tboard.lastServerConfirmedItemSerializations = new Map();\n\tfor (const item of snapshotItems) {\n\t\tconst id = getItemId(item);\n\t\tif (id) {\n\t\t\tboard.lastServerConfirmedIds.add(id);\n\t\t\tboard.lastServerConfirmedItemSerializations.set(id, serializeItem(item));\n\t\t}\n\t}\n}\n\n/**\n * Replace the entire Y.Doc state with a snapshot, discarding any local\n * changes. Used on initial load when no local draft exists and we just want\n * the server's view.\n */\nexport function replaceYDocWithSnapshot(\n\tboard: YjsBoardDoc,\n\toptions: ApplyServerSnapshotOptions,\n): void {\n\tconst { items: snapshotItems, origin } = options;\n\tconst now = Date.now();\n\tboard.doc.transact(() => {\n\t\tif (board.yItems.length > 0) {\n\t\t\tboard.yItems.delete(0, board.yItems.length);\n\t\t}\n\t\tfor (const item of snapshotItems) {\n\t\t\tboard.yItems.push([vectorItemToYMap(item)]);\n\t\t}\n\t}, origin);\n\tboard.lastServerConfirmedIds = new Set();\n\tboard.lastServerConfirmedItemSerializations = new Map();\n\tboard.serverItemSeenAt = new Map();\n\tfor (const item of snapshotItems) {\n\t\tconst id = getItemId(item);\n\t\tif (id) {\n\t\t\tboard.lastServerConfirmedIds.add(id);\n\t\t\tboard.lastServerConfirmedItemSerializations.set(id, serializeItem(item));\n\t\t\tboard.serverItemSeenAt.set(id, now);\n\t\t}\n\t}\n}\n\n/**\n * Return ids of items currently in the Y.Doc that have not yet been\n * confirmed in a server snapshot. These are the user's local additions still\n * waiting for the server to round-trip.\n */\nexport function getLocallyPendingItemIds(board: YjsBoardDoc): Set<string> {\n\tconst pending = new Set<string>();\n\tfor (let i = 0; i < board.yItems.length; i++) {\n\t\tconst yMap = board.yItems.get(i);\n\t\tif (!yMap) continue;\n\t\tconst id = getItemId(yMap);\n\t\tif (!id) continue;\n\t\tconst confirmedSerialized = board.lastServerConfirmedItemSerializations.get(id);\n\t\tif (!confirmedSerialized || serializeItem(yMap) !== confirmedSerialized) {\n\t\t\tpending.add(id);\n\t\t}\n\t}\n\treturn pending;\n}\n\n/**\n * Encode the Y.Doc state for persistence (localStorage offline draft).\n * Returns a base64-ish string suitable for JSON storage.\n */\nexport function encodeYDocState(board: YjsBoardDoc): string {\n\tconst update = Y.encodeStateAsUpdate(board.doc);\n\tlet binary = \"\";\n\tfor (let i = 0; i < update.length; i++) {\n\t\tbinary += String.fromCharCode(update[i] as number);\n\t}\n\treturn btoa(binary);\n}\n\n/**\n * Decode and apply a previously-encoded Y.Doc state. Returns true if the\n * state was applied successfully.\n */\nexport function decodeYDocState(board: YjsBoardDoc, encoded: string): boolean {\n\ttry {\n\t\tconst binary = atob(encoded);\n\t\tconst update = new Uint8Array(binary.length);\n\t\tfor (let i = 0; i < binary.length; i++) {\n\t\t\tupdate[i] = binary.charCodeAt(i);\n\t\t}\n\t\tY.applyUpdate(board.doc, update);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n","\"use client\";\n\nimport type { RefObject } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { VectorSceneItem } from \"../../../scene/types\";\nimport type { PlacementPreview } from \"../../InteractionOverlay\";\nimport type { VectorCanvasRemoteAdapter } from \"../../persistence\";\nimport { remoteMarkupStrokeFromPlacementPreview } from \"../../presence\";\nimport type {\n\tVectorViewportHandle,\n\tVectorViewportProps,\n} from \"../../VectorViewport\";\nimport {\n\tparseRealtimeServerMessage,\n\ttype RealtimeClientMessage,\n\ttype RealtimeConnectionInfo,\n\ttype RealtimeDocumentSnapshot,\n\ttype RealtimeSessionPeer,\n} from \"./protocol\";\nimport { consumeViewportFollowSync } from \"./use-realtime-peer-follow\";\nimport {\n\tapplyLocalItemsToYDoc,\n\tapplyServerSnapshotToYDoc,\n\tcreateYjsBoardDoc,\n\tdecodeYDocState,\n\tencodeYDocState,\n\tgetLocallyPendingItemIds,\n\treadVectorItems,\n\treplaceYDocWithSnapshot,\n\ttype YjsBoardDoc,\n} from \"./yjs-document\";\n\n// Origin tags for Y.Doc transactions. Used to distinguish local edits from\n// remote applies when observing the doc so we can avoid feedback loops.\nconst ORIGIN_LOCAL = Symbol(\"canvu/realtime/local\");\nconst ORIGIN_REMOTE = Symbol(\"canvu/realtime/remote\");\nconst ORIGIN_BOOTSTRAP = Symbol(\"canvu/realtime/bootstrap\");\n\ntype RealtimeSessionPeerInput = {\n\tid: string;\n\tdisplayName?: string;\n\tcolor?: string;\n\timage?: string;\n\tclientId?: string;\n};\n\nexport type UseRealtimeSessionOptions = {\n\turl: string;\n\troomId: string;\n\tpeer: RealtimeSessionPeerInput;\n\tenabled?: boolean;\n\treconnect?: boolean;\n\theartbeatMs?: number;\n\tmaxReconnectDelayMs?: number;\n\tinitialReconnectDelayMs?: number;\n\tconnectTimeoutMs?: number;\n\tonError?: (message: string) => void;\n};\n\nexport type RealtimeViewportPresenceBindings = Pick<\n\tVectorViewportProps,\n\t| \"remotePresence\"\n\t| \"onWorldPointerMove\"\n\t| \"onWorldPointerLeave\"\n\t| \"onPlacementPreviewChange\"\n\t| \"onCameraChange\"\n>;\n\ntype BindViewportPresenceOptions = {\n\tactiveTool?: string;\n\tviewportRef?: RefObject<VectorViewportHandle | null>;\n};\n\nexport type RealtimeSyncState =\n\t| \"connected\"\n\t| \"reconnecting\"\n\t| \"offline\"\n\t| \"conflicted\";\n\nexport type RealtimeDocumentConflict = {\n\treadonly serverRevision: number;\n\treadonly serverItems: VectorSceneItem[];\n\treadonly localItems: VectorSceneItem[];\n};\n\ntype RealtimeOfflineDraft = {\n\treadonly roomId: string;\n\treadonly baseRevision: number;\n\treadonly items: VectorSceneItem[];\n\treadonly updatedAt: number;\n\t/**\n\t * Optional encoded Y.Doc state. When present, applying the draft on\n\t * reconnect uses the binary state (CRDT-preserving). Older drafts may\n\t * only have `items` (legacy format) — in that case we bootstrap a fresh\n\t * Y.Doc from the items array.\n\t */\n\treadonly yDocState?: string;\n\t/**\n\t * Optional list of ids that were not yet server-confirmed when the draft\n\t * was written. Lets us continue treating them as locally-pending after\n\t * reload.\n\t */\n\treadonly pendingIds?: string[];\n};\n\nexport type UseRealtimeSessionResult = {\n\tconnection: RealtimeConnectionInfo;\n\tsessionPeers: RealtimeSessionPeer[];\n\tremotePresence: RealtimeSessionPeer[];\n\tremoteAdapter: VectorCanvasRemoteAdapter;\n\tdocument: RealtimeDocumentSnapshot | null;\n\thasLocalOfflineDraft: boolean;\n\thasPendingDocumentSync: boolean;\n\tsyncState: RealtimeSyncState;\n\tconflict: RealtimeDocumentConflict | null;\n\tbindViewportPresence: (\n\t\toptions?: BindViewportPresenceOptions,\n\t) => RealtimeViewportPresenceBindings;\n\tsyncViewportPresence: (options?: BindViewportPresenceOptions) => boolean;\n\tresolveConflict: (action: \"keep-local\" | \"use-server\") => void;\n\tclearLocalDraft: () => void;\n\tflushDocumentSync: () => Promise<void>;\n\tdisconnect: () => void;\n\treconnectNow: () => void;\n};\n\nconst DRAFT_STORAGE_PREFIX = \"canvu-realtime-draft:\";\nconst DOCUMENT_FLUSH_DEBOUNCE_MS = 120;\nconst DRAFT_PERSIST_DEBOUNCE_MS = 420;\n\ntype IdleCallbackHandle = number;\n\nfunction requestWindowIdleCallback(\n\tcallback: () => void,\n\ttimeout: number,\n): IdleCallbackHandle {\n\tif (typeof window.requestIdleCallback === \"function\") {\n\t\treturn window.requestIdleCallback(callback, { timeout });\n\t}\n\treturn window.setTimeout(callback, timeout);\n}\n\nfunction cancelWindowIdleCallback(handle: IdleCallbackHandle | null): void {\n\tif (handle == null) return;\n\tif (typeof window.cancelIdleCallback === \"function\") {\n\t\twindow.cancelIdleCallback(handle);\n\t\treturn;\n\t}\n\twindow.clearTimeout(handle);\n}\n\nfunction createClientId(): string {\n\tif (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n\t\treturn crypto.randomUUID();\n\t}\n\treturn `client-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction normalizeSocketUrl(input: string): string {\n\tif (!input) return \"\";\n\tif (input.startsWith(\"ws://\") || input.startsWith(\"wss://\")) return input;\n\tif (input.startsWith(\"http://\")) return `ws://${input.slice(\"http://\".length)}`;\n\tif (input.startsWith(\"https://\")) return `wss://${input.slice(\"https://\".length)}`;\n\tif (input.startsWith(\"/\")) {\n\t\tconst protocol = window.location.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n\t\treturn `${protocol}//${window.location.host}${input}`;\n\t}\n\treturn input;\n}\n\nfunction isValidSocketUrl(input: string): boolean {\n\tif (!input || input.includes(\"<\") || input.includes(\">\")) return false;\n\ttry {\n\t\tconst parsed = new URL(input);\n\t\treturn parsed.protocol === \"ws:\" || parsed.protocol === \"wss:\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction sanitizeRealtimeItem(item: VectorSceneItem): VectorSceneItem {\n\tif (item.toolKind !== \"image\") return item;\n\treturn {\n\t\t...item,\n\t\timageBlobId: undefined,\n\t\timageThumbnailBlobId: undefined,\n\t\timageRasterHref: undefined,\n\t\timageThumbnailHref: undefined,\n\t\tchildrenSvg: \"\",\n\t};\n}\n\nfunction sanitizeRealtimeItems(\n\titems: readonly VectorSceneItem[],\n): VectorSceneItem[] {\n\treturn items.map(sanitizeRealtimeItem);\n}\n\nfunction sanitizeRealtimeSnapshot(\n\tsnapshot: RealtimeDocumentSnapshot,\n): RealtimeDocumentSnapshot {\n\treturn {\n\t\t...snapshot,\n\t\titems: sanitizeRealtimeItems(snapshot.items),\n\t};\n}\n\nfunction serializeItems(items: VectorSceneItem[]): string | null {\n\ttry {\n\t\treturn JSON.stringify(sanitizeRealtimeItems(items));\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction sameSerializedItems(\n\tleft: VectorSceneItem[] | null | undefined,\n\tright: VectorSceneItem[] | null | undefined,\n): boolean {\n\tif (left === right) return true;\n\tif (!left || !right) return false;\n\tconst leftJson = serializeItems(left);\n\tconst rightJson = serializeItems(right);\n\treturn leftJson != null && leftJson === rightJson;\n}\n\nfunction nowMs(): number {\n\treturn Date.now();\n}\n\nfunction draftStorageKey(roomId: string): string {\n\treturn `${DRAFT_STORAGE_PREFIX}${roomId}`;\n}\n\nfunction isRealtimeOfflineDraft(value: unknown): value is RealtimeOfflineDraft {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst record = value as Record<string, unknown>;\n\tif (\n\t\ttypeof record.roomId !== \"string\" ||\n\t\ttypeof record.baseRevision !== \"number\" ||\n\t\ttypeof record.updatedAt !== \"number\" ||\n\t\t!Array.isArray(record.items)\n\t) {\n\t\treturn false;\n\t}\n\tif (record.yDocState != null && typeof record.yDocState !== \"string\") {\n\t\treturn false;\n\t}\n\tif (record.pendingIds != null && !Array.isArray(record.pendingIds)) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nfunction readRealtimeOfflineDraft(roomId: string): RealtimeOfflineDraft | null {\n\tif (typeof window === \"undefined\" || !roomId) return null;\n\ttry {\n\t\tconst raw = window.localStorage.getItem(draftStorageKey(roomId));\n\t\tif (!raw) return null;\n\t\tconst parsed = JSON.parse(raw) as unknown;\n\t\tif (!isRealtimeOfflineDraft(parsed)) return null;\n\t\treturn {\n\t\t\t...parsed,\n\t\t\titems: sanitizeRealtimeItems(parsed.items),\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction writeRealtimeOfflineDraft(draft: RealtimeOfflineDraft | null): void {\n\tif (typeof window === \"undefined\") return;\n\tif (!draft) return;\n\ttry {\n\t\twindow.localStorage.setItem(\n\t\t\tdraftStorageKey(draft.roomId),\n\t\t\tJSON.stringify({\n\t\t\t\t...draft,\n\t\t\t\titems: sanitizeRealtimeItems(draft.items),\n\t\t\t}),\n\t\t);\n\t} catch {}\n}\n\nfunction removeRealtimeOfflineDraft(roomId: string): void {\n\tif (typeof window === \"undefined\" || !roomId) return;\n\ttry {\n\t\twindow.localStorage.removeItem(draftStorageKey(roomId));\n\t} catch {}\n}\n\nfunction getViewportCameraSnapshot(\n\tviewport: VectorViewportHandle | null | undefined,\n): RealtimeSessionPeer[\"camera\"] | null {\n\tif (!viewport) return null;\n\tconst camera = viewport.getCamera();\n\tif (!camera) return null;\n\tconst viewportSize = viewport.getViewportSize();\n\treturn {\n\t\tx: camera.x,\n\t\ty: camera.y,\n\t\tzoom: camera.zoom,\n\t\tviewportWidth: viewportSize.width,\n\t\tviewportHeight: viewportSize.height,\n\t};\n}\n\nfunction prepareRealtimeItems(\n\titems: readonly VectorSceneItem[],\n): { items: VectorSceneItem[]; serialized: string } | null {\n\ttry {\n\t\tconst sanitizedItems = sanitizeRealtimeItems(items);\n\t\treturn {\n\t\t\titems: sanitizedItems,\n\t\t\tserialized: JSON.stringify(sanitizedItems),\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction getRealtimeItemId(item: VectorSceneItem): string | null {\n\tconst id = (item as { id?: unknown }).id;\n\treturn typeof id === \"string\" ? id : null;\n}\n\nfunction serializeRealtimeItem(item: VectorSceneItem): string | null {\n\ttry {\n\t\treturn JSON.stringify(sanitizeRealtimeItem(item));\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction resolvePendingDraftItemIds(\n\tboard: YjsBoardDoc,\n\titems: readonly VectorSceneItem[],\n): string[] | undefined {\n\tconst pendingIds = new Set<string>();\n\tfor (const item of items) {\n\t\tconst id = getRealtimeItemId(item);\n\t\tif (!id) continue;\n\t\tconst confirmedSerialized = board.lastServerConfirmedItemSerializations.get(id);\n\t\tconst serialized = serializeRealtimeItem(item);\n\t\tif (!confirmedSerialized || !serialized || serialized !== confirmedSerialized) {\n\t\t\tpendingIds.add(id);\n\t\t}\n\t}\n\treturn pendingIds.size > 0 ? Array.from(pendingIds) : undefined;\n}\n\nexport function useRealtimeSession(\n\toptions: UseRealtimeSessionOptions,\n): UseRealtimeSessionResult {\n\tconst {\n\t\turl,\n\t\troomId,\n\t\tpeer,\n\t\tenabled = true,\n\t\treconnect = true,\n\t\theartbeatMs = 10_000,\n\t\tmaxReconnectDelayMs = 12_000,\n\t\tinitialReconnectDelayMs = 800,\n\t\tconnectTimeoutMs = 10_000,\n\t\tonError,\n\t} = options;\n\n\tconst clientIdRef = useRef(peer.clientId ?? createClientId());\n\tconst wsRef = useRef<WebSocket | null>(null);\n\tconst reconnectTimerRef = useRef<number | null>(null);\n\tconst heartbeatTimerRef = useRef<number | null>(null);\n\tconst connectTimeoutRef = useRef<number | null>(null);\n\tconst documentFlushTimerRef = useRef<number | null>(null);\n\tconst documentFlushIdleRef = useRef<IdleCallbackHandle | null>(null);\n\tconst draftPersistTimerRef = useRef<number | null>(null);\n\tconst draftPersistIdleRef = useRef<IdleCallbackHandle | null>(null);\n\tconst manualDisconnectRef = useRef(false);\n\tconst retryCountRef = useRef(0);\n\tconst currentRevisionRef = useRef(0);\n\tconst outboundInFlightRef = useRef<{\n\t\tbaseRevision: number;\n\t\titems: VectorSceneItem[];\n\t\tserialized: string | null;\n\t} | null>(null);\n\tconst queuedDirtyRef = useRef(false);\n\t// Latest items snapshot the consumer wants to push, captured by\n\t// queueDocumentSend at potentially 60fps. The expensive merge into the\n\t// Y.Doc, projection, encoding and React state updates are all deferred\n\t// to flushQueuedDocument so the input thread on iPad isn't saturated\n\t// during continuous drawing.\n\tconst pendingLocalItemsRef = useRef<VectorSceneItem[] | null>(null);\n\tconst subscriberRefs = useRef(new Set<(items: VectorSceneItem[]) => void>());\n\tconst boardRef = useRef<YjsBoardDoc | null>(null);\n\tif (boardRef.current == null) {\n\t\tboardRef.current = createYjsBoardDoc();\n\t}\n\tconst lastCursorRef = useRef<{ x: number; y: number } | null>(null);\n\tconst lastMarkupStrokeRef = useRef<\n\t\tRealtimeSessionPeer[\"markupStroke\"] | null | undefined\n\t>(null);\n\tconst lastCameraRef = useRef<RealtimeSessionPeer[\"camera\"] | null | undefined>(\n\t\tnull,\n\t);\n\tconst lastActiveToolRef = useRef<string | undefined>(undefined);\n\tconst latestDocumentRef = useRef<RealtimeDocumentSnapshot | null>(null);\n\tconst connectionStateRef = useRef<RealtimeConnectionInfo[\"state\"]>(\n\t\tenabled ? \"connecting\" : \"offline\",\n\t);\n\tconst localDraftRef = useRef<RealtimeOfflineDraft | null>(null);\n\tconst conflictRef = useRef<RealtimeDocumentConflict | null>(null);\n\tconst onErrorRef = useRef(onError);\n\tonErrorRef.current = onError;\n\n\tconst [connectSequence, setConnectSequence] = useState(0);\n\tconst [connection, setConnection] = useState<RealtimeConnectionInfo>({\n\t\tstate: enabled ? \"connecting\" : \"offline\",\n\t\tconnected: false,\n\t\troomId,\n\t\tclientId: null,\n\t\tretryCount: 0,\n\t\tlastConnectedAt: null,\n\t\tlastMessageAt: null,\n\t\tlastPongAt: null,\n\t\tlastError: null,\n\t});\n\tconst [sessionPeers, setSessionPeers] = useState<RealtimeSessionPeer[]>([]);\n\tconst [document, setDocument] = useState<RealtimeDocumentSnapshot | null>(null);\n\tconst [hasLocalOfflineDraft, setHasLocalOfflineDraft] = useState(false);\n\tconst [hasPendingDocumentSync, setHasPendingDocumentSync] = useState(false);\n\tconst [conflict, setConflict] = useState<RealtimeDocumentConflict | null>(null);\n\tconnectionStateRef.current = connection.state;\n\n\tconst syncState = useMemo<RealtimeSyncState>(() => {\n\t\tif (conflict != null) return \"conflicted\";\n\t\tif (connection.connected) return \"connected\";\n\t\tif (connection.state === \"reconnecting\" || connection.state === \"connecting\") {\n\t\t\treturn \"reconnecting\";\n\t\t}\n\t\treturn \"offline\";\n\t}, [conflict, connection.connected, connection.state]);\n\n\tconst clearReconnectTimer = useCallback(() => {\n\t\tif (reconnectTimerRef.current != null) {\n\t\t\twindow.clearTimeout(reconnectTimerRef.current);\n\t\t\treconnectTimerRef.current = null;\n\t\t}\n\t}, []);\n\n\tconst clearHeartbeatTimer = useCallback(() => {\n\t\tif (heartbeatTimerRef.current != null) {\n\t\t\twindow.clearInterval(heartbeatTimerRef.current);\n\t\t\theartbeatTimerRef.current = null;\n\t\t}\n\t}, []);\n\n\tconst clearConnectTimeout = useCallback(() => {\n\t\tif (connectTimeoutRef.current != null) {\n\t\t\twindow.clearTimeout(connectTimeoutRef.current);\n\t\t\tconnectTimeoutRef.current = null;\n\t\t}\n\t}, []);\n\n\tconst clearDocumentFlushSchedule = useCallback(() => {\n\t\tif (documentFlushTimerRef.current != null) {\n\t\t\twindow.clearTimeout(documentFlushTimerRef.current);\n\t\t\tdocumentFlushTimerRef.current = null;\n\t\t}\n\t\tcancelWindowIdleCallback(documentFlushIdleRef.current);\n\t\tdocumentFlushIdleRef.current = null;\n\t}, []);\n\n\tconst clearDraftPersistSchedule = useCallback(() => {\n\t\tif (draftPersistTimerRef.current != null) {\n\t\t\twindow.clearTimeout(draftPersistTimerRef.current);\n\t\t\tdraftPersistTimerRef.current = null;\n\t\t}\n\t\tcancelWindowIdleCallback(draftPersistIdleRef.current);\n\t\tdraftPersistIdleRef.current = null;\n\t}, []);\n\n\tconst updateConnection = useCallback(\n\t\t(\n\t\t\tpatch:\n\t\t\t\t| Partial<RealtimeConnectionInfo>\n\t\t\t\t| ((prev: RealtimeConnectionInfo) => RealtimeConnectionInfo),\n\t\t) => {\n\t\t\tsetConnection((prev) => {\n\t\t\t\tif (typeof patch === \"function\") return patch(prev);\n\t\t\t\treturn { ...prev, ...patch };\n\t\t\t});\n\t\t},\n\t\t[],\n\t);\n\n\tconst notifySubscribers = useCallback((items: VectorSceneItem[]) => {\n\t\tfor (const subscriber of subscriberRefs.current) {\n\t\t\tsubscriber(items);\n\t\t}\n\t}, []);\n\n\t// applyDocument merges a snapshot into the local Y.Doc. When `replace` is\n\t// true (used for the very first bootstrap when we have no local items), the\n\t// Y.Doc is reset to exactly the snapshot. Otherwise applyServerSnapshotToYDoc\n\t// runs the smart merge that preserves locally-pending items and respects\n\t// server-side deletes.\n\tconst applyDocument = useCallback(\n\t\t(\n\t\t\tsnapshot: RealtimeDocumentSnapshot,\n\t\t\toptions?: { suppressSubscriberNotify?: boolean; replace?: boolean },\n\t\t) => {\n\t\t\tconst currentSnapshot = latestDocumentRef.current;\n\t\t\tif (\n\t\t\t\tcurrentSnapshot &&\n\t\t\t\tcurrentSnapshot.revision === snapshot.revision &&\n\t\t\t\tcurrentSnapshot.updatedByClientId === snapshot.updatedByClientId &&\n\t\t\t\tsameSerializedItems(currentSnapshot.items, snapshot.items)\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst board = boardRef.current;\n\t\t\tif (board) {\n\t\t\t\t// Drain any pending local items into the Y.Doc *before* applying\n\t\t\t\t// the server snapshot. queueDocumentSend only stashes the latest\n\t\t\t\t// items in pendingLocalItemsRef so the canvas hot path stays\n\t\t\t\t// cheap, but that means items the user just drew may not be in\n\t\t\t\t// the Y.Doc yet. If we merge the server snapshot first, the\n\t\t\t\t// projected items would be missing those local strokes and\n\t\t\t\t// trazo would receive a snapshot that wipes them from view\n\t\t\t\t// until the next flush round-trip echoes them back.\n\t\t\t\tif (!options?.replace) {\n\t\t\t\t\tconst pendingLocal = pendingLocalItemsRef.current;\n\t\t\t\t\tif (pendingLocal) {\n\t\t\t\t\t\tpendingLocalItemsRef.current = null;\n\t\t\t\t\t\tapplyLocalItemsToYDoc(board, {\n\t\t\t\t\t\t\titems: pendingLocal,\n\t\t\t\t\t\t\torigin: ORIGIN_LOCAL,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tqueuedDirtyRef.current = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (options?.replace) {\n\t\t\t\t\treplaceYDocWithSnapshot(board, {\n\t\t\t\t\t\titems: snapshot.items,\n\t\t\t\t\t\torigin: ORIGIN_REMOTE,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tapplyServerSnapshotToYDoc(board, {\n\t\t\t\t\t\titems: snapshot.items,\n\t\t\t\t\t\torigin: ORIGIN_REMOTE,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst mergedItems = board ? readVectorItems(board.yItems) : snapshot.items;\n\t\t\tconst mergedSnapshot: RealtimeDocumentSnapshot = {\n\t\t\t\t...snapshot,\n\t\t\t\titems: mergedItems,\n\t\t\t};\n\t\t\tcurrentRevisionRef.current = snapshot.revision;\n\t\t\tlatestDocumentRef.current = mergedSnapshot;\n\t\t\tsetDocument(mergedSnapshot);\n\t\t\tif (!options?.suppressSubscriberNotify) {\n\t\t\t\tnotifySubscribers(mergedItems);\n\t\t\t}\n\t\t},\n\t\t[notifySubscribers],\n\t);\n\n\tconst setConflictState = useCallback(\n\t\t(nextConflict: RealtimeDocumentConflict | null) => {\n\t\t\tconflictRef.current = nextConflict;\n\t\t\tsetConflict(nextConflict);\n\t\t},\n\t\t[],\n\t);\n\n\tconst setLocalDraft = useCallback(\n\t\t(nextDraft: RealtimeOfflineDraft | null) => {\n\t\t\tlocalDraftRef.current = nextDraft;\n\t\t\tsetHasLocalOfflineDraft(nextDraft != null);\n\t\t\tif (nextDraft) return;\n\t\t\tremoveRealtimeOfflineDraft(roomId);\n\t\t},\n\t\t[roomId],\n\t);\n\n\tconst persistLocalDraft = useCallback(() => {\n\t\tclearDraftPersistSchedule();\n\t\tif (!localDraftRef.current) {\n\t\t\tremoveRealtimeOfflineDraft(roomId);\n\t\t\treturn;\n\t\t}\n\t\t// Encode the Y.Doc state lazily, right before writing to localStorage,\n\t\t// so the expensive Y.encodeStateAsUpdate + base64 work stays out of\n\t\t// the per-flush hot path. flushQueuedDocument only updates the\n\t\t// in-memory draft (items + meta + pendingIds); the binary CRDT state\n\t\t// is materialised here on the debounced persistence schedule.\n\t\tconst board = boardRef.current;\n\t\tconst draft = localDraftRef.current;\n\t\tconst canEncodeYDocState =\n\t\t\tboard &&\n\t\t\tdraft.yDocState == null &&\n\t\t\tsameSerializedItems(readVectorItems(board.yItems), draft.items);\n\t\tconst draftToWrite = canEncodeYDocState\n\t\t\t? { ...draft, yDocState: encodeYDocState(board) }\n\t\t\t: draft;\n\t\twriteRealtimeOfflineDraft(draftToWrite);\n\t}, [clearDraftPersistSchedule, roomId]);\n\n\tconst scheduleDraftPersistence = useCallback(() => {\n\t\tclearDraftPersistSchedule();\n\t\tdraftPersistTimerRef.current = window.setTimeout(() => {\n\t\t\tdraftPersistTimerRef.current = null;\n\t\t\tdraftPersistIdleRef.current = requestWindowIdleCallback(() => {\n\t\t\t\tdraftPersistIdleRef.current = null;\n\t\t\t\tpersistLocalDraft();\n\t\t\t}, DRAFT_PERSIST_DEBOUNCE_MS);\n\t\t}, DRAFT_PERSIST_DEBOUNCE_MS);\n\t}, [clearDraftPersistSchedule, persistLocalDraft]);\n\n\tconst clearLocalDraft = useCallback(() => {\n\t\tsetLocalDraft(null);\n\t\tclearDraftPersistSchedule();\n\t}, [clearDraftPersistSchedule, setLocalDraft]);\n\n\tconst createSelfPeer = useCallback(\n\t\t(state: RealtimeConnectionInfo[\"state\"]): RealtimeSessionPeer => ({\n\t\t\tid: peer.id,\n\t\t\tclientId: clientIdRef.current,\n\t\t\tpeerId: peer.id,\n\t\t\troomId,\n\t\t\tjoinedAt: connection.lastConnectedAt ?? nowMs(),\n\t\t\tlastSeenAt: nowMs(),\n\t\t\tcursor: lastCursorRef.current,\n\t\t\tisSelf: true,\n\t\t\tconnectionState: state,\n\t\t\t...(peer.displayName ? { displayName: peer.displayName } : {}),\n\t\t\t...(peer.color ? { color: peer.color } : {}),\n\t\t\t...(peer.image ? { image: peer.image } : {}),\n\t\t\t...(lastMarkupStrokeRef.current !== undefined\n\t\t\t\t? { markupStroke: lastMarkupStrokeRef.current ?? null }\n\t\t\t\t: {}),\n\t\t\t...(lastCameraRef.current !== undefined\n\t\t\t\t? { camera: lastCameraRef.current ?? null }\n\t\t\t\t: {}),\n\t\t\t...(lastActiveToolRef.current\n\t\t\t\t? { activeTool: lastActiveToolRef.current }\n\t\t\t\t: {}),\n\t\t}),\n\t\t[\n\t\t\tconnection.lastConnectedAt,\n\t\t\tpeer.color,\n\t\t\tpeer.displayName,\n\t\t\tpeer.id,\n\t\t\tpeer.image,\n\t\t\troomId,\n\t\t],\n\t);\n\n\tconst collapsePeersToSelf = useCallback(\n\t\t(state: RealtimeConnectionInfo[\"state\"]) => {\n\t\t\tsetSessionPeers((prev) => {\n\t\t\t\tconst selfPeer = prev.find(\n\t\t\t\t\t(peerState) => peerState.clientId === clientIdRef.current,\n\t\t\t\t);\n\t\t\t\treturn [\n\t\t\t\t\tselfPeer\n\t\t\t\t\t\t? { ...selfPeer, isSelf: true, connectionState: state }\n\t\t\t\t\t\t: createSelfPeer(state),\n\t\t\t\t];\n\t\t\t});\n\t\t},\n\t\t[createSelfPeer],\n\t);\n\n\tconst applyPeers = useCallback((peers: RealtimeSessionPeer[]) => {\n\t\tconst selfClientId = clientIdRef.current;\n\t\tsetSessionPeers(\n\t\t\tpeers.map((peerState) =>\n\t\t\t\tpeerState.clientId === selfClientId\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...peerState,\n\t\t\t\t\t\t\tisSelf: true,\n\t\t\t\t\t\t\tconnectionState: connectionStateRef.current,\n\t\t\t\t\t\t}\n\t\t\t\t\t: peerState,\n\t\t\t),\n\t\t);\n\t}, []);\n\n\tconst buildClientMessage = useCallback(\n\t\t(message: RealtimeClientMessage): string => JSON.stringify(message),\n\t\t[],\n\t);\n\n\tconst sendRaw = useCallback(\n\t\t(message: RealtimeClientMessage): boolean => {\n\t\t\tconst ws = wsRef.current;\n\t\t\tif (!ws || ws.readyState !== WebSocket.OPEN) return false;\n\t\t\tws.send(buildClientMessage(message));\n\t\t\treturn true;\n\t\t},\n\t\t[buildClientMessage],\n\t);\n\n\tconst flushQueuedDocument = useCallback(() => {\n\t\tclearDocumentFlushSchedule();\n\t\tconst board = boardRef.current;\n\t\tif (!board) return;\n\t\tif (!queuedDirtyRef.current && pendingLocalItemsRef.current == null) return;\n\t\tif (outboundInFlightRef.current) return;\n\t\t// Heavy work deferred from queueDocumentSend: apply the latest local\n\t\t// items snapshot the consumer pushed (possibly accumulated over many\n\t\t// 60fps onItemsChange firings) into the Y.Doc once.\n\t\tconst pendingLocal = pendingLocalItemsRef.current;\n\t\tif (pendingLocal) {\n\t\t\tpendingLocalItemsRef.current = null;\n\t\t\tapplyLocalItemsToYDoc(board, {\n\t\t\t\titems: pendingLocal,\n\t\t\t\torigin: ORIGIN_LOCAL,\n\t\t\t});\n\t\t}\n\t\tconst baseRevision = currentRevisionRef.current;\n\t\tconst mergedItems = readVectorItems(board.yItems);\n\t\tconst preparedItems = prepareRealtimeItems(mergedItems);\n\t\tif (!preparedItems) return;\n\t\tqueuedDirtyRef.current = false;\n\t\toutboundInFlightRef.current = {\n\t\t\tbaseRevision,\n\t\t\titems: preparedItems.items,\n\t\t\tserialized: preparedItems.serialized,\n\t\t};\n\t\tconst didSend = sendRawRef.current({\n\t\t\ttype: \"document:update\",\n\t\t\troomId,\n\t\t\tclientId: clientIdRef.current,\n\t\t\tbaseRevision,\n\t\t\titems: preparedItems.items,\n\t\t});\n\t\t// Refresh the offline draft with the post-merge state. Doing this\n\t\t// here (~8x/sec at flush rate) instead of on every queueDocumentSend\n\t\t// avoids encoding the full Y.Doc and triggering React state churn at\n\t\t// 60fps during drawing.\n\t\tconst pendingIds = getLocallyPendingItemIds(board);\n\t\tif (pendingIds.size > 0) {\n\t\t\t// Don't encode the Y.Doc here — persistLocalDraft materialises it\n\t\t\t// lazily so this hot path stays cheap during 60fps drawing.\n\t\t\tsetLocalDraftRef.current({\n\t\t\t\troomId,\n\t\t\t\tbaseRevision,\n\t\t\t\titems: mergedItems,\n\t\t\t\tupdatedAt: nowMs(),\n\t\t\t\tpendingIds: Array.from(pendingIds),\n\t\t\t});\n\t\t\tscheduleDraftPersistenceRef.current?.();\n\t\t}\n\t\tif (!didSend) {\n\t\t\tqueuedDirtyRef.current = true;\n\t\t\toutboundInFlightRef.current = null;\n\t\t\tsetHasPendingDocumentSync(true);\n\t\t}\n\t}, [clearDocumentFlushSchedule, roomId]);\n\n\tconst scheduleDocumentFlush = useCallback(() => {\n\t\tclearDocumentFlushSchedule();\n\t\tdocumentFlushTimerRef.current = window.setTimeout(() => {\n\t\t\tdocumentFlushTimerRef.current = null;\n\t\t\tdocumentFlushIdleRef.current = requestWindowIdleCallback(() => {\n\t\t\t\tdocumentFlushIdleRef.current = null;\n\t\t\t\tflushQueuedDocument();\n\t\t\t}, DOCUMENT_FLUSH_DEBOUNCE_MS);\n\t\t}, DOCUMENT_FLUSH_DEBOUNCE_MS);\n\t}, [clearDocumentFlushSchedule, flushQueuedDocument]);\n\n\t// queueDocumentSend is on the canvas hot path — invoked at up to 60fps\n\t// during continuous drawing. Keep it O(1): just stash the latest items\n\t// snapshot and schedule a flush. All Y.Doc mutations, projection,\n\t// encoding and React state updates are amortised across the flush\n\t// window (DOCUMENT_FLUSH_DEBOUNCE_MS) inside flushQueuedDocument.\n\tconst queueDocumentSend = useCallback(\n\t\t(items: VectorSceneItem[]) => {\n\t\t\tpendingLocalItemsRef.current = items;\n\t\t\tqueuedDirtyRef.current = true;\n\t\t\tsetHasPendingDocumentSync(true);\n\t\t\tsetHasLocalOfflineDraft(true);\n\t\t\tconst board = boardRef.current;\n\t\t\tconst draftItems = sanitizeRealtimeItems(items);\n\t\t\tsetLocalDraftRef.current({\n\t\t\t\troomId,\n\t\t\t\tbaseRevision: currentRevisionRef.current,\n\t\t\t\titems: draftItems,\n\t\t\t\tupdatedAt: nowMs(),\n\t\t\t\tpendingIds: board\n\t\t\t\t\t? resolvePendingDraftItemIds(board, draftItems)\n\t\t\t\t\t: undefined,\n\t\t\t});\n\t\t\tscheduleDraftPersistenceRef.current?.();\n\t\t\tscheduleDocumentFlushRef.current();\n\t\t},\n\t\t[roomId],\n\t);\n\n\t// Bootstrap the Y.Doc from a persisted draft. When the draft has a binary\n\t// yDocState (new format), we decode it directly to preserve CRDT history\n\t// and pending-id tracking. For legacy drafts (items only), we replace the\n\t// Y.Doc with the items array and conservatively mark every item as still\n\t// \"pending server confirmation\" — the next server snapshot will reconcile.\n\tconst applyDraftSnapshot = useCallback(\n\t\t(\n\t\t\tdraft: RealtimeOfflineDraft,\n\t\t\toptions?: { suppressSubscriberNotify?: boolean },\n\t\t) => {\n\t\t\tconst board = boardRef.current;\n\t\t\tif (board) {\n\t\t\t\tlet restoredFromBinary = false;\n\t\t\t\tif (draft.yDocState) {\n\t\t\t\t\tif (board.yItems.length > 0) {\n\t\t\t\t\t\tboard.doc.transact(() => {\n\t\t\t\t\t\t\tboard.yItems.delete(0, board.yItems.length);\n\t\t\t\t\t\t}, ORIGIN_BOOTSTRAP);\n\t\t\t\t\t}\n\t\t\t\t\trestoredFromBinary = decodeYDocState(board, draft.yDocState);\n\t\t\t\t\tif (restoredFromBinary) {\n\t\t\t\t\t\tconst allIds = new Set<string>();\n\t\t\t\t\t\tconst allItems = readVectorItems(board.yItems);\n\t\t\t\t\t\tfor (let i = 0; i < board.yItems.length; i++) {\n\t\t\t\t\t\t\tconst yMap = board.yItems.get(i);\n\t\t\t\t\t\t\tif (!yMap) continue;\n\t\t\t\t\t\t\tconst id = yMap.get(\"id\");\n\t\t\t\t\t\t\tif (typeof id === \"string\") allIds.add(id);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst pendingIds = new Set(draft.pendingIds ?? []);\n\t\t\t\t\t\tboard.lastServerConfirmedIds = new Set();\n\t\t\t\t\t\tboard.lastServerConfirmedItemSerializations = new Map();\n\t\t\t\t\t\tfor (const id of allIds) {\n\t\t\t\t\t\t\tif (!pendingIds.has(id)) {\n\t\t\t\t\t\t\t\tboard.lastServerConfirmedIds.add(id);\n\t\t\t\t\t\t\t\tconst item = allItems.find((candidate) => candidate.id === id);\n\t\t\t\t\t\t\t\tif (item) {\n\t\t\t\t\t\t\t\t\tboard.lastServerConfirmedItemSerializations.set(\n\t\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\t\tJSON.stringify(item),\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!restoredFromBinary) {\n\t\t\t\t\treplaceYDocWithSnapshot(board, {\n\t\t\t\t\t\titems: draft.items,\n\t\t\t\t\t\torigin: ORIGIN_BOOTSTRAP,\n\t\t\t\t\t});\n\t\t\t\t\t// Legacy draft: no record of which ids were already confirmed by the\n\t\t\t\t\t// server. Mark all as pending so the next server snapshot can\n\t\t\t\t\t// reconcile correctly (additive merge will preserve them, and any\n\t\t\t\t\t// server-deleted ids will simply not be in lastServerConfirmedIds\n\t\t\t\t\t// to be re-added).\n\t\t\t\t\tboard.lastServerConfirmedIds = new Set();\n\t\t\t\t\tboard.lastServerConfirmedItemSerializations = new Map();\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst items = board ? readVectorItems(board.yItems) : draft.items;\n\t\t\tconst snapshot: RealtimeDocumentSnapshot = {\n\t\t\t\trevision: draft.baseRevision,\n\t\t\t\titems,\n\t\t\t\tupdatedAt: draft.updatedAt,\n\t\t\t\tupdatedByClientId: clientIdRef.current,\n\t\t\t};\n\t\t\tcurrentRevisionRef.current = snapshot.revision;\n\t\t\tlatestDocumentRef.current = snapshot;\n\t\t\tsetDocument(snapshot);\n\t\t\tif (!options?.suppressSubscriberNotify) {\n\t\t\t\tnotifySubscribers(items);\n\t\t\t}\n\t\t},\n\t\t[notifySubscribers],\n\t);\n\n\t// With Yjs as the source of truth, conflicts no longer exist as a concept.\n\t// Every server snapshot is merged into the Y.Doc; locally-added items that\n\t// the server has not yet seen are preserved, and items the server deleted\n\t// (i.e. id was in the previous server snapshot but is absent now) are\n\t// removed. The legacy \"keep-local vs use-server\" choice is gone.\n\t//\n\t// Returns true when the local Y.Doc still has pending items the server\n\t// hasn't seen after the merge (so the caller knows to re-schedule a flush).\n\tconst resolveAuthoritativeDocument = useCallback(\n\t\t(\n\t\t\tserverDocument: RealtimeDocumentSnapshot,\n\t\t\toptions?: { suppressSubscriberNotify?: boolean },\n\t\t): boolean => {\n\t\t\tconst board = boardRef.current;\n\t\t\tconst hadLocalContent =\n\t\t\t\tlocalDraftRef.current != null || (board != null && board.yItems.length > 0);\n\n\t\t\tapplyDocument(serverDocument, {\n\t\t\t\t...options,\n\t\t\t\treplace: !hadLocalContent,\n\t\t\t});\n\n\t\t\tif (!board) {\n\t\t\t\tsetHasPendingDocumentSync(false);\n\t\t\t\tclearLocalDraftRef.current();\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst pendingIds = getLocallyPendingItemIds(board);\n\t\t\tif (pendingIds.size === 0) {\n\t\t\t\tclearLocalDraftRef.current();\n\t\t\t\tsetHasPendingDocumentSync(false);\n\t\t\t\toutboundInFlightRef.current = null;\n\t\t\t\tqueuedDirtyRef.current = false;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst mergedItems = readVectorItems(board.yItems);\n\t\t\tsetLocalDraft({\n\t\t\t\troomId,\n\t\t\t\tbaseRevision: serverDocument.revision,\n\t\t\t\titems: mergedItems,\n\t\t\t\tupdatedAt: nowMs(),\n\t\t\t\tpendingIds: Array.from(pendingIds),\n\t\t\t});\n\t\t\toutboundInFlightRef.current = null;\n\t\t\tqueuedDirtyRef.current = true;\n\t\t\tsetHasPendingDocumentSync(true);\n\t\t\tscheduleDocumentFlush();\n\t\t\treturn true;\n\t\t},\n\t\t[applyDocument, roomId, scheduleDocumentFlush, setLocalDraft],\n\t);\n\n\tconst sendPresenceUpdate = useCallback(() => {\n\t\tsendRaw({\n\t\t\ttype: \"presence:update\",\n\t\t\troomId,\n\t\t\tclientId: clientIdRef.current,\n\t\t\tpresence: {\n\t\t\t\tcursor: lastCursorRef.current,\n\t\t\t\tmarkupStroke: lastMarkupStrokeRef.current ?? null,\n\t\t\t\tcamera: lastCameraRef.current ?? null,\n\t\t\t\t...(lastActiveToolRef.current\n\t\t\t\t\t? { activeTool: lastActiveToolRef.current }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t});\n\t}, [roomId, sendRaw]);\n\n\tconst scheduleReconnect = useCallback(() => {\n\t\tif (!reconnect || manualDisconnectRef.current) return;\n\t\tclearReconnectTimer();\n\t\tretryCountRef.current += 1;\n\t\tconst delay = Math.min(\n\t\t\tmaxReconnectDelayMs,\n\t\t\tinitialReconnectDelayMs * 2 ** Math.max(0, retryCountRef.current - 1),\n\t\t);\n\t\tupdateConnection((prev) => ({\n\t\t\t...prev,\n\t\t\tstate: \"reconnecting\",\n\t\t\tconnected: false,\n\t\t\tretryCount: retryCountRef.current,\n\t\t}));\n\t\treconnectTimerRef.current = window.setTimeout(() => {\n\t\t\tsetConnectSequence((value) => value + 1);\n\t\t}, delay);\n\t}, [\n\t\tclearReconnectTimer,\n\t\tinitialReconnectDelayMs,\n\t\tmaxReconnectDelayMs,\n\t\treconnect,\n\t\tupdateConnection,\n\t]);\n\n\t// Kept for API back-compat with consumers that still call resolveConflict.\n\t// Yjs handles merge automatically inside resolveAuthoritativeDocument, so\n\t// `conflict` is always null and this becomes a no-op. We accept the action\n\t// argument silently so callers don't break.\n\tconst resolveConflict = useCallback((_action: \"keep-local\" | \"use-server\") => {\n\t\tvoid _action;\n\t}, []);\n\n\tconst setConflictStateRef = useRef(setConflictState);\n\tsetConflictStateRef.current = setConflictState;\n\tconst updateConnectionRef = useRef(updateConnection);\n\tupdateConnectionRef.current = updateConnection;\n\tconst applyDocumentRef = useRef(applyDocument);\n\tapplyDocumentRef.current = applyDocument;\n\tconst clearLocalDraftRef = useRef(clearLocalDraft);\n\tclearLocalDraftRef.current = clearLocalDraft;\n\tconst collapsePeersToSelfRef = useRef(collapsePeersToSelf);\n\tcollapsePeersToSelfRef.current = collapsePeersToSelf;\n\tconst applyPeersRef = useRef(applyPeers);\n\tapplyPeersRef.current = applyPeers;\n\tconst resolveAuthoritativeDocumentRef = useRef(resolveAuthoritativeDocument);\n\tresolveAuthoritativeDocumentRef.current = resolveAuthoritativeDocument;\n\tconst scheduleDocumentFlushRef = useRef(scheduleDocumentFlush);\n\tscheduleDocumentFlushRef.current = scheduleDocumentFlush;\n\tconst scheduleReconnectRef = useRef(scheduleReconnect);\n\tscheduleReconnectRef.current = scheduleReconnect;\n\tconst sendRawRef = useRef(sendRaw);\n\tsendRawRef.current = sendRaw;\n\tconst setLocalDraftRef = useRef(setLocalDraft);\n\tsetLocalDraftRef.current = setLocalDraft;\n\tconst scheduleDraftPersistenceRef = useRef(scheduleDraftPersistence);\n\tscheduleDraftPersistenceRef.current = scheduleDraftPersistence;\n\tconst persistLocalDraftRef = useRef(persistLocalDraft);\n\tpersistLocalDraftRef.current = persistLocalDraft;\n\n\tuseEffect(() => {\n\t\tconst persistDraft = () => {\n\t\t\tpersistLocalDraftRef.current();\n\t\t};\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (window.document.visibilityState === \"hidden\") persistDraft();\n\t\t};\n\t\twindow.addEventListener(\"pagehide\", persistDraft);\n\t\twindow.document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"pagehide\", persistDraft);\n\t\t\twindow.document.removeEventListener(\n\t\t\t\t\"visibilitychange\",\n\t\t\t\thandleVisibilityChange,\n\t\t\t);\n\t\t};\n\t}, []);\n\n\tuseEffect(() => {\n\t\t// Fresh Y.Doc per roomId — destroy the previous one to release CRDT\n\t\t// state and observers, then start clean. This keeps memory bounded\n\t\t// when navigating between boards.\n\t\tif (boardRef.current) {\n\t\t\tboardRef.current.doc.destroy();\n\t\t}\n\t\tboardRef.current = createYjsBoardDoc();\n\t\tif (!roomId) {\n\t\t\tclearDocumentFlushSchedule();\n\t\t\tclearDraftPersistSchedule();\n\t\t\tlocalDraftRef.current = null;\n\t\t\tsetHasLocalOfflineDraft(false);\n\t\t\tsetHasPendingDocumentSync(false);\n\t\t\tsetConflictState(null);\n\t\t\tqueuedDirtyRef.current = false;\n\t\t\tpendingLocalItemsRef.current = null;\n\t\t\toutboundInFlightRef.current = null;\n\t\t\tlatestDocumentRef.current = null;\n\t\t\tsetDocument(null);\n\t\t\tcurrentRevisionRef.current = 0;\n\t\t\treturn;\n\t\t}\n\t\tconst localDraft = readRealtimeOfflineDraft(roomId);\n\t\tsetLocalDraft(localDraft);\n\t\tsetHasPendingDocumentSync(localDraft != null);\n\t\tsetConflictState(null);\n\t\tqueuedDirtyRef.current = localDraft != null;\n\t\tpendingLocalItemsRef.current = null;\n\t\toutboundInFlightRef.current = null;\n\t\tif (localDraft) {\n\t\t\tapplyDraftSnapshot(localDraft, {\n\t\t\t\tsuppressSubscriberNotify: sameSerializedItems(\n\t\t\t\t\tlatestDocumentRef.current?.items,\n\t\t\t\t\tlocalDraft.items,\n\t\t\t\t),\n\t\t\t});\n\t\t} else {\n\t\t\tlatestDocumentRef.current = null;\n\t\t\tsetDocument(null);\n\t\t\tcurrentRevisionRef.current = 0;\n\t\t}\n\t}, [\n\t\tapplyDraftSnapshot,\n\t\tclearDocumentFlushSchedule,\n\t\tclearDraftPersistSchedule,\n\t\troomId,\n\t\tsetConflictState,\n\t\tsetLocalDraft,\n\t]);\n\n\tuseEffect(() => {\n\t\tvoid connectSequence;\n\t\tif (!enabled) {\n\t\t\tmanualDisconnectRef.current = true;\n\t\t\tclearReconnectTimer();\n\t\t\tclearHeartbeatTimer();\n\t\t\tclearConnectTimeout();\n\t\t\tclearDocumentFlushSchedule();\n\t\t\twsRef.current?.close();\n\t\t\twsRef.current = null;\n\t\t\tqueuedDirtyRef.current = localDraftRef.current != null;\n\t\t\toutboundInFlightRef.current = null;\n\t\t\tsetHasPendingDocumentSync(localDraftRef.current != null);\n\t\t\tcollapsePeersToSelfRef.current(\"offline\");\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tstate: \"offline\",\n\t\t\t\tconnected: false,\n\t\t\t\troomId,\n\t\t\t\tclientId: null,\n\t\t\t}));\n\t\t\treturn;\n\t\t}\n\n\t\tmanualDisconnectRef.current = false;\n\t\tconst socketUrl = normalizeSocketUrl(url);\n\t\tif (!socketUrl) {\n\t\t\tcollapsePeersToSelfRef.current(\"offline\");\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tstate: \"offline\",\n\t\t\t\tconnected: false,\n\t\t\t\troomId,\n\t\t\t\tlastError: null,\n\t\t\t}));\n\t\t\treturn;\n\t\t}\n\t\tif (!isValidSocketUrl(socketUrl)) {\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tstate: \"error\",\n\t\t\t\tconnected: false,\n\t\t\t\troomId,\n\t\t\t\tlastError: \"URL de websocket invalida.\",\n\t\t\t}));\n\t\t\tonErrorRef.current?.(\"URL de websocket invalida.\");\n\t\t\treturn;\n\t\t}\n\t\tlet disposed = false;\n\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t...prev,\n\t\t\tstate: retryCountRef.current > 0 ? \"reconnecting\" : \"connecting\",\n\t\t\tconnected: false,\n\t\t\troomId,\n\t\t\tlastError: null,\n\t\t}));\n\n\t\tconst socket = new WebSocket(socketUrl);\n\t\twsRef.current = socket;\n\t\tclearConnectTimeout();\n\t\tconnectTimeoutRef.current = window.setTimeout(() => {\n\t\t\tif (socket.readyState === WebSocket.CONNECTING) {\n\t\t\t\tsocket.close();\n\t\t\t}\n\t\t}, connectTimeoutMs);\n\n\t\tsocket.addEventListener(\"open\", () => {\n\t\t\tif (disposed) return;\n\t\t\tclearConnectTimeout();\n\t\t\tsendRawRef.current({\n\t\t\t\ttype: \"session:join\",\n\t\t\t\troomId,\n\t\t\t\tpeer: {\n\t\t\t\t\tclientId: clientIdRef.current,\n\t\t\t\t\tpeerId: peer.id,\n\t\t\t\t\t...(peer.displayName ? { displayName: peer.displayName } : {}),\n\t\t\t\t\t...(peer.color ? { color: peer.color } : {}),\n\t\t\t\t\t...(peer.image ? { image: peer.image } : {}),\n\t\t\t\t},\n\t\t\t});\n\t\t\tclearHeartbeatTimer();\n\t\t\theartbeatTimerRef.current = window.setInterval(() => {\n\t\t\t\tsendRawRef.current({\n\t\t\t\t\ttype: \"session:ping\",\n\t\t\t\t\troomId,\n\t\t\t\t\tclientId: clientIdRef.current,\n\t\t\t\t\tsentAt: nowMs(),\n\t\t\t\t});\n\t\t\t}, heartbeatMs);\n\t\t});\n\n\t\tsocket.addEventListener(\"message\", (event) => {\n\t\t\tif (disposed) return;\n\t\t\tlet payload: unknown = event.data;\n\t\t\tif (typeof event.data === \"string\") {\n\t\t\t\ttry {\n\t\t\t\t\tpayload = JSON.parse(event.data);\n\t\t\t\t} catch {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst parsed = parseRealtimeServerMessage(payload);\n\t\t\tif (!parsed) return;\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tlastMessageAt: nowMs(),\n\t\t\t}));\n\n\t\t\tif (parsed.type === \"session:welcome\") {\n\t\t\t\tretryCountRef.current = 0;\n\t\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tstate: \"connected\",\n\t\t\t\t\tconnected: true,\n\t\t\t\t\tclientId: parsed.clientId,\n\t\t\t\t\tretryCount: 0,\n\t\t\t\t\tlastConnectedAt: nowMs(),\n\t\t\t\t\tlastError: null,\n\t\t\t\t}));\n\t\t\t\tapplyPeersRef.current(parsed.peers);\n\t\t\t\tconst handledByDraft = resolveAuthoritativeDocumentRef.current(\n\t\t\t\t\tsanitizeRealtimeSnapshot(parsed.document),\n\t\t\t\t\t{\n\t\t\t\t\t\tsuppressSubscriberNotify:\n\t\t\t\t\t\t\tlocalDraftRef.current != null &&\n\t\t\t\t\t\t\tsameSerializedItems(\n\t\t\t\t\t\t\t\tlatestDocumentRef.current?.items,\n\t\t\t\t\t\t\t\tlocalDraftRef.current.items,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tif (!handledByDraft) {\n\t\t\t\t\tqueuedDirtyRef.current = false;\n\t\t\t\t\toutboundInFlightRef.current = null;\n\t\t\t\t\tsetHasPendingDocumentSync(false);\n\t\t\t\t}\n\t\t\t\tscheduleDocumentFlushRef.current();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"presence:sync\") {\n\t\t\t\tapplyPeersRef.current(parsed.peers);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"session:peer-joined\") {\n\t\t\t\tsetSessionPeers((prev) => {\n\t\t\t\t\tconst next = prev.filter(\n\t\t\t\t\t\t(peerState) => peerState.clientId !== parsed.peer.clientId,\n\t\t\t\t\t);\n\t\t\t\t\tnext.push(\n\t\t\t\t\t\tparsed.peer.clientId === clientIdRef.current\n\t\t\t\t\t\t\t? { ...parsed.peer, isSelf: true }\n\t\t\t\t\t\t\t: parsed.peer,\n\t\t\t\t\t);\n\t\t\t\t\treturn next;\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"session:peer-left\") {\n\t\t\t\tsetSessionPeers((prev) =>\n\t\t\t\t\tprev.filter((peerState) => peerState.clientId !== parsed.clientId),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"session:pong\") {\n\t\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tlastPongAt: parsed.serverTime,\n\t\t\t\t}));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"session:error\") {\n\t\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tstate: prev.connected ? prev.state : \"error\",\n\t\t\t\t\tlastError: parsed.message,\n\t\t\t\t}));\n\t\t\t\tonErrorRef.current?.(parsed.message);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"document:sync\") {\n\t\t\t\tconst selfClientId = clientIdRef.current;\n\t\t\t\tconst inFlight = outboundInFlightRef.current;\n\t\t\t\tconst isSelfAck = parsed.document.updatedByClientId === selfClientId;\n\t\t\t\tif (!isSelfAck) {\n\t\t\t\t\t// Update from another peer. Clear in-flight (server moved on, our\n\t\t\t\t\t// pending send will be re-flushed against the new revision) and\n\t\t\t\t\t// run the smart merge.\n\t\t\t\t\toutboundInFlightRef.current = null;\n\t\t\t\t\tresolveAuthoritativeDocumentRef.current(\n\t\t\t\t\t\tsanitizeRealtimeSnapshot(parsed.document),\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Our own update was acked. Apply the canonical server view (with\n\t\t\t\t// any normalisation the server might have done) into the Y.Doc as\n\t\t\t\t// a smart merge — if we already drew more strokes during the round\n\t\t\t\t// trip, they survive as locally-pending.\n\t\t\t\tconst shouldSuppress =\n\t\t\t\t\tinFlight != null &&\n\t\t\t\t\tsameSerializedItems(inFlight.items, parsed.document.items);\n\t\t\t\toutboundInFlightRef.current = null;\n\t\t\t\tapplyDocumentRef.current(sanitizeRealtimeSnapshot(parsed.document), {\n\t\t\t\t\tsuppressSubscriberNotify: shouldSuppress,\n\t\t\t\t});\n\t\t\t\tconst board = boardRef.current;\n\t\t\t\tconst stillPending = board\n\t\t\t\t\t? getLocallyPendingItemIds(board).size > 0\n\t\t\t\t\t: false;\n\t\t\t\tif (stillPending) {\n\t\t\t\t\tconst mergedItems = board ? readVectorItems(board.yItems) : [];\n\t\t\t\t\tsetLocalDraftRef.current({\n\t\t\t\t\t\troomId,\n\t\t\t\t\t\tbaseRevision: currentRevisionRef.current,\n\t\t\t\t\t\titems: mergedItems,\n\t\t\t\t\t\tupdatedAt: nowMs(),\n\t\t\t\t\t\tpendingIds: board\n\t\t\t\t\t\t\t? Array.from(getLocallyPendingItemIds(board))\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t});\n\t\t\t\t\tqueuedDirtyRef.current = true;\n\t\t\t\t\tsetHasPendingDocumentSync(true);\n\t\t\t\t\tscheduleDocumentFlushRef.current();\n\t\t\t\t} else {\n\t\t\t\t\tqueuedDirtyRef.current = false;\n\t\t\t\t\tclearLocalDraftRef.current();\n\t\t\t\t\tsetHasPendingDocumentSync(false);\n\t\t\t\t}\n\t\t\t\tsetConflictStateRef.current(null);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (parsed.type === \"document:resync-required\") {\n\t\t\t\toutboundInFlightRef.current = null;\n\t\t\t\tqueuedDirtyRef.current = localDraftRef.current != null;\n\t\t\t\tsetHasPendingDocumentSync(queuedDirtyRef.current);\n\t\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tlastError: parsed.reason,\n\t\t\t\t}));\n\t\t\t\tresolveAuthoritativeDocumentRef.current(\n\t\t\t\t\tsanitizeRealtimeSnapshot(parsed.document),\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tsocket.addEventListener(\"error\", () => {\n\t\t\tif (disposed) return;\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tstate: prev.connected ? prev.state : \"error\",\n\t\t\t\tlastError: \"Falha de conexão websocket.\",\n\t\t\t}));\n\t\t});\n\n\t\tsocket.addEventListener(\"close\", () => {\n\t\t\tif (disposed) return;\n\t\t\tclearHeartbeatTimer();\n\t\t\tclearConnectTimeout();\n\t\t\twsRef.current = null;\n\t\t\tcollapsePeersToSelfRef.current(\n\t\t\t\tmanualDisconnectRef.current || !enabled ? \"offline\" : \"reconnecting\",\n\t\t\t);\n\t\t\tupdateConnectionRef.current((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tconnected: false,\n\t\t\t\tclientId: prev.clientId,\n\t\t\t\tstate: manualDisconnectRef.current || !enabled ? \"offline\" : prev.state,\n\t\t\t}));\n\t\t\tif (!manualDisconnectRef.current && enabled) {\n\t\t\t\tscheduleReconnectRef.current();\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tdisposed = true;\n\t\t\tclearReconnectTimer();\n\t\t\tclearHeartbeatTimer();\n\t\t\tclearConnectTimeout();\n\t\t\tclearDocumentFlushSchedule();\n\t\t\tsocket.close();\n\t\t};\n\t}, [\n\t\tclearConnectTimeout,\n\t\tclearDocumentFlushSchedule,\n\t\tclearHeartbeatTimer,\n\t\tclearReconnectTimer,\n\t\tconnectSequence,\n\t\tconnectTimeoutMs,\n\t\tenabled,\n\t\theartbeatMs,\n\t\tpeer.color,\n\t\tpeer.displayName,\n\t\tpeer.id,\n\t\tpeer.image,\n\t\troomId,\n\t\turl,\n\t]);\n\n\tuseEffect(() => {\n\t\tsetSessionPeers((prev) =>\n\t\t\tprev.map((peerState) =>\n\t\t\t\tpeerState.clientId === clientIdRef.current\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...peerState,\n\t\t\t\t\t\t\tisSelf: true,\n\t\t\t\t\t\t\tconnectionState: connection.state,\n\t\t\t\t\t\t}\n\t\t\t\t\t: peerState,\n\t\t\t),\n\t\t);\n\t}, [connection.state]);\n\n\tuseEffect(\n\t\t() => () => {\n\t\t\tclearDocumentFlushSchedule();\n\t\t\tclearDraftPersistSchedule();\n\t\t\tif (boardRef.current) {\n\t\t\t\tboardRef.current.doc.destroy();\n\t\t\t\tboardRef.current = null;\n\t\t\t}\n\t\t},\n\t\t[clearDocumentFlushSchedule, clearDraftPersistSchedule],\n\t);\n\n\tconst flushDocumentSync = useCallback(async () => {\n\t\t// Manual flush (saveCurrentCanvas in trazo): drain pendingLocalItemsRef\n\t\t// into the Y.Doc and update the draft synchronously before persisting,\n\t\t// so the localStorage snapshot reflects the latest local changes even\n\t\t// when called while a previous send is still in-flight.\n\t\tconst board = boardRef.current;\n\t\tconst pendingLocal = pendingLocalItemsRef.current;\n\t\tif (board && pendingLocal) {\n\t\t\tpendingLocalItemsRef.current = null;\n\t\t\tapplyLocalItemsToYDoc(board, {\n\t\t\t\titems: pendingLocal,\n\t\t\t\torigin: ORIGIN_LOCAL,\n\t\t\t});\n\t\t\tconst mergedItems = readVectorItems(board.yItems);\n\t\t\tconst pendingIds = getLocallyPendingItemIds(board);\n\t\t\tif (pendingIds.size > 0) {\n\t\t\t\tsetLocalDraftRef.current({\n\t\t\t\t\troomId,\n\t\t\t\t\tbaseRevision: currentRevisionRef.current,\n\t\t\t\t\titems: mergedItems,\n\t\t\t\t\tupdatedAt: nowMs(),\n\t\t\t\t\tpendingIds: Array.from(pendingIds),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tpersistLocalDraft();\n\t\tif (!connection.connected) return;\n\t\tflushQueuedDocument();\n\t}, [connection.connected, flushQueuedDocument, persistLocalDraft, roomId]);\n\n\tconst remoteAdapter = useMemo<VectorCanvasRemoteAdapter>(\n\t\t() => ({\n\t\t\tsubscribe(onItems) {\n\t\t\t\tsubscriberRefs.current.add(onItems);\n\t\t\t\tif (latestDocumentRef.current) {\n\t\t\t\t\tonItems(latestDocumentRef.current.items);\n\t\t\t\t}\n\t\t\t\treturn () => {\n\t\t\t\t\tsubscriberRefs.current.delete(onItems);\n\t\t\t\t};\n\t\t\t},\n\t\t\tsend(items) {\n\t\t\t\tqueueDocumentSend(items);\n\t\t\t},\n\t\t\tflush() {\n\t\t\t\treturn flushDocumentSync();\n\t\t\t},\n\t\t}),\n\t\t[flushDocumentSync, queueDocumentSend],\n\t);\n\n\tconst disconnect = useCallback(() => {\n\t\tmanualDisconnectRef.current = true;\n\t\tclearReconnectTimer();\n\t\tclearHeartbeatTimer();\n\t\tclearConnectTimeout();\n\t\tsendRaw({\n\t\t\ttype: \"session:leave\",\n\t\t\troomId,\n\t\t\tclientId: clientIdRef.current,\n\t\t});\n\t\twsRef.current?.close();\n\t\twsRef.current = null;\n\t\tcollapsePeersToSelf(\"offline\");\n\t\tupdateConnection((prev) => ({\n\t\t\t...prev,\n\t\t\tstate: \"offline\",\n\t\t\tconnected: false,\n\t\t}));\n\t}, [\n\t\tclearConnectTimeout,\n\t\tclearHeartbeatTimer,\n\t\tclearReconnectTimer,\n\t\tcollapsePeersToSelf,\n\t\troomId,\n\t\tsendRaw,\n\t\tupdateConnection,\n\t]);\n\n\tconst reconnectNow = useCallback(() => {\n\t\tdisconnect();\n\t\tmanualDisconnectRef.current = false;\n\t\tretryCountRef.current = 0;\n\t\tsetConnectSequence((value) => value + 1);\n\t}, [disconnect]);\n\n\tconst remotePresence = useMemo(\n\t\t() => sessionPeers.filter((peerState) => !peerState.isSelf),\n\t\t[sessionPeers],\n\t);\n\n\tconst syncViewportPresence = useCallback(\n\t\t(bindingOptions?: BindViewportPresenceOptions) => {\n\t\t\tconst viewport = bindingOptions?.viewportRef?.current;\n\t\t\tconst cameraSnapshot = getViewportCameraSnapshot(viewport);\n\t\t\tif (!cameraSnapshot) return false;\n\t\t\tlastCameraRef.current = cameraSnapshot;\n\t\t\tlastActiveToolRef.current = bindingOptions?.activeTool;\n\t\t\tsendPresenceUpdate();\n\t\t\treturn true;\n\t\t},\n\t\t[sendPresenceUpdate],\n\t);\n\n\tconst bindViewportPresence = useCallback(\n\t\t(\n\t\t\tbindingOptions?: BindViewportPresenceOptions,\n\t\t): RealtimeViewportPresenceBindings => ({\n\t\t\tremotePresence,\n\t\t\tonWorldPointerMove(world) {\n\t\t\t\tlastCursorRef.current = world;\n\t\t\t\tlastActiveToolRef.current = bindingOptions?.activeTool;\n\t\t\t\tsendPresenceUpdate();\n\t\t\t},\n\t\t\tonWorldPointerLeave() {\n\t\t\t\tlastCursorRef.current = null;\n\t\t\t\tlastActiveToolRef.current = bindingOptions?.activeTool;\n\t\t\t\tsendPresenceUpdate();\n\t\t\t},\n\t\t\tonPlacementPreviewChange(preview: PlacementPreview | null) {\n\t\t\t\tlastMarkupStrokeRef.current =\n\t\t\t\t\tremoteMarkupStrokeFromPlacementPreview(preview);\n\t\t\t\tlastActiveToolRef.current = bindingOptions?.activeTool;\n\t\t\t\tsendPresenceUpdate();\n\t\t\t},\n\t\t\tonCameraChange() {\n\t\t\t\tconst viewport = bindingOptions?.viewportRef?.current;\n\t\t\t\tconst cameraSnapshot = getViewportCameraSnapshot(viewport);\n\t\t\t\tif (!cameraSnapshot) return;\n\t\t\t\tif (viewport && consumeViewportFollowSync(viewport, cameraSnapshot)) {\n\t\t\t\t\tlastCameraRef.current = cameraSnapshot;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlastCameraRef.current = cameraSnapshot;\n\t\t\t\tlastActiveToolRef.current = bindingOptions?.activeTool;\n\t\t\t\tsendPresenceUpdate();\n\t\t\t},\n\t\t}),\n\t\t[remotePresence, sendPresenceUpdate],\n\t);\n\n\treturn {\n\t\tconnection,\n\t\tsessionPeers,\n\t\tremotePresence,\n\t\tremoteAdapter,\n\t\tdocument,\n\t\thasLocalOfflineDraft,\n\t\thasPendingDocumentSync,\n\t\tsyncState,\n\t\tconflict,\n\t\tbindViewportPresence,\n\t\tsyncViewportPresence,\n\t\tresolveConflict,\n\t\tclearLocalDraft,\n\t\tflushDocumentSync,\n\t\tdisconnect,\n\t\treconnectNow,\n\t};\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo } from \"react\";\nimport { defaultPresenceColorForId } from \"../../presence\";\nimport {\n\ttype CanvasPlugin,\n\ttype CanvasPluginContribution,\n\ttype CanvasPluginItemsChangeMiddlewareContext,\n\tcreateCanvuPlugin,\n\tuseCanvuDocumentContext,\n\tuseCanvuPluginContribution,\n\tuseCanvuViewportContext,\n} from \"../types\";\nimport {\n\tRealtimeSessionPanel,\n\ttype RealtimeSessionPanelProps,\n} from \"./RealtimeSessionPanel\";\nimport {\n\ttype RealtimeCommentsAuthor,\n\ttype UseRealtimeCommentsOptions,\n\tuseRealtimeComments,\n} from \"./use-realtime-comments\";\nimport {\n\ttype UseRealtimeSessionOptions,\n\tuseRealtimeSession,\n} from \"./use-realtime-session\";\n\nexport type RealtimeCollaborationPluginOptions = UseRealtimeSessionOptions & {\n\t/** Enable or disable the built-in session panel. Default: `true`. */\n\tshowSessionPanel?: boolean;\n\t/** Optional visual customization for the built-in session panel. */\n\tsessionPanel?: Partial<\n\t\tOmit<\n\t\t\tRealtimeSessionPanelProps,\n\t\t\t\"peers\" | \"connected\" | \"connectionState\" | \"roomId\"\n\t\t>\n\t>;\n\t/**\n\t * Enable or configure the built-in collaborative comments experience.\n\t *\n\t * Pass `false` to disable comments entirely. When omitted, comments are enabled.\n\t */\n\tcomments?:\n\t\t| false\n\t\t| Omit<\n\t\t\t\tUseRealtimeCommentsOptions,\n\t\t\t\t\"items\" | \"onItemsChange\" | \"author\" | \"viewportRef\" | \"roomId\" | \"setToolId\"\n\t\t >;\n};\n\nfunction RealtimeCollaborationPluginComponent({\n\tpluginId,\n\toptions,\n}: {\n\tpluginId: string;\n\toptions: RealtimeCollaborationPluginOptions;\n}) {\n\tconst { viewportRef, viewport } = useCanvuViewportContext();\n\tconst { items, onItemsChange } = useCanvuDocumentContext();\n\tconst session = useRealtimeSession(options);\n\tconst peerDisplayName = options.peer.displayName ?? options.peer.id;\n\tconst peerColor = options.peer.color ?? defaultPresenceColorForId(options.peer.id);\n\tconst peerAuthor = useMemo<RealtimeCommentsAuthor>(\n\t\t() => ({\n\t\t\tpeerId: options.peer.id,\n\t\t\tdisplayName: peerDisplayName,\n\t\t\tcolor: peerColor,\n\t\t\t...(options.peer.image ? { image: options.peer.image } : {}),\n\t\t}),\n\t\t[options.peer.id, options.peer.image, peerColor, peerDisplayName],\n\t);\n\tconst commentOptions = useMemo(\n\t\t() => (options.comments === false ? null : (options.comments ?? {})),\n\t\t[options.comments],\n\t);\n\tconst handleCommentItemsChange = useCallback(\n\t\t(nextItems: typeof items) => {\n\t\t\tonItemsChange?.([...nextItems]);\n\t\t\tsession.remoteAdapter.send?.([...nextItems]);\n\t\t},\n\t\t[onItemsChange, session.remoteAdapter],\n\t);\n\tconst comments = useRealtimeComments({\n\t\titems,\n\t\tonItemsChange: handleCommentItemsChange,\n\t\tauthor: peerAuthor,\n\t\tviewportRef,\n\t\tactiveToolId: viewport.toolId,\n\t\troomId: options.roomId,\n\t\tsetToolId: viewport.onToolChangeRequest,\n\t\t...(commentOptions ?? {}),\n\t});\n\tconst presenceBindings = useMemo(\n\t\t() =>\n\t\t\tsession.bindViewportPresence({\n\t\t\t\tactiveTool: viewport.toolId,\n\t\t\t\tviewportRef,\n\t\t\t}),\n\t\t[session.bindViewportPresence, viewport.toolId, viewportRef],\n\t);\n\tconst onViewportCameraChange = useCallback(() => {\n\t\tpresenceBindings.onCameraChange?.();\n\t\tcomments.viewport.onCameraChange?.();\n\t}, [comments.viewport, presenceBindings]);\n\n\tuseEffect(() => {\n\t\tif (!session.connection.connected) return;\n\t\tlet animationFrameId = 0;\n\t\tconst syncViewportPresence = () => {\n\t\t\tconst didSync = session.syncViewportPresence({\n\t\t\t\tactiveTool: viewport.toolId,\n\t\t\t\tviewportRef,\n\t\t\t});\n\t\t\tif (didSync) return;\n\t\t\tanimationFrameId = window.requestAnimationFrame(syncViewportPresence);\n\t\t};\n\t\tsyncViewportPresence();\n\t\treturn () => {\n\t\t\twindow.cancelAnimationFrame(animationFrameId);\n\t\t};\n\t}, [\n\t\tsession.connection.connected,\n\t\tsession.syncViewportPresence,\n\t\tviewport.toolId,\n\t\tviewportRef,\n\t]);\n\n\tuseEffect(() => {\n\t\tif (!onItemsChange || !session.document) return;\n\t\tif (session.document.updatedByClientId === session.connection.clientId) return;\n\t\tonItemsChange(session.document.items);\n\t}, [onItemsChange, session.connection.clientId, session.document]);\n\n\tconst contribution = useMemo<CanvasPluginContribution>(\n\t\t() => ({\n\t\t\ttoolTransform: commentOptions ? () => comments.tools : undefined,\n\t\t\tcustomPlacements: commentOptions\n\t\t\t\t? comments.viewport.customPlacement\n\t\t\t\t\t? [comments.viewport.customPlacement]\n\t\t\t\t\t: undefined\n\t\t\t\t: undefined,\n\t\t\tviewportProps: {\n\t\t\t\tremotePresence: presenceBindings.remotePresence,\n\t\t\t},\n\t\t\tcallbacks: {\n\t\t\t\tonWorldPointerMove: presenceBindings.onWorldPointerMove,\n\t\t\t\tonWorldPointerLeave: presenceBindings.onWorldPointerLeave,\n\t\t\t\tonPlacementPreviewChange: presenceBindings.onPlacementPreviewChange,\n\t\t\t\tonCameraChange: onViewportCameraChange,\n\t\t\t},\n\t\t\twrapOnItemsChange: (\n\t\t\t\tnextItems,\n\t\t\t\tctx: CanvasPluginItemsChangeMiddlewareContext,\n\t\t\t) => {\n\t\t\t\tif (commentOptions) {\n\t\t\t\t\tcomments.handleViewportItemsChange(nextItems, (processedItems) => {\n\t\t\t\t\t\tctx.next(processedItems);\n\t\t\t\t\t\tsession.remoteAdapter.send?.([...processedItems]);\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tctx.next(nextItems);\n\t\t\t\tsession.remoteAdapter.send?.(nextItems);\n\t\t\t},\n\t\t}),\n\t\t[\n\t\t\tcommentOptions,\n\t\t\tcomments.tools,\n\t\t\tcomments.viewport,\n\t\t\tcomments.handleViewportItemsChange,\n\t\t\tonViewportCameraChange,\n\t\t\tpresenceBindings,\n\t\t\tsession.remoteAdapter,\n\t\t],\n\t);\n\tuseCanvuPluginContribution(pluginId, contribution);\n\n\treturn (\n\t\t<>\n\t\t\t{options.showSessionPanel === false ? null : (\n\t\t\t\t<RealtimeSessionPanel\n\t\t\t\t\ttitle={options.sessionPanel?.title ?? \"Sessão realtime\"}\n\t\t\t\t\tpeers={session.sessionPeers}\n\t\t\t\t\tconnected={session.connection.connected}\n\t\t\t\t\tconnectionState={session.connection.state}\n\t\t\t\t\troomId={options.roomId}\n\t\t\t\t>\n\t\t\t\t\t{options.sessionPanel?.children}\n\t\t\t\t</RealtimeSessionPanel>\n\t\t\t)}\n\t\t\t{commentOptions ? comments.overlay : null}\n\t\t</>\n\t);\n}\n\n/**\n * High-level plug and play collaboration plugin for `VectorViewport`.\n *\n * Use this when you want realtime presence, session UI, collaborative comments, and document sync\n * without manually wiring `useRealtimeSession`, `useRealtimeComments`, or extra viewport props.\n *\n * For advanced customizations and bespoke UIs, use `useRealtimeSession(...)` and\n * `useRealtimeComments(...)` directly.\n */\nexport function realtimeCollaborationPlugin(\n\toptions: RealtimeCollaborationPluginOptions,\n): CanvasPlugin {\n\tconst pluginId = `canvu.plugin.realtime-collaboration:${options.roomId}:${options.peer.clientId ?? options.peer.id}`;\n\treturn createCanvuPlugin({\n\t\tid: pluginId,\n\t\tComponent() {\n\t\t\treturn (\n\t\t\t\t<RealtimeCollaborationPluginComponent\n\t\t\t\t\tpluginId={pluginId}\n\t\t\t\t\toptions={options}\n\t\t\t\t/>\n\t\t\t);\n\t\t},\n\t});\n}\n","import type { CanvasPlugin } from \"../types\";\nimport {\n\tRealtimeSessionPanel,\n\ttype RealtimeSessionPanelProps,\n} from \"./RealtimeSessionPanel\";\n\nexport type RealtimeSessionPluginOptions = RealtimeSessionPanelProps;\n\n/**\n * Optional UI roster for who is in the session (your WebSocket layer fills `peers`).\n * World-space cursors and strokes use {@link VectorViewport} `remotePresence` and\n * `onWorldPointerMove` — this plugin only renders a small panel in the viewport plugin layer.\n *\n * @example\n * ```tsx\n * <VectorViewport\n * items={doc.items}\n * onItemsChange={doc.onItemsChange}\n * plugins={[\n * realtimeSessionPlugin({ peers: presenceRoster, connected: wsOpen }),\n * ]}\n * />\n * ```\n */\nexport function realtimeSessionPlugin(\n\toptions: RealtimeSessionPluginOptions,\n): CanvasPlugin {\n\treturn {\n\t\tid: \"trazo.plugin.realtime-session\",\n\t\trender: () => <RealtimeSessionPanel {...options} />,\n\t};\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { VectorSceneItem } from \"../../../scene/types\";\nimport type {\n\tRealtimeDocumentConflict,\n\tRealtimeSyncState,\n\tUseRealtimeSessionResult,\n} from \"./use-realtime-session\";\n\ntype UseRealtimeCanvasDocumentOptions = {\n\tsession: Pick<\n\t\tUseRealtimeSessionResult,\n\t\t| \"connection\"\n\t\t| \"document\"\n\t\t| \"remoteAdapter\"\n\t\t| \"hasLocalOfflineDraft\"\n\t\t| \"hasPendingDocumentSync\"\n\t\t| \"syncState\"\n\t\t| \"conflict\"\n\t\t| \"resolveConflict\"\n\t\t| \"clearLocalDraft\"\n\t\t| \"flushDocumentSync\"\n\t> | null;\n\titems: readonly VectorSceneItem[];\n\tonItemsChange?: (nextItems: VectorSceneItem[]) => void;\n\tnormalizeItems?: (nextItems: readonly VectorSceneItem[]) => VectorSceneItem[];\n\thydrateItems?: (\n\t\tnextItems: readonly VectorSceneItem[],\n\t) => Promise<VectorSceneItem[]>;\n\tenabled?: boolean;\n};\n\nexport type UseRealtimeCanvasDocumentResult = {\n\titems: readonly VectorSceneItem[];\n\tonItemsChange?: (nextItems: VectorSceneItem[]) => void;\n\tloading: boolean;\n\tsaving: boolean;\n\thasLocalOfflineDraft: boolean;\n\tsyncState: RealtimeSyncState;\n\tconflict: RealtimeDocumentConflict | null;\n\tresolveConflict: (action: \"keep-local\" | \"use-server\") => void;\n\tclearLocalDraft: () => void;\n\tflush: () => Promise<void>;\n};\n\nfunction getSceneItemId(item: VectorSceneItem): string | null {\n\tconst id = (item as { id?: unknown }).id;\n\treturn typeof id === \"string\" ? id : null;\n}\n\nfunction hasMissingLocalItems(\n\tlocalItems: readonly VectorSceneItem[],\n\tincomingItems: readonly VectorSceneItem[],\n): boolean {\n\tconst incomingIds = new Set<string>();\n\tfor (const item of incomingItems) {\n\t\tconst id = getSceneItemId(item);\n\t\tif (id) incomingIds.add(id);\n\t}\n\tfor (const item of localItems) {\n\t\tconst id = getSceneItemId(item);\n\t\tif (id && !incomingIds.has(id)) return true;\n\t}\n\treturn false;\n}\n\nexport function useRealtimeCanvasDocument(\n\toptions: UseRealtimeCanvasDocumentOptions,\n): UseRealtimeCanvasDocumentResult {\n\tconst {\n\t\tsession,\n\t\titems,\n\t\tonItemsChange,\n\t\tnormalizeItems,\n\t\thydrateItems,\n\t\tenabled = true,\n\t} = options;\n\tconst [loading, setLoading] = useState(false);\n\tconst lastAppliedRevisionRef = useRef<number | null>(null);\n\tconst inFlightRevisionRef = useRef<number | null>(null);\n\t// Once we've ever propagated a non-empty items set to the consumer, treat\n\t// a subsequent inbound empty document as suspicious and skip it. This\n\t// guards against rare races (tab killed before localStorage debounce\n\t// flushed, Y.Doc reset, stale snapshot) that would otherwise wipe the\n\t// consumer's view to []. Genuine empty boards on first load still work\n\t// because hasEverPropagatedItemsRef starts false.\n\tconst hasEverPropagatedItemsRef = useRef(false);\n\tconst realtimeEnabled = enabled && session != null;\n\tconst documentRevision = session?.document?.revision ?? null;\n\tconst documentItems = session?.document?.items;\n\tconst documentUpdatedByClientId = session?.document?.updatedByClientId ?? null;\n\tconst connectionClientId = session?.connection.clientId ?? null;\n\tconst hasLocalOfflineDraft = session?.hasLocalOfflineDraft ?? false;\n\tconst hasPendingDocumentSync = session?.hasPendingDocumentSync ?? false;\n\n\tconst applyIncomingItems = useCallback(\n\t\tasync (nextItems: readonly VectorSceneItem[]) => {\n\t\t\tconst normalizedItems = normalizeItems\n\t\t\t\t? normalizeItems(nextItems)\n\t\t\t\t: [...nextItems];\n\t\t\tif (!hydrateItems) return normalizedItems;\n\t\t\treturn await hydrateItems(normalizedItems);\n\t\t},\n\t\t[hydrateItems, normalizeItems],\n\t);\n\n\tconst handleItemsChange = useCallback(\n\t\t(nextItems: VectorSceneItem[]) => {\n\t\t\tif (!enabled) {\n\t\t\t\tonItemsChange?.(normalizeItems ? normalizeItems(nextItems) : nextItems);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst normalizedItems = normalizeItems ? normalizeItems(nextItems) : nextItems;\n\t\t\tonItemsChange?.(normalizedItems);\n\t\t\tsession?.remoteAdapter.send?.(normalizedItems);\n\t\t},\n\t\t[enabled, normalizeItems, onItemsChange, session],\n\t);\n\n\tuseEffect(() => {\n\t\tif (items.length > 0) {\n\t\t\thasEverPropagatedItemsRef.current = true;\n\t\t}\n\t}, [items.length]);\n\n\tuseEffect(() => {\n\t\tif (!realtimeEnabled || !onItemsChange || !session?.document) return;\n\t\tif (documentUpdatedByClientId === connectionClientId) return;\n\t\tif (documentRevision == null) return;\n\t\tif (lastAppliedRevisionRef.current === documentRevision) return;\n\t\tif (inFlightRevisionRef.current === documentRevision) return;\n\t\tinFlightRevisionRef.current = documentRevision;\n\t\tlet cancelled = false;\n\t\tsetLoading(true);\n\t\tvoid applyIncomingItems(documentItems ?? [])\n\t\t\t.then((resolvedItems) => {\n\t\t\t\tif (cancelled) return;\n\t\t\t\tif (inFlightRevisionRef.current !== documentRevision) return;\n\t\t\t\tlastAppliedRevisionRef.current = documentRevision;\n\t\t\t\tconst hasLocalItems = items.length > 0;\n\t\t\t\tconst hasPendingLocalChanges =\n\t\t\t\t\thasLocalOfflineDraft || hasPendingDocumentSync;\n\t\t\t\tif (\n\t\t\t\t\tresolvedItems.length === 0 &&\n\t\t\t\t\t(hasEverPropagatedItemsRef.current ||\n\t\t\t\t\t\thasLocalItems ||\n\t\t\t\t\t\thasPendingLocalChanges)\n\t\t\t\t) {\n\t\t\t\t\t// Defensive: a previously non-empty document is now empty.\n\t\t\t\t\t// Almost always a stale or buggy snapshot — skip rather\n\t\t\t\t\t// than wipe the consumer's view. The next snapshot will\n\t\t\t\t\t// reconcile if the emptiness was real.\n\t\t\t\t\tif (hasLocalItems) {\n\t\t\t\t\t\tconst normalizedLocalItems = normalizeItems\n\t\t\t\t\t\t\t? normalizeItems(items)\n\t\t\t\t\t\t\t: [...items];\n\t\t\t\t\t\tsession.remoteAdapter.send?.(normalizedLocalItems);\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\thasPendingLocalChanges &&\n\t\t\t\t\thasLocalItems &&\n\t\t\t\t\thasMissingLocalItems(items, resolvedItems)\n\t\t\t\t) {\n\t\t\t\t\tconst normalizedLocalItems = normalizeItems\n\t\t\t\t\t\t? normalizeItems(items)\n\t\t\t\t\t\t: [...items];\n\t\t\t\t\tsession.remoteAdapter.send?.(normalizedLocalItems);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (resolvedItems.length > 0) {\n\t\t\t\t\thasEverPropagatedItemsRef.current = true;\n\t\t\t\t}\n\t\t\t\tonItemsChange(resolvedItems);\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (inFlightRevisionRef.current === documentRevision) {\n\t\t\t\t\tinFlightRevisionRef.current = null;\n\t\t\t\t}\n\t\t\t\tif (cancelled) return;\n\t\t\t\tsetLoading(false);\n\t\t\t});\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, [\n\t\tapplyIncomingItems,\n\t\tconnectionClientId,\n\t\tdocumentItems,\n\t\tdocumentRevision,\n\t\tdocumentUpdatedByClientId,\n\t\thasLocalOfflineDraft,\n\t\thasPendingDocumentSync,\n\t\titems,\n\t\tnormalizeItems,\n\t\tonItemsChange,\n\t\trealtimeEnabled,\n\t\tsession?.remoteAdapter,\n\t\tsession?.document,\n\t]);\n\n\treturn useMemo(\n\t\t() => ({\n\t\t\titems,\n\t\t\tonItemsChange: onItemsChange ? handleItemsChange : undefined,\n\t\t\tloading,\n\t\t\tsaving: session?.hasPendingDocumentSync ?? false,\n\t\t\thasLocalOfflineDraft: session?.hasLocalOfflineDraft ?? false,\n\t\t\tsyncState: session?.syncState ?? \"offline\",\n\t\t\tconflict: session?.conflict ?? null,\n\t\t\tresolveConflict: session?.resolveConflict ?? (() => {}),\n\t\t\tclearLocalDraft: session?.clearLocalDraft ?? (() => {}),\n\t\t\tflush: session?.flushDocumentSync ?? (async () => {}),\n\t\t}),\n\t\t[handleItemsChange, items, loading, onItemsChange, session],\n\t);\n}\n"]}