canvu-react 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +156 -0
  3. package/dist/camera-BwQjm5oh.d.cts +50 -0
  4. package/dist/camera-KwCYYPhm.d.ts +50 -0
  5. package/dist/chatbot.cjs +221 -0
  6. package/dist/chatbot.cjs.map +1 -0
  7. package/dist/chatbot.d.cts +36 -0
  8. package/dist/chatbot.d.ts +36 -0
  9. package/dist/chatbot.js +218 -0
  10. package/dist/chatbot.js.map +1 -0
  11. package/dist/index.cjs +1920 -0
  12. package/dist/index.cjs.map +1 -0
  13. package/dist/index.d.cts +276 -0
  14. package/dist/index.d.ts +276 -0
  15. package/dist/index.js +1867 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/native.cjs +2572 -0
  18. package/dist/native.cjs.map +1 -0
  19. package/dist/native.d.cts +217 -0
  20. package/dist/native.d.ts +217 -0
  21. package/dist/native.js +2562 -0
  22. package/dist/native.js.map +1 -0
  23. package/dist/react.cjs +8540 -0
  24. package/dist/react.cjs.map +1 -0
  25. package/dist/react.d.cts +481 -0
  26. package/dist/react.d.ts +481 -0
  27. package/dist/react.js +8492 -0
  28. package/dist/react.js.map +1 -0
  29. package/dist/realtime.cjs +2338 -0
  30. package/dist/realtime.cjs.map +1 -0
  31. package/dist/realtime.d.cts +309 -0
  32. package/dist/realtime.d.ts +309 -0
  33. package/dist/realtime.js +2317 -0
  34. package/dist/realtime.js.map +1 -0
  35. package/dist/shape-builders-DTYvub8W.d.ts +93 -0
  36. package/dist/shape-builders-DxPoOecg.d.cts +93 -0
  37. package/dist/tldraw.cjs +1948 -0
  38. package/dist/tldraw.cjs.map +1 -0
  39. package/dist/tldraw.d.cts +98 -0
  40. package/dist/tldraw.d.ts +98 -0
  41. package/dist/tldraw.js +1941 -0
  42. package/dist/tldraw.js.map +1 -0
  43. package/dist/types--ALu1mF-.d.ts +356 -0
  44. package/dist/types-B58i5k-u.d.cts +35 -0
  45. package/dist/types-CB0TZZuk.d.cts +157 -0
  46. package/dist/types-CB0TZZuk.d.ts +157 -0
  47. package/dist/types-D1ftVsOQ.d.cts +356 -0
  48. package/dist/types-DgEArHkA.d.ts +35 -0
  49. package/package.json +103 -0
@@ -0,0 +1,276 @@
1
+ import { C as Camera2D } from './camera-BwQjm5oh.cjs';
2
+ export { a as Camera2DOptions } from './camera-BwQjm5oh.cjs';
3
+ import { V as VectorSceneItem, A as ArrowEndpointBinding, R as Rect } from './types-CB0TZZuk.cjs';
4
+ export { a as ArrowBindings, b as VectorPathPoint, n as normalizeRect, r as rectsIntersect } from './types-CB0TZZuk.cjs';
5
+ export { D as DEFAULT_STROKE_STYLE, F as FreehandSvgPayload, S as StrokeStyle, a as applyStrokeToItem, b as buildArrowSvg, c as buildDrawDotSvg, d as buildEllipseSvg, e as buildFreehandPathSvg, f as buildLineSvg, g as buildRectSvg, h as computeFreehandSvgPayload, i as createDrawDotItem, j as createEllipseItem, k as createFreehandStrokeItem, l as createImageFromVectorTrace, m as createImageItem, n as createLineItem, o as createRectangleItem, p as createShapeId, q as createTextItem, r as lineEndpointsToLocal, s as rebuildItemSvg, t as resolveStrokeStyle } from './shape-builders-DxPoOecg.cjs';
6
+
7
+ /**
8
+ * Embeds the bitmap as a single SVG `<image>` (data URL or blob URL) instead of tracing paths.
9
+ * Avoids huge path counts and keeps screenshots/photos sharp.
10
+ */
11
+ /**
12
+ * Default max width/height (px) before encoding. Larger = sharper zoom / bigger snapshots.
13
+ * Override per app via {@link loadImageFileAsRasterSceneSource} or `VectorViewport` `imageRasterMaxDimension`.
14
+ */
15
+ declare const MAX_RASTER_EMBED_DIMENSION = 4096;
16
+ /** How raster pixels are exposed to SVG `<image href>`. */
17
+ type RasterEmbedMode = "dataUrl" | "blobUrl";
18
+ type LoadRasterImageFileOptions = {
19
+ /** Longest edge (px). Images larger than this are scaled down (canvas). */
20
+ maxDimension?: number;
21
+ /**
22
+ * `dataUrl` — easy to persist (JSON), higher memory use with many large images.
23
+ * `blobUrl` — lower overhead; **revoke** URLs when items leave the scene (handled by `VectorViewport` for its own loads).
24
+ */
25
+ embedMode?: RasterEmbedMode;
26
+ };
27
+ type RasterSceneSource = {
28
+ /**
29
+ * Value for SVG `<image href>`: `data:image/...;base64,...` or `blob:https://...`.
30
+ * Despite the name, `blobUrl` mode stores a blob URL here.
31
+ */
32
+ dataUrl: string;
33
+ width: number;
34
+ height: number;
35
+ };
36
+ /**
37
+ * Decodes a file and returns a raster source for {@link createImageItem}.
38
+ *
39
+ * - `dataUrl` (default): canvas downscale + base64 (serializable).
40
+ * - `blobUrl`: uses `URL.createObjectURL(file)` at **full resolution** when the longest edge
41
+ * is ≤ `maxDimension`; otherwise downscales like data mode but keeps a blob URL (smaller than base64).
42
+ */
43
+ declare function loadImageFileAsRasterSceneSource(file: File, maxDimensionOrOptions?: number | LoadRasterImageFileOptions): Promise<RasterSceneSource>;
44
+
45
+ type ApplePencilNavOptions = {
46
+ element: HTMLElement;
47
+ camera: Camera2D;
48
+ /** Current tool id from your app (e.g. `"hand"` vs `"draw"`). */
49
+ getCurrentToolId: () => string;
50
+ onUpdate: () => void;
51
+ touchPanSensitivity?: number;
52
+ };
53
+ /**
54
+ * After a **stylus** (`pointerType === "pen"`) has been used, finger touches on the canvas
55
+ * pan/pinch the camera instead of passing through to drawing tools — similar to iPad behavior
56
+ * in many design apps. No-op until the first pen contact.
57
+ *
58
+ * Compose with {@link attachViewportInput} by calling this **after** it so capture handlers run first,
59
+ * or use only one of them depending on product needs.
60
+ */
61
+ declare function attachApplePencilNavigation(options: ApplePencilNavOptions): () => void;
62
+
63
+ type ViewportInputOptions = {
64
+ element: HTMLElement;
65
+ camera: Camera2D;
66
+ /** Called after any camera mutation so the renderer can redraw. */
67
+ onUpdate: () => void;
68
+ /**
69
+ * Element to attach the wheel listener to. Defaults to `element`.
70
+ * Useful when an overlay with `pointer-events: auto` sits above `element` and
71
+ * would otherwise intercept wheel events before they reach the scene container.
72
+ */
73
+ wheelElement?: HTMLElement;
74
+ wheelPanSensitivity?: number;
75
+ /** Multiplier applied to wheel delta for zoom (with Ctrl/Meta). */
76
+ wheelZoomSensitivity?: number;
77
+ touchPanSensitivity?: number;
78
+ /**
79
+ * When `true`, pointer events with `pointerType === "touch"` are ignored so another layer
80
+ * (e.g. `attachApplePencilNavigation`) can handle them without double panning.
81
+ */
82
+ touchHandledElsewhere?: boolean;
83
+ /**
84
+ * When `false`, one-finger / primary-button drag does **not** pan the camera (e.g. shape tools).
85
+ * Wheel zoom and two-finger pinch still work.
86
+ */
87
+ allowPrimaryPointerPan?: () => boolean;
88
+ };
89
+ /**
90
+ * Attaches wheel (pan / Ctrl+zoom), pointer drag pan, and two-finger pinch zoom.
91
+ * Uses `touch-action: none` on `element` — set that in CSS on the same node.
92
+ *
93
+ * @returns A dispose function that removes all listeners.
94
+ */
95
+ declare function attachViewportInput(options: ViewportInputOptions): () => void;
96
+
97
+ /** Default screen px — converted to world with `/ camera.zoom` when snapping. */
98
+ declare const ARROW_BIND_SNAP_PX = 16;
99
+ declare function isArrowBindTarget(item: VectorSceneItem): boolean;
100
+ /**
101
+ * If `worldX/worldY` is within `maxDistWorld` of a bindable shape’s boundary,
102
+ * returns the snapped point on that boundary plus binding metadata.
103
+ */
104
+ declare function snapArrowEndpointToShape(worldX: number, worldY: number, items: readonly VectorSceneItem[], excludeIds: ReadonlySet<string>, maxDistWorld: number): {
105
+ world: {
106
+ x: number;
107
+ y: number;
108
+ };
109
+ binding: ArrowEndpointBinding;
110
+ } | null;
111
+ /**
112
+ * Recomputes every arrow item that has {@link VectorSceneItem.arrowBind} so endpoints
113
+ * follow bound shapes (move/resize).
114
+ */
115
+ declare function resolveArrowBindingsInScene(items: readonly VectorSceneItem[]): readonly VectorSceneItem[];
116
+ /**
117
+ * Converts a bound arrow to a plain arrow (drops bindings) using the current resolved
118
+ * geometry so move/resize gestures don’t fight binding resolution.
119
+ */
120
+ declare function bakeArrowItemToAbsolute(item: VectorSceneItem, items: readonly VectorSceneItem[]): VectorSceneItem;
121
+
122
+ type HitTestWorldPointOptions = {
123
+ /** Max distance to a line segment in **world** units (e.g. ~10 / camera.zoom for ~10px on screen). */
124
+ lineHitWorld?: number;
125
+ /** When true, locked items are ignored as interaction targets. */
126
+ ignoreLocked?: boolean;
127
+ };
128
+ /**
129
+ * Whether `worldX/worldY` hits this item’s visible geometry (stroke/area).
130
+ */
131
+ declare function itemHitTestWorldPoint(item: VectorSceneItem, worldX: number, worldY: number, options?: HitTestWorldPointOptions): boolean;
132
+ /**
133
+ * Hit-tests a scene item in world coordinates (top-most = last in array wins if overlapping).
134
+ */
135
+ declare function hitTestWorldPoint(items: readonly VectorSceneItem[], worldX: number, worldY: number, options?: HitTestWorldPointOptions): VectorSceneItem | null;
136
+ /**
137
+ * Eraser: IDs of every **unlocked** item hit at this point.
138
+ * Locked items are ignored so protected background layers do not block erasing editable shapes above them.
139
+ */
140
+ declare function collectEraserTargetsAtWorldPoint(items: readonly VectorSceneItem[], worldX: number, worldY: number, options?: HitTestWorldPointOptions): string[];
141
+
142
+ /**
143
+ * Mutable collection of vector scene items (replace wholesale for simplicity in MVP).
144
+ */
145
+ declare class VectorScene {
146
+ private items;
147
+ getItems(): readonly VectorSceneItem[];
148
+ /**
149
+ * Replaces the entire scene contents.
150
+ */
151
+ setItems(next: readonly VectorSceneItem[]): void;
152
+ clear(): void;
153
+ }
154
+
155
+ /**
156
+ * Builds the SVG `transform` attribute for mapping world coordinates to viewport CSS pixels.
157
+ */
158
+ declare function formatCameraTransform(camera: Camera2D): string;
159
+ /**
160
+ * Transform for item `<g>`: `translate(x,y)` plus optional rotation around the bounds center.
161
+ * SVG `rotate` uses degrees.
162
+ */
163
+ declare function formatItemPlacementTransform(item: VectorSceneItem): string;
164
+ type SvgVectorRendererOptions = {
165
+ /** Root element (typically `position: relative` and fixed size). */
166
+ container: HTMLElement;
167
+ scene: VectorScene;
168
+ camera: Camera2D;
169
+ /**
170
+ * When true, the scene SVG ignores pointer events so an overlay can own hit-testing
171
+ * (interactive selection / resize / placement).
172
+ */
173
+ pointerEventsNone?: boolean;
174
+ };
175
+ /**
176
+ * Renders vector scene items into a single SVG: camera as an outer `<g>` transform,
177
+ * so geometry stays sharp at any zoom (no fixed-resolution raster).
178
+ *
179
+ * Uses incremental DOM updates: keeps a stable `<g>` per visible item id, updates
180
+ * `innerHTML` only when `childrenSvg` changes, and only adjusts the camera transform
181
+ * when pan/zoom changes without content edits.
182
+ */
183
+ declare class SvgVectorRenderer {
184
+ private readonly container;
185
+ private readonly scene;
186
+ private readonly camera;
187
+ private readonly svg;
188
+ private readonly rootG;
189
+ private readonly itemNodeCache;
190
+ private readonly resizeObserver;
191
+ constructor(options: SvgVectorRendererOptions);
192
+ /**
193
+ * Reads container size, culls items, and updates the SVG (incrementally when possible).
194
+ */
195
+ render(): void;
196
+ private syncVisibleItems;
197
+ destroy(): void;
198
+ /** Toggle whether the scene SVG receives pointer events (vs overlay handling them). */
199
+ setPointerEventsNone(value: boolean): void;
200
+ }
201
+
202
+ /** Width/height of the shape’s local drawing box (same as `bounds` at creation). */
203
+ type CustomShapeSize = {
204
+ width: number;
205
+ height: number;
206
+ };
207
+ /**
208
+ * How to build the inner SVG (inside the item’s bounding box).
209
+ *
210
+ * - **`svg`**: paste-friendly markup. Use `{{w}}`, `{{h}}`, `{{width}}`, or `{{height}}` where the size should go.
211
+ * - **`render`**: a small function when you prefer code over a string template.
212
+ */
213
+ type CreateCustomShapeContent = {
214
+ /**
215
+ * SVG fragment for `<g>` contents (no outer `<svg>`). Placeholders are replaced with numeric sizes:
216
+ * `{{w}}`, `{{h}}`, `{{width}}`, `{{height}}`.
217
+ */
218
+ svg: string;
219
+ } | {
220
+ /** Returns inner SVG for the given box size (same coordinate range as `bounds`). */
221
+ render: (size: CustomShapeSize) => string;
222
+ };
223
+ /**
224
+ * Replaces `{{w}}`, `{{h}}`, `{{width}}`, and `{{height}}` in a string with the given dimensions.
225
+ * Use this if you build SVG strings yourself and want the same rules as {@link createCustomShapeItem}.
226
+ */
227
+ declare function expandCustomShapeTemplate(template: string, width: number, height: number): string;
228
+ /**
229
+ * Builds the scaled `<g>` wrapper used for `childrenSvg` on custom shapes that support resize.
230
+ */
231
+ declare function buildCustomShapeChildrenSvg(inner: string, intrinsic: CustomShapeSize, bounds: Rect): string;
232
+ /**
233
+ * Creates a user-defined shape from SVG markup or a `render` callback.
234
+ *
235
+ * Coordinates are **local**: draw from `(0,0)` to `(width, height)` of `bounds`. The library stores an
236
+ * intrinsic copy so resize handles (when interactive) scale the drawing uniformly.
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * const star = createCustomShapeItem(createShapeId(), rect, {
241
+ * svg: `<polygon points="..." fill="gold" stroke="#b45309" stroke-width="2" />`,
242
+ * });
243
+ * ```
244
+ *
245
+ * @example Template (good for copy-paste from design tools)
246
+ * ```ts
247
+ * createCustomShapeItem(id, rect, {
248
+ * svg: `<rect width="{{w}}" height="{{h}}" rx="8" fill="#e0e7ff" stroke="#6366f1" />`,
249
+ * });
250
+ * ```
251
+ */
252
+ declare function createCustomShapeItem(id: string, bounds: Rect, content: CreateCustomShapeContent): VectorSceneItem;
253
+
254
+ /**
255
+ * Deep-clones an item with a new id. Rebuilds SVG where the id is embedded (arrow, text, custom).
256
+ */
257
+ declare function cloneVectorSceneItemWithNewId(item: VectorSceneItem): VectorSceneItem;
258
+ declare function cloneVectorSceneItemsWithNewIds(items: readonly VectorSceneItem[]): VectorSceneItem[];
259
+
260
+ /**
261
+ * Returns scene items whose `bounds` intersect the visible world rectangle.
262
+ *
263
+ * Uses a uniform grid when there are many items; otherwise a linear filter (faster for
264
+ * small scenes due to grid build overhead).
265
+ */
266
+ declare function cullItemsByViewport(items: readonly VectorSceneItem[], visibleWorld: Rect): VectorSceneItem[];
267
+
268
+ /** Default body font size for vector text (local SVG units). */
269
+ declare const DEFAULT_TEXT_FONT_SIZE = 18;
270
+ /**
271
+ * Builds SVG `<text>` markup for a text box in local coordinates [0, w] × [0, h].
272
+ * @param fillColor — Text fill (defaults to blue-gray placeholder / blue body).
273
+ */
274
+ declare function buildTextSvg(content: string, _width: number, _height: number, fillColor?: string, fontSize?: number): string;
275
+
276
+ export { ARROW_BIND_SNAP_PX, type ApplePencilNavOptions, ArrowEndpointBinding, Camera2D, type CreateCustomShapeContent, type CustomShapeSize, DEFAULT_TEXT_FONT_SIZE, type LoadRasterImageFileOptions, MAX_RASTER_EMBED_DIMENSION, type RasterEmbedMode, type RasterSceneSource, Rect, SvgVectorRenderer, type SvgVectorRendererOptions, VectorScene, VectorSceneItem, type ViewportInputOptions, attachApplePencilNavigation, attachViewportInput, bakeArrowItemToAbsolute, buildCustomShapeChildrenSvg, buildTextSvg, cloneVectorSceneItemWithNewId, cloneVectorSceneItemsWithNewIds, collectEraserTargetsAtWorldPoint, createCustomShapeItem, cullItemsByViewport, expandCustomShapeTemplate, formatCameraTransform, formatItemPlacementTransform, hitTestWorldPoint, isArrowBindTarget, itemHitTestWorldPoint, loadImageFileAsRasterSceneSource, resolveArrowBindingsInScene, snapArrowEndpointToShape };
@@ -0,0 +1,276 @@
1
+ import { C as Camera2D } from './camera-KwCYYPhm.js';
2
+ export { a as Camera2DOptions } from './camera-KwCYYPhm.js';
3
+ import { V as VectorSceneItem, A as ArrowEndpointBinding, R as Rect } from './types-CB0TZZuk.js';
4
+ export { a as ArrowBindings, b as VectorPathPoint, n as normalizeRect, r as rectsIntersect } from './types-CB0TZZuk.js';
5
+ export { D as DEFAULT_STROKE_STYLE, F as FreehandSvgPayload, S as StrokeStyle, a as applyStrokeToItem, b as buildArrowSvg, c as buildDrawDotSvg, d as buildEllipseSvg, e as buildFreehandPathSvg, f as buildLineSvg, g as buildRectSvg, h as computeFreehandSvgPayload, i as createDrawDotItem, j as createEllipseItem, k as createFreehandStrokeItem, l as createImageFromVectorTrace, m as createImageItem, n as createLineItem, o as createRectangleItem, p as createShapeId, q as createTextItem, r as lineEndpointsToLocal, s as rebuildItemSvg, t as resolveStrokeStyle } from './shape-builders-DTYvub8W.js';
6
+
7
+ /**
8
+ * Embeds the bitmap as a single SVG `<image>` (data URL or blob URL) instead of tracing paths.
9
+ * Avoids huge path counts and keeps screenshots/photos sharp.
10
+ */
11
+ /**
12
+ * Default max width/height (px) before encoding. Larger = sharper zoom / bigger snapshots.
13
+ * Override per app via {@link loadImageFileAsRasterSceneSource} or `VectorViewport` `imageRasterMaxDimension`.
14
+ */
15
+ declare const MAX_RASTER_EMBED_DIMENSION = 4096;
16
+ /** How raster pixels are exposed to SVG `<image href>`. */
17
+ type RasterEmbedMode = "dataUrl" | "blobUrl";
18
+ type LoadRasterImageFileOptions = {
19
+ /** Longest edge (px). Images larger than this are scaled down (canvas). */
20
+ maxDimension?: number;
21
+ /**
22
+ * `dataUrl` — easy to persist (JSON), higher memory use with many large images.
23
+ * `blobUrl` — lower overhead; **revoke** URLs when items leave the scene (handled by `VectorViewport` for its own loads).
24
+ */
25
+ embedMode?: RasterEmbedMode;
26
+ };
27
+ type RasterSceneSource = {
28
+ /**
29
+ * Value for SVG `<image href>`: `data:image/...;base64,...` or `blob:https://...`.
30
+ * Despite the name, `blobUrl` mode stores a blob URL here.
31
+ */
32
+ dataUrl: string;
33
+ width: number;
34
+ height: number;
35
+ };
36
+ /**
37
+ * Decodes a file and returns a raster source for {@link createImageItem}.
38
+ *
39
+ * - `dataUrl` (default): canvas downscale + base64 (serializable).
40
+ * - `blobUrl`: uses `URL.createObjectURL(file)` at **full resolution** when the longest edge
41
+ * is ≤ `maxDimension`; otherwise downscales like data mode but keeps a blob URL (smaller than base64).
42
+ */
43
+ declare function loadImageFileAsRasterSceneSource(file: File, maxDimensionOrOptions?: number | LoadRasterImageFileOptions): Promise<RasterSceneSource>;
44
+
45
+ type ApplePencilNavOptions = {
46
+ element: HTMLElement;
47
+ camera: Camera2D;
48
+ /** Current tool id from your app (e.g. `"hand"` vs `"draw"`). */
49
+ getCurrentToolId: () => string;
50
+ onUpdate: () => void;
51
+ touchPanSensitivity?: number;
52
+ };
53
+ /**
54
+ * After a **stylus** (`pointerType === "pen"`) has been used, finger touches on the canvas
55
+ * pan/pinch the camera instead of passing through to drawing tools — similar to iPad behavior
56
+ * in many design apps. No-op until the first pen contact.
57
+ *
58
+ * Compose with {@link attachViewportInput} by calling this **after** it so capture handlers run first,
59
+ * or use only one of them depending on product needs.
60
+ */
61
+ declare function attachApplePencilNavigation(options: ApplePencilNavOptions): () => void;
62
+
63
+ type ViewportInputOptions = {
64
+ element: HTMLElement;
65
+ camera: Camera2D;
66
+ /** Called after any camera mutation so the renderer can redraw. */
67
+ onUpdate: () => void;
68
+ /**
69
+ * Element to attach the wheel listener to. Defaults to `element`.
70
+ * Useful when an overlay with `pointer-events: auto` sits above `element` and
71
+ * would otherwise intercept wheel events before they reach the scene container.
72
+ */
73
+ wheelElement?: HTMLElement;
74
+ wheelPanSensitivity?: number;
75
+ /** Multiplier applied to wheel delta for zoom (with Ctrl/Meta). */
76
+ wheelZoomSensitivity?: number;
77
+ touchPanSensitivity?: number;
78
+ /**
79
+ * When `true`, pointer events with `pointerType === "touch"` are ignored so another layer
80
+ * (e.g. `attachApplePencilNavigation`) can handle them without double panning.
81
+ */
82
+ touchHandledElsewhere?: boolean;
83
+ /**
84
+ * When `false`, one-finger / primary-button drag does **not** pan the camera (e.g. shape tools).
85
+ * Wheel zoom and two-finger pinch still work.
86
+ */
87
+ allowPrimaryPointerPan?: () => boolean;
88
+ };
89
+ /**
90
+ * Attaches wheel (pan / Ctrl+zoom), pointer drag pan, and two-finger pinch zoom.
91
+ * Uses `touch-action: none` on `element` — set that in CSS on the same node.
92
+ *
93
+ * @returns A dispose function that removes all listeners.
94
+ */
95
+ declare function attachViewportInput(options: ViewportInputOptions): () => void;
96
+
97
+ /** Default screen px — converted to world with `/ camera.zoom` when snapping. */
98
+ declare const ARROW_BIND_SNAP_PX = 16;
99
+ declare function isArrowBindTarget(item: VectorSceneItem): boolean;
100
+ /**
101
+ * If `worldX/worldY` is within `maxDistWorld` of a bindable shape’s boundary,
102
+ * returns the snapped point on that boundary plus binding metadata.
103
+ */
104
+ declare function snapArrowEndpointToShape(worldX: number, worldY: number, items: readonly VectorSceneItem[], excludeIds: ReadonlySet<string>, maxDistWorld: number): {
105
+ world: {
106
+ x: number;
107
+ y: number;
108
+ };
109
+ binding: ArrowEndpointBinding;
110
+ } | null;
111
+ /**
112
+ * Recomputes every arrow item that has {@link VectorSceneItem.arrowBind} so endpoints
113
+ * follow bound shapes (move/resize).
114
+ */
115
+ declare function resolveArrowBindingsInScene(items: readonly VectorSceneItem[]): readonly VectorSceneItem[];
116
+ /**
117
+ * Converts a bound arrow to a plain arrow (drops bindings) using the current resolved
118
+ * geometry so move/resize gestures don’t fight binding resolution.
119
+ */
120
+ declare function bakeArrowItemToAbsolute(item: VectorSceneItem, items: readonly VectorSceneItem[]): VectorSceneItem;
121
+
122
+ type HitTestWorldPointOptions = {
123
+ /** Max distance to a line segment in **world** units (e.g. ~10 / camera.zoom for ~10px on screen). */
124
+ lineHitWorld?: number;
125
+ /** When true, locked items are ignored as interaction targets. */
126
+ ignoreLocked?: boolean;
127
+ };
128
+ /**
129
+ * Whether `worldX/worldY` hits this item’s visible geometry (stroke/area).
130
+ */
131
+ declare function itemHitTestWorldPoint(item: VectorSceneItem, worldX: number, worldY: number, options?: HitTestWorldPointOptions): boolean;
132
+ /**
133
+ * Hit-tests a scene item in world coordinates (top-most = last in array wins if overlapping).
134
+ */
135
+ declare function hitTestWorldPoint(items: readonly VectorSceneItem[], worldX: number, worldY: number, options?: HitTestWorldPointOptions): VectorSceneItem | null;
136
+ /**
137
+ * Eraser: IDs of every **unlocked** item hit at this point.
138
+ * Locked items are ignored so protected background layers do not block erasing editable shapes above them.
139
+ */
140
+ declare function collectEraserTargetsAtWorldPoint(items: readonly VectorSceneItem[], worldX: number, worldY: number, options?: HitTestWorldPointOptions): string[];
141
+
142
+ /**
143
+ * Mutable collection of vector scene items (replace wholesale for simplicity in MVP).
144
+ */
145
+ declare class VectorScene {
146
+ private items;
147
+ getItems(): readonly VectorSceneItem[];
148
+ /**
149
+ * Replaces the entire scene contents.
150
+ */
151
+ setItems(next: readonly VectorSceneItem[]): void;
152
+ clear(): void;
153
+ }
154
+
155
+ /**
156
+ * Builds the SVG `transform` attribute for mapping world coordinates to viewport CSS pixels.
157
+ */
158
+ declare function formatCameraTransform(camera: Camera2D): string;
159
+ /**
160
+ * Transform for item `<g>`: `translate(x,y)` plus optional rotation around the bounds center.
161
+ * SVG `rotate` uses degrees.
162
+ */
163
+ declare function formatItemPlacementTransform(item: VectorSceneItem): string;
164
+ type SvgVectorRendererOptions = {
165
+ /** Root element (typically `position: relative` and fixed size). */
166
+ container: HTMLElement;
167
+ scene: VectorScene;
168
+ camera: Camera2D;
169
+ /**
170
+ * When true, the scene SVG ignores pointer events so an overlay can own hit-testing
171
+ * (interactive selection / resize / placement).
172
+ */
173
+ pointerEventsNone?: boolean;
174
+ };
175
+ /**
176
+ * Renders vector scene items into a single SVG: camera as an outer `<g>` transform,
177
+ * so geometry stays sharp at any zoom (no fixed-resolution raster).
178
+ *
179
+ * Uses incremental DOM updates: keeps a stable `<g>` per visible item id, updates
180
+ * `innerHTML` only when `childrenSvg` changes, and only adjusts the camera transform
181
+ * when pan/zoom changes without content edits.
182
+ */
183
+ declare class SvgVectorRenderer {
184
+ private readonly container;
185
+ private readonly scene;
186
+ private readonly camera;
187
+ private readonly svg;
188
+ private readonly rootG;
189
+ private readonly itemNodeCache;
190
+ private readonly resizeObserver;
191
+ constructor(options: SvgVectorRendererOptions);
192
+ /**
193
+ * Reads container size, culls items, and updates the SVG (incrementally when possible).
194
+ */
195
+ render(): void;
196
+ private syncVisibleItems;
197
+ destroy(): void;
198
+ /** Toggle whether the scene SVG receives pointer events (vs overlay handling them). */
199
+ setPointerEventsNone(value: boolean): void;
200
+ }
201
+
202
+ /** Width/height of the shape’s local drawing box (same as `bounds` at creation). */
203
+ type CustomShapeSize = {
204
+ width: number;
205
+ height: number;
206
+ };
207
+ /**
208
+ * How to build the inner SVG (inside the item’s bounding box).
209
+ *
210
+ * - **`svg`**: paste-friendly markup. Use `{{w}}`, `{{h}}`, `{{width}}`, or `{{height}}` where the size should go.
211
+ * - **`render`**: a small function when you prefer code over a string template.
212
+ */
213
+ type CreateCustomShapeContent = {
214
+ /**
215
+ * SVG fragment for `<g>` contents (no outer `<svg>`). Placeholders are replaced with numeric sizes:
216
+ * `{{w}}`, `{{h}}`, `{{width}}`, `{{height}}`.
217
+ */
218
+ svg: string;
219
+ } | {
220
+ /** Returns inner SVG for the given box size (same coordinate range as `bounds`). */
221
+ render: (size: CustomShapeSize) => string;
222
+ };
223
+ /**
224
+ * Replaces `{{w}}`, `{{h}}`, `{{width}}`, and `{{height}}` in a string with the given dimensions.
225
+ * Use this if you build SVG strings yourself and want the same rules as {@link createCustomShapeItem}.
226
+ */
227
+ declare function expandCustomShapeTemplate(template: string, width: number, height: number): string;
228
+ /**
229
+ * Builds the scaled `<g>` wrapper used for `childrenSvg` on custom shapes that support resize.
230
+ */
231
+ declare function buildCustomShapeChildrenSvg(inner: string, intrinsic: CustomShapeSize, bounds: Rect): string;
232
+ /**
233
+ * Creates a user-defined shape from SVG markup or a `render` callback.
234
+ *
235
+ * Coordinates are **local**: draw from `(0,0)` to `(width, height)` of `bounds`. The library stores an
236
+ * intrinsic copy so resize handles (when interactive) scale the drawing uniformly.
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * const star = createCustomShapeItem(createShapeId(), rect, {
241
+ * svg: `<polygon points="..." fill="gold" stroke="#b45309" stroke-width="2" />`,
242
+ * });
243
+ * ```
244
+ *
245
+ * @example Template (good for copy-paste from design tools)
246
+ * ```ts
247
+ * createCustomShapeItem(id, rect, {
248
+ * svg: `<rect width="{{w}}" height="{{h}}" rx="8" fill="#e0e7ff" stroke="#6366f1" />`,
249
+ * });
250
+ * ```
251
+ */
252
+ declare function createCustomShapeItem(id: string, bounds: Rect, content: CreateCustomShapeContent): VectorSceneItem;
253
+
254
+ /**
255
+ * Deep-clones an item with a new id. Rebuilds SVG where the id is embedded (arrow, text, custom).
256
+ */
257
+ declare function cloneVectorSceneItemWithNewId(item: VectorSceneItem): VectorSceneItem;
258
+ declare function cloneVectorSceneItemsWithNewIds(items: readonly VectorSceneItem[]): VectorSceneItem[];
259
+
260
+ /**
261
+ * Returns scene items whose `bounds` intersect the visible world rectangle.
262
+ *
263
+ * Uses a uniform grid when there are many items; otherwise a linear filter (faster for
264
+ * small scenes due to grid build overhead).
265
+ */
266
+ declare function cullItemsByViewport(items: readonly VectorSceneItem[], visibleWorld: Rect): VectorSceneItem[];
267
+
268
+ /** Default body font size for vector text (local SVG units). */
269
+ declare const DEFAULT_TEXT_FONT_SIZE = 18;
270
+ /**
271
+ * Builds SVG `<text>` markup for a text box in local coordinates [0, w] × [0, h].
272
+ * @param fillColor — Text fill (defaults to blue-gray placeholder / blue body).
273
+ */
274
+ declare function buildTextSvg(content: string, _width: number, _height: number, fillColor?: string, fontSize?: number): string;
275
+
276
+ export { ARROW_BIND_SNAP_PX, type ApplePencilNavOptions, ArrowEndpointBinding, Camera2D, type CreateCustomShapeContent, type CustomShapeSize, DEFAULT_TEXT_FONT_SIZE, type LoadRasterImageFileOptions, MAX_RASTER_EMBED_DIMENSION, type RasterEmbedMode, type RasterSceneSource, Rect, SvgVectorRenderer, type SvgVectorRendererOptions, VectorScene, VectorSceneItem, type ViewportInputOptions, attachApplePencilNavigation, attachViewportInput, bakeArrowItemToAbsolute, buildCustomShapeChildrenSvg, buildTextSvg, cloneVectorSceneItemWithNewId, cloneVectorSceneItemsWithNewIds, collectEraserTargetsAtWorldPoint, createCustomShapeItem, cullItemsByViewport, expandCustomShapeTemplate, formatCameraTransform, formatItemPlacementTransform, hitTestWorldPoint, isArrowBindTarget, itemHitTestWorldPoint, loadImageFileAsRasterSceneSource, resolveArrowBindingsInScene, snapArrowEndpointToShape };