@svgsketch/core 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -136,6 +136,32 @@ interface AnimationTrack {
136
136
  locked: boolean;
137
137
  /** SVG path data for motion-path animation (property should be 'pathMotion'). */
138
138
  motionPath?: string;
139
+ /**
140
+ * When set, the motion path was authored as a reference to another shape
141
+ * (SVG `<mpath href="#shapeId"/>`). `motionPath` still holds the resolved
142
+ * path data string (kept in sync with the referenced shape's geometry) so
143
+ * the runtime renderer doesn't need to dereference; the `mode` field
144
+ * controls how that data is interpreted and whether export can round-trip
145
+ * the reference as `<mpath>`.
146
+ *
147
+ * - `'trackShape'` — motionPath is displacement-relative to the animated
148
+ * element's center, so the overlay and playback render on top of the
149
+ * referenced shape's absolute canvas position ("follow this shape").
150
+ * Exports as inline `path=` because `<mpath>` would double-offset.
151
+ * - `'curveTemplate'` — motionPath is normalized so `M 0,0` is the
152
+ * animation's starting displacement ("trace this curve from wherever
153
+ * the element is"). Exports spec-correctly as `<mpath href>` since
154
+ * the referenced shape's `d` (normalized to origin) matches the stored
155
+ * motionPath byte-for-byte, enabling reuse across animations.
156
+ *
157
+ * Missing `mode` (legacy data) defaults to `'trackShape'` for back-compat.
158
+ *
159
+ * @see https://svgwg.org/specs/animations/#MPathElement
160
+ */
161
+ motionPathRef?: {
162
+ shapeId: string;
163
+ mode?: 'trackShape' | 'curveTemplate';
164
+ };
139
165
  /** Trigger to begin the animation (defaults to '0s'). */
140
166
  beginTrigger?: AnimationTrigger;
141
167
  /** Trigger to end the animation. */
@@ -206,6 +232,12 @@ interface SerializedAnimationTimeline {
206
232
  locked?: boolean;
207
233
  motionPath?: string;
208
234
  motionPathMatrix?: number[];
235
+ /** See `AnimationTrack.motionPathRef`. Persists the authoring reference to
236
+ * another shape's geometry so a round-trip re-emits `<mpath href>`. */
237
+ motionPathRef?: {
238
+ shapeId: string;
239
+ mode?: 'trackShape' | 'curveTemplate';
240
+ };
209
241
  beginTrigger?: AnimationTrigger;
210
242
  endTrigger?: AnimationTrigger;
211
243
  cycleDuration?: number;
@@ -830,6 +862,30 @@ interface ShapeMetadata {
830
862
  linkUrl: string;
831
863
  linkTarget: LinkTarget;
832
864
  customData: Record<string, string>;
865
+ /**
866
+ * Lossless carrier for any `<metadata>` elements that appeared as children
867
+ * of this shape's SVG element. Stored as a serialized string containing
868
+ * one or more complete `<metadata ...>...</metadata>` blocks in document
869
+ * order. Preserves element-level attributes (id, lang, class, style,
870
+ * xml:space), arbitrary child elements from any namespace, character data,
871
+ * mixed content, and multiple sibling blocks.
872
+ *
873
+ * Spec: SVG 2 §5.8 — content model is "Any elements or character data",
874
+ * and the element may appear on any container or graphical element.
875
+ */
876
+ rawMetadata?: string;
877
+ /**
878
+ * Lossless carrier for the inner XML of the `<desc>` element when it
879
+ * contains foreign XML (per SVG 2 §5.7 — the spec example shows
880
+ * `<myfoo:…>` elements inside `<desc>`). Populated only when `<desc>`
881
+ * has non-text children; plain-prose desc uses `description` alone.
882
+ *
883
+ * Emit rule: if the textContent of `rawDescription` still equals the
884
+ * current `description` value, emit the raw (foreign XML round-trips).
885
+ * If `description` has been edited and the textual views diverge, emit
886
+ * plain text from `description` (user intent takes precedence).
887
+ */
888
+ rawDescription?: string;
833
889
  }
834
890
  /**
835
891
  * Provider attribution metadata for an image shape sourced from a third-party
@@ -868,6 +924,29 @@ interface DocumentMetadata {
868
924
  licenseUrl: string;
869
925
  language: string;
870
926
  customMetadata: Record<string, string>;
927
+ /**
928
+ * Lossless carrier for any `<metadata>` elements that appeared as direct
929
+ * children of the root `<svg>`. Stored as a serialized string containing
930
+ * one or more complete `<metadata ...>...</metadata>` blocks in document
931
+ * order. Preserves element-level attributes, arbitrary child elements
932
+ * from any namespace (RDF, XMP, Inkscape, custom), character data and
933
+ * mixed content, and multiple sibling blocks.
934
+ *
935
+ * Typed fields above (`author`, `keywords`, `license`, `licenseUrl`,
936
+ * `customMetadata`) are a structured view over a designated managed
937
+ * `<rdf:Description>` inside this carrier. On export the managed
938
+ * description is spliced into the preserved raw; foreign siblings and
939
+ * non-RDF content survive untouched.
940
+ *
941
+ * Spec: SVG 2 §5.8.
942
+ */
943
+ rawMetadata?: string;
944
+ /**
945
+ * Lossless carrier for the inner XML of the document-level `<desc>`
946
+ * element when it contains foreign XML (SVG 2 §5.7). Mirrors
947
+ * `ShapeMetadata.rawDescription`; see there for the emit rule.
948
+ */
949
+ rawDescription?: string;
871
950
  /**
872
951
  * Decimal precision for coordinate values when the document is
873
952
  * serialized — file save, cloud sync, undo capture, and SVG export.
@@ -1015,261 +1094,11 @@ interface Measurement {
1015
1094
  }
1016
1095
 
1017
1096
  /**
1018
- * Typed property interfaces for every node type in the scene graph.
1019
- *
1020
- * This is the **single source of truth** for shape property types across
1021
- * the entire SVGSketch stack (editor, API worker, server renderer, etc.).
1097
+ * @svgsketch/core Serialized document types.
1022
1098
  *
1023
- * Each shape type declares the exact set of properties it owns.
1024
- * These interfaces drive:
1025
- * - Compile-time type safety on `SceneNode.get()` / `.set()` calls
1026
- * - The `NodeTypePropsMap` lookup used by `SceneNode.create()`
1027
- * - Schema defaults and validators in the editor's `node-schema.ts`
1028
- * - Serialization format for the `.svgs` document format
1029
- */
1030
-
1031
- interface CommonNodeProps {
1032
- fillColor: string;
1033
- borderColor: string;
1034
- borderWidth: number;
1035
- opacity: number;
1036
- fillOpacity: number;
1037
- strokeOpacity: number;
1038
- rotation: number;
1039
- skewX: number;
1040
- skewY: number;
1041
- customPivot: Point | null;
1042
- locked: boolean;
1043
- visible: boolean;
1044
- fillType: string;
1045
- fillGradient: unknown | null;
1046
- strokeType: string;
1047
- strokeGradient: unknown | null;
1048
- fillRule: 'nonzero' | 'evenodd';
1049
- strokeLinejoin: 'miter' | 'round' | 'bevel';
1050
- strokeLinecap: 'butt' | 'round' | 'square';
1051
- strokeMiterlimit: number;
1052
- lineStyle: string;
1053
- dashLength: number;
1054
- gapLength: number;
1055
- dashOffset: number;
1056
- strokeDasharray: string | null;
1057
- filters: unknown[];
1058
- filterColorInterpolation: 'auto' | 'sRGB' | 'linearRGB' | null;
1059
- filterUnits: 'userSpaceOnUse' | 'objectBoundingBox' | null;
1060
- primitiveUnits: 'userSpaceOnUse' | 'objectBoundingBox' | null;
1061
- filterX: string | null;
1062
- filterY: string | null;
1063
- filterWidth: string | null;
1064
- filterHeight: string | null;
1065
- rawTransform: string | null;
1066
- metadata: unknown | null;
1067
- cssClipPath: string | null;
1068
- cssMaskProperties: Record<string, string> | null;
1069
- groupId: string | null;
1070
- }
1071
- type CornerShapeValue = 'round' | 'notch' | 'bevel' | 'scoop';
1072
- interface RectangleNodeProps extends CommonNodeProps {
1073
- x: number;
1074
- y: number;
1075
- width: number;
1076
- height: number;
1077
- cornerRadius: number;
1078
- cornerShape: CornerShapeValue;
1079
- cornerMode: 'uniform' | 'non-uniform';
1080
- cornerRadiusTL: number;
1081
- cornerRadiusTR: number;
1082
- cornerRadiusBL: number;
1083
- cornerRadiusBR: number;
1084
- cornerShapeTL: CornerShapeValue;
1085
- cornerShapeTR: CornerShapeValue;
1086
- cornerShapeBL: CornerShapeValue;
1087
- cornerShapeBR: CornerShapeValue;
1088
- }
1089
- type SquareNodeProps = RectangleNodeProps;
1090
- interface CircleNodeProps extends CommonNodeProps {
1091
- x: number;
1092
- y: number;
1093
- radius: number;
1094
- }
1095
- interface EllipseNodeProps extends CommonNodeProps {
1096
- x: number;
1097
- y: number;
1098
- rx: number;
1099
- ry: number;
1100
- }
1101
- type LineEndpointValue = 'none' | 'arrow' | 'open-arrow' | 'circle' | 'diamond' | 'square';
1102
- interface LineNodeProps extends CommonNodeProps {
1103
- x1: number;
1104
- y1: number;
1105
- x2: number;
1106
- y2: number;
1107
- startEndpoint: LineEndpointValue;
1108
- endEndpoint: LineEndpointValue;
1109
- }
1110
- interface TextNodeProps extends CommonNodeProps {
1111
- x: number;
1112
- y: number;
1113
- width: number;
1114
- height: number;
1115
- textX: number;
1116
- textY: number;
1117
- fontSize: number;
1118
- text: string;
1119
- fontFamily: string;
1120
- fontWeight: string;
1121
- fontStyle: string;
1122
- textDecoration: Record<string, boolean>;
1123
- textTransform: string;
1124
- baselineShift: string;
1125
- dominantBaseline: string;
1126
- writingMode: string;
1127
- textAnchor: string;
1128
- letterSpacing: number;
1129
- wordSpacing: number;
1130
- lineHeight: number;
1131
- inlineSize: number;
1132
- overflowWrap: string;
1133
- whiteSpace: string;
1134
- textDirection: string;
1135
- unicodeBidi: string;
1136
- scaleX: number;
1137
- scaleY: number;
1138
- scaleAnchor: Point | null;
1139
- useRichText: boolean;
1140
- richTextData: unknown | null;
1141
- charOffsets: {
1142
- x: number;
1143
- y: number;
1144
- rotate: number;
1145
- }[] | null;
1146
- fontVariationSettings: Record<string, number>;
1147
- isTextPath: boolean;
1148
- textPathPoints: unknown[] | null;
1149
- textPathStartOffset: number;
1150
- textPathSide: 'left' | 'right';
1151
- shapeInsideRef: string | null;
1152
- shapePadding: number;
1153
- }
1154
- interface ImageNodeProps extends CommonNodeProps {
1155
- x: number;
1156
- y: number;
1157
- width: number;
1158
- height: number;
1159
- href: string;
1160
- originalWidth: number;
1161
- originalHeight: number;
1162
- preserveAspectRatio: boolean;
1163
- imageOpacity: number;
1164
- }
1165
- interface SplineNodeProps extends CommonNodeProps {
1166
- x: number;
1167
- y: number;
1168
- width: number;
1169
- height: number;
1170
- splinePoints: unknown[];
1171
- splineArcParams: unknown[];
1172
- splineControlBounds: {
1173
- x: number;
1174
- y: number;
1175
- width: number;
1176
- height: number;
1177
- } | null;
1178
- startEndpoint: LineEndpointValue;
1179
- endEndpoint: LineEndpointValue;
1180
- }
1181
- interface PolylineNodeProps extends CommonNodeProps {
1182
- x: number;
1183
- y: number;
1184
- width: number;
1185
- height: number;
1186
- polylinePoints: Point[];
1187
- polylineClosed: boolean;
1188
- }
1189
- interface PolygonBaseNodeProps extends CommonNodeProps {
1190
- cx: number;
1191
- cy: number;
1192
- radius: number;
1193
- cornerRadius: number;
1194
- shiftAngle: number;
1195
- }
1196
- interface TriangleNodeProps extends PolygonBaseNodeProps {
1197
- sides: 3;
1198
- }
1199
- interface NGonNodeProps extends PolygonBaseNodeProps {
1200
- sides: number;
1201
- }
1202
- interface StarNodeProps extends PolygonBaseNodeProps {
1203
- arms: number;
1204
- innerRadiusPercent: number;
1205
- }
1206
- interface CrossNodeProps extends PolygonBaseNodeProps {
1207
- armWidthPercent: number;
1208
- }
1209
- interface RingNodeProps extends PolygonBaseNodeProps {
1210
- innerRadiusPercent: number;
1211
- }
1212
- interface SpiralNodeProps extends PolygonBaseNodeProps {
1213
- turns: number;
1214
- thicknessPercent: number;
1215
- spiralDirection: number;
1216
- }
1217
- interface GearNodeProps extends PolygonBaseNodeProps {
1218
- teeth: number;
1219
- toothDepthPercent: number;
1220
- holeRadiusPercent: number;
1221
- }
1222
- interface ArrowNodeProps extends PolygonBaseNodeProps {
1223
- headWidthPercent: number;
1224
- headLengthPercent: number;
1225
- shaftWidthPercent: number;
1226
- }
1227
- interface SymbolInstanceNodeProps extends CommonNodeProps {
1228
- x: number;
1229
- y: number;
1230
- width: number;
1231
- height: number;
1232
- symbolId: string;
1233
- }
1234
- interface GroupNodeProps {
1235
- groupId: string | null;
1236
- }
1237
- type DocumentNodeProps = Record<string, never>;
1238
- /**
1239
- * Maps each node type string to its typed property interface.
1240
- * Used by `SceneNode.create()` for compile-time type safety.
1241
- */
1242
- interface NodeTypePropsMap {
1243
- rectangle: RectangleNodeProps;
1244
- square: SquareNodeProps;
1245
- circle: CircleNodeProps;
1246
- ellipse: EllipseNodeProps;
1247
- line: LineNodeProps;
1248
- text: TextNodeProps;
1249
- image: ImageNodeProps;
1250
- spline: SplineNodeProps;
1251
- polyline: PolylineNodeProps;
1252
- triangle: TriangleNodeProps;
1253
- ngon: NGonNodeProps;
1254
- star: StarNodeProps;
1255
- cross: CrossNodeProps;
1256
- ring: RingNodeProps;
1257
- spiral: SpiralNodeProps;
1258
- gear: GearNodeProps;
1259
- arrow: ArrowNodeProps;
1260
- 'symbol-instance': SymbolInstanceNodeProps;
1261
- group: GroupNodeProps;
1262
- document: DocumentNodeProps;
1263
- }
1264
- /** Union of all node prop types. */
1265
- type AnyNodeProps = RectangleNodeProps | SquareNodeProps | CircleNodeProps | EllipseNodeProps | LineNodeProps | TextNodeProps | ImageNodeProps | SplineNodeProps | PolylineNodeProps | TriangleNodeProps | NGonNodeProps | StarNodeProps | CrossNodeProps | RingNodeProps | SpiralNodeProps | GearNodeProps | ArrowNodeProps | SymbolInstanceNodeProps | GroupNodeProps | DocumentNodeProps;
1266
-
1267
- /**
1268
- * @svgsketch/core — Serialized document types.
1269
- *
1270
- * These types define the .svgs document format. SerializedShape and
1271
- * HistorySnapshot are the canonical data structures for persisting
1272
- * SVGSketch documents.
1099
+ * These types define the .svgs document format. SerializedShape and
1100
+ * HistorySnapshot are the canonical data structures for persisting
1101
+ * SVGSketch documents.
1273
1102
  */
1274
1103
 
1275
1104
  interface SerializedShape {
@@ -1412,17 +1241,67 @@ interface SerializedShape {
1412
1241
  * overrides the SVG visibility attribute.
1413
1242
  */
1414
1243
  visibility?: 'visible' | 'hidden' | 'collapse';
1244
+ /**
1245
+ * Structural role of the shape in the exported SVG.
1246
+ * - `'normal'` / absent — rendered inline in document order (default).
1247
+ * - `'motionOnly'` — emitted inside `<defs>` as an `<mpath>` reference
1248
+ * target; not rendered. Used for `<path>` elements imported from
1249
+ * `<defs>` that serve only as animateMotion paths.
1250
+ * @see https://svgwg.org/specs/animations/#MPathElement
1251
+ */
1252
+ displayMode?: 'normal' | 'motionOnly';
1415
1253
  fillType?: FillType;
1254
+ /**
1255
+ * @deprecated from v2 for linear/radial kinds — canonical storage is a
1256
+ * `LinearGradientLibraryDef` / `RadialGradientLibraryDef` keyed by
1257
+ * `fillLibraryId`. Still used for `PatternFill` until Phase 3 promotes
1258
+ * patterns, and retained as a runtime shadow copy of the library def so
1259
+ * legacy readers keep working through the transition.
1260
+ */
1416
1261
  fillGradient?: LinearGradient | RadialGradient | PatternFill;
1262
+ /**
1263
+ * Reference into the unified library (v2+). When `fillType` is
1264
+ * `'linear-gradient'` or `'radial-gradient'`, `fillLibraryId` points at
1265
+ * the canonical `LinearGradientLibraryDef` / `RadialGradientLibraryDef`.
1266
+ * For `'pattern'` this field is unused in v2 (patterns still live on
1267
+ * `fillGradient`) and will be populated in Phase 3. For `'solid'` /
1268
+ * `'none'` this field is ignored.
1269
+ */
1270
+ fillLibraryId?: string;
1417
1271
  strokeType?: StrokeType;
1272
+ /** @deprecated see `fillGradient`. */
1418
1273
  strokeGradient?: LinearGradient | RadialGradient | PatternFill;
1274
+ /** See `fillLibraryId`. */
1275
+ strokeLibraryId?: string;
1276
+ /**
1277
+ * @deprecated from v2 — canonical storage is a `FilterLibraryDef` keyed
1278
+ * by entries in `filterLibraryIds`. Retained as a runtime shadow copy of
1279
+ * the library def so legacy readers and the editor's filter-manager keep
1280
+ * working through the transition.
1281
+ */
1419
1282
  filters?: ShapeFilter[];
1283
+ /**
1284
+ * Ordered list of library filter-def ids applied to this shape. On
1285
+ * export each id emits `url(#id)`; the `filter` CSS property chains the
1286
+ * list serially (CSS Filter Effects §Filter Property). Today the list
1287
+ * always has length 0 or 1 — the editor wraps a shape's primitive chain
1288
+ * in a single compound `FilterLibraryDef`. Future phases may split
1289
+ * independent filter chains into multiple library entries.
1290
+ */
1291
+ filterLibraryIds?: string[];
1292
+ /** @deprecated v2 — scope fields live on `FilterLibraryDef` from Phase 4 on. */
1420
1293
  filterColorInterpolation?: 'auto' | 'sRGB' | 'linearRGB';
1294
+ /** @deprecated v2 — see `filterColorInterpolation`. */
1421
1295
  filterUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
1296
+ /** @deprecated v2 — see `filterColorInterpolation`. */
1422
1297
  primitiveUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
1298
+ /** @deprecated v2 — lives on `FilterLibraryDef` from Phase 4 on. */
1423
1299
  filterX?: string;
1300
+ /** @deprecated v2 — see `filterX`. */
1424
1301
  filterY?: string;
1302
+ /** @deprecated v2 — see `filterX`. */
1425
1303
  filterWidth?: string;
1304
+ /** @deprecated v2 — see `filterX`. */
1426
1305
  filterHeight?: string;
1427
1306
  rawTransform?: string;
1428
1307
  splinePoints?: SplinePoint[];
@@ -1503,6 +1382,21 @@ interface SerializedShape {
1503
1382
  * variant (`def.shapes`). Only meaningful on `symbol-instance` shapes.
1504
1383
  */
1505
1384
  variantKey?: string;
1385
+ /**
1386
+ * Id of the canvas shape this `shape-reference` (Linked Copy) targets.
1387
+ * A Linked Copy renders as a live clone of another top-level shape and
1388
+ * exports to `<use href="#targetShapeId">` per SVG 2 §5.5. Only
1389
+ * meaningful on shapes of type `shape-reference`.
1390
+ */
1391
+ targetShapeId?: string;
1392
+ /**
1393
+ * For `shape-reference` shapes: x/y offset from the source's reference
1394
+ * point. Maps to the `x`/`y` on the exported `<use>` per SVG 2 §5.5.2
1395
+ * (an additional translate applied to the use element), so the instance
1396
+ * tracks the source's position natively.
1397
+ */
1398
+ offsetX?: number;
1399
+ offsetY?: number;
1506
1400
  /**
1507
1401
  * Map of geometry-property name → CSS custom-property name (without
1508
1402
  * the leading `--`) the property is bound to.
@@ -1576,7 +1470,7 @@ type SerializedViewbox = Viewbox;
1576
1470
  * (version - 1) snapshots into the new format.
1577
1471
  * c. Register it in the migrateSnapshot() chain.
1578
1472
  */
1579
- declare const CURRENT_SCHEMA_VERSION = 1;
1473
+ declare const CURRENT_SCHEMA_VERSION = 2;
1580
1474
  interface HistorySnapshot {
1581
1475
  /**
1582
1476
  * Schema version — written on save, read on load to trigger migrations.
@@ -1606,234 +1500,564 @@ interface HistorySnapshot {
1606
1500
  templateVariables?: TemplateVariable[];
1607
1501
  /** Animation timeline (tracks, keyframes, easing). */
1608
1502
  animationTimeline?: SerializedAnimationTimeline;
1609
- /** User-defined custom patterns stored in the document. */
1503
+ /**
1504
+ * Unified library of reusable `<defs>` content. Authoritative from v2 onward
1505
+ * for symbols and markers (and, as later phases land, gradients, patterns,
1506
+ * and filters too). Built-in markers are reconstituted at load time by
1507
+ * MarkerManager and are NOT persisted here — only user-authored defs are.
1508
+ */
1509
+ library?: LibraryDef[];
1510
+ /** @deprecated v2 — use `library`. Read-only: v1 docs migrate into `library`. */
1610
1511
  customPatterns?: CustomPatternDef[];
1611
- /** Symbol definitions (reusable component templates). */
1512
+ /** @deprecated v2 use `library`. Read-only: v1 docs migrate into `library`. */
1612
1513
  symbols?: SerializedSymbolDef[];
1514
+ /** @deprecated v2 — use `library`. Read-only: v1 docs migrate into `library`. */
1515
+ markers?: SerializedMarkerDef[];
1516
+ }
1517
+ /**
1518
+ * A variant axis on a component symbol. Each axis has a name (e.g.
1519
+ * `state`, `size`, `theme`) and an ordered list of allowed values
1520
+ * (e.g. `[default, hover, pressed]`). The default value is always
1521
+ * the first entry in `values`.
1522
+ */
1523
+ interface SerializedVariantAxis {
1524
+ name: string;
1525
+ values: string[];
1526
+ }
1527
+ /**
1528
+ * A reusable symbol definition. Contains the shapes that make up the
1529
+ * symbol template, plus metadata for the symbols panel.
1530
+ *
1531
+ * **Variants:** when `variantAxes` is present, the symbol carries
1532
+ * multiple alternative shape arrays keyed by variant combination
1533
+ * (e.g. `state=hover,size=md`). The base `shapes` field is always
1534
+ * the **default variant** — the combination where every axis is at
1535
+ * its first value. Other variants live in `variants[variantKey]`.
1536
+ * Variant resolution falls back to `shapes` whenever `variantKey`
1537
+ * is missing or empty.
1538
+ */
1539
+ type SerializedSymbolDef = SymbolLibraryDef;
1540
+ /**
1541
+ * A reusable `<marker>` definition (SVG 2 §11.6). Markers are vertex-attached
1542
+ * graphics — arrowheads, vertex dots, decorations — referenced via
1543
+ * `marker-start` / `marker-mid` / `marker-end` attributes on stroked shapes.
1544
+ *
1545
+ * The browser handles per-vertex positioning, scaling (via `markerUnits`),
1546
+ * and orientation (via `orient`, including tangent-aware `auto` mode on
1547
+ * curved paths). MarkerManager only maintains the DOM `<defs>` entries in
1548
+ * sync with this serialized state.
1549
+ *
1550
+ * Simpler than `SerializedSymbolDef` — markers have no variants, no instance
1551
+ * overrides, and no placed instances (they attach via attribute references).
1552
+ */
1553
+ type SerializedMarkerDef = MarkerLibraryDef;
1554
+ interface SerializedGroup {
1555
+ id: string;
1556
+ parentId: string | null;
1557
+ /** CSS transform-origin value (e.g. "50px 50px") for group animations */
1558
+ transformOrigin?: string;
1559
+ /**
1560
+ * Zero-based position of this group among its parent container's
1561
+ * children (including both sibling groups and sibling shape nodes).
1562
+ * Used during restoration to correctly interleave groups and shapes
1563
+ * so that SVG document order (painting order) is preserved.
1564
+ */
1565
+ siblingIndex?: number;
1566
+ /** Plugin that owns this group (e.g. 'svgsketch-charts') */
1567
+ pluginId?: string;
1568
+ /** Serialized plugin-specific state (JSON string) */
1569
+ pluginData?: string;
1570
+ /** Additional custom data-* attributes set by plugins */
1571
+ attributes?: Record<string, string>;
1572
+ fill?: string;
1573
+ fillOpacity?: string;
1574
+ strokeOpacity?: string;
1575
+ opacity?: string;
1576
+ filter?: string;
1577
+ cssFilter?: string;
1578
+ mixBlendMode?: string;
1579
+ clipPath?: string;
1580
+ mask?: string;
1613
1581
  /**
1614
- * Marker definitions (reusable vertex-attached graphics: arrowheads, dots,
1615
- * etc.). Built-in markers are reconstituted at load time by MarkerManager
1616
- * and are NOT persisted here only user-authored defs are stored.
1582
+ * Lossless carrier for any `<metadata>` elements that appeared as
1583
+ * children of this group's source `<g>` element. Same semantics as
1584
+ * `ShapeMetadata.rawMetadata` / `DocumentMetadata.rawMetadata`see
1585
+ * SVG 2 §5.8 (`<metadata>` can appear on any container).
1617
1586
  */
1618
- markers?: SerializedMarkerDef[];
1587
+ rawMetadata?: string;
1588
+ }
1589
+ /** Serialized clip or mask group */
1590
+ interface SerializedClipMaskGroup {
1591
+ id: string;
1592
+ type: 'clip' | 'mask';
1593
+ /**
1594
+ * @deprecated Use `clipShapeIds` instead. Kept for backward compatibility
1595
+ * when reading older documents that used a single clip/mask shape.
1596
+ */
1597
+ clipShapeId?: string;
1598
+ /** IDs of shape(s) that form the clip/mask definition. */
1599
+ clipShapeIds: string[];
1600
+ /** IDs of the content shapes being clipped/masked. */
1601
+ contentShapeIds: string[];
1602
+ parentId: string | null;
1603
+ /**
1604
+ * Position of the clip/mask group among its parent container's children,
1605
+ * so that SVG document order (painting order) is preserved across
1606
+ * save / restore.
1607
+ */
1608
+ siblingIndex?: number;
1609
+ /**
1610
+ * Coordinate system for the `<mask>` bounds (`x`, `y`, `width`, `height`).
1611
+ * @see CSS Masking Module §9.1 — `maskUnits`
1612
+ * @default 'objectBoundingBox'
1613
+ */
1614
+ maskUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
1615
+ /**
1616
+ * Coordinate system for the **contents** of a `<mask>`.
1617
+ * @see CSS Masking Module §9.1 — `maskContentUnits`
1618
+ * @default 'userSpaceOnUse'
1619
+ */
1620
+ maskContentUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
1621
+ /**
1622
+ * Coordinate system for the contents of a `<clipPath>`.
1623
+ * @see CSS Masking Module §6.1 — `clipPathUnits`
1624
+ * @default 'userSpaceOnUse'
1625
+ */
1626
+ clipPathUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
1627
+ /**
1628
+ * Explicit mask bounds (`x`, `y`, `width`, `height`).
1629
+ * When omitted the browser defaults apply (−10% / 120%).
1630
+ */
1631
+ maskBounds?: {
1632
+ x: string;
1633
+ y: string;
1634
+ width: string;
1635
+ height: string;
1636
+ };
1637
+ /**
1638
+ * Whether the mask uses luminance or alpha channel.
1639
+ * @see CSS Masking Module §9.2 — `mask-type`
1640
+ * @default 'luminance'
1641
+ */
1642
+ maskType?: 'luminance' | 'alpha';
1643
+ /**
1644
+ * Raw SVG markup for imported mask/clip definitions that cannot be
1645
+ * decomposed into editor `Shape` objects (e.g. multi-element masks
1646
+ * with gradients, patterns, or nested groups). When present the
1647
+ * editor preserves the original `<mask>` / `<clipPath>` verbatim
1648
+ * and `clipShapeIds` may be empty.
1649
+ */
1650
+ rawDefinition?: string;
1651
+ }
1652
+
1653
+ /**
1654
+ * @svgsketch/core — Library (defs) types.
1655
+ *
1656
+ * A `LibraryDef` is any reusable element that lives in an SVG `<defs>` and is
1657
+ * referenced from shapes via `url(#id)`. The library is the authoritative store
1658
+ * for these definitions; shapes carry only ID references.
1659
+ *
1660
+ * Kinds covered here:
1661
+ * - symbol (SVG 2 §5.5, referenced by `<use href="#id">`)
1662
+ * - marker (SVG 2 §13.7, referenced by `marker-start/-mid/-end`)
1663
+ * - linear-gradient / radial-gradient (SVG 2 §14, referenced by fill/stroke)
1664
+ * - pattern (SVG 2 §14.3, referenced by fill/stroke)
1665
+ * - filter (CSS Filter Effects §Filter Property, referenced by `filter`)
1666
+ *
1667
+ * ClipPath, mask, and <style> are deliberately out of scope for this pass.
1668
+ */
1669
+
1670
+ /** Discriminator for the `LibraryDef` union. */
1671
+ type LibraryKind = 'symbol' | 'marker' | 'linear-gradient' | 'radial-gradient' | 'pattern' | 'filter';
1672
+ /**
1673
+ * Common fields shared by every kind of library def. ID prefix convention:
1674
+ * sym- / mkr- / grd- / pat- / flt-
1675
+ */
1676
+ interface LibraryDefBase {
1677
+ /** Unique identifier, prefixed by kind (see convention above). */
1678
+ id: string;
1679
+ /** Kind discriminator — required on every def. */
1680
+ kind: LibraryKind;
1681
+ /** Human-readable name shown in the library panel. */
1682
+ name: string;
1683
+ /** Base64 data-URI thumbnail, rendered by the kind's thumbnail generator. */
1684
+ thumbnail?: string;
1685
+ /**
1686
+ * Editor-shipped seed that isn't deletable, renamable, or user-editable
1687
+ * (today: built-in markers). Only set when the kind actually has built-ins.
1688
+ */
1689
+ builtIn?: boolean;
1690
+ /**
1691
+ * Original id from the imported source SVG. Runtime `id` is always a fresh
1692
+ * GUID; `sourceId` lets export restore human-friendly ids when uncontested.
1693
+ */
1694
+ sourceId?: string;
1695
+ }
1696
+ /**
1697
+ * Reusable component template. Shapes inside are edited via symbol isolation
1698
+ * mode and placed onto the canvas as `SymbolInstance` shapes (which emit as
1699
+ * `<use href="#id">` on export — SVG 2 §5.5).
1700
+ */
1701
+ interface SymbolLibraryDef extends LibraryDefBase {
1702
+ kind: 'symbol';
1703
+ viewBox: string;
1704
+ /**
1705
+ * Default variant shapes. When `variantAxes` is present this represents the
1706
+ * variant where every axis is at its first value.
1707
+ */
1708
+ shapes: SerializedShape[];
1709
+ groups?: SerializedGroup[];
1710
+ /**
1711
+ * Ordered list of variant axes. The order is stable so variant keys can be
1712
+ * canonicalized as `axis1=val1,axis2=val2`.
1713
+ */
1714
+ variantAxes?: SerializedVariantAxis[];
1715
+ /** Non-default variant shape arrays keyed by canonical axis combination. */
1716
+ variants?: Record<string, SerializedShape[]>;
1717
+ /** Per-variant thumbnails keyed by canonical variant string. */
1718
+ variantThumbnails?: Record<string, string>;
1719
+ }
1720
+ /**
1721
+ * Vertex-attached graphic (arrowheads, dots, decorations). Referenced via
1722
+ * `marker-start` / `marker-mid` / `marker-end` on stroked shapes — SVG 2
1723
+ * §13.7.2 specifies each attribute accepts a single `<marker-ref>`.
1724
+ */
1725
+ interface MarkerLibraryDef extends LibraryDefBase {
1726
+ kind: 'marker';
1727
+ viewBox: string;
1728
+ /** X reference point — where the marker's tip aligns with the host vertex. */
1729
+ refX: number;
1730
+ refY: number;
1731
+ markerWidth: number;
1732
+ markerHeight: number;
1733
+ /**
1734
+ * `strokeWidth` scales with the host's stroke; `userSpaceOnUse` renders at
1735
+ * fixed size regardless of stroke.
1736
+ */
1737
+ markerUnits: 'strokeWidth' | 'userSpaceOnUse';
1738
+ /**
1739
+ * `auto` rotates to match path tangent; `auto-start-reverse` reverses the
1740
+ * start marker; a number is a fixed rotation in degrees.
1741
+ */
1742
+ orient: 'auto' | 'auto-start-reverse' | number;
1743
+ /**
1744
+ * Inner geometry (authoritative for user markers). Built-ins render from
1745
+ * the descriptor registry and carry `shapes: []`.
1746
+ */
1747
+ shapes: SerializedShape[];
1748
+ groups?: SerializedGroup[];
1749
+ /**
1750
+ * Animation tracks scoped to the marker's inner shapes. Emitted as SMIL
1751
+ * `<animate>` children of the exported `<marker>`.
1752
+ */
1753
+ animations?: SerializedAnimationTimeline['tracks'];
1754
+ }
1755
+ /**
1756
+ * Linear gradient def (SVG 2 §14.6). Referenced via `fill="url(#id)"` or
1757
+ * `stroke="url(#id)"`. Inner geometry is the existing `LinearGradient` shape,
1758
+ * minus the fields that live on `LibraryDefBase` (`id`, `sourceId`).
1759
+ */
1760
+ interface LinearGradientLibraryDef extends LibraryDefBase {
1761
+ kind: 'linear-gradient';
1762
+ gradient: Omit<LinearGradient, 'id' | 'sourceId'>;
1763
+ }
1764
+ /** Radial gradient def (SVG 2 §14.7). See `LinearGradientLibraryDef`. */
1765
+ interface RadialGradientLibraryDef extends LibraryDefBase {
1766
+ kind: 'radial-gradient';
1767
+ gradient: Omit<RadialGradient, 'id' | 'sourceId'>;
1768
+ }
1769
+ /**
1770
+ * Pattern def (SVG 2 §14.3). Subsumes today's `CustomPatternDef` (user-created
1771
+ * reusable tiles) and the per-shape `PatternFill` — both collapse into one
1772
+ * persisted representation keyed by `LibraryDefBase.id`.
1773
+ *
1774
+ * `customPatternId` is stripped because once the pattern IS the library entry,
1775
+ * the back-reference is redundant.
1776
+ */
1777
+ interface PatternLibraryDef extends LibraryDefBase {
1778
+ kind: 'pattern';
1779
+ pattern: Omit<PatternFill, 'id' | 'sourceId' | 'customPatternId'>;
1780
+ }
1781
+ /**
1782
+ * Filter def (CSS Filter Effects). Referenced via `filter="url(#id)"`. When a
1783
+ * shape chains multiple filters, the CSS `filter` property accepts a
1784
+ * space-separated list (`<filter-value-list>`) and composes them serially —
1785
+ * each url()'s input is the previous url()'s output.
1786
+ *
1787
+ * Filter region and unit attributes live on `<filter>` itself (per the spec),
1788
+ * so they move here from the per-shape state.
1789
+ */
1790
+ interface FilterLibraryDef extends LibraryDefBase {
1791
+ kind: 'filter';
1792
+ /** Ordered primitive chain (same editable model used per-shape today). */
1793
+ filters: ShapeFilter[];
1794
+ colorInterpolation?: 'auto' | 'sRGB' | 'linearRGB';
1795
+ filterUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
1796
+ primitiveUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
1797
+ x?: string;
1798
+ y?: string;
1799
+ width?: string;
1800
+ height?: string;
1801
+ }
1802
+ /** Discriminated union over `kind`. */
1803
+ type LibraryDef = SymbolLibraryDef | MarkerLibraryDef | LinearGradientLibraryDef | RadialGradientLibraryDef | PatternLibraryDef | FilterLibraryDef;
1804
+ /**
1805
+ * Narrow helper — picks the library-def type for a given kind. Useful for
1806
+ * `getByKind('symbol')` return types.
1807
+ */
1808
+ type LibraryDefOfKind<K extends LibraryKind> = Extract<LibraryDef, {
1809
+ kind: K;
1810
+ }>;
1811
+
1812
+ /**
1813
+ * Typed property interfaces for every node type in the scene graph.
1814
+ *
1815
+ * This is the **single source of truth** for shape property types across
1816
+ * the entire SVGSketch stack (editor, API worker, server renderer, etc.).
1817
+ *
1818
+ * Each shape type declares the exact set of properties it owns.
1819
+ * These interfaces drive:
1820
+ * - Compile-time type safety on `SceneNode.get()` / `.set()` calls
1821
+ * - The `NodeTypePropsMap` lookup used by `SceneNode.create()`
1822
+ * - Schema defaults and validators in the editor's `node-schema.ts`
1823
+ * - Serialization format for the `.svgs` document format
1824
+ */
1825
+
1826
+ interface CommonNodeProps {
1827
+ fillColor: string;
1828
+ borderColor: string;
1829
+ borderWidth: number;
1830
+ opacity: number;
1831
+ fillOpacity: number;
1832
+ strokeOpacity: number;
1833
+ rotation: number;
1834
+ skewX: number;
1835
+ skewY: number;
1836
+ customPivot: Point | null;
1837
+ locked: boolean;
1838
+ visible: boolean;
1839
+ fillType: string;
1840
+ fillGradient: unknown | null;
1841
+ strokeType: string;
1842
+ strokeGradient: unknown | null;
1843
+ fillRule: 'nonzero' | 'evenodd';
1844
+ strokeLinejoin: 'miter' | 'round' | 'bevel';
1845
+ strokeLinecap: 'butt' | 'round' | 'square';
1846
+ strokeMiterlimit: number;
1847
+ lineStyle: string;
1848
+ dashLength: number;
1849
+ gapLength: number;
1850
+ dashOffset: number;
1851
+ strokeDasharray: string | null;
1852
+ filters: unknown[];
1853
+ filterColorInterpolation: 'auto' | 'sRGB' | 'linearRGB' | null;
1854
+ filterUnits: 'userSpaceOnUse' | 'objectBoundingBox' | null;
1855
+ primitiveUnits: 'userSpaceOnUse' | 'objectBoundingBox' | null;
1856
+ filterX: string | null;
1857
+ filterY: string | null;
1858
+ filterWidth: string | null;
1859
+ filterHeight: string | null;
1860
+ rawTransform: string | null;
1861
+ metadata: unknown | null;
1862
+ cssClipPath: string | null;
1863
+ cssMaskProperties: Record<string, string> | null;
1864
+ groupId: string | null;
1865
+ }
1866
+ type CornerShapeValue = 'round' | 'notch' | 'bevel' | 'scoop';
1867
+ interface RectangleNodeProps extends CommonNodeProps {
1868
+ x: number;
1869
+ y: number;
1870
+ width: number;
1871
+ height: number;
1872
+ cornerRadius: number;
1873
+ cornerShape: CornerShapeValue;
1874
+ cornerMode: 'uniform' | 'non-uniform';
1875
+ cornerRadiusTL: number;
1876
+ cornerRadiusTR: number;
1877
+ cornerRadiusBL: number;
1878
+ cornerRadiusBR: number;
1879
+ cornerShapeTL: CornerShapeValue;
1880
+ cornerShapeTR: CornerShapeValue;
1881
+ cornerShapeBL: CornerShapeValue;
1882
+ cornerShapeBR: CornerShapeValue;
1883
+ }
1884
+ type SquareNodeProps = RectangleNodeProps;
1885
+ interface CircleNodeProps extends CommonNodeProps {
1886
+ x: number;
1887
+ y: number;
1888
+ radius: number;
1889
+ }
1890
+ interface EllipseNodeProps extends CommonNodeProps {
1891
+ x: number;
1892
+ y: number;
1893
+ rx: number;
1894
+ ry: number;
1895
+ }
1896
+ type LineEndpointValue = 'none' | 'arrow' | 'open-arrow' | 'circle' | 'diamond' | 'square';
1897
+ interface LineNodeProps extends CommonNodeProps {
1898
+ x1: number;
1899
+ y1: number;
1900
+ x2: number;
1901
+ y2: number;
1902
+ startEndpoint: LineEndpointValue;
1903
+ endEndpoint: LineEndpointValue;
1904
+ }
1905
+ interface TextNodeProps extends CommonNodeProps {
1906
+ x: number;
1907
+ y: number;
1908
+ width: number;
1909
+ height: number;
1910
+ textX: number;
1911
+ textY: number;
1912
+ fontSize: number;
1913
+ text: string;
1914
+ fontFamily: string;
1915
+ fontWeight: string;
1916
+ fontStyle: string;
1917
+ textDecoration: Record<string, boolean>;
1918
+ textTransform: string;
1919
+ baselineShift: string;
1920
+ dominantBaseline: string;
1921
+ writingMode: string;
1922
+ textAnchor: string;
1923
+ letterSpacing: number;
1924
+ wordSpacing: number;
1925
+ lineHeight: number;
1926
+ inlineSize: number;
1927
+ overflowWrap: string;
1928
+ whiteSpace: string;
1929
+ textDirection: string;
1930
+ unicodeBidi: string;
1931
+ scaleX: number;
1932
+ scaleY: number;
1933
+ scaleAnchor: Point | null;
1934
+ useRichText: boolean;
1935
+ richTextData: unknown | null;
1936
+ charOffsets: {
1937
+ x: number;
1938
+ y: number;
1939
+ rotate: number;
1940
+ }[] | null;
1941
+ fontVariationSettings: Record<string, number>;
1942
+ isTextPath: boolean;
1943
+ textPathPoints: unknown[] | null;
1944
+ textPathStartOffset: number;
1945
+ textPathSide: 'left' | 'right';
1946
+ shapeInsideRef: string | null;
1947
+ shapePadding: number;
1948
+ }
1949
+ interface ImageNodeProps extends CommonNodeProps {
1950
+ x: number;
1951
+ y: number;
1952
+ width: number;
1953
+ height: number;
1954
+ href: string;
1955
+ originalWidth: number;
1956
+ originalHeight: number;
1957
+ preserveAspectRatio: boolean;
1958
+ imageOpacity: number;
1959
+ }
1960
+ interface SplineNodeProps extends CommonNodeProps {
1961
+ x: number;
1962
+ y: number;
1963
+ width: number;
1964
+ height: number;
1965
+ splinePoints: unknown[];
1966
+ splineArcParams: unknown[];
1967
+ splineControlBounds: {
1968
+ x: number;
1969
+ y: number;
1970
+ width: number;
1971
+ height: number;
1972
+ } | null;
1973
+ startEndpoint: LineEndpointValue;
1974
+ endEndpoint: LineEndpointValue;
1975
+ }
1976
+ interface PolylineNodeProps extends CommonNodeProps {
1977
+ x: number;
1978
+ y: number;
1979
+ width: number;
1980
+ height: number;
1981
+ polylinePoints: Point[];
1982
+ polylineClosed: boolean;
1983
+ }
1984
+ interface PolygonBaseNodeProps extends CommonNodeProps {
1985
+ cx: number;
1986
+ cy: number;
1987
+ radius: number;
1988
+ cornerRadius: number;
1989
+ shiftAngle: number;
1990
+ }
1991
+ interface TriangleNodeProps extends PolygonBaseNodeProps {
1992
+ sides: 3;
1993
+ }
1994
+ interface NGonNodeProps extends PolygonBaseNodeProps {
1995
+ sides: number;
1996
+ }
1997
+ interface StarNodeProps extends PolygonBaseNodeProps {
1998
+ arms: number;
1999
+ innerRadiusPercent: number;
2000
+ }
2001
+ interface CrossNodeProps extends PolygonBaseNodeProps {
2002
+ armWidthPercent: number;
2003
+ }
2004
+ interface RingNodeProps extends PolygonBaseNodeProps {
2005
+ innerRadiusPercent: number;
2006
+ }
2007
+ interface SpiralNodeProps extends PolygonBaseNodeProps {
2008
+ turns: number;
2009
+ thicknessPercent: number;
2010
+ spiralDirection: number;
2011
+ }
2012
+ interface GearNodeProps extends PolygonBaseNodeProps {
2013
+ teeth: number;
2014
+ toothDepthPercent: number;
2015
+ holeRadiusPercent: number;
2016
+ }
2017
+ interface ArrowNodeProps extends PolygonBaseNodeProps {
2018
+ headWidthPercent: number;
2019
+ headLengthPercent: number;
2020
+ shaftWidthPercent: number;
1619
2021
  }
1620
- /**
1621
- * A variant axis on a component symbol. Each axis has a name (e.g.
1622
- * `state`, `size`, `theme`) and an ordered list of allowed values
1623
- * (e.g. `[default, hover, pressed]`). The default value is always
1624
- * the first entry in `values`.
1625
- */
1626
- interface SerializedVariantAxis {
1627
- name: string;
1628
- values: string[];
2022
+ interface SymbolInstanceNodeProps extends CommonNodeProps {
2023
+ x: number;
2024
+ y: number;
2025
+ width: number;
2026
+ height: number;
2027
+ symbolId: string;
1629
2028
  }
1630
- /**
1631
- * A reusable symbol definition. Contains the shapes that make up the
1632
- * symbol template, plus metadata for the symbols panel.
1633
- *
1634
- * **Variants:** when `variantAxes` is present, the symbol carries
1635
- * multiple alternative shape arrays keyed by variant combination
1636
- * (e.g. `state=hover,size=md`). The base `shapes` field is always
1637
- * the **default variant** — the combination where every axis is at
1638
- * its first value. Other variants live in `variants[variantKey]`.
1639
- * Variant resolution falls back to `shapes` whenever `variantKey`
1640
- * is missing or empty.
1641
- */
1642
- interface SerializedSymbolDef {
1643
- /** Unique identifier for this symbol definition. */
1644
- id: string;
1645
- /** Human-readable name shown in the symbols panel. */
1646
- name: string;
1647
- /** SVG viewBox string ("minX minY width height"). */
1648
- viewBox: string;
1649
- /**
1650
- * Default variant shapes. When `variantAxes` is present, this represents
1651
- * the variant where every axis is at its first value.
1652
- */
1653
- shapes: SerializedShape[];
1654
- /** Groups within the symbol. */
1655
- groups?: SerializedGroup[];
1656
- /** Base64 data-URI thumbnail for the symbols panel. */
1657
- thumbnail?: string;
1658
- /**
1659
- * Ordered list of variant axes available on this symbol. The order is
1660
- * stable so that variant keys can be canonicalized as
1661
- * `axis1=val1,axis2=val2`.
1662
- */
1663
- variantAxes?: SerializedVariantAxis[];
1664
- /**
1665
- * Non-default variant shape arrays keyed by canonical axis combination
1666
- * string (e.g. `state=hover,size=md`). Missing keys fall back to the
1667
- * base `shapes` array.
1668
- */
1669
- variants?: Record<string, SerializedShape[]>;
1670
- /**
1671
- * Per-variant thumbnails as base64 data URIs, keyed by canonical
1672
- * variant combination string. The empty string `""` keys the default
1673
- * variant (which also lives in `thumbnail` for backwards compatibility).
1674
- * Used by the variant matrix view to show real previews of each cell.
1675
- */
1676
- variantThumbnails?: Record<string, string>;
2029
+ interface GroupNodeProps {
2030
+ groupId: string | null;
1677
2031
  }
2032
+ type DocumentNodeProps = Record<string, never>;
1678
2033
  /**
1679
- * A reusable `<marker>` definition (SVG 2 §11.6). Markers are vertex-attached
1680
- * graphics arrowheads, vertex dots, decorations — referenced via
1681
- * `marker-start` / `marker-mid` / `marker-end` attributes on stroked shapes.
1682
- *
1683
- * The browser handles per-vertex positioning, scaling (via `markerUnits`),
1684
- * and orientation (via `orient`, including tangent-aware `auto` mode on
1685
- * curved paths). MarkerManager only maintains the DOM `<defs>` entries in
1686
- * sync with this serialized state.
1687
- *
1688
- * Simpler than `SerializedSymbolDef` — markers have no variants, no instance
1689
- * overrides, and no placed instances (they attach via attribute references).
2034
+ * Maps each node type string to its typed property interface.
2035
+ * Used by `SceneNode.create()` for compile-time type safety.
1690
2036
  */
1691
- interface SerializedMarkerDef {
1692
- /**
1693
- * Unique identifier.
1694
- * - Built-in markers use stable ids: `mkr-builtin-arrow`, `mkr-builtin-open-arrow`,
1695
- * `mkr-builtin-circle`, `mkr-builtin-diamond`, `mkr-builtin-square`.
1696
- * - User-created markers use `mkr-<guid>`.
1697
- */
1698
- id: string;
1699
- /** Human-readable name shown in the markers panel. */
1700
- name: string;
1701
- /** SVG viewBox string ("minX minY width height"). */
1702
- viewBox: string;
1703
- /** X reference point — where the marker's "tip" aligns with the host vertex. */
1704
- refX: number;
1705
- refY: number;
1706
- markerWidth: number;
1707
- markerHeight: number;
1708
- /**
1709
- * `strokeWidth` scales the marker with the host's stroke-width (default,
1710
- * typical for arrows). `userSpaceOnUse` renders at fixed size regardless
1711
- * of stroke.
1712
- */
1713
- markerUnits: 'strokeWidth' | 'userSpaceOnUse';
1714
- /**
1715
- * `auto` rotates to match the path tangent at each vertex.
1716
- * `auto-start-reverse` reverses the start marker (so arrowheads don't
1717
- * point inward at path starts). A number is a fixed rotation in degrees.
1718
- */
1719
- orient: 'auto' | 'auto-start-reverse' | number;
1720
- /**
1721
- * Inner geometry. For user markers this is the authoritative source —
1722
- * edited via isolation mode and re-rendered into the DOM `<marker>` child.
1723
- * For built-ins this is `[]` in v1; built-ins render from the descriptor
1724
- * registry (`getMarkerDescriptors()`) and are not editable.
1725
- */
1726
- shapes: SerializedShape[];
1727
- /** Groups within the marker (mirrors `SerializedSymbolDef.groups`). */
1728
- groups?: SerializedGroup[];
1729
- /** Base64 data-URI thumbnail for the markers panel. */
1730
- thumbnail?: string;
1731
- /**
1732
- * Animation tracks scoped to the marker's inner shapes. Each track's
1733
- * `shapeId` references an id in `shapes`. During isolation editing these
1734
- * tracks are merged into the document timeline (tagged `scope:
1735
- * 'marker:<id>'`) so the user can edit them; on save they're extracted
1736
- * back here. On SVG export the tracks render as SMIL `<animate>` elements
1737
- * inside the `<marker>` DOM so they play at every attached vertex.
1738
- */
1739
- animations?: SerializedAnimationTimeline['tracks'];
1740
- /**
1741
- * True for editor-shipped built-ins (arrow, open-arrow, circle, diamond,
1742
- * square). Built-ins are non-deletable, non-renamable, and non-editable.
1743
- */
1744
- builtIn?: boolean;
1745
- }
1746
- interface SerializedGroup {
1747
- id: string;
1748
- parentId: string | null;
1749
- /** CSS transform-origin value (e.g. "50px 50px") for group animations */
1750
- transformOrigin?: string;
1751
- /**
1752
- * Zero-based position of this group among its parent container's
1753
- * children (including both sibling groups and sibling shape nodes).
1754
- * Used during restoration to correctly interleave groups and shapes
1755
- * so that SVG document order (painting order) is preserved.
1756
- */
1757
- siblingIndex?: number;
1758
- /** Plugin that owns this group (e.g. 'svgsketch-charts') */
1759
- pluginId?: string;
1760
- /** Serialized plugin-specific state (JSON string) */
1761
- pluginData?: string;
1762
- /** Additional custom data-* attributes set by plugins */
1763
- attributes?: Record<string, string>;
1764
- fill?: string;
1765
- fillOpacity?: string;
1766
- strokeOpacity?: string;
1767
- opacity?: string;
1768
- filter?: string;
1769
- cssFilter?: string;
1770
- mixBlendMode?: string;
1771
- clipPath?: string;
1772
- mask?: string;
1773
- }
1774
- /** Serialized clip or mask group */
1775
- interface SerializedClipMaskGroup {
1776
- id: string;
1777
- type: 'clip' | 'mask';
1778
- /**
1779
- * @deprecated Use `clipShapeIds` instead. Kept for backward compatibility
1780
- * when reading older documents that used a single clip/mask shape.
1781
- */
1782
- clipShapeId?: string;
1783
- /** IDs of shape(s) that form the clip/mask definition. */
1784
- clipShapeIds: string[];
1785
- /** IDs of the content shapes being clipped/masked. */
1786
- contentShapeIds: string[];
1787
- parentId: string | null;
1788
- /**
1789
- * Position of the clip/mask group among its parent container's children,
1790
- * so that SVG document order (painting order) is preserved across
1791
- * save / restore.
1792
- */
1793
- siblingIndex?: number;
1794
- /**
1795
- * Coordinate system for the `<mask>` bounds (`x`, `y`, `width`, `height`).
1796
- * @see CSS Masking Module §9.1 — `maskUnits`
1797
- * @default 'objectBoundingBox'
1798
- */
1799
- maskUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
1800
- /**
1801
- * Coordinate system for the **contents** of a `<mask>`.
1802
- * @see CSS Masking Module §9.1 — `maskContentUnits`
1803
- * @default 'userSpaceOnUse'
1804
- */
1805
- maskContentUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
1806
- /**
1807
- * Coordinate system for the contents of a `<clipPath>`.
1808
- * @see CSS Masking Module §6.1 — `clipPathUnits`
1809
- * @default 'userSpaceOnUse'
1810
- */
1811
- clipPathUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
1812
- /**
1813
- * Explicit mask bounds (`x`, `y`, `width`, `height`).
1814
- * When omitted the browser defaults apply (−10% / 120%).
1815
- */
1816
- maskBounds?: {
1817
- x: string;
1818
- y: string;
1819
- width: string;
1820
- height: string;
1821
- };
1822
- /**
1823
- * Whether the mask uses luminance or alpha channel.
1824
- * @see CSS Masking Module §9.2 — `mask-type`
1825
- * @default 'luminance'
1826
- */
1827
- maskType?: 'luminance' | 'alpha';
1828
- /**
1829
- * Raw SVG markup for imported mask/clip definitions that cannot be
1830
- * decomposed into editor `Shape` objects (e.g. multi-element masks
1831
- * with gradients, patterns, or nested groups). When present the
1832
- * editor preserves the original `<mask>` / `<clipPath>` verbatim
1833
- * and `clipShapeIds` may be empty.
1834
- */
1835
- rawDefinition?: string;
2037
+ interface NodeTypePropsMap {
2038
+ rectangle: RectangleNodeProps;
2039
+ square: SquareNodeProps;
2040
+ circle: CircleNodeProps;
2041
+ ellipse: EllipseNodeProps;
2042
+ line: LineNodeProps;
2043
+ text: TextNodeProps;
2044
+ image: ImageNodeProps;
2045
+ spline: SplineNodeProps;
2046
+ polyline: PolylineNodeProps;
2047
+ triangle: TriangleNodeProps;
2048
+ ngon: NGonNodeProps;
2049
+ star: StarNodeProps;
2050
+ cross: CrossNodeProps;
2051
+ ring: RingNodeProps;
2052
+ spiral: SpiralNodeProps;
2053
+ gear: GearNodeProps;
2054
+ arrow: ArrowNodeProps;
2055
+ 'symbol-instance': SymbolInstanceNodeProps;
2056
+ group: GroupNodeProps;
2057
+ document: DocumentNodeProps;
1836
2058
  }
2059
+ /** Union of all node prop types. */
2060
+ type AnyNodeProps = RectangleNodeProps | SquareNodeProps | CircleNodeProps | EllipseNodeProps | LineNodeProps | TextNodeProps | ImageNodeProps | SplineNodeProps | PolylineNodeProps | TriangleNodeProps | NGonNodeProps | StarNodeProps | CrossNodeProps | RingNodeProps | SpiralNodeProps | GearNodeProps | ArrowNodeProps | SymbolInstanceNodeProps | GroupNodeProps | DocumentNodeProps;
1837
2061
 
1838
2062
  /**
1839
2063
  * @svgsketch/core — Schema migrations.
@@ -1870,17 +2094,6 @@ interface SerializedClipMaskGroup {
1870
2094
  * It must return the transformed snapshot (typically the same object).
1871
2095
  */
1872
2096
  type Migration = (snapshot: HistorySnapshot) => HistorySnapshot;
1873
- /**
1874
- * Registry of schema migrations, keyed by **source** version.
1875
- *
1876
- * Entry `N: fn` means "`fn` transforms a version-N snapshot into a
1877
- * version-(N+1) snapshot." The dispatcher in {@link migrateSnapshot}
1878
- * walks this registry from the snapshot's current version up to
1879
- * {@link CURRENT_SCHEMA_VERSION}.
1880
- *
1881
- * This object is exported so tests (and diagnostic tooling) can read
1882
- * the registered migrations, but it should not be mutated at runtime.
1883
- */
1884
2097
  declare const MIGRATIONS: Readonly<Record<number, Migration>>;
1885
2098
  /**
1886
2099
  * Migrate a snapshot from any older schema version to the current version.
@@ -2260,14 +2473,25 @@ declare function renderFilterPrimitivesForType(filter: ShapeFilter, input: strin
2260
2473
  /**
2261
2474
  * Generate `<filter>` definition strings for all shapes that have filters.
2262
2475
  *
2476
+ * Phase 4: filters are library-first. Each distinct `filterLibraryIds`
2477
+ * entry emits exactly one `<filter>` in the output — two shapes sharing
2478
+ * the same library filter id produce one `<filter>`, not two. Falls back
2479
+ * to the legacy `filter-${shape.id}` id when a shape has inline filters
2480
+ * but no library ids set (shapes that haven't re-serialized since the
2481
+ * migration, or callers working against an in-memory object).
2482
+ *
2263
2483
  * @returns Concatenated `<filter>` elements to include in `<defs>`.
2264
2484
  */
2265
2485
  declare function renderFilterDefs(shapes: SerializedShape[]): string;
2266
2486
  /**
2267
2487
  * Get the `filter="url(#...)"` attribute value for a shape, or empty string
2268
2488
  * if the shape has no enabled filters.
2489
+ *
2490
+ * Phase 4: reads from `filterLibraryIds` when set, joining multiple ids as
2491
+ * a space-separated `<filter-value-list>` (CSS Filter Effects §Filter
2492
+ * Property). Falls back to the legacy shape-derived id for unmigrated input.
2269
2493
  */
2270
- declare function filterAttr(shapeId: string, filters: ShapeFilter[] | undefined): string;
2494
+ declare function filterAttr(shapeId: string, filters: ShapeFilter[] | undefined, filterLibraryIds?: string[]): string;
2271
2495
 
2272
2496
  /**
2273
2497
  * Shape renderers — convert SerializedShape → SVG element string.
@@ -2287,6 +2511,31 @@ declare function renderImage(shape: SerializedShape): string;
2287
2511
  declare function renderPolygonShape(shape: SerializedShape): string;
2288
2512
  /** Render any SerializedShape to an SVG element string. */
2289
2513
  declare function renderShape(shape: SerializedShape): string;
2514
+ /**
2515
+ * Walk shapes to find referenced marker ids. Returns two sets:
2516
+ * - `ids`: raw marker ids from `state.markerStart` / `markerMid` /
2517
+ * `markerEnd` — can be built-in ids (`mkr-builtin-arrow`,
2518
+ * `line-marker-arrow`) or user marker ids.
2519
+ * - `legacyEndpoints`: endpoint names from `state.startEndpoint` /
2520
+ * `endEndpoint` (e.g. `'arrow'`, `'circle'`). Lines emit these as a
2521
+ * shortcut to built-in markers without explicit `marker-*` attrs.
2522
+ */
2523
+ interface MarkerReferenceSets {
2524
+ ids: Set<string>;
2525
+ legacyEndpoints: Set<string>;
2526
+ }
2527
+ /**
2528
+ * Emit only built-in marker `<marker>` definitions referenced by a shape
2529
+ * collection. Split out of `renderMarkerDefs` so the library-first
2530
+ * pipeline can compose built-in handling with
2531
+ * `renderReferencedLibraryDefs` (which covers user-authored markers via
2532
+ * `snapshot.library`).
2533
+ *
2534
+ * Takes a pre-collected `MarkerReferenceSets` so callers can avoid walking
2535
+ * shapes twice when they need both the reference sets and the built-in
2536
+ * defs.
2537
+ */
2538
+ declare function renderBuiltinMarkerDefs(referenced: MarkerReferenceSets | SerializedShape[]): string;
2290
2539
 
2291
2540
  /**
2292
2541
  * Pure geometry functions for computing shape vertices and paths.
@@ -2535,6 +2784,95 @@ declare function getBuiltInMarkerDefs(): SerializedMarkerDef[];
2535
2784
  */
2536
2785
  declare function renderAnimationElements(timeline: SerializedAnimationTimeline): Map<string, string[]>;
2537
2786
 
2787
+ /**
2788
+ * Library renderers — convert `LibraryDef` entries into SVG `<defs>` strings.
2789
+ *
2790
+ * This is the headless/string-based renderer for library defs. The editor's
2791
+ * live `<defs>` rendering is handled by the kind-specific managers
2792
+ * (SymbolManager, MarkerManager, GradientManager, FilterManager) writing D3
2793
+ * DOM nodes; this module is the equivalent path for the CLI/SDK export pipe.
2794
+ *
2795
+ * Implementations delegate to the existing per-shape renderers where
2796
+ * possible — library defs carry the same render-affecting data as the
2797
+ * inline payloads those renderers were built for, with `LibraryDefBase`
2798
+ * metadata (id, name, thumbnail) peeled off at the outer call.
2799
+ *
2800
+ * @packageDocumentation
2801
+ */
2802
+
2803
+ /**
2804
+ * Deterministic emission order for `<defs>` contents. Put paint servers
2805
+ * (gradients, patterns) and filters **before** symbols/markers so that when a
2806
+ * symbol or marker's inner shapes reference a library paint or filter by
2807
+ * `url(#id)`, the forward reference resolves in parsers that do a single
2808
+ * forward pass.
2809
+ *
2810
+ * This matches the plan's export ordering rule: symbols and markers can
2811
+ * reference any other library kind, but not vice versa.
2812
+ */
2813
+ declare const LIBRARY_EMIT_ORDER: readonly LibraryKind[];
2814
+ /** Top-level dispatch. Picks the right kind-renderer for a library def. */
2815
+ declare function renderLibraryDef(def: LibraryDef): string;
2816
+ declare function renderSymbolLibraryDef(def: SymbolLibraryDef): string;
2817
+ declare function renderMarkerLibraryDef(def: MarkerLibraryDef): string;
2818
+ declare function renderLinearGradientLibraryDef(def: LinearGradientLibraryDef): string;
2819
+ declare function renderRadialGradientLibraryDef(def: RadialGradientLibraryDef): string;
2820
+ declare function renderPatternLibraryDef(def: PatternLibraryDef): string;
2821
+ declare function renderFilterLibraryDef(def: FilterLibraryDef): string;
2822
+ /**
2823
+ * Render every library def as a single `<defs>`-body string, in the
2824
+ * canonical order defined by `LIBRARY_EMIT_ORDER`. Useful for callers that
2825
+ * want to emit the entire library regardless of which defs are actually
2826
+ * referenced — the editor's export finalizer uses a reference-walker
2827
+ * instead, but standalone SVG producers (e.g. CLI fixture generation) may
2828
+ * prefer this unconditional emission.
2829
+ */
2830
+ declare function renderLibraryDefs(defs: readonly LibraryDef[]): string;
2831
+ /**
2832
+ * Collect every library-def id referenced by a shape collection. Covers
2833
+ * all the ways a shape points at a library entry:
2834
+ *
2835
+ * - `fillLibraryId` / `strokeLibraryId` (gradient / pattern paint servers)
2836
+ * - `filterLibraryIds[]` (filter chain)
2837
+ * - `markerStart` / `markerMid` / `markerEnd` (vertex markers)
2838
+ * - `symbolId` (symbol instances)
2839
+ *
2840
+ * Ids for built-in markers (e.g. `mkr-builtin-arrow`, `line-marker-arrow`)
2841
+ * are included in the result — callers that emit built-ins from the
2842
+ * descriptor registry should still look here for the reference signal.
2843
+ *
2844
+ * Does NOT include `url(#...)` strings parsed out of inline fill/stroke
2845
+ * CSS text — the library-first pipeline assumes shapes set `fillLibraryId`
2846
+ * explicitly when they reference a library def.
2847
+ */
2848
+ declare function collectReferencedLibraryIds(shapes: readonly SerializedShape[]): Set<string>;
2849
+ /**
2850
+ * Library-first `<defs>` emission: walks shapes and emits one `<defs>`
2851
+ * entry per unique paint-server / filter / user-marker referenced by the
2852
+ * scene. Built-in markers (which live in the descriptor registry, not
2853
+ * `snapshot.library`) are NOT emitted by this function — callers should
2854
+ * compose with `renderBuiltinMarkerDefs` or similar.
2855
+ *
2856
+ * Two input sources are merged, with library-first precedence:
2857
+ *
2858
+ * 1. **Library refs**: shapes set `fillLibraryId`, `strokeLibraryId`,
2859
+ * `filterLibraryIds`, `markerStart/Mid/End`, or `symbolId` pointing
2860
+ * into `library`. The library entry is authoritative for the def.
2861
+ * 2. **Legacy inline payloads**: shapes with `fillGradient` /
2862
+ * `strokeGradient` / `filters[]` but NO matching library ref. A
2863
+ * transient library def is synthesized from the inline data on the
2864
+ * fly so renders remain correct for snapshots that bypass the
2865
+ * migrator (e.g. older tests, hand-built snapshots via the SDK).
2866
+ *
2867
+ * Dedup is by emitted id. A shape that has both a library ref AND an
2868
+ * inline payload with the same id emits the library entry once.
2869
+ *
2870
+ * Defs are emitted in `LIBRARY_EMIT_ORDER` so cross-kind references
2871
+ * (e.g. a `<symbol>` whose inner shapes reference a gradient) resolve
2872
+ * during single-pass parsing.
2873
+ */
2874
+ declare function renderReferencedLibraryDefs(shapes: readonly SerializedShape[], library: readonly LibraryDef[]): string;
2875
+
2538
2876
  /**
2539
2877
  * Code generation dispatcher — routes to format-specific generators.
2540
2878
  */
@@ -2836,6 +3174,26 @@ declare abstract class ShapeBuilder<T extends ShapeBuilder<T>> {
2836
3174
  locked(value?: boolean): T;
2837
3175
  /** Set visibility. */
2838
3176
  visible(value?: boolean): T;
3177
+ /**
3178
+ * Set the shape's structural role in the exported SVG.
3179
+ *
3180
+ * - `'normal'` (default) — rendered inline in document order.
3181
+ * - `'motionOnly'` — emitted inside `<defs>` as an `<mpath>` reference
3182
+ * target and NOT rendered. Pair with `Track.motionPathRef(shapeId,
3183
+ * 'curveTemplate')` so the animation's `<mpath>` resolves to this
3184
+ * shape's origin-normalized `d`. The exporter automatically
3185
+ * translates the shape's `d` so its first moveto is at `M 0,0`,
3186
+ * the canonical "curve template" form that lets multiple animations
3187
+ * share one motion-path `<defs>` entry.
3188
+ *
3189
+ * @see https://svgwg.org/specs/animations/#MPathElement
3190
+ */
3191
+ displayMode(mode: 'normal' | 'motionOnly'): T;
3192
+ /**
3193
+ * Convenience alias for `.displayMode('motionOnly')` — marks this shape
3194
+ * as an `<mpath>` reference target (not rendered; placed in `<defs>`).
3195
+ */
3196
+ motionOnly(): T;
2839
3197
  /** Set a solid fill color. */
2840
3198
  fill(color: string, opacity?: number): T;
2841
3199
  /** Set fill to none (transparent). */
@@ -3365,6 +3723,42 @@ declare class Track {
3365
3723
  locked(): Track;
3366
3724
  /** Set an SVG path for motion-path animation. */
3367
3725
  motionPath(path: string): Track;
3726
+ /**
3727
+ * Link this motion-path track to another shape's geometry as an
3728
+ * `<mpath href="#shapeId"/>` reference. The track's `motionPath` is
3729
+ * expected to have been set (or will be) to the referenced shape's
3730
+ * path data — the two fields together model SVG Animations §19.2
3731
+ * semantics where `<mpath>` supersedes inline `path=` on export.
3732
+ *
3733
+ * The `mode` controls how the reference is interpreted:
3734
+ * - `'trackShape'` (default) — the motion path is displacement-
3735
+ * relative to the animated element's center, so playback and
3736
+ * editor overlay render on top of the referenced shape's absolute
3737
+ * position. Exports as inline `path=` (spec-correct).
3738
+ * - `'curveTemplate'` — the motion path's first point is `M 0,0`,
3739
+ * matching how `<mpath>` semantics want a reusable curve-template.
3740
+ * Exports as `<mpath href="#shapeId"/>` pointing at a `<defs>` path
3741
+ * with the same origin-normalized `d` — reusable across animations.
3742
+ *
3743
+ * Pair with `.motionPath(d)` where `d` is in the form the mode expects:
3744
+ * absolute-minus-element-center for trackShape, origin-normalized for
3745
+ * curveTemplate.
3746
+ *
3747
+ * @example
3748
+ * ```ts
3749
+ * const curve = new Spline(...).id('curve');
3750
+ * doc.add(curve);
3751
+ *
3752
+ * const track = new Track('rect-1', 'pathMotion')
3753
+ * .motionPath('M0,0 C 50,-100 150,-100 200,0') // origin-normalized
3754
+ * .motionPathRef('curve', 'curveTemplate') // emits <mpath href="#curve"/>
3755
+ * .keyframe(0, 0)
3756
+ * .keyframe(3, 1);
3757
+ * ```
3758
+ *
3759
+ * @see https://svgwg.org/specs/animations/#MPathElement
3760
+ */
3761
+ motionPathRef(shapeId: string, mode?: 'trackShape' | 'curveTemplate'): Track;
3368
3762
  /**
3369
3763
  * Set the begin trigger for this track.
3370
3764
  *
@@ -3784,4 +4178,4 @@ declare class Document {
3784
4178
  private _ensureMetadata;
3785
4179
  }
3786
4180
 
3787
- export { type AnimatablePropertyDescriptor, type AnimationKeyframe, type AnimationTimeline, type AnimationTrack, type AnimationTrigger, type AnimationTriggerType, type AnyNodeProps, type ArcParams$1 as ArcParams, type AriaRole, Arrow, type ArrowNodeProps, BUILTIN_MARKER_ID_MAP, type BaseFilter, type BlackAndWhiteFilter, type BlurQuality, type BrightnessFilter, CURRENT_SCHEMA_VERSION, type ChannelPainterFilter, Circle, type CircleNodeProps, type CodeFormat, type CodegenOptions, type CommonNodeProps, type ConnectionDirection, type ConnectionPoint, type ContouringDiscreteFilter, type ContouringTableFilter, type ContrastFilter, type CornerShapeValue, type CreateDocumentOptions, type CreateShapeOptions, Cross, type CrossNodeProps, type CrumpledPlasticFilter, type CustomPatternDef, type CycleBehavior, DEFAULT_COORDINATE_PRECISION, type DiffuseLightingFilter, Document, type DocumentMetadata, type DocumentNodeProps, type DocumentOptions, type DocumentScript, type DocumentStyle, type DropShadowFilter, type DuotoneFilter, EASING_CURVES, EVENT_TRIGGER_OPTIONS, EasingType, Ellipse, type EllipseNodeProps, type EmbossFilter, type ExtractedVariables, type FillType, type FilmGrainFilter, type FilterType, type GaussianBlurFilter, Gear, type GearNodeProps, type GlowFilter, type GouacheFilter, type GradientDefinition, type GradientSpreadMethod, type GradientStop, type GradientUnits, type GrayscaleFilter, type GroupNodeProps, type Guide, type HistorySnapshot, type HueRotateFilter, type ImageAttribution, type ImageNodeProps, ImageShape, type InkBlotFilter, type InnerGlowFilter, type InnerShadowFilter, type InvertFilter, type LicenseType, type LightSource, Line, type LineEndpointValue, type LineNodeProps, type LinearEasingPoint, type LinearGradient, LinearGradientBuilder, type LinkTarget, MARKER_HEIGHT, MARKER_VIEWBOX, MARKER_WIDTH, MAX_COORDINATE_PRECISION, MIGRATIONS, type MarkerDescriptor, type Measurement, type Migration, type MorphologyFilter, type MorphologyOperator, type MotionBlurFilter, NGon, type NGonNodeProps, type NodeTypePropsMap, type NoiseFilter, type OpacityFilter, type OutlineFilter, type OutlinePosition, type ParseOptions, PatternBuilder, type PatternElement, type PatternFill, type PatternParams, type PatternSvgContentResult, type PatternType, type PixelateFilter, type Point, type PointLightFilter, type PolygonBaseNodeProps, Polyline, type PolylineNodeProps, type RadialGradient, RadialGradientBuilder, type RawSvgFilter, Rectangle, type RectangleNodeProps, type RenderOptions, type RichTextData, type RichTextLine, type RichTextSegment, type RichTextSegmentStyle, type RiddledFilter, Ring, type RingNodeProps, type RoundEdgesFilter, type SaturateFilter, type SegmentCurveType, type SepiaFilter, type SerializedAnimationTimeline, type SerializedClipMaskGroup, type SerializedGroup, type SerializedMarkerDef, type SerializedShape, type SerializedSymbolDef, type SerializedVariantAxis, type SerializedViewbox, ShapeBuilder, type ShapeFilter, type ShapeMetadata, type SharpenFilter, type SpecularLightingFilter, Spiral, type SpiralNodeProps, Spline, SplineCurveType, type SplineNodeProps, type SplinePoint, SplinePointType, type SpotLightFilter, Square, type SquareNodeProps, Star, type StarNodeProps, type StepPosition, type StepsParams, type StringifyOptions, type StrokeType, type SymbolInstanceNodeProps, type TemplateVariable, type TemplateVariableSource, type TemplateVariableType, Text, type TextNodeProps, Timeline, Track, Triangle, type TriangleNodeProps, type ValidationError, type ValidationResult, type VariableMap, type Viewbox, type WarpFilter, type WarpType, type WatercolorFilter, type XrayFilter, computeArrowVertices, computeCloudPath, computeCrossVertices, computeDashArray, computeGearPath, computeGearVertices, computeHeartPath, computeLightningVertices, computePolygonVertices, computeRectanglePath, computeRingPath, computeSpeechBubbleVertices, computeSpiralPath, computeSplinePath, computeStarVertices, createDocument, createShape, createViewbox, escXml, extractVariables, filterAttr, generateCode, generateCssCode, generateD3Code, generateId, generatePatternSvgContent, generateReactCode, generateSvgCode, generateVueCode, getBuiltInMarkerDefs, getEasingCubicBezier, getEffectivePrecision, getMarkerDescriptors, getPatternElements, linearGradient, migrateSnapshot, parseDocument, parseVariableArgs, pattern, radialGradient, renderAnimationElements, renderCircle, renderEllipse, renderFilterDefs, renderFilterPrimitivesForType, renderImage, renderLine, renderPolygonShape, renderPolyline, renderRectangle, renderShape, renderSpline, renderText, renderToSvg, roundCoord, roundNumberString, roundSerializedShape, roundSnapshot, stringifyDocument, substituteString, substituteVariables, validateSnapshot, verticesToPath };
4181
+ export { type AnimatablePropertyDescriptor, type AnimationKeyframe, type AnimationTimeline, type AnimationTrack, type AnimationTrigger, type AnimationTriggerType, type AnyNodeProps, type ArcParams$1 as ArcParams, type AriaRole, Arrow, type ArrowNodeProps, BUILTIN_MARKER_ID_MAP, type BaseFilter, type BlackAndWhiteFilter, type BlurQuality, type BrightnessFilter, CURRENT_SCHEMA_VERSION, type ChannelPainterFilter, Circle, type CircleNodeProps, type CodeFormat, type CodegenOptions, type CommonNodeProps, type ConnectionDirection, type ConnectionPoint, type ContouringDiscreteFilter, type ContouringTableFilter, type ContrastFilter, type CornerShapeValue, type CreateDocumentOptions, type CreateShapeOptions, Cross, type CrossNodeProps, type CrumpledPlasticFilter, type CustomPatternDef, type CycleBehavior, DEFAULT_COORDINATE_PRECISION, type DiffuseLightingFilter, Document, type DocumentMetadata, type DocumentNodeProps, type DocumentOptions, type DocumentScript, type DocumentStyle, type DropShadowFilter, type DuotoneFilter, EASING_CURVES, EVENT_TRIGGER_OPTIONS, EasingType, Ellipse, type EllipseNodeProps, type EmbossFilter, type ExtractedVariables, type FillType, type FilmGrainFilter, type FilterLibraryDef, type FilterType, type GaussianBlurFilter, Gear, type GearNodeProps, type GlowFilter, type GouacheFilter, type GradientDefinition, type GradientSpreadMethod, type GradientStop, type GradientUnits, type GrayscaleFilter, type GroupNodeProps, type Guide, type HistorySnapshot, type HueRotateFilter, type ImageAttribution, type ImageNodeProps, ImageShape, type InkBlotFilter, type InnerGlowFilter, type InnerShadowFilter, type InvertFilter, LIBRARY_EMIT_ORDER, type LibraryDef, type LibraryDefBase, type LibraryDefOfKind, type LibraryKind, type LicenseType, type LightSource, Line, type LineEndpointValue, type LineNodeProps, type LinearEasingPoint, type LinearGradient, LinearGradientBuilder, type LinearGradientLibraryDef, type LinkTarget, MARKER_HEIGHT, MARKER_VIEWBOX, MARKER_WIDTH, MAX_COORDINATE_PRECISION, MIGRATIONS, type MarkerDescriptor, type MarkerLibraryDef, type Measurement, type Migration, type MorphologyFilter, type MorphologyOperator, type MotionBlurFilter, NGon, type NGonNodeProps, type NodeTypePropsMap, type NoiseFilter, type OpacityFilter, type OutlineFilter, type OutlinePosition, type ParseOptions, PatternBuilder, type PatternElement, type PatternFill, type PatternLibraryDef, type PatternParams, type PatternSvgContentResult, type PatternType, type PixelateFilter, type Point, type PointLightFilter, type PolygonBaseNodeProps, Polyline, type PolylineNodeProps, type RadialGradient, RadialGradientBuilder, type RadialGradientLibraryDef, type RawSvgFilter, Rectangle, type RectangleNodeProps, type RenderOptions, type RichTextData, type RichTextLine, type RichTextSegment, type RichTextSegmentStyle, type RiddledFilter, Ring, type RingNodeProps, type RoundEdgesFilter, type SaturateFilter, type SegmentCurveType, type SepiaFilter, type SerializedAnimationTimeline, type SerializedClipMaskGroup, type SerializedGroup, type SerializedMarkerDef, type SerializedShape, type SerializedSymbolDef, type SerializedVariantAxis, type SerializedViewbox, ShapeBuilder, type ShapeFilter, type ShapeMetadata, type SharpenFilter, type SpecularLightingFilter, Spiral, type SpiralNodeProps, Spline, SplineCurveType, type SplineNodeProps, type SplinePoint, SplinePointType, type SpotLightFilter, Square, type SquareNodeProps, Star, type StarNodeProps, type StepPosition, type StepsParams, type StringifyOptions, type StrokeType, type SymbolInstanceNodeProps, type SymbolLibraryDef, type TemplateVariable, type TemplateVariableSource, type TemplateVariableType, Text, type TextNodeProps, Timeline, Track, Triangle, type TriangleNodeProps, type ValidationError, type ValidationResult, type VariableMap, type Viewbox, type WarpFilter, type WarpType, type WatercolorFilter, type XrayFilter, collectReferencedLibraryIds, computeArrowVertices, computeCloudPath, computeCrossVertices, computeDashArray, computeGearPath, computeGearVertices, computeHeartPath, computeLightningVertices, computePolygonVertices, computeRectanglePath, computeRingPath, computeSpeechBubbleVertices, computeSpiralPath, computeSplinePath, computeStarVertices, createDocument, createShape, createViewbox, escXml, extractVariables, filterAttr, generateCode, generateCssCode, generateD3Code, generateId, generatePatternSvgContent, generateReactCode, generateSvgCode, generateVueCode, getBuiltInMarkerDefs, getEasingCubicBezier, getEffectivePrecision, getMarkerDescriptors, getPatternElements, linearGradient, migrateSnapshot, parseDocument, parseVariableArgs, pattern, radialGradient, renderAnimationElements, renderBuiltinMarkerDefs, renderCircle, renderEllipse, renderFilterDefs, renderFilterLibraryDef, renderFilterPrimitivesForType, renderImage, renderLibraryDef, renderLibraryDefs, renderLine, renderLinearGradientLibraryDef, renderMarkerLibraryDef, renderPatternLibraryDef, renderPolygonShape, renderPolyline, renderRadialGradientLibraryDef, renderRectangle, renderReferencedLibraryDefs, renderShape, renderSpline, renderSymbolLibraryDef, renderText, renderToSvg, roundCoord, roundNumberString, roundSerializedShape, roundSnapshot, stringifyDocument, substituteString, substituteVariables, validateSnapshot, verticesToPath };