@pixerate/editor-react 0.76.0 → 0.77.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.
@@ -20,323 +20,336 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/canvas/index.ts
21
21
  var canvas_exports = {};
22
22
  __export(canvas_exports, {
23
- ANIMATABLE_PROPERTIES: () => import_canvas31.ANIMATABLE_PROPERTIES,
24
- ANIMATION_DATA_KEY: () => import_canvas31.ANIMATION_DATA_KEY,
25
- ANIMATION_EASING_LABELS: () => import_canvas31.ANIMATION_EASING_LABELS,
26
- ANIMATION_EASING_PRESETS: () => import_canvas31.ANIMATION_EASING_PRESETS,
27
- ANIMATION_TIME_EPSILON: () => import_canvas31.ANIMATION_TIME_EPSILON,
28
- AUTO_LAYOUT_DATA_KEY: () => import_canvas29.AUTO_LAYOUT_DATA_KEY,
23
+ ANIMATABLE_PROPERTIES: () => import_canvas32.ANIMATABLE_PROPERTIES,
24
+ ANIMATION_DATA_KEY: () => import_canvas32.ANIMATION_DATA_KEY,
25
+ ANIMATION_EASING_LABELS: () => import_canvas32.ANIMATION_EASING_LABELS,
26
+ ANIMATION_EASING_PRESETS: () => import_canvas32.ANIMATION_EASING_PRESETS,
27
+ ANIMATION_TIME_EPSILON: () => import_canvas32.ANIMATION_TIME_EPSILON,
28
+ AUTO_LAYOUT_DATA_KEY: () => import_canvas30.AUTO_LAYOUT_DATA_KEY,
29
29
  AgentPresenceLayer: () => AgentPresenceLayer,
30
- AnimationEditError: () => import_canvas31.AnimationEditError,
31
- AnimationPlayer: () => import_canvas31.AnimationPlayer,
30
+ AnimationEditError: () => import_canvas32.AnimationEditError,
31
+ AnimationPlayer: () => import_canvas32.AnimationPlayer,
32
32
  AnimationTimeline: () => AnimationTimeline,
33
- CANVAS_COMPONENT_DRAG_TYPE: () => import_canvas32.CANVAS_COMPONENT_DRAG_TYPE,
34
- CANVAS_GRADIENT_PRESETS: () => import_canvas32.CANVAS_GRADIENT_PRESETS,
35
- CANVAS_TOKEN_PROPERTIES: () => import_canvas30.CANVAS_TOKEN_PROPERTIES,
36
- CHILD_LAYOUT_DATA_KEY: () => import_canvas29.CHILD_LAYOUT_DATA_KEY,
37
- CONNECTION_LINE_TYPES: () => import_canvas25.CONNECTION_LINE_TYPES,
38
- CSS_ANIMATION_PROPERTIES: () => import_canvas31.CSS_ANIMATION_PROPERTIES,
39
- CUBIC_BEZIER_PRESETS: () => import_canvas31.CUBIC_BEZIER_PRESETS,
33
+ CANVAS_COMPONENT_DRAG_TYPE: () => import_canvas33.CANVAS_COMPONENT_DRAG_TYPE,
34
+ CANVAS_GRADIENT_PRESETS: () => import_canvas33.CANVAS_GRADIENT_PRESETS,
35
+ CANVAS_TOKEN_PROPERTIES: () => import_canvas31.CANVAS_TOKEN_PROPERTIES,
36
+ CHILD_LAYOUT_DATA_KEY: () => import_canvas30.CHILD_LAYOUT_DATA_KEY,
37
+ CONNECTION_LINE_TYPES: () => import_canvas26.CONNECTION_LINE_TYPES,
38
+ CSS_ANIMATION_PROPERTIES: () => import_canvas32.CSS_ANIMATION_PROPERTIES,
39
+ CUBIC_BEZIER_PRESETS: () => import_canvas32.CUBIC_BEZIER_PRESETS,
40
40
  CanvasComponentsPanel: () => CanvasComponentsPanel,
41
41
  CanvasDrawLayer: () => CanvasDrawLayer,
42
42
  CanvasGuidesLayer: () => CanvasGuidesLayer,
43
43
  CanvasInstanceInspector: () => CanvasInstanceInspector,
44
- CanvasScenesStore: () => import_canvas25.CanvasScenesStore,
45
- DEFAULT_ARRANGE_SHORTCUTS: () => import_canvas25.DEFAULT_ARRANGE_SHORTCUTS,
44
+ CanvasScenesStore: () => import_canvas26.CanvasScenesStore,
45
+ DEFAULT_ARRANGE_SHORTCUTS: () => import_canvas26.DEFAULT_ARRANGE_SHORTCUTS,
46
46
  DiagramPresenceLayer: () => DiagramPresenceLayer,
47
- MAX_KEYFRAME_REFS: () => import_canvas31.MAX_KEYFRAME_REFS,
48
- ManualClock: () => import_canvas28.ManualClock,
47
+ MAX_KEYFRAME_REFS: () => import_canvas32.MAX_KEYFRAME_REFS,
48
+ ManualClock: () => import_canvas29.ManualClock,
49
49
  MermaidDiagramGroup: () => MermaidDiagramGroup,
50
50
  MermaidDiagramNode: () => MermaidDiagramNode,
51
51
  MermaidFamilyScene: () => MermaidFamilyScene,
52
52
  MermaidThumbnail: () => MermaidThumbnail,
53
- RESIZE_HANDLES: () => import_canvas24.RESIZE_HANDLES,
54
- SHAPE_DATA_KEY: () => import_canvas26.SHAPE_DATA_KEY,
55
- SHAPE_KINDS: () => import_canvas26.SHAPE_KINDS,
56
- SHAPE_NODE_TYPE: () => import_canvas26.SHAPE_NODE_TYPE,
57
- SHAPE_OPERATIONS: () => import_canvas26.SHAPE_OPERATIONS,
53
+ RESIZE_HANDLES: () => import_canvas25.RESIZE_HANDLES,
54
+ SHAPE_DATA_KEY: () => import_canvas27.SHAPE_DATA_KEY,
55
+ SHAPE_KINDS: () => import_canvas27.SHAPE_KINDS,
56
+ SHAPE_NODE_TYPE: () => import_canvas27.SHAPE_NODE_TYPE,
57
+ SHAPE_OPERATIONS: () => import_canvas27.SHAPE_OPERATIONS,
58
58
  ShapeNode: () => ShapeNode,
59
- TOKEN_BINDINGS_DATA_KEY: () => import_canvas30.TOKEN_BINDINGS_DATA_KEY,
60
- TOKEN_MODES_DATA_KEY: () => import_canvas30.TOKEN_MODES_DATA_KEY,
59
+ ShapeNodeZoomContext: () => ShapeNodeZoomContext,
60
+ ShapeNodeZoomProvider: () => ShapeNodeZoomProvider,
61
+ TOKEN_BINDINGS_DATA_KEY: () => import_canvas31.TOKEN_BINDINGS_DATA_KEY,
62
+ TOKEN_MODES_DATA_KEY: () => import_canvas31.TOKEN_MODES_DATA_KEY,
61
63
  TokenBindingPicker: () => TokenBindingPicker,
62
64
  TokenModeSwitcher: () => TokenModeSwitcher,
63
- addCanvasVariant: () => import_canvas32.addCanvasVariant,
64
- addKeyframesAtTime: () => import_canvas31.addKeyframesAtTime,
65
- alignNodes: () => import_canvas25.alignNodes,
66
- angleToSvgLinearCoords: () => import_canvas32.angleToSvgLinearCoords,
67
- animateNode: () => import_canvas31.animateNode,
68
- applyAnimation: () => import_canvas31.applyAnimation,
69
- applyAnimationOverrides: () => import_canvas31.applyAnimationOverrides,
70
- applyConstraints: () => import_canvas29.applyConstraints,
71
- applyNodeUpdates: () => import_canvas25.applyNodeUpdates,
72
- applyShapeCombination: () => import_canvas26.applyShapeCombination,
73
- applyShapeReplacement: () => import_canvas27.applyShapeReplacement,
74
- bezierPathArea: () => import_canvas27.bezierPathArea,
75
- bezierPathBounds: () => import_canvas27.bezierPathBounds,
76
- bezierPathLength: () => import_canvas27.bezierPathLength,
77
- bezierPathPointAtLength: () => import_canvas27.bezierPathPointAtLength,
78
- bezierPathSignedArea: () => import_canvas27.bezierPathSignedArea,
79
- bezierPathToSvg: () => import_canvas27.bezierPathToSvg,
80
- bindCanvasComponentProperty: () => import_canvas32.bindCanvasComponentProperty,
81
- bindCanvasToken: () => import_canvas30.bindCanvasToken,
82
- blendLayout: () => import_canvas28.blendLayout,
83
- boundsOf: () => import_canvas28.boundsOf,
84
- calculateDagreReflowDisplacement: () => import_canvas28.calculateDagreReflowDisplacement,
85
- calculateDirectionalDisplacement: () => import_canvas28.calculateDirectionalDisplacement,
86
- canCombineShapeNodes: () => import_canvas26.canCombineShapeNodes,
87
- canOffsetShapeNodes: () => import_canvas27.canOffsetShapeNodes,
88
- canOutlineShapeNodeStrokes: () => import_canvas27.canOutlineShapeNodeStrokes,
89
- canvasHeight: () => import_canvas28.canvasHeight,
90
- centerNodes: () => import_canvas28.centerNodes,
91
- centre: () => import_canvas28.centre,
92
- clampAnimationValue: () => import_canvas31.clampAnimationValue,
93
- clampLayoutSize: () => import_canvas29.clampLayoutSize,
94
- combineCanvasComponentsAsVariants: () => import_canvas32.combineCanvasComponentsAsVariants,
95
- combineShapeNodes: () => import_canvas26.combineShapeNodes,
96
- computeNodesBoundingBox: () => import_canvas28.computeNodesBoundingBox,
97
- computeSnapGuides: () => import_canvas25.computeSnapGuides,
98
- connectedOnly: () => import_canvas28.connectedOnly,
99
- copyKeyframes: () => import_canvas31.copyKeyframes,
100
- countPathSegments: () => import_canvas27.countPathSegments,
101
- createAnimationPlayer: () => import_canvas31.createAnimationPlayer,
102
- createBezierTrajectory: () => import_canvas28.createBezierTrajectory,
103
- createCanvasAnimationController: () => import_canvas31.createCanvasAnimationController,
104
- createCanvasAutoLayoutController: () => import_canvas29.createCanvasAutoLayoutController,
105
- createCanvasComponent: () => import_canvas32.createCanvasComponent,
106
- createCanvasComponentsController: () => import_canvas32.createCanvasComponentsController,
107
- createCanvasDrawController: () => import_canvas32.createCanvasDrawController,
108
- createCanvasInstance: () => import_canvas32.createCanvasInstance,
109
- createCanvasScenesStore: () => import_canvas25.createCanvasScenesStore,
110
- createDefaultStrokeStyle: () => import_canvas32.createDefaultStrokeStyle,
111
- createFanOutTrajectory: () => import_canvas28.createFanOutTrajectory,
112
- createGuideIndex: () => import_canvas25.createGuideIndex,
113
- createNodeGuideIndex: () => import_canvas25.createNodeGuideIndex,
114
- cubicBezierAt: () => import_canvas31.cubicBezierAt,
115
- cubicPointAt: () => import_canvas24.cubicPointAt,
116
- cubicsToPathData: () => import_canvas24.cubicsToPathData,
117
- dashContours: () => import_canvas27.dashContours,
118
- defaultEasing: () => import_canvas28.defaultEasing,
119
- deleteKeyframes: () => import_canvas31.deleteKeyframes,
120
- detachCanvasInstance: () => import_canvas32.detachCanvasInstance,
121
- detachTokenBindings: () => import_canvas30.detachTokenBindings,
122
- distanceToBezierPath: () => import_canvas27.distanceToBezierPath,
123
- distributeNodes: () => import_canvas25.distributeNodes,
124
- dividePaths: () => import_canvas27.dividePaths,
125
- dividePolygons: () => import_canvas26.dividePolygons,
126
- easingFromInfluence: () => import_canvas31.easingFromInfluence,
127
- easingLabel: () => import_canvas31.easingLabel,
128
- easingToCss: () => import_canvas31.easingToCss,
129
- ensureLayout: () => import_canvas28.ensureLayout,
130
- estimateCanvasHeight: () => import_canvas28.estimateCanvasHeight,
131
- estimateNodeSize: () => import_canvas28.estimateNodeSize,
132
- evaluateAnimation: () => import_canvas31.evaluateAnimation,
133
- evaluateEasing: () => import_canvas31.evaluateEasing,
134
- evaluateTrack: () => import_canvas31.evaluateTrack,
135
- excludePaths: () => import_canvas27.excludePaths,
136
- exportCssAnimation: () => import_canvas31.exportCssAnimation,
137
- findConnectorSnap: () => import_canvas25.findConnectorSnap,
138
- findStrokesAtPoint: () => import_canvas32.findStrokesAtPoint,
139
- fitCubicRun: () => import_canvas24.fitCubicRun,
140
- fitCubics: () => import_canvas24.fitCubics,
141
- fitFreehandPath: () => import_canvas24.fitFreehandPath,
142
- fitPathData: () => import_canvas24.fitPathData,
143
- fitViewportToNodes: () => import_canvas25.fitViewportToNodes,
144
- fitViewportToRect: () => import_canvas25.fitViewportToRect,
145
- flattenSvgPath: () => import_canvas26.flattenSvgPath,
146
- flowSide: () => import_canvas28.flowSide,
147
- formatAnimationTime: () => import_canvas31.formatAnimationTime,
148
- formatOklab: () => import_canvas31.formatOklab,
149
- getAbsolutePosition: () => import_canvas25.getAbsolutePosition,
150
- getAnimatableProperty: () => import_canvas31.getAnimatableProperty,
151
- getAnimatedProperties: () => import_canvas31.getAnimatedProperties,
152
- getAnimatedValue: () => import_canvas31.getAnimatedValue,
153
- getAnimationDuration: () => import_canvas31.getAnimationDuration,
154
- getAnimationTrack: () => import_canvas31.getAnimationTrack,
155
- getAutoLayout: () => import_canvas29.getAutoLayout,
156
- getAutoLayoutGrid: () => import_canvas29.getAutoLayoutGrid,
157
- getAutoLayoutInsertTarget: () => import_canvas29.getAutoLayoutInsertTarget,
158
- getBindableTokenProperties: () => import_canvas30.getBindableTokenProperties,
159
- getCanvasComponentDragId: () => import_canvas32.getCanvasComponentDragId,
160
- getCanvasTokenProperty: () => import_canvas30.getCanvasTokenProperty,
161
- getCenteredNodePosition: () => import_canvas28.getCenteredNodePosition,
162
- getChildLayout: () => import_canvas29.getChildLayout,
163
- getComponentSourceId: () => import_canvas32.getComponentSourceId,
164
- getCssPropertyAnimations: () => import_canvas31.getCssPropertyAnimations,
165
- getEffectiveTokenModes: () => import_canvas30.getEffectiveTokenModes,
166
- getFlowChildren: () => import_canvas29.getFlowChildren,
167
- getInstanceData: () => import_canvas32.getInstanceData,
168
- getInstanceStatus: () => import_canvas32.getInstanceStatus,
169
- getKeyframeTimes: () => import_canvas31.getKeyframeTimes,
170
- getLayoutParent: () => import_canvas29.getLayoutParent,
171
- getLayoutSizing: () => import_canvas29.getLayoutSizing,
172
- getLayoutedNodes: () => import_canvas28.getLayoutedNodes,
173
- getNextVariantValues: () => import_canvas32.getNextVariantValues,
174
- getNodeAnimation: () => import_canvas31.getNodeAnimation,
175
- getNodeOverrides: () => import_canvas32.getNodeOverrides,
176
- getNodeRect: () => import_canvas25.getNodeRect,
177
- getNodeShape: () => import_canvas26.getNodeShape,
178
- getNodeSize: () => import_canvas25.getNodeSize,
179
- getNodeTokenBindings: () => import_canvas30.getNodeTokenBindings,
180
- getNodeTokenModes: () => import_canvas30.getNodeTokenModes,
181
- getResizingNodeRect: () => import_canvas24.getResizingNodeRect,
182
- getShapeRenderData: () => import_canvas26.getShapeRenderData,
183
- getShapeSvg: () => import_canvas26.getShapeSvg,
184
- getTimelineRows: () => import_canvas31.getTimelineRows,
185
- getTimelineTicks: () => import_canvas31.getTimelineTicks,
186
- getTokenPropertyScope: () => import_canvas30.getTokenPropertyScope,
187
- getTokensForProperty: () => import_canvas30.getTokensForProperty,
188
- gradientToSvgDef: () => import_canvas32.gradientToSvgDef,
189
- handlePoint: () => import_canvas25.handlePoint,
190
- hasVisibleStroke: () => import_canvas27.hasVisibleStroke,
191
- inferResizeHandle: () => import_canvas24.inferResizeHandle,
192
- inspectCanvasInstance: () => import_canvas32.inspectCanvasInstance,
193
- inspectNodeTokens: () => import_canvas30.inspectNodeTokens,
194
- interpolateAnimationValue: () => import_canvas31.interpolateAnimationValue,
195
- intersectPaths: () => import_canvas27.intersectPaths,
196
- intersectPolygons: () => import_canvas26.intersectPolygons,
197
- invertNodeUpdates: () => import_canvas25.invertNodeUpdates,
198
- isAnimationEasing: () => import_canvas31.isAnimationEasing,
199
- isAnimationKeyframe: () => import_canvas31.isAnimationKeyframe,
200
- isAutoLayoutFrame: () => import_canvas29.isAutoLayoutFrame,
201
- isCanvasComponent: () => import_canvas32.isCanvasComponent,
202
- isCanvasComponentSet: () => import_canvas32.isCanvasComponentSet,
203
- isCanvasGradient: () => import_canvas32.isCanvasGradient,
204
- isCanvasInstance: () => import_canvas32.isCanvasInstance,
205
- isCssExportExact: () => import_canvas31.isCssExportExact,
206
- isEventFromTextInput: () => import_canvas28.isEventFromTextInput,
207
- isKeyframeSelected: () => import_canvas31.isKeyframeSelected,
208
- isLocked: () => import_canvas25.isLocked,
209
- isMeasureModifierHeld: () => import_canvas24.isMeasureModifierHeld,
210
- isNodeAnimated: () => import_canvas31.isNodeAnimated,
211
- isShapeDescription: () => import_canvas26.isShapeDescription,
212
- isShapeNode: () => import_canvas26.isShapeNode,
213
- isStraightCubic: () => import_canvas24.isStraightCubic,
214
- isValidCanvasNode: () => import_canvas28.isValidCanvasNode,
215
- isValidUrl: () => import_canvas28.isValidUrl,
216
- layoutAll: () => import_canvas29.layoutAll,
217
- layoutBounds: () => import_canvas28.layoutBounds,
218
- layoutFrame: () => import_canvas29.layoutFrame,
219
- layoutUp: () => import_canvas29.layoutUp,
220
- layoutUpMany: () => import_canvas29.layoutUpMany,
221
- linearPositionTrajectory: () => import_canvas28.linearPositionTrajectory,
222
- linearTrajectory: () => import_canvas28.linearTrajectory,
223
- listCanvasComponents: () => import_canvas32.listCanvasComponents,
224
- lockNodes: () => import_canvas25.lockNodes,
225
- makeSizingCoherent: () => import_canvas29.makeSizingCoherent,
226
- matchArrangeShortcut: () => import_canvas25.matchArrangeShortcut,
227
- matchSize: () => import_canvas25.matchSize,
228
- measureBetween: () => import_canvas24.measureBetween,
229
- measureLabel: () => import_canvas24.measureLabel,
230
- measureSelection: () => import_canvas24.measureSelection,
231
- measureToLine: () => import_canvas24.measureToLine,
232
- mergeNodeUpdates: () => import_canvas29.mergeNodeUpdates,
65
+ addCanvasVariant: () => import_canvas33.addCanvasVariant,
66
+ addKeyframesAtTime: () => import_canvas32.addKeyframesAtTime,
67
+ alignNodes: () => import_canvas26.alignNodes,
68
+ angleToSvgLinearCoords: () => import_canvas33.angleToSvgLinearCoords,
69
+ animateNode: () => import_canvas32.animateNode,
70
+ applyAnimation: () => import_canvas32.applyAnimation,
71
+ applyAnimationOverrides: () => import_canvas32.applyAnimationOverrides,
72
+ applyConstraints: () => import_canvas30.applyConstraints,
73
+ applyNodeUpdates: () => import_canvas26.applyNodeUpdates,
74
+ applyShapeCombination: () => import_canvas27.applyShapeCombination,
75
+ applyShapeReplacement: () => import_canvas28.applyShapeReplacement,
76
+ bezierPathArea: () => import_canvas28.bezierPathArea,
77
+ bezierPathBounds: () => import_canvas28.bezierPathBounds,
78
+ bezierPathLength: () => import_canvas28.bezierPathLength,
79
+ bezierPathPointAtLength: () => import_canvas28.bezierPathPointAtLength,
80
+ bezierPathSignedArea: () => import_canvas28.bezierPathSignedArea,
81
+ bezierPathToSvg: () => import_canvas28.bezierPathToSvg,
82
+ bindCanvasComponentProperty: () => import_canvas33.bindCanvasComponentProperty,
83
+ bindCanvasToken: () => import_canvas31.bindCanvasToken,
84
+ blendLayout: () => import_canvas29.blendLayout,
85
+ boundsOf: () => import_canvas29.boundsOf,
86
+ brushstrokeScaleBucket: () => import_canvas33.brushstrokeScaleBucket,
87
+ calculateDagreReflowDisplacement: () => import_canvas29.calculateDagreReflowDisplacement,
88
+ calculateDirectionalDisplacement: () => import_canvas29.calculateDirectionalDisplacement,
89
+ canCombineShapeNodes: () => import_canvas27.canCombineShapeNodes,
90
+ canOffsetShapeNodes: () => import_canvas28.canOffsetShapeNodes,
91
+ canOutlineShapeNodeStrokes: () => import_canvas28.canOutlineShapeNodeStrokes,
92
+ canvasHeight: () => import_canvas29.canvasHeight,
93
+ centerNodes: () => import_canvas29.centerNodes,
94
+ centre: () => import_canvas29.centre,
95
+ clampAnimationValue: () => import_canvas32.clampAnimationValue,
96
+ clampLayoutSize: () => import_canvas30.clampLayoutSize,
97
+ combineCanvasComponentsAsVariants: () => import_canvas33.combineCanvasComponentsAsVariants,
98
+ combineShapeNodes: () => import_canvas27.combineShapeNodes,
99
+ computeNodesBoundingBox: () => import_canvas29.computeNodesBoundingBox,
100
+ computeSnapGuides: () => import_canvas26.computeSnapGuides,
101
+ connectedOnly: () => import_canvas29.connectedOnly,
102
+ copyKeyframes: () => import_canvas32.copyKeyframes,
103
+ countPathSegments: () => import_canvas28.countPathSegments,
104
+ createAnimationPlayer: () => import_canvas32.createAnimationPlayer,
105
+ createBezierTrajectory: () => import_canvas29.createBezierTrajectory,
106
+ createCanvasAnimationController: () => import_canvas32.createCanvasAnimationController,
107
+ createCanvasAutoLayoutController: () => import_canvas30.createCanvasAutoLayoutController,
108
+ createCanvasComponent: () => import_canvas33.createCanvasComponent,
109
+ createCanvasComponentsController: () => import_canvas33.createCanvasComponentsController,
110
+ createCanvasDrawController: () => import_canvas33.createCanvasDrawController,
111
+ createCanvasInstance: () => import_canvas33.createCanvasInstance,
112
+ createCanvasScenesStore: () => import_canvas26.createCanvasScenesStore,
113
+ createDefaultStrokeStyle: () => import_canvas33.createDefaultStrokeStyle,
114
+ createFanOutTrajectory: () => import_canvas29.createFanOutTrajectory,
115
+ createGuideIndex: () => import_canvas26.createGuideIndex,
116
+ createNodeGuideIndex: () => import_canvas26.createNodeGuideIndex,
117
+ cubicBezierAt: () => import_canvas32.cubicBezierAt,
118
+ cubicPointAt: () => import_canvas25.cubicPointAt,
119
+ cubicsToPathData: () => import_canvas25.cubicsToPathData,
120
+ dashContours: () => import_canvas28.dashContours,
121
+ defaultEasing: () => import_canvas29.defaultEasing,
122
+ deleteKeyframes: () => import_canvas32.deleteKeyframes,
123
+ detachCanvasInstance: () => import_canvas33.detachCanvasInstance,
124
+ detachTokenBindings: () => import_canvas31.detachTokenBindings,
125
+ distanceToBezierPath: () => import_canvas28.distanceToBezierPath,
126
+ distributeNodes: () => import_canvas26.distributeNodes,
127
+ dividePaths: () => import_canvas28.dividePaths,
128
+ dividePolygons: () => import_canvas27.dividePolygons,
129
+ easingFromInfluence: () => import_canvas32.easingFromInfluence,
130
+ easingLabel: () => import_canvas32.easingLabel,
131
+ easingToCss: () => import_canvas32.easingToCss,
132
+ ensureLayout: () => import_canvas29.ensureLayout,
133
+ estimateCanvasHeight: () => import_canvas29.estimateCanvasHeight,
134
+ estimateNodeSize: () => import_canvas29.estimateNodeSize,
135
+ evaluateAnimation: () => import_canvas32.evaluateAnimation,
136
+ evaluateEasing: () => import_canvas32.evaluateEasing,
137
+ evaluateTrack: () => import_canvas32.evaluateTrack,
138
+ excludePaths: () => import_canvas28.excludePaths,
139
+ exportCssAnimation: () => import_canvas32.exportCssAnimation,
140
+ findConnectorSnap: () => import_canvas26.findConnectorSnap,
141
+ findStrokesAtPoint: () => import_canvas33.findStrokesAtPoint,
142
+ fitCubicRun: () => import_canvas25.fitCubicRun,
143
+ fitCubics: () => import_canvas25.fitCubics,
144
+ fitFreehandPath: () => import_canvas25.fitFreehandPath,
145
+ fitPathData: () => import_canvas25.fitPathData,
146
+ fitViewportToNodes: () => import_canvas26.fitViewportToNodes,
147
+ fitViewportToRect: () => import_canvas26.fitViewportToRect,
148
+ flattenSvgPath: () => import_canvas27.flattenSvgPath,
149
+ flowSide: () => import_canvas29.flowSide,
150
+ formatAnimationTime: () => import_canvas32.formatAnimationTime,
151
+ formatOklab: () => import_canvas32.formatOklab,
152
+ freehandBrushstroke: () => import_canvas33.freehandBrushstroke,
153
+ getAbsolutePosition: () => import_canvas26.getAbsolutePosition,
154
+ getAnimatableProperty: () => import_canvas32.getAnimatableProperty,
155
+ getAnimatedProperties: () => import_canvas32.getAnimatedProperties,
156
+ getAnimatedValue: () => import_canvas32.getAnimatedValue,
157
+ getAnimationDuration: () => import_canvas32.getAnimationDuration,
158
+ getAnimationTrack: () => import_canvas32.getAnimationTrack,
159
+ getAutoLayout: () => import_canvas30.getAutoLayout,
160
+ getAutoLayoutGrid: () => import_canvas30.getAutoLayoutGrid,
161
+ getAutoLayoutInsertTarget: () => import_canvas30.getAutoLayoutInsertTarget,
162
+ getBindableTokenProperties: () => import_canvas31.getBindableTokenProperties,
163
+ getBrushedShapeSvg: () => import_canvas33.getBrushedShapeSvg,
164
+ getCanvasComponentDragId: () => import_canvas33.getCanvasComponentDragId,
165
+ getCanvasTokenProperty: () => import_canvas31.getCanvasTokenProperty,
166
+ getCenteredNodePosition: () => import_canvas29.getCenteredNodePosition,
167
+ getChildLayout: () => import_canvas30.getChildLayout,
168
+ getComponentSourceId: () => import_canvas33.getComponentSourceId,
169
+ getCssPropertyAnimations: () => import_canvas32.getCssPropertyAnimations,
170
+ getEffectiveTokenModes: () => import_canvas31.getEffectiveTokenModes,
171
+ getFlowChildren: () => import_canvas30.getFlowChildren,
172
+ getInstanceData: () => import_canvas33.getInstanceData,
173
+ getInstanceStatus: () => import_canvas33.getInstanceStatus,
174
+ getKeyframeTimes: () => import_canvas32.getKeyframeTimes,
175
+ getLayoutParent: () => import_canvas30.getLayoutParent,
176
+ getLayoutSizing: () => import_canvas30.getLayoutSizing,
177
+ getLayoutedNodes: () => import_canvas29.getLayoutedNodes,
178
+ getNextVariantValues: () => import_canvas33.getNextVariantValues,
179
+ getNodeAnimation: () => import_canvas32.getNodeAnimation,
180
+ getNodeOverrides: () => import_canvas33.getNodeOverrides,
181
+ getNodeRect: () => import_canvas26.getNodeRect,
182
+ getNodeShape: () => import_canvas27.getNodeShape,
183
+ getNodeSize: () => import_canvas26.getNodeSize,
184
+ getNodeTokenBindings: () => import_canvas31.getNodeTokenBindings,
185
+ getNodeTokenModes: () => import_canvas31.getNodeTokenModes,
186
+ getResizingNodeRect: () => import_canvas25.getResizingNodeRect,
187
+ getShapeRenderData: () => import_canvas27.getShapeRenderData,
188
+ getShapeSvg: () => import_canvas27.getShapeSvg,
189
+ getTimelineRows: () => import_canvas32.getTimelineRows,
190
+ getTimelineTicks: () => import_canvas32.getTimelineTicks,
191
+ getTokenPropertyScope: () => import_canvas31.getTokenPropertyScope,
192
+ getTokensForProperty: () => import_canvas31.getTokensForProperty,
193
+ gradientToSvgDef: () => import_canvas33.gradientToSvgDef,
194
+ handlePoint: () => import_canvas26.handlePoint,
195
+ hasVisibleStroke: () => import_canvas28.hasVisibleStroke,
196
+ inferResizeHandle: () => import_canvas25.inferResizeHandle,
197
+ inspectCanvasInstance: () => import_canvas33.inspectCanvasInstance,
198
+ inspectNodeTokens: () => import_canvas31.inspectNodeTokens,
199
+ interpolateAnimationValue: () => import_canvas32.interpolateAnimationValue,
200
+ intersectPaths: () => import_canvas28.intersectPaths,
201
+ intersectPolygons: () => import_canvas27.intersectPolygons,
202
+ invertNodeUpdates: () => import_canvas26.invertNodeUpdates,
203
+ isAnimationEasing: () => import_canvas32.isAnimationEasing,
204
+ isAnimationKeyframe: () => import_canvas32.isAnimationKeyframe,
205
+ isAutoLayoutFrame: () => import_canvas30.isAutoLayoutFrame,
206
+ isBrushedShape: () => import_canvas33.isBrushedShape,
207
+ isCanvasComponent: () => import_canvas33.isCanvasComponent,
208
+ isCanvasComponentSet: () => import_canvas33.isCanvasComponentSet,
209
+ isCanvasGradient: () => import_canvas33.isCanvasGradient,
210
+ isCanvasInstance: () => import_canvas33.isCanvasInstance,
211
+ isCssExportExact: () => import_canvas32.isCssExportExact,
212
+ isEventFromTextInput: () => import_canvas29.isEventFromTextInput,
213
+ isKeyframeSelected: () => import_canvas32.isKeyframeSelected,
214
+ isLocked: () => import_canvas26.isLocked,
215
+ isMeasureModifierHeld: () => import_canvas25.isMeasureModifierHeld,
216
+ isNodeAnimated: () => import_canvas32.isNodeAnimated,
217
+ isShapeDescription: () => import_canvas27.isShapeDescription,
218
+ isShapeNode: () => import_canvas27.isShapeNode,
219
+ isStraightCubic: () => import_canvas25.isStraightCubic,
220
+ isValidCanvasNode: () => import_canvas29.isValidCanvasNode,
221
+ isValidUrl: () => import_canvas29.isValidUrl,
222
+ layoutAll: () => import_canvas30.layoutAll,
223
+ layoutBounds: () => import_canvas29.layoutBounds,
224
+ layoutFrame: () => import_canvas30.layoutFrame,
225
+ layoutUp: () => import_canvas30.layoutUp,
226
+ layoutUpMany: () => import_canvas30.layoutUpMany,
227
+ linearPositionTrajectory: () => import_canvas29.linearPositionTrajectory,
228
+ linearTrajectory: () => import_canvas29.linearTrajectory,
229
+ listCanvasBrushes: () => import_canvas33.listCanvasBrushes,
230
+ listCanvasComponents: () => import_canvas33.listCanvasComponents,
231
+ loadCanvasBrushstrokeRenderer: () => import_canvas33.loadCanvasBrushstrokeRenderer,
232
+ lockNodes: () => import_canvas26.lockNodes,
233
+ makeSizingCoherent: () => import_canvas30.makeSizingCoherent,
234
+ matchArrangeShortcut: () => import_canvas26.matchArrangeShortcut,
235
+ matchSize: () => import_canvas26.matchSize,
236
+ measureBetween: () => import_canvas25.measureBetween,
237
+ measureLabel: () => import_canvas25.measureLabel,
238
+ measureSelection: () => import_canvas25.measureSelection,
239
+ measureToLine: () => import_canvas25.measureToLine,
240
+ mergeNodeUpdates: () => import_canvas30.mergeNodeUpdates,
233
241
  mermaidNodeStyle: () => mermaidNodeStyle,
234
- mixColorsOklab: () => import_canvas31.mixColorsOklab,
235
- moveKeyframes: () => import_canvas31.moveKeyframes,
236
- moveLayoutChild: () => import_canvas29.moveLayoutChild,
237
- multiPolygonArea: () => import_canvas26.multiPolygonArea,
238
- multiPolygonBounds: () => import_canvas26.multiPolygonBounds,
239
- nearestHandlePositions: () => import_canvas25.nearestHandlePositions,
240
- normalizeBezierPath: () => import_canvas27.normalizeBezierPath,
241
- normalizeKeyframes: () => import_canvas31.normalizeKeyframes,
242
- offsetPath: () => import_canvas27.offsetPath,
243
- offsetShapeNodes: () => import_canvas27.offsetShapeNodes,
244
- oklabToRgb: () => import_canvas31.oklabToRgb,
245
- oppositePosition: () => import_canvas25.oppositePosition,
246
- outlineShapeNodeStrokes: () => import_canvas27.outlineShapeNodeStrokes,
247
- outlineStroke: () => import_canvas27.outlineStroke,
248
- overlaps: () => import_canvas28.overlaps,
249
- parseCanvasClipboardData: () => import_canvas28.parseCanvasClipboardData,
250
- parseCanvasScenes: () => import_canvas25.parseCanvasScenes,
251
- parseCssEasing: () => import_canvas31.parseCssEasing,
252
- parseCssGradient: () => import_canvas32.parseCssGradient,
253
- parseKeyframeClipboard: () => import_canvas31.parseKeyframeClipboard,
254
- parseOklab: () => import_canvas31.parseOklab,
255
- parseSvgPath: () => import_canvas26.parseSvgPath,
256
- pasteKeyframes: () => import_canvas31.pasteKeyframes,
257
- pathBoolean: () => import_canvas27.pathBoolean,
258
- placeBeside: () => import_canvas28.placeBeside,
259
- playWebAnimations: () => import_canvas31.playWebAnimations,
260
- pointInBezierPath: () => import_canvas27.pointInBezierPath,
261
- pointInMultiPolygon: () => import_canvas26.pointInMultiPolygon,
262
- pointInRings: () => import_canvas26.pointInRings,
263
- polygonArea: () => import_canvas26.polygonArea,
264
- polygonBoolean: () => import_canvas26.polygonBoolean,
265
- polygonToSvgPath: () => import_canvas26.polygonToSvgPath,
266
- positionToSide: () => import_canvas25.positionToSide,
267
- pruneCanvasTokenModes: () => import_canvas30.pruneCanvasTokenModes,
268
- pushCanvasInstanceOverrides: () => import_canvas32.pushCanvasInstanceOverrides,
269
- readAnimatableValue: () => import_canvas31.readAnimatableValue,
270
- readNodeStyleProperty: () => import_canvas30.readNodeStyleProperty,
271
- readStyleSize: () => import_canvas25.readStyleSize,
272
- realClock: () => import_canvas28.realClock,
273
- recordAnimationChanges: () => import_canvas31.recordAnimationChanges,
274
- relayoutUpdates: () => import_canvas29.relayoutUpdates,
275
- remapPastedNodes: () => import_canvas28.remapPastedNodes,
276
- removeCanvasVariant: () => import_canvas32.removeCanvasVariant,
277
- removeTrack: () => import_canvas31.removeTrack,
278
- renameCanvasVariantProperty: () => import_canvas32.renameCanvasVariantProperty,
279
- renameCanvasVariantValue: () => import_canvas32.renameCanvasVariantValue,
280
- reorderNodes: () => import_canvas25.reorderNodes,
281
- repositionNodesTo: () => import_canvas28.repositionNodesTo,
282
- resetCanvasInstanceOverrides: () => import_canvas32.resetCanvasInstanceOverrides,
283
- resizeHandleAxes: () => import_canvas24.resizeHandleAxes,
284
- resolveCanvasGradient: () => import_canvas32.resolveCanvasGradient,
285
- resolveCanvasTokens: () => import_canvas30.resolveCanvasTokens,
286
- resolveEasing: () => import_canvas31.resolveEasing,
287
- resolvePadding: () => import_canvas29.resolvePadding,
288
- restoreCanvasMainComponent: () => import_canvas32.restoreCanvasMainComponent,
289
- revertShapeCombination: () => import_canvas26.revertShapeCombination,
290
- rgbToOklab: () => import_canvas31.rgbToOklab,
291
- ringSignedArea: () => import_canvas26.ringSignedArea,
292
- runMultiNodeTransition: () => import_canvas28.runMultiNodeTransition,
293
- sampleAnimationFrames: () => import_canvas31.sampleAnimationFrames,
294
- scaleKeyframes: () => import_canvas31.scaleKeyframes,
295
- serializeCanvasNodes: () => import_canvas28.serializeCanvasNodes,
296
- setCanvasComponentProperty: () => import_canvas32.setCanvasComponentProperty,
297
- setCanvasInstanceProperties: () => import_canvas32.setCanvasInstanceProperties,
298
- setCanvasTokenMode: () => import_canvas30.setCanvasTokenMode,
299
- setCanvasVariantProperties: () => import_canvas32.setCanvasVariantProperties,
300
- setKeyframe: () => import_canvas31.setKeyframe,
301
- setKeyframeEasing: () => import_canvas31.setKeyframeEasing,
302
- setMotionPath: () => import_canvas31.setMotionPath,
303
- setTrackEnabled: () => import_canvas31.setTrackEnabled,
304
- shapeNodeToBezierPath: () => import_canvas27.shapeNodeToBezierPath,
305
- shapeNodeToPolygon: () => import_canvas26.shapeNodeToPolygon,
306
- shapeToBezierPath: () => import_canvas27.shapeToBezierPath,
307
- shapeToPolygon: () => import_canvas26.shapeToPolygon,
308
- sideToPosition: () => import_canvas25.sideToPosition,
309
- simplifyRing: () => import_canvas26.simplifyRing,
310
- snapKeyframeDelta: () => import_canvas31.snapKeyframeDelta,
311
- snapNodeDrag: () => import_canvas25.snapNodeDrag,
312
- snapNodeResize: () => import_canvas24.snapNodeResize,
313
- snapResize: () => import_canvas24.snapResize,
314
- snapTimeToFrame: () => import_canvas31.snapTimeToFrame,
315
- snapToGrid: () => import_canvas24.snapToGrid,
316
- springAt: () => import_canvas31.springAt,
317
- streamlinePoints: () => import_canvas32.streamlinePoints,
318
- strokeOutlineRings: () => import_canvas27.strokeOutlineRings,
319
- strokePointsToPathData: () => import_canvas32.strokePointsToPathData,
320
- strokeToShapeNode: () => import_canvas32.strokeToShapeNode,
321
- subtractPaths: () => import_canvas27.subtractPaths,
322
- subtractPolygons: () => import_canvas26.subtractPolygons,
323
- swapCanvasInstance: () => import_canvas32.swapCanvasInstance,
324
- syncAllCanvasInstances: () => import_canvas32.syncAllCanvasInstances,
325
- syncCanvasComponents: () => import_canvas32.syncCanvasComponents,
326
- syncCanvasInstance: () => import_canvas32.syncCanvasInstance,
327
- timeToX: () => import_canvas31.timeToX,
328
- toBezierPath: () => import_canvas27.toBezierPath,
329
- toWebAnimations: () => import_canvas31.toWebAnimations,
330
- toggleLockNodes: () => import_canvas25.toggleLockNodes,
331
- transformBezierPath: () => import_canvas27.transformBezierPath,
332
- unionPolygons: () => import_canvas26.unionPolygons,
333
- unitePaths: () => import_canvas27.unitePaths,
334
- unlockNodes: () => import_canvas25.unlockNodes,
335
- updateKeyframe: () => import_canvas31.updateKeyframe,
242
+ mixColorsOklab: () => import_canvas32.mixColorsOklab,
243
+ moveKeyframes: () => import_canvas32.moveKeyframes,
244
+ moveLayoutChild: () => import_canvas30.moveLayoutChild,
245
+ multiPolygonArea: () => import_canvas27.multiPolygonArea,
246
+ multiPolygonBounds: () => import_canvas27.multiPolygonBounds,
247
+ nearestHandlePositions: () => import_canvas26.nearestHandlePositions,
248
+ normalizeBezierPath: () => import_canvas28.normalizeBezierPath,
249
+ normalizeKeyframes: () => import_canvas32.normalizeKeyframes,
250
+ offsetPath: () => import_canvas28.offsetPath,
251
+ offsetShapeNodes: () => import_canvas28.offsetShapeNodes,
252
+ oklabToRgb: () => import_canvas32.oklabToRgb,
253
+ oppositePosition: () => import_canvas26.oppositePosition,
254
+ outlineShapeNodeStrokes: () => import_canvas28.outlineShapeNodeStrokes,
255
+ outlineStroke: () => import_canvas28.outlineStroke,
256
+ overlaps: () => import_canvas29.overlaps,
257
+ parseCanvasClipboardData: () => import_canvas29.parseCanvasClipboardData,
258
+ parseCanvasScenes: () => import_canvas26.parseCanvasScenes,
259
+ parseCssEasing: () => import_canvas32.parseCssEasing,
260
+ parseCssGradient: () => import_canvas33.parseCssGradient,
261
+ parseKeyframeClipboard: () => import_canvas32.parseKeyframeClipboard,
262
+ parseOklab: () => import_canvas32.parseOklab,
263
+ parseSvgPath: () => import_canvas27.parseSvgPath,
264
+ pasteKeyframes: () => import_canvas32.pasteKeyframes,
265
+ pathBoolean: () => import_canvas28.pathBoolean,
266
+ pathDataToPolyline: () => import_canvas33.pathDataToPolyline,
267
+ placeBeside: () => import_canvas29.placeBeside,
268
+ playWebAnimations: () => import_canvas32.playWebAnimations,
269
+ pointInBezierPath: () => import_canvas28.pointInBezierPath,
270
+ pointInMultiPolygon: () => import_canvas27.pointInMultiPolygon,
271
+ pointInRings: () => import_canvas27.pointInRings,
272
+ pointerPenSample: () => import_canvas33.pointerPenSample,
273
+ polygonArea: () => import_canvas27.polygonArea,
274
+ polygonBoolean: () => import_canvas27.polygonBoolean,
275
+ polygonToSvgPath: () => import_canvas27.polygonToSvgPath,
276
+ positionToSide: () => import_canvas26.positionToSide,
277
+ profileAlongPolyline: () => import_canvas33.profileAlongPolyline,
278
+ pruneCanvasTokenModes: () => import_canvas31.pruneCanvasTokenModes,
279
+ pushCanvasInstanceOverrides: () => import_canvas33.pushCanvasInstanceOverrides,
280
+ readAnimatableValue: () => import_canvas32.readAnimatableValue,
281
+ readNodeStyleProperty: () => import_canvas31.readNodeStyleProperty,
282
+ readStyleSize: () => import_canvas26.readStyleSize,
283
+ realClock: () => import_canvas29.realClock,
284
+ recordAnimationChanges: () => import_canvas32.recordAnimationChanges,
285
+ relayoutUpdates: () => import_canvas30.relayoutUpdates,
286
+ remapPastedNodes: () => import_canvas29.remapPastedNodes,
287
+ removeCanvasVariant: () => import_canvas33.removeCanvasVariant,
288
+ removeTrack: () => import_canvas32.removeTrack,
289
+ renameCanvasVariantProperty: () => import_canvas33.renameCanvasVariantProperty,
290
+ renameCanvasVariantValue: () => import_canvas33.renameCanvasVariantValue,
291
+ renderShapeBrushstroke: () => import_canvas33.renderShapeBrushstroke,
292
+ reorderNodes: () => import_canvas26.reorderNodes,
293
+ repositionNodesTo: () => import_canvas29.repositionNodesTo,
294
+ resetCanvasInstanceOverrides: () => import_canvas33.resetCanvasInstanceOverrides,
295
+ resizeHandleAxes: () => import_canvas25.resizeHandleAxes,
296
+ resolveCanvasGradient: () => import_canvas33.resolveCanvasGradient,
297
+ resolveCanvasTokens: () => import_canvas31.resolveCanvasTokens,
298
+ resolveEasing: () => import_canvas32.resolveEasing,
299
+ resolvePadding: () => import_canvas30.resolvePadding,
300
+ restoreCanvasMainComponent: () => import_canvas33.restoreCanvasMainComponent,
301
+ revertShapeCombination: () => import_canvas27.revertShapeCombination,
302
+ rgbToOklab: () => import_canvas32.rgbToOklab,
303
+ ringSignedArea: () => import_canvas27.ringSignedArea,
304
+ runMultiNodeTransition: () => import_canvas29.runMultiNodeTransition,
305
+ sampleAnimationFrames: () => import_canvas32.sampleAnimationFrames,
306
+ scaleKeyframes: () => import_canvas32.scaleKeyframes,
307
+ serializeCanvasNodes: () => import_canvas29.serializeCanvasNodes,
308
+ setCanvasComponentProperty: () => import_canvas33.setCanvasComponentProperty,
309
+ setCanvasInstanceProperties: () => import_canvas33.setCanvasInstanceProperties,
310
+ setCanvasTokenMode: () => import_canvas31.setCanvasTokenMode,
311
+ setCanvasVariantProperties: () => import_canvas33.setCanvasVariantProperties,
312
+ setKeyframe: () => import_canvas32.setKeyframe,
313
+ setKeyframeEasing: () => import_canvas32.setKeyframeEasing,
314
+ setMotionPath: () => import_canvas32.setMotionPath,
315
+ setTrackEnabled: () => import_canvas32.setTrackEnabled,
316
+ shapeNodeToBezierPath: () => import_canvas28.shapeNodeToBezierPath,
317
+ shapeNodeToPolygon: () => import_canvas27.shapeNodeToPolygon,
318
+ shapeToBezierPath: () => import_canvas28.shapeToBezierPath,
319
+ shapeToPolygon: () => import_canvas27.shapeToPolygon,
320
+ sideToPosition: () => import_canvas26.sideToPosition,
321
+ simplifyRing: () => import_canvas27.simplifyRing,
322
+ snapKeyframeDelta: () => import_canvas32.snapKeyframeDelta,
323
+ snapNodeDrag: () => import_canvas26.snapNodeDrag,
324
+ snapNodeResize: () => import_canvas25.snapNodeResize,
325
+ snapResize: () => import_canvas25.snapResize,
326
+ snapTimeToFrame: () => import_canvas32.snapTimeToFrame,
327
+ snapToGrid: () => import_canvas25.snapToGrid,
328
+ springAt: () => import_canvas32.springAt,
329
+ streamlinePoints: () => import_canvas33.streamlinePoints,
330
+ strokeOutlineRings: () => import_canvas28.strokeOutlineRings,
331
+ strokePointsToPathData: () => import_canvas33.strokePointsToPathData,
332
+ strokeToShapeNode: () => import_canvas33.strokeToShapeNode,
333
+ subtractPaths: () => import_canvas28.subtractPaths,
334
+ subtractPolygons: () => import_canvas27.subtractPolygons,
335
+ swapCanvasInstance: () => import_canvas33.swapCanvasInstance,
336
+ syncAllCanvasInstances: () => import_canvas33.syncAllCanvasInstances,
337
+ syncCanvasComponents: () => import_canvas33.syncCanvasComponents,
338
+ syncCanvasInstance: () => import_canvas33.syncCanvasInstance,
339
+ timeToX: () => import_canvas32.timeToX,
340
+ toBezierPath: () => import_canvas28.toBezierPath,
341
+ toWebAnimations: () => import_canvas32.toWebAnimations,
342
+ toggleLockNodes: () => import_canvas26.toggleLockNodes,
343
+ transformBezierPath: () => import_canvas28.transformBezierPath,
344
+ unionPolygons: () => import_canvas27.unionPolygons,
345
+ unitePaths: () => import_canvas28.unitePaths,
346
+ unlockNodes: () => import_canvas26.unlockNodes,
347
+ updateKeyframe: () => import_canvas32.updateKeyframe,
336
348
  useCanvasAnimation: () => useCanvasAnimation,
337
349
  useCanvasArrange: () => useCanvasArrange,
338
350
  useCanvasArrangeShortcuts: () => useCanvasArrangeShortcuts,
339
351
  useCanvasAutoLayout: () => useCanvasAutoLayout,
352
+ useCanvasBrushes: () => useCanvasBrushes,
340
353
  useCanvasCapture: () => useCanvasCapture,
341
354
  useCanvasClipboard: () => useCanvasClipboard,
342
355
  useCanvasComponents: () => useCanvasComponents,
@@ -354,14 +367,16 @@ __export(canvas_exports, {
354
367
  useMermaidDiagram: () => useMermaidDiagram,
355
368
  useMermaidStream: () => useMermaidStream,
356
369
  usePresenceState: () => usePresenceState,
370
+ useShapeBrushstroke: () => useShapeBrushstroke,
357
371
  useStreamingCanvas: () => useStreamingCanvas,
358
- withNodeAnimation: () => import_canvas31.withNodeAnimation,
359
- withStyleSize: () => import_canvas25.withStyleSize,
360
- wouldCreateComponentCycle: () => import_canvas32.wouldCreateComponentCycle,
361
- wrapAnimationTime: () => import_canvas31.wrapAnimationTime,
362
- writeNodeStyleProperty: () => import_canvas30.writeNodeStyleProperty,
363
- xToTime: () => import_canvas31.xToTime,
364
- xorPolygons: () => import_canvas26.xorPolygons
372
+ validateCanvasBrush: () => import_canvas33.validateCanvasBrush,
373
+ withNodeAnimation: () => import_canvas32.withNodeAnimation,
374
+ withStyleSize: () => import_canvas26.withStyleSize,
375
+ wouldCreateComponentCycle: () => import_canvas33.wouldCreateComponentCycle,
376
+ wrapAnimationTime: () => import_canvas32.wrapAnimationTime,
377
+ writeNodeStyleProperty: () => import_canvas31.writeNodeStyleProperty,
378
+ xToTime: () => import_canvas32.xToTime,
379
+ xorPolygons: () => import_canvas27.xorPolygons
365
380
  });
366
381
  module.exports = __toCommonJS(canvas_exports);
367
382
 
@@ -1393,7 +1408,9 @@ function useCanvasDraw(options) {
1393
1408
  continueStroke: controller.continueStroke,
1394
1409
  endStroke: controller.endStroke,
1395
1410
  cancelStroke: controller.cancelStroke,
1396
- eraseAt: controller.eraseAt
1411
+ eraseAt: controller.eraseAt,
1412
+ drawStroke: controller.drawStroke,
1413
+ listBrushes: controller.listBrushes
1397
1414
  }),
1398
1415
  [tool, style, activeStroke, controller]
1399
1416
  );
@@ -1457,7 +1474,7 @@ function CanvasDrawLayer({
1457
1474
  e.stopPropagation();
1458
1475
  e.target.setPointerCapture?.(e.pointerId);
1459
1476
  const flowPt = clientToFlow(e.clientX, e.clientY);
1460
- draw.startStroke(flowPt);
1477
+ draw.startStroke(flowPt, (0, import_canvas10.pointerPenSample)(e));
1461
1478
  if (draw.tool === "eraser") {
1462
1479
  setEraserPos([e.clientX, e.clientY]);
1463
1480
  }
@@ -1470,8 +1487,10 @@ function CanvasDrawLayer({
1470
1487
  if (e.buttons === 1) {
1471
1488
  e.preventDefault();
1472
1489
  e.stopPropagation();
1473
- const flowPt = clientToFlow(e.clientX, e.clientY);
1474
- draw.continueStroke(flowPt);
1490
+ const events = draw.style.brush !== void 0 ? e.nativeEvent.getCoalescedEvents?.() ?? [] : [];
1491
+ for (const ev of events.length ? events : [e.nativeEvent]) {
1492
+ draw.continueStroke(clientToFlow(ev.clientX, ev.clientY), (0, import_canvas10.pointerPenSample)(ev));
1493
+ }
1475
1494
  }
1476
1495
  };
1477
1496
  const handlePointerUp = (e) => {
@@ -1605,17 +1624,72 @@ function useCanvasMeasure(options) {
1605
1624
  }
1606
1625
 
1607
1626
  // src/canvas/index.ts
1608
- var import_canvas24 = require("@pixerate/editor/canvas");
1609
1627
  var import_canvas25 = require("@pixerate/editor/canvas");
1628
+ var import_canvas26 = require("@pixerate/editor/canvas");
1610
1629
 
1611
1630
  // src/canvas/ShapeNode.tsx
1631
+ var import_canvas13 = require("@pixerate/editor/canvas");
1632
+
1633
+ // src/canvas/useShapeBrushstroke.tsx
1634
+ var import_react14 = require("react");
1612
1635
  var import_canvas12 = require("@pixerate/editor/canvas");
1613
1636
  var import_jsx_runtime4 = require("react/jsx-runtime");
1637
+ var ShapeNodeZoomContext = (0, import_react14.createContext)(1);
1638
+ function ShapeNodeZoomProvider({ zoom, children }) {
1639
+ const bucket = (0, import_canvas12.brushstrokeScaleBucket)(zoom);
1640
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ShapeNodeZoomContext.Provider, { value: bucket, children });
1641
+ }
1642
+ function useShapeBrushstroke(shape, width, height) {
1643
+ const zoom = (0, import_react14.useContext)(ShapeNodeZoomContext);
1644
+ const brushed = (0, import_canvas12.isBrushedShape)(shape) ? shape : null;
1645
+ const vb = brushed?.viewBox;
1646
+ const nodeScale = vb && width && height && vb[2] > 0 && vb[3] > 0 ? Math.max(width / vb[2], height / vb[3]) : 1;
1647
+ const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
1648
+ const scale = (0, import_canvas12.brushstrokeScaleBucket)(zoom * nodeScale, dpr);
1649
+ const [image, setImage] = (0, import_react14.useState)(null);
1650
+ (0, import_react14.useEffect)(() => {
1651
+ if (!brushed) {
1652
+ setImage(null);
1653
+ return;
1654
+ }
1655
+ let live = true;
1656
+ (0, import_canvas12.renderShapeBrushstroke)(brushed, { scale }).then(
1657
+ (img) => live && setImage(img),
1658
+ (error) => {
1659
+ if (!live) return;
1660
+ setImage(null);
1661
+ console.warn("[pixerate] brushed stroke not rendered:", error instanceof Error ? error.message : error);
1662
+ }
1663
+ );
1664
+ return () => {
1665
+ live = false;
1666
+ };
1667
+ }, [brushed, scale]);
1668
+ return image;
1669
+ }
1670
+ function useCanvasBrushes() {
1671
+ const [state, setState] = (0, import_react14.useState)({ brushes: [], loading: true, error: null });
1672
+ (0, import_react14.useEffect)(() => {
1673
+ let live = true;
1674
+ (0, import_canvas12.listCanvasBrushes)().then(
1675
+ (brushes) => live && setState({ brushes, loading: false, error: null }),
1676
+ (error) => live && setState({ brushes: [], loading: false, error: error instanceof Error ? error.message : String(error) })
1677
+ );
1678
+ return () => {
1679
+ live = false;
1680
+ };
1681
+ }, []);
1682
+ return (0, import_react14.useMemo)(() => state, [state]);
1683
+ }
1684
+
1685
+ // src/canvas/ShapeNode.tsx
1686
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1614
1687
  function ShapeNode({ id, data, width, height, selected, className = "", children }) {
1615
1688
  const shape = data?.shape;
1616
- if (!(0, import_canvas12.isShapeDescription)(shape)) return null;
1617
- const render = (0, import_canvas12.getShapeRenderData)(shape, { width, height }, { id: id || data?.id });
1618
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1689
+ const brushImage = useShapeBrushstroke((0, import_canvas13.isShapeDescription)(shape) ? shape : null, width, height);
1690
+ if (!(0, import_canvas13.isShapeDescription)(shape)) return null;
1691
+ const render = (0, import_canvas13.getShapeRenderData)(shape, { width, height }, { id: id || data?.id });
1692
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1619
1693
  "div",
1620
1694
  {
1621
1695
  className: `pixerate-shape-node ${className}`.trim(),
@@ -1623,7 +1697,7 @@ function ShapeNode({ id, data, width, height, selected, className = "", children
1623
1697
  "data-selected": selected ? "true" : void 0,
1624
1698
  style: { position: "relative", width: "100%", height: "100%" },
1625
1699
  children: [
1626
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1700
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1627
1701
  "svg",
1628
1702
  {
1629
1703
  viewBox: render.viewBox,
@@ -1633,13 +1707,25 @@ function ShapeNode({ id, data, width, height, selected, className = "", children
1633
1707
  style: { display: "block", overflow: "visible" },
1634
1708
  "aria-hidden": "true",
1635
1709
  children: [
1636
- (render.fillGradient || render.strokeGradient) && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("defs", { children: [
1637
- render.fillGradient && render.fillGradient.type === "linear" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("linearGradient", { id: render.fillGradient.id, ...render.fillGradient.attrs, children: render.fillGradient.stops.map((stop, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) }),
1638
- render.fillGradient && render.fillGradient.type === "radial" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("radialGradient", { id: render.fillGradient.id, ...render.fillGradient.attrs, children: render.fillGradient.stops.map((stop, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) }),
1639
- render.strokeGradient && render.strokeGradient.type === "linear" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("linearGradient", { id: render.strokeGradient.id, ...render.strokeGradient.attrs, children: render.strokeGradient.stops.map((stop, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) }),
1640
- render.strokeGradient && render.strokeGradient.type === "radial" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("radialGradient", { id: render.strokeGradient.id, ...render.strokeGradient.attrs, children: render.strokeGradient.stops.map((stop, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) })
1710
+ (render.fillGradient || render.strokeGradient) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("defs", { children: [
1711
+ render.fillGradient && render.fillGradient.type === "linear" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("linearGradient", { id: render.fillGradient.id, ...render.fillGradient.attrs, children: render.fillGradient.stops.map((stop, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) }),
1712
+ render.fillGradient && render.fillGradient.type === "radial" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("radialGradient", { id: render.fillGradient.id, ...render.fillGradient.attrs, children: render.fillGradient.stops.map((stop, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) }),
1713
+ render.strokeGradient && render.strokeGradient.type === "linear" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("linearGradient", { id: render.strokeGradient.id, ...render.strokeGradient.attrs, children: render.strokeGradient.stops.map((stop, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) }),
1714
+ render.strokeGradient && render.strokeGradient.type === "radial" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("radialGradient", { id: render.strokeGradient.id, ...render.strokeGradient.attrs, children: render.strokeGradient.stops.map((stop, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("stop", { offset: stop.offset, stopColor: stop.stopColor, stopOpacity: stop.stopOpacity }, i)) })
1641
1715
  ] }),
1642
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1716
+ brushImage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("g", { transform: render.transform, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1717
+ "image",
1718
+ {
1719
+ className: "pixerate-shape-brushstroke",
1720
+ href: brushImage.href,
1721
+ x: brushImage.x,
1722
+ y: brushImage.y,
1723
+ width: brushImage.width,
1724
+ height: brushImage.height,
1725
+ preserveAspectRatio: "none",
1726
+ opacity: render.opacity
1727
+ }
1728
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1643
1729
  "path",
1644
1730
  {
1645
1731
  d: render.d,
@@ -1664,22 +1750,22 @@ function ShapeNode({ id, data, width, height, selected, className = "", children
1664
1750
  }
1665
1751
 
1666
1752
  // src/canvas/index.ts
1667
- var import_canvas26 = require("@pixerate/editor/canvas");
1668
1753
  var import_canvas27 = require("@pixerate/editor/canvas");
1669
1754
  var import_canvas28 = require("@pixerate/editor/canvas");
1670
1755
  var import_canvas29 = require("@pixerate/editor/canvas");
1756
+ var import_canvas30 = require("@pixerate/editor/canvas");
1671
1757
 
1672
1758
  // src/canvas/useCanvasAutoLayout.ts
1673
- var import_react14 = require("react");
1674
- var import_canvas13 = require("@pixerate/editor/canvas");
1759
+ var import_react15 = require("react");
1760
+ var import_canvas14 = require("@pixerate/editor/canvas");
1675
1761
  function useCanvasAutoLayout(options) {
1676
- const [guides, setGuides] = (0, import_react14.useState)([]);
1677
- const nodesRef = (0, import_react14.useRef)(options.nodes);
1762
+ const [guides, setGuides] = (0, import_react15.useState)([]);
1763
+ const nodesRef = (0, import_react15.useRef)(options.nodes);
1678
1764
  nodesRef.current = options.nodes;
1679
- const optionsRef = (0, import_react14.useRef)(options);
1765
+ const optionsRef = (0, import_react15.useRef)(options);
1680
1766
  optionsRef.current = options;
1681
- const controller = (0, import_react14.useMemo)(
1682
- () => (0, import_canvas13.createCanvasAutoLayoutController)({
1767
+ const controller = (0, import_react15.useMemo)(
1768
+ () => (0, import_canvas14.createCanvasAutoLayoutController)({
1683
1769
  getNodes: () => nodesRef.current,
1684
1770
  setNodes: (next) => {
1685
1771
  nodesRef.current = next;
@@ -1704,10 +1790,10 @@ function useCanvasAutoLayout(options) {
1704
1790
  }),
1705
1791
  []
1706
1792
  );
1707
- (0, import_react14.useLayoutEffect)(() => {
1793
+ (0, import_react15.useLayoutEffect)(() => {
1708
1794
  if (controller.hasPending) controller.flush();
1709
1795
  }, [options.nodes, controller]);
1710
- return (0, import_react14.useMemo)(
1796
+ return (0, import_react15.useMemo)(
1711
1797
  () => ({
1712
1798
  ...controller,
1713
1799
  /** Drop marker of the active reorder drag (flow coordinates). */
@@ -1721,47 +1807,47 @@ function useCanvasAutoLayout(options) {
1721
1807
  }
1722
1808
 
1723
1809
  // src/canvas/useCanvasTokens.ts
1724
- var import_react15 = require("react");
1725
- var import_canvas14 = require("@pixerate/editor/canvas");
1810
+ var import_react16 = require("react");
1811
+ var import_canvas15 = require("@pixerate/editor/canvas");
1726
1812
  function useCanvasTokens(options) {
1727
1813
  const { store, nodes, setNodes, modes, properties } = options;
1728
- const state = (0, import_react15.useSyncExternalStore)(store.subscribe, store.getState, store.getState);
1729
- const latest = (0, import_react15.useRef)({ nodes, setNodes, modes, properties });
1814
+ const state = (0, import_react16.useSyncExternalStore)(store.subscribe, store.getState, store.getState);
1815
+ const latest = (0, import_react16.useRef)({ nodes, setNodes, modes, properties });
1730
1816
  latest.current = { nodes, setNodes, modes, properties };
1731
1817
  const opts = () => ({ modes: latest.current.modes, properties: latest.current.properties });
1732
- (0, import_react15.useEffect)(
1818
+ (0, import_react16.useEffect)(
1733
1819
  () => store.subscribe((event) => {
1734
1820
  if (event.deletedVariableIds.length === 0) return;
1735
- latest.current.setNodes((prev) => (0, import_canvas14.detachTokenBindings)(prev, event.previous, event.deletedVariableIds, opts()));
1821
+ latest.current.setNodes((prev) => (0, import_canvas15.detachTokenBindings)(prev, event.previous, event.deletedVariableIds, opts()));
1736
1822
  }),
1737
1823
  // eslint-disable-next-line react-hooks/exhaustive-deps
1738
1824
  [store]
1739
1825
  );
1740
1826
  const modesKey = JSON.stringify(modes ?? {});
1741
- (0, import_react15.useEffect)(() => {
1742
- const next = (0, import_canvas14.resolveCanvasTokens)(nodes, state, opts());
1827
+ (0, import_react16.useEffect)(() => {
1828
+ const next = (0, import_canvas15.resolveCanvasTokens)(nodes, state, opts());
1743
1829
  if (next !== nodes) setNodes(next);
1744
1830
  }, [nodes, state, modesKey, properties]);
1745
- const bind = (0, import_react15.useCallback)(
1831
+ const bind = (0, import_react16.useCallback)(
1746
1832
  (ids, propertyKey, variableId) => {
1747
- const next = (0, import_canvas14.bindCanvasToken)(latest.current.nodes, ids, propertyKey, variableId, store.getState(), opts());
1833
+ const next = (0, import_canvas15.bindCanvasToken)(latest.current.nodes, ids, propertyKey, variableId, store.getState(), opts());
1748
1834
  if (next !== latest.current.nodes) latest.current.setNodes(next);
1749
1835
  },
1750
1836
  // eslint-disable-next-line react-hooks/exhaustive-deps
1751
1837
  [store]
1752
1838
  );
1753
- const setMode = (0, import_react15.useCallback)(
1839
+ const setMode = (0, import_react16.useCallback)(
1754
1840
  (ids, collectionId, modeId) => {
1755
- const next = (0, import_canvas14.setCanvasTokenMode)(latest.current.nodes, ids, collectionId, modeId, store.getState(), opts());
1841
+ const next = (0, import_canvas15.setCanvasTokenMode)(latest.current.nodes, ids, collectionId, modeId, store.getState(), opts());
1756
1842
  if (next !== latest.current.nodes) latest.current.setNodes(next);
1757
1843
  },
1758
1844
  // eslint-disable-next-line react-hooks/exhaustive-deps
1759
1845
  [store]
1760
1846
  );
1761
- const modesOf = (0, import_react15.useCallback)(
1847
+ const modesOf = (0, import_react16.useCallback)(
1762
1848
  (nodeId) => {
1763
1849
  const node = latest.current.nodes.find((n) => n.id === nodeId);
1764
- return node ? (0, import_canvas14.getEffectiveTokenModes)(node, latest.current.nodes, store.getState(), opts()) : {};
1850
+ return node ? (0, import_canvas15.getEffectiveTokenModes)(node, latest.current.nodes, store.getState(), opts()) : {};
1765
1851
  },
1766
1852
  // eslint-disable-next-line react-hooks/exhaustive-deps
1767
1853
  [store]
@@ -1770,9 +1856,9 @@ function useCanvasTokens(options) {
1770
1856
  }
1771
1857
 
1772
1858
  // src/canvas/TokenBindingPicker.tsx
1773
- var import_canvas15 = require("@pixerate/editor/canvas");
1859
+ var import_canvas16 = require("@pixerate/editor/canvas");
1774
1860
  var import_tokens = require("@pixerate/editor/tokens");
1775
- var import_jsx_runtime5 = require("react/jsx-runtime");
1861
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1776
1862
  function TokenBindingPicker({
1777
1863
  state,
1778
1864
  nodes,
@@ -1786,18 +1872,18 @@ function TokenBindingPicker({
1786
1872
  const selected = nodes.filter((n) => selectedIds.includes(n.id));
1787
1873
  const first = selected[0];
1788
1874
  if (!first) return null;
1789
- let rows = (0, import_canvas15.getBindableTokenProperties)(first, options);
1875
+ let rows = (0, import_canvas16.getBindableTokenProperties)(first, options);
1790
1876
  if (properties) rows = properties.map((key) => rows.find((p) => p.key === key)).filter((p) => !!p);
1791
- const modes = (0, import_canvas15.getEffectiveTokenModes)(first, nodes, state, options);
1792
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { "data-token-binding-picker": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: [
1877
+ const modes = (0, import_canvas16.getEffectiveTokenModes)(first, nodes, state, options);
1878
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-token-binding-picker": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: [
1793
1879
  rows.map((property) => {
1794
- const ids = new Set(selected.map((n) => (0, import_canvas15.getNodeTokenBindings)(n)[property.key] ?? ""));
1880
+ const ids = new Set(selected.map((n) => (0, import_canvas16.getNodeTokenBindings)(n)[property.key] ?? ""));
1795
1881
  const value = ids.size === 1 ? [...ids][0] : "__mixed";
1796
- const candidates = (0, import_canvas15.getTokensForProperty)(state, property, first);
1882
+ const candidates = (0, import_canvas16.getTokensForProperty)(state, property, first);
1797
1883
  const resolved = value && value !== "__mixed" ? (0, import_tokens.resolveToken)(state, value, modes) : null;
1798
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "flex items-center gap-2", "data-token-property": property.key, children: [
1799
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-28 shrink-0 text-muted-foreground", children: property.label }),
1800
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1884
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "flex items-center gap-2", "data-token-property": property.key, children: [
1885
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w-28 shrink-0 text-muted-foreground", children: property.label }),
1886
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1801
1887
  "select",
1802
1888
  {
1803
1889
  "aria-label": `${property.label} variable`,
@@ -1806,17 +1892,17 @@ function TokenBindingPicker({
1806
1892
  onChange: (e) => {
1807
1893
  const id = e.currentTarget.value || null;
1808
1894
  try {
1809
- onChange((0, import_canvas15.bindCanvasToken)(nodes, selectedIds, property.key, id, state, options));
1895
+ onChange((0, import_canvas16.bindCanvasToken)(nodes, selectedIds, property.key, id, state, options));
1810
1896
  } catch (error) {
1811
1897
  onError?.(error);
1812
1898
  }
1813
1899
  },
1814
1900
  children: [
1815
- value === "__mixed" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "__mixed", children: "Mixed" }) : null,
1816
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "", children: "None" }),
1901
+ value === "__mixed" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "__mixed", children: "Mixed" }) : null,
1902
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "", children: "None" }),
1817
1903
  candidates.map((v) => {
1818
1904
  const collection = state.collections.find((c) => c.id === v.collectionId);
1819
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("option", { value: v.id, children: [
1905
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("option", { value: v.id, children: [
1820
1906
  v.name,
1821
1907
  collection && state.collections.length > 1 ? ` (${collection.name})` : ""
1822
1908
  ] }, v.id);
@@ -1824,17 +1910,17 @@ function TokenBindingPicker({
1824
1910
  ]
1825
1911
  }
1826
1912
  ),
1827
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-16 shrink-0 truncate text-right text-muted-foreground", "data-token-resolved": "", children: resolved?.ok ? property.type === "color" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1913
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w-16 shrink-0 truncate text-right text-muted-foreground", "data-token-resolved": "", children: resolved?.ok ? property.type === "color" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1828
1914
  "span",
1829
1915
  {
1830
1916
  className: "inline-block h-3 w-3 rounded border border-border align-middle",
1831
1917
  style: { background: String(resolved.value) },
1832
1918
  title: String(resolved.value)
1833
1919
  }
1834
- ) : String(resolved.value) : resolved ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { title: resolved.message, children: "\u26A0" }) : null })
1920
+ ) : String(resolved.value) : resolved ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { title: resolved.message, children: "\u26A0" }) : null })
1835
1921
  ] }, property.key);
1836
1922
  }),
1837
- state.collections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-muted-foreground", children: "No variables yet." }) : null
1923
+ state.collections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-muted-foreground", children: "No variables yet." }) : null
1838
1924
  ] });
1839
1925
  }
1840
1926
  function TokenModeSwitcher({
@@ -1848,29 +1934,29 @@ function TokenModeSwitcher({
1848
1934
  }) {
1849
1935
  const first = nodes.find((n) => nodeIds.includes(n.id));
1850
1936
  if (!first) return null;
1851
- const own = (0, import_canvas15.getNodeTokenModes)(first);
1937
+ const own = (0, import_canvas16.getNodeTokenModes)(first);
1852
1938
  const parent = first.parentId ? nodes.find((n) => n.id === first.parentId) : void 0;
1853
- const inherited = parent ? (0, import_canvas15.getEffectiveTokenModes)(parent, nodes, state, options) : { ...options.modes };
1939
+ const inherited = parent ? (0, import_canvas16.getEffectiveTokenModes)(parent, nodes, state, options) : { ...options.modes };
1854
1940
  const collections = state.collections.filter((c) => showSingleMode || c.modes.length > 1);
1855
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { "data-token-mode-switcher": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: collections.map((collection) => {
1941
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { "data-token-mode-switcher": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: collections.map((collection) => {
1856
1942
  const auto = (0, import_tokens.getCurrentMode)(collection, inherited);
1857
1943
  const explicit = collection.modes.some((m) => m.id === own[collection.id]) ? own[collection.id] : "";
1858
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "flex items-center gap-2", "data-token-collection": collection.id, children: [
1859
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-28 shrink-0 truncate text-muted-foreground", children: collection.name }),
1860
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1944
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "flex items-center gap-2", "data-token-collection": collection.id, children: [
1945
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "w-28 shrink-0 truncate text-muted-foreground", children: collection.name }),
1946
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1861
1947
  "select",
1862
1948
  {
1863
1949
  "aria-label": `${collection.name} mode`,
1864
1950
  className: "min-w-0 flex-1 rounded border border-border bg-background px-1 py-0.5 text-xs",
1865
1951
  value: explicit,
1866
- onChange: (e) => onChange((0, import_canvas15.setCanvasTokenMode)(nodes, nodeIds, collection.id, e.currentTarget.value || null, state, options)),
1952
+ onChange: (e) => onChange((0, import_canvas16.setCanvasTokenMode)(nodes, nodeIds, collection.id, e.currentTarget.value || null, state, options)),
1867
1953
  children: [
1868
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("option", { value: "", children: [
1954
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("option", { value: "", children: [
1869
1955
  "Auto (",
1870
1956
  auto.name,
1871
1957
  ")"
1872
1958
  ] }),
1873
- collection.modes.map((m) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: m.id, children: m.name }, m.id))
1959
+ collection.modes.map((m) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: m.id, children: m.name }, m.id))
1874
1960
  ]
1875
1961
  }
1876
1962
  )
@@ -1879,18 +1965,18 @@ function TokenModeSwitcher({
1879
1965
  }
1880
1966
 
1881
1967
  // src/canvas/index.ts
1882
- var import_canvas30 = require("@pixerate/editor/canvas");
1968
+ var import_canvas31 = require("@pixerate/editor/canvas");
1883
1969
 
1884
1970
  // src/canvas/useCanvasAnimation.ts
1885
- var import_react16 = require("react");
1886
- var import_canvas16 = require("@pixerate/editor/canvas");
1971
+ var import_react17 = require("react");
1972
+ var import_canvas17 = require("@pixerate/editor/canvas");
1887
1973
  function useCanvasAnimation(options) {
1888
- const nodesRef = (0, import_react16.useRef)(options.nodes);
1974
+ const nodesRef = (0, import_react17.useRef)(options.nodes);
1889
1975
  nodesRef.current = options.nodes;
1890
- const optionsRef = (0, import_react16.useRef)(options);
1976
+ const optionsRef = (0, import_react17.useRef)(options);
1891
1977
  optionsRef.current = options;
1892
- const controller = (0, import_react16.useMemo)(
1893
- () => (0, import_canvas16.createCanvasAnimationController)({
1978
+ const controller = (0, import_react17.useMemo)(
1979
+ () => (0, import_canvas17.createCanvasAnimationController)({
1894
1980
  getNodes: () => nodesRef.current,
1895
1981
  setNodes: (next) => {
1896
1982
  nodesRef.current = next;
@@ -1916,26 +2002,26 @@ function useCanvasAnimation(options) {
1916
2002
  }),
1917
2003
  []
1918
2004
  );
1919
- (0, import_react16.useEffect)(() => () => controller.destroy(), [controller]);
1920
- (0, import_react16.useEffect)(() => {
2005
+ (0, import_react17.useEffect)(() => () => controller.destroy(), [controller]);
2006
+ (0, import_react17.useEffect)(() => {
1921
2007
  if (options.loop !== void 0) controller.setLoop(options.loop);
1922
2008
  }, [controller, options.loop]);
1923
- (0, import_react16.useEffect)(() => {
2009
+ (0, import_react17.useEffect)(() => {
1924
2010
  if (options.playbackRate !== void 0) controller.setPlaybackRate(options.playbackRate);
1925
2011
  }, [controller, options.playbackRate]);
1926
- (0, import_react16.useEffect)(() => {
2012
+ (0, import_react17.useEffect)(() => {
1927
2013
  if (options.recording !== void 0) controller.setRecording(options.recording);
1928
2014
  }, [controller, options.recording]);
1929
- const state = (0, import_react16.useSyncExternalStore)(
2015
+ const state = (0, import_react17.useSyncExternalStore)(
1930
2016
  (listener) => controller.subscribe(listener),
1931
2017
  () => controller.getState(),
1932
2018
  () => controller.getState()
1933
2019
  );
1934
- (0, import_react16.useEffect)(() => {
2020
+ (0, import_react17.useEffect)(() => {
1935
2021
  controller.refresh();
1936
2022
  }, [controller, options.nodes]);
1937
- const displayNodes = (0, import_react16.useMemo)(() => controller.display(options.nodes), [controller, options.nodes, state.time]);
1938
- return (0, import_react16.useMemo)(
2023
+ const displayNodes = (0, import_react17.useMemo)(() => controller.display(options.nodes), [controller, options.nodes, state.time]);
2024
+ return (0, import_react17.useMemo)(
1939
2025
  () => ({
1940
2026
  ...controller,
1941
2027
  state,
@@ -1956,24 +2042,24 @@ function useCanvasAnimation(options) {
1956
2042
  }
1957
2043
 
1958
2044
  // src/canvas/AnimationTimeline.tsx
1959
- var import_react17 = require("react");
1960
- var import_canvas17 = require("@pixerate/editor/canvas");
1961
- var import_jsx_runtime6 = require("react/jsx-runtime");
2045
+ var import_react18 = require("react");
2046
+ var import_canvas18 = require("@pixerate/editor/canvas");
2047
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1962
2048
  var LOOP_LABELS = { none: "Once", loop: "Loop", "ping-pong": "Ping-pong" };
1963
2049
  var easingValue = (easing) => typeof easing === "string" ? easing : easing ? "custom" : "linear";
1964
2050
  function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8, labelOf, className = "" }) {
1965
2051
  const { state } = animation;
1966
2052
  const duration = state.duration;
1967
2053
  const rows = animation.timelineRows(nodeIds ?? void 0, labelOf ? { labelOf } : {});
1968
- const ticks = (0, import_canvas17.getTimelineTicks)(duration, width);
2054
+ const ticks = (0, import_canvas18.getTimelineTicks)(duration, width);
1969
2055
  const selectedEasing = (() => {
1970
2056
  const first = state.selection[0];
1971
2057
  if (!first) return "";
1972
2058
  for (const row of rows) for (const k of row.keyframes) if (k.selected && k.ref.property === first.property && k.ref.nodeId === first.nodeId) return easingValue(k.easing);
1973
2059
  return "";
1974
2060
  })();
1975
- const dragRef = (0, import_react17.useRef)(null);
1976
- (0, import_react17.useEffect)(() => {
2061
+ const dragRef = (0, import_react18.useRef)(null);
2062
+ (0, import_react18.useEffect)(() => {
1977
2063
  const onKey = (event) => {
1978
2064
  if (event.key === "Escape" && dragRef.current) {
1979
2065
  dragRef.current = null;
@@ -1986,8 +2072,8 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
1986
2072
  const onRulerDown = (event) => {
1987
2073
  const lane = event.currentTarget;
1988
2074
  const left = lane.getBoundingClientRect().left;
1989
- animation.scrub((0, import_canvas17.xToTime)(event.clientX - left, duration, width));
1990
- const move = (e) => animation.scrub((0, import_canvas17.xToTime)(e.clientX - left, duration, width));
2075
+ animation.scrub((0, import_canvas18.xToTime)(event.clientX - left, duration, width));
2076
+ const move = (e) => animation.scrub((0, import_canvas18.xToTime)(e.clientX - left, duration, width));
1991
2077
  const up = () => {
1992
2078
  window.removeEventListener("pointermove", move);
1993
2079
  window.removeEventListener("pointerup", up);
@@ -2027,12 +2113,12 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
2027
2113
  }
2028
2114
  };
2029
2115
  const btn = "rounded border border-border px-2 py-0.5 text-xs hover:bg-muted disabled:opacity-50";
2030
- const playheadX = (0, import_canvas17.timeToX)(state.time, duration, width);
2116
+ const playheadX = (0, import_canvas18.timeToX)(state.time, duration, width);
2031
2117
  const labelWidth = 120;
2032
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-animation-timeline": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, tabIndex: 0, onKeyDown: onTimelineKey, children: [
2033
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "toolbar", "aria-label": "Animation", children: [
2034
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: btn, "data-action": "toggle-play", "aria-label": state.playing ? "Pause" : "Play", onClick: () => animation.toggle(), children: state.playing ? "\u275A\u275A" : "\u25B6" }),
2035
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2118
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-animation-timeline": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, tabIndex: 0, onKeyDown: onTimelineKey, children: [
2119
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap items-center gap-2", role: "toolbar", "aria-label": "Animation", children: [
2120
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: btn, "data-action": "toggle-play", "aria-label": state.playing ? "Pause" : "Play", onClick: () => animation.toggle(), children: state.playing ? "\u275A\u275A" : "\u25B6" }),
2121
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2036
2122
  "button",
2037
2123
  {
2038
2124
  type: "button",
@@ -2044,13 +2130,13 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
2044
2130
  children: "\u25CF Rec"
2045
2131
  }
2046
2132
  ),
2047
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: btn, "data-action": "add-keyframe", onClick: () => animation.addKeyframe(), children: "\u25C6 Key" }),
2048
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { "data-time": "", className: "tabular-nums text-muted-foreground", children: [
2049
- (0, import_canvas17.formatAnimationTime)(state.time),
2133
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: btn, "data-action": "add-keyframe", onClick: () => animation.addKeyframe(), children: "\u25C6 Key" }),
2134
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { "data-time": "", className: "tabular-nums text-muted-foreground", children: [
2135
+ (0, import_canvas18.formatAnimationTime)(state.time),
2050
2136
  " / ",
2051
- (0, import_canvas17.formatAnimationTime)(duration)
2137
+ (0, import_canvas18.formatAnimationTime)(duration)
2052
2138
  ] }),
2053
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2139
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2054
2140
  "select",
2055
2141
  {
2056
2142
  "aria-label": "Easing",
@@ -2060,13 +2146,13 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
2060
2146
  disabled: state.selection.length === 0,
2061
2147
  onChange: (e) => e.target.value && e.target.value !== "custom" && animation.setEasing(e.target.value),
2062
2148
  children: [
2063
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "", children: "Easing\u2026" }),
2064
- import_canvas17.ANIMATION_EASING_PRESETS.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: preset, children: import_canvas17.ANIMATION_EASING_LABELS[preset] }, preset)),
2065
- selectedEasing === "custom" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "custom", children: "Custom" }) : null
2149
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "", children: "Easing\u2026" }),
2150
+ import_canvas18.ANIMATION_EASING_PRESETS.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: preset, children: import_canvas18.ANIMATION_EASING_LABELS[preset] }, preset)),
2151
+ selectedEasing === "custom" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "custom", children: "Custom" }) : null
2066
2152
  ]
2067
2153
  }
2068
2154
  ),
2069
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2155
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2070
2156
  "select",
2071
2157
  {
2072
2158
  "aria-label": "Loop",
@@ -2074,13 +2160,13 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
2074
2160
  className: "rounded border border-border bg-background px-1 py-0.5",
2075
2161
  value: state.loop,
2076
2162
  onChange: (e) => animation.setLoop(e.target.value),
2077
- children: Object.keys(LOOP_LABELS).map((mode) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: mode, children: LOOP_LABELS[mode] }, mode))
2163
+ children: Object.keys(LOOP_LABELS).map((mode) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: mode, children: LOOP_LABELS[mode] }, mode))
2078
2164
  }
2079
2165
  )
2080
2166
  ] }),
2081
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex", children: [
2082
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { width: labelWidth }, className: "shrink-0" }),
2083
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2167
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex", children: [
2168
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { width: labelWidth }, className: "shrink-0" }),
2169
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2084
2170
  "div",
2085
2171
  {
2086
2172
  "data-timeline-ruler": "",
@@ -2088,15 +2174,15 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
2088
2174
  style: { width },
2089
2175
  onPointerDown: onRulerDown,
2090
2176
  children: [
2091
- ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "absolute top-0 -translate-x-1/2 text-[10px] text-muted-foreground", style: { left: tick.x }, children: tick.label }, tick.time)),
2092
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { "data-playhead": "", className: "absolute top-0 h-5 w-px bg-red-500", style: { left: playheadX } })
2177
+ ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "absolute top-0 -translate-x-1/2 text-[10px] text-muted-foreground", style: { left: tick.x }, children: tick.label }, tick.time)),
2178
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { "data-playhead": "", className: "absolute top-0 h-5 w-px bg-red-500", style: { left: playheadX } })
2093
2179
  ]
2094
2180
  }
2095
2181
  )
2096
2182
  ] }),
2097
- rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-muted-foreground", "data-timeline-empty": "", children: "Select an animated node, or press \u25C6 Key to add a keyframe." }) : rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center", "data-track": row.id, children: [
2098
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "flex shrink-0 items-center gap-1 truncate pr-2", style: { width: labelWidth }, title: `${row.nodeLabel} \xB7 ${row.label}`, children: [
2099
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2183
+ rows.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-muted-foreground", "data-timeline-empty": "", children: "Select an animated node, or press \u25C6 Key to add a keyframe." }) : rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center", "data-track": row.id, children: [
2184
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex shrink-0 items-center gap-1 truncate pr-2", style: { width: labelWidth }, title: `${row.nodeLabel} \xB7 ${row.label}`, children: [
2185
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2100
2186
  "input",
2101
2187
  {
2102
2188
  type: "checkbox",
@@ -2105,24 +2191,24 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
2105
2191
  onChange: (e) => animation.setTrackEnabled(row.nodeId, row.property, e.target.checked)
2106
2192
  }
2107
2193
  ),
2108
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "truncate", children: [
2194
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "truncate", children: [
2109
2195
  rows.filter((r) => r.nodeId === row.nodeId).length < rows.length ? `${row.nodeLabel} \xB7 ` : "",
2110
2196
  row.label
2111
2197
  ] })
2112
2198
  ] }),
2113
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { "data-lane": "", className: `relative h-5 rounded bg-muted/40 ${row.enabled ? "" : "opacity-50"}`, style: { width }, children: [
2114
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "pointer-events-none absolute top-0 h-5 w-px bg-red-500/60", style: { left: playheadX } }),
2115
- state.drag?.target != null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { "data-snap-target": "", className: "pointer-events-none absolute top-0 h-5 w-px bg-sky-400", style: { left: (0, import_canvas17.timeToX)(state.drag.target, duration, width) } }) : null,
2116
- row.keyframes.map((k) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2199
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-lane": "", className: `relative h-5 rounded bg-muted/40 ${row.enabled ? "" : "opacity-50"}`, style: { width }, children: [
2200
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "pointer-events-none absolute top-0 h-5 w-px bg-red-500/60", style: { left: playheadX } }),
2201
+ state.drag?.target != null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { "data-snap-target": "", className: "pointer-events-none absolute top-0 h-5 w-px bg-sky-400", style: { left: (0, import_canvas18.timeToX)(state.drag.target, duration, width) } }) : null,
2202
+ row.keyframes.map((k) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2117
2203
  "button",
2118
2204
  {
2119
2205
  type: "button",
2120
2206
  "data-keyframe": k.ref.time,
2121
2207
  "aria-pressed": k.selected,
2122
- "aria-label": `${row.label} keyframe at ${(0, import_canvas17.formatAnimationTime)(k.ref.time)}`,
2123
- title: `${(0, import_canvas17.formatAnimationTime)(k.time)} \xB7 ${String(k.value)}`,
2208
+ "aria-label": `${row.label} keyframe at ${(0, import_canvas18.formatAnimationTime)(k.ref.time)}`,
2209
+ title: `${(0, import_canvas18.formatAnimationTime)(k.time)} \xB7 ${String(k.value)}`,
2124
2210
  className: `absolute top-1/2 h-2.5 w-2.5 -translate-x-1/2 -translate-y-1/2 rotate-45 border ${k.selected ? "border-sky-300 bg-sky-500" : "border-foreground/60 bg-background"} ${k.easing === "hold" ? "rounded-none" : "rounded-[1px]"}`,
2125
- style: { left: (0, import_canvas17.timeToX)(k.time, duration, width) },
2211
+ style: { left: (0, import_canvas18.timeToX)(k.time, duration, width) },
2126
2212
  onPointerDown: onKeyDown(k.ref)
2127
2213
  },
2128
2214
  k.ref.time
@@ -2133,18 +2219,18 @@ function AnimationTimeline({ animation, nodeIds, width = 360, snapThreshold = 8,
2133
2219
  }
2134
2220
 
2135
2221
  // src/canvas/index.ts
2136
- var import_canvas31 = require("@pixerate/editor/canvas");
2222
+ var import_canvas32 = require("@pixerate/editor/canvas");
2137
2223
 
2138
2224
  // src/canvas/useCanvasComponents.ts
2139
- var import_react18 = require("react");
2140
- var import_canvas18 = require("@pixerate/editor/canvas");
2225
+ var import_react19 = require("react");
2226
+ var import_canvas19 = require("@pixerate/editor/canvas");
2141
2227
  function useCanvasComponents(options) {
2142
- const nodesRef = (0, import_react18.useRef)(options.nodes);
2228
+ const nodesRef = (0, import_react19.useRef)(options.nodes);
2143
2229
  nodesRef.current = options.nodes;
2144
- const optionsRef = (0, import_react18.useRef)(options);
2230
+ const optionsRef = (0, import_react19.useRef)(options);
2145
2231
  optionsRef.current = options;
2146
- const controller = (0, import_react18.useMemo)(
2147
- () => (0, import_canvas18.createCanvasComponentsController)({
2232
+ const controller = (0, import_react19.useMemo)(
2233
+ () => (0, import_canvas19.createCanvasComponentsController)({
2148
2234
  getNodes: () => nodesRef.current,
2149
2235
  setNodes: (next) => {
2150
2236
  nodesRef.current = next;
@@ -2172,18 +2258,18 @@ function useCanvasComponents(options) {
2172
2258
  }),
2173
2259
  []
2174
2260
  );
2175
- (0, import_react18.useLayoutEffect)(() => {
2261
+ (0, import_react19.useLayoutEffect)(() => {
2176
2262
  if (optionsRef.current.autoSync !== false) controller.sync();
2177
2263
  }, [options.nodes, controller]);
2178
2264
  return controller;
2179
2265
  }
2180
2266
 
2181
2267
  // src/canvas/CanvasComponentsPanel.tsx
2182
- var import_react19 = require("react");
2183
- var import_canvas19 = require("@pixerate/editor/canvas");
2184
- var import_jsx_runtime7 = require("react/jsx-runtime");
2268
+ var import_react20 = require("react");
2269
+ var import_canvas20 = require("@pixerate/editor/canvas");
2270
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2185
2271
  function InlineField({ value, label, onCommit }) {
2186
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2272
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2187
2273
  "input",
2188
2274
  {
2189
2275
  type: "text",
@@ -2214,11 +2300,11 @@ function CanvasComponentsPanel({
2214
2300
  search = true,
2215
2301
  className = ""
2216
2302
  }) {
2217
- const [query, setQuery] = (0, import_react19.useState)("");
2218
- const [propsOpen, setPropsOpen] = (0, import_react19.useState)(null);
2219
- const [menuFor, setMenuFor] = (0, import_react19.useState)(null);
2220
- const [editing, setEditing] = (0, import_react19.useState)(null);
2221
- const { components: all, sets } = (0, import_canvas19.listCanvasComponents)(nodes);
2303
+ const [query, setQuery] = (0, import_react20.useState)("");
2304
+ const [propsOpen, setPropsOpen] = (0, import_react20.useState)(null);
2305
+ const [menuFor, setMenuFor] = (0, import_react20.useState)(null);
2306
+ const [editing, setEditing] = (0, import_react20.useState)(null);
2307
+ const { components: all, sets } = (0, import_canvas20.listCanvasComponents)(nodes);
2222
2308
  const q = query.trim().toLowerCase();
2223
2309
  const match = (name) => !q || name.toLowerCase().includes(q);
2224
2310
  const lone = all.filter((c) => !c.setId && match(c.name));
@@ -2229,7 +2315,7 @@ function CanvasComponentsPanel({
2229
2315
  };
2230
2316
  const small = "shrink-0 rounded px-1 text-[10px] text-muted-foreground hover:bg-muted hover:text-foreground disabled:opacity-40";
2231
2317
  const menuItem = "rounded px-2 py-0.5 text-left hover:bg-muted disabled:opacity-40";
2232
- const item = (id, name, count, extra = {}, onContextMenu) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2318
+ const item = (id, name, count, extra = {}, onContextMenu) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2233
2319
  "button",
2234
2320
  {
2235
2321
  type: "button",
@@ -2241,22 +2327,22 @@ function CanvasComponentsPanel({
2241
2327
  onClick: () => onInsert(id),
2242
2328
  onContextMenu,
2243
2329
  onDragStart: (e) => {
2244
- e.dataTransfer.setData(import_canvas19.CANVAS_COMPONENT_DRAG_TYPE, id);
2330
+ e.dataTransfer.setData(import_canvas20.CANVAS_COMPONENT_DRAG_TYPE, id);
2245
2331
  e.dataTransfer.setData("text/plain", name);
2246
2332
  e.dataTransfer.effectAllowed = "copy";
2247
2333
  },
2248
2334
  children: [
2249
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "truncate", children: [
2250
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "aria-hidden": true, className: "mr-1 text-muted-foreground", children: "\u25C7" }),
2335
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "truncate", children: [
2336
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "aria-hidden": true, className: "mr-1 text-muted-foreground", children: "\u25C7" }),
2251
2337
  name
2252
2338
  ] }),
2253
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-[10px] text-muted-foreground", "data-instance-count": "", children: count })
2339
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-[10px] text-muted-foreground", "data-instance-count": "", children: count })
2254
2340
  ]
2255
2341
  },
2256
2342
  id
2257
2343
  );
2258
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-components-panel": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: [
2259
- search ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2344
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { "data-components-panel": "", className: `flex flex-col gap-1 text-xs text-foreground ${className}`, children: [
2345
+ search ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2260
2346
  "input",
2261
2347
  {
2262
2348
  type: "search",
@@ -2266,11 +2352,11 @@ function CanvasComponentsPanel({
2266
2352
  onInput: (e) => setQuery(e.target.value)
2267
2353
  }
2268
2354
  ) : null,
2269
- shownSets.map((set) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-component-set": set.id, className: "flex flex-col", children: [
2270
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-1", children: [
2355
+ shownSets.map((set) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { "data-component-set": set.id, className: "flex flex-col", children: [
2356
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-1", children: [
2271
2357
  item(set.id, set.name, set.variants.reduce((sum, v) => sum + v.instanceCount, 0), { "data-kind": "set" }),
2272
- components ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2273
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2358
+ components ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2359
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2274
2360
  "button",
2275
2361
  {
2276
2362
  type: "button",
@@ -2282,7 +2368,7 @@ function CanvasComponentsPanel({
2282
2368
  children: "+\xA0Variant"
2283
2369
  }
2284
2370
  ),
2285
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2371
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2286
2372
  "button",
2287
2373
  {
2288
2374
  type: "button",
@@ -2297,8 +2383,8 @@ function CanvasComponentsPanel({
2297
2383
  )
2298
2384
  ] }) : null
2299
2385
  ] }),
2300
- components && propsOpen === set.id ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { "data-variant-properties": set.id, className: "ml-3 flex flex-col gap-1 border-l border-border py-1 pl-2", children: set.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-variant-option": option.name, className: "flex flex-col gap-0.5", children: [
2301
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2386
+ components && propsOpen === set.id ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { "data-variant-properties": set.id, className: "ml-3 flex flex-col gap-1 border-l border-border py-1 pl-2", children: set.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { "data-variant-option": option.name, className: "flex flex-col gap-0.5", children: [
2387
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2302
2388
  InlineField,
2303
2389
  {
2304
2390
  value: option.name,
@@ -2306,7 +2392,7 @@ function CanvasComponentsPanel({
2306
2392
  onCommit: (next) => report(components.renameVariantProperty(option.name, next, set.id))
2307
2393
  }
2308
2394
  ),
2309
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ml-2 flex flex-wrap gap-1", children: option.values.map((value) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2395
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "ml-2 flex flex-wrap gap-1", children: option.values.map((value) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2310
2396
  InlineField,
2311
2397
  {
2312
2398
  value,
@@ -2316,8 +2402,8 @@ function CanvasComponentsPanel({
2316
2402
  value
2317
2403
  )) })
2318
2404
  ] }, option.name)) }) : null,
2319
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ml-3 flex flex-col border-l border-border pl-1", children: set.variants.map((v) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-variant-row": v.id, className: "flex flex-col", children: [
2320
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-1", children: [
2405
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "ml-3 flex flex-col border-l border-border pl-1", children: set.variants.map((v) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { "data-variant-row": v.id, className: "flex flex-col", children: [
2406
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-1", children: [
2321
2407
  item(
2322
2408
  v.id,
2323
2409
  v.name,
@@ -2328,7 +2414,7 @@ function CanvasComponentsPanel({
2328
2414
  setMenuFor(v.id);
2329
2415
  } : void 0
2330
2416
  ),
2331
- components ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2417
+ components ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2332
2418
  "button",
2333
2419
  {
2334
2420
  type: "button",
@@ -2342,8 +2428,8 @@ function CanvasComponentsPanel({
2342
2428
  }
2343
2429
  ) : null
2344
2430
  ] }),
2345
- components && menuFor === v.id ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { role: "menu", "data-variant-menu": v.id, className: "ml-2 flex flex-col rounded border border-border bg-background p-1 shadow", children: [
2346
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2431
+ components && menuFor === v.id ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { role: "menu", "data-variant-menu": v.id, className: "ml-2 flex flex-col rounded border border-border bg-background p-1 shadow", children: [
2432
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2347
2433
  "button",
2348
2434
  {
2349
2435
  type: "button",
@@ -2357,7 +2443,7 @@ function CanvasComponentsPanel({
2357
2443
  children: "Edit values\u2026"
2358
2444
  }
2359
2445
  ),
2360
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2446
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2361
2447
  "button",
2362
2448
  {
2363
2449
  type: "button",
@@ -2371,7 +2457,7 @@ function CanvasComponentsPanel({
2371
2457
  children: "Duplicate"
2372
2458
  }
2373
2459
  ),
2374
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2460
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2375
2461
  "button",
2376
2462
  {
2377
2463
  type: "button",
@@ -2388,7 +2474,7 @@ function CanvasComponentsPanel({
2388
2474
  }
2389
2475
  )
2390
2476
  ] }) : null,
2391
- components && editing === v.id ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2477
+ components && editing === v.id ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2392
2478
  "form",
2393
2479
  {
2394
2480
  "data-variant-editor": v.id,
@@ -2402,9 +2488,9 @@ function CanvasComponentsPanel({
2402
2488
  if (report(components.setVariantProperties(values, v.id))) setEditing(null);
2403
2489
  },
2404
2490
  children: [
2405
- set.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex items-center gap-2", children: [
2406
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w-16 shrink-0 truncate text-muted-foreground", children: option.name }),
2407
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2491
+ set.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-2", children: [
2492
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "w-16 shrink-0 truncate text-muted-foreground", children: option.name }),
2493
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2408
2494
  "input",
2409
2495
  {
2410
2496
  type: "text",
@@ -2415,9 +2501,9 @@ function CanvasComponentsPanel({
2415
2501
  }
2416
2502
  )
2417
2503
  ] }, option.name)),
2418
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex gap-1", children: [
2419
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "submit", className: "rounded border border-border px-2 py-0.5 hover:bg-muted", "data-action": "save-variant", children: "Save" }),
2420
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "rounded px-2 py-0.5 hover:bg-muted", "data-action": "cancel-variant", onClick: () => setEditing(null), children: "Cancel" })
2504
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex gap-1", children: [
2505
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "submit", className: "rounded border border-border px-2 py-0.5 hover:bg-muted", "data-action": "save-variant", children: "Save" }),
2506
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "rounded px-2 py-0.5 hover:bg-muted", "data-action": "cancel-variant", onClick: () => setEditing(null), children: "Cancel" })
2421
2507
  ] })
2422
2508
  ]
2423
2509
  }
@@ -2425,7 +2511,7 @@ function CanvasComponentsPanel({
2425
2511
  ] }, v.id)) })
2426
2512
  ] }, set.id)),
2427
2513
  lone.map((c) => item(c.id, c.name, c.instanceCount, { "data-kind": "component" })),
2428
- all.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-muted-foreground", children: "No components yet. Select a frame and choose Create Component." }) : null
2514
+ all.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-muted-foreground", children: "No components yet. Select a frame and choose Create Component." }) : null
2429
2515
  ] });
2430
2516
  }
2431
2517
  function CanvasInstanceInspector({
@@ -2435,36 +2521,36 @@ function CanvasInstanceInspector({
2435
2521
  onError,
2436
2522
  className = ""
2437
2523
  }) {
2438
- const info = nodeId ? (0, import_canvas19.inspectCanvasInstance)(nodes, nodeId) : void 0;
2524
+ const info = nodeId ? (0, import_canvas20.inspectCanvasInstance)(nodes, nodeId) : void 0;
2439
2525
  if (!info) return null;
2440
2526
  const report = (result) => {
2441
2527
  if (result && !result.ok && result.reason) onError?.(result.reason);
2442
2528
  };
2443
2529
  const setProp = (name, value) => report(components.setInstanceProperties({ [name]: value }, [info.id]));
2444
- const allComponents = (0, import_canvas19.listCanvasComponents)(nodes).components;
2530
+ const allComponents = (0, import_canvas20.listCanvasComponents)(nodes).components;
2445
2531
  const linked = info.status === "linked";
2446
2532
  const btn = "rounded border border-border px-2 py-0.5 text-xs hover:bg-muted disabled:opacity-40";
2447
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { "data-instance-inspector": "", "data-instance-id": info.id, className: `flex flex-col gap-2 text-xs text-foreground ${className}`, children: [
2448
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
2449
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "truncate font-medium", "data-instance-main": "", children: linked ? info.componentName : "Main component missing" }),
2450
- info.nested ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-muted-foreground", children: "Nested" }) : null
2533
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { "data-instance-inspector": "", "data-instance-id": info.id, className: `flex flex-col gap-2 text-xs text-foreground ${className}`, children: [
2534
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
2535
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "truncate font-medium", "data-instance-main": "", children: linked ? info.componentName : "Main component missing" }),
2536
+ info.nested ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-muted-foreground", children: "Nested" }) : null
2451
2537
  ] }),
2452
- info.variantOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex items-center gap-2", "data-variant-property": option.name, children: [
2453
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w-24 shrink-0 truncate text-muted-foreground", children: option.name }),
2454
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2538
+ info.variantOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-2", "data-variant-property": option.name, children: [
2539
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "w-24 shrink-0 truncate text-muted-foreground", children: option.name }),
2540
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2455
2541
  "select",
2456
2542
  {
2457
2543
  "aria-label": `${option.name} variant`,
2458
2544
  className: "min-w-0 flex-1 rounded border border-border bg-background px-1 py-0.5 text-xs",
2459
2545
  value: info.variant[option.name] ?? "",
2460
2546
  onChange: (e) => setProp(option.name, e.currentTarget.value),
2461
- children: option.values.map((v) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: v, children: v }, v))
2547
+ children: option.values.map((v) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: v, children: v }, v))
2462
2548
  }
2463
2549
  )
2464
2550
  ] }, option.name)),
2465
- info.properties.map((p) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "flex items-center gap-2", "data-component-property": p.name, children: [
2466
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "w-24 shrink-0 truncate text-muted-foreground", children: p.name }),
2467
- p.type === "boolean" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "checkbox", "aria-label": p.name, checked: p.value === true, onChange: (e) => setProp(p.name, e.currentTarget.checked) }) : p.type === "text" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2551
+ info.properties.map((p) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "flex items-center gap-2", "data-component-property": p.name, children: [
2552
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "w-24 shrink-0 truncate text-muted-foreground", children: p.name }),
2553
+ p.type === "boolean" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("input", { type: "checkbox", "aria-label": p.name, checked: p.value === true, onChange: (e) => setProp(p.name, e.currentTarget.checked) }) : p.type === "text" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2468
2554
  "input",
2469
2555
  {
2470
2556
  type: "text",
@@ -2479,22 +2565,22 @@ function CanvasInstanceInspector({
2479
2565
  }
2480
2566
  },
2481
2567
  String(p.value)
2482
- ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2568
+ ) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2483
2569
  "select",
2484
2570
  {
2485
2571
  "aria-label": p.name,
2486
2572
  className: "min-w-0 flex-1 rounded border border-border bg-background px-1 py-0.5 text-xs",
2487
2573
  value: String(p.value),
2488
2574
  onChange: (e) => setProp(p.name, e.currentTarget.value),
2489
- children: allComponents.filter((c) => !p.preferred?.length || p.preferred.includes(c.id) || c.id === p.value).map((c) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: c.id, children: c.name }, c.id))
2575
+ children: allComponents.filter((c) => !p.preferred?.length || p.preferred.includes(c.id) || c.id === p.value).map((c) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: c.id, children: c.name }, c.id))
2490
2576
  }
2491
2577
  )
2492
2578
  ] }, p.name)),
2493
- info.overrides.length ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col gap-1", "data-instance-overrides": "", children: [
2494
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-muted-foreground", children: "Overrides" }),
2495
- info.overrides.map((o) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap items-center gap-1", "data-override-layer": o.id, children: [
2496
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "mr-1 truncate", children: o.name }),
2497
- o.groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2579
+ info.overrides.length ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col gap-1", "data-instance-overrides": "", children: [
2580
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-muted-foreground", children: "Overrides" }),
2581
+ info.overrides.map((o) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-wrap items-center gap-1", "data-override-layer": o.id, children: [
2582
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "mr-1 truncate", children: o.name }),
2583
+ o.groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2498
2584
  "button",
2499
2585
  {
2500
2586
  type: "button",
@@ -2511,11 +2597,11 @@ function CanvasInstanceInspector({
2511
2597
  ))
2512
2598
  ] }, o.id))
2513
2599
  ] }) : null,
2514
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
2515
- linked ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2516
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: btn, "data-action": "reset", onClick: () => report(components.resetOverrides(info.id)), children: "Reset all" }),
2517
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: btn, "data-action": "go-to-main", onClick: () => components.goToMainComponent(info.id), children: "Go to main" }),
2518
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2600
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
2601
+ linked ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
2602
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: btn, "data-action": "reset", onClick: () => report(components.resetOverrides(info.id)), children: "Reset all" }),
2603
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: btn, "data-action": "go-to-main", onClick: () => components.goToMainComponent(info.id), children: "Go to main" }),
2604
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2519
2605
  "button",
2520
2606
  {
2521
2607
  type: "button",
@@ -2526,8 +2612,8 @@ function CanvasInstanceInspector({
2526
2612
  children: "Push changes"
2527
2613
  }
2528
2614
  )
2529
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: btn, "data-action": "restore", onClick: () => report(components.restoreMainComponent(info.rootId)), children: "Restore main component" }),
2530
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2615
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: btn, "data-action": "restore", onClick: () => report(components.restoreMainComponent(info.rootId)), children: "Restore main component" }),
2616
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2531
2617
  "button",
2532
2618
  {
2533
2619
  type: "button",
@@ -2544,12 +2630,12 @@ function CanvasInstanceInspector({
2544
2630
  }
2545
2631
 
2546
2632
  // src/canvas/index.ts
2547
- var import_canvas32 = require("@pixerate/editor/canvas");
2633
+ var import_canvas33 = require("@pixerate/editor/canvas");
2548
2634
 
2549
2635
  // src/canvas/MermaidFamilyScene.tsx
2550
- var import_react20 = require("react");
2551
- var import_canvas20 = require("@pixerate/editor/canvas");
2552
- var import_jsx_runtime8 = require("react/jsx-runtime");
2636
+ var import_react21 = require("react");
2637
+ var import_canvas21 = require("@pixerate/editor/canvas");
2638
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2553
2639
  function MermaidFamilyScene({
2554
2640
  scene,
2555
2641
  padding = 16,
@@ -2562,7 +2648,7 @@ function MermaidFamilyScene({
2562
2648
  style,
2563
2649
  title
2564
2650
  }) {
2565
- const uid = (0, import_react20.useId)().replace(/:/g, "");
2651
+ const uid = (0, import_react21.useId)().replace(/:/g, "");
2566
2652
  const marker = (kind) => kind ? `url(#${uid}-${kind})` : void 0;
2567
2653
  const x = scene.x - padding;
2568
2654
  const y = scene.y - padding;
@@ -2580,7 +2666,7 @@ function MermaidFamilyScene({
2580
2666
  cursor: "pointer"
2581
2667
  } : { pointerEvents: "none" };
2582
2668
  const stroke = (mark) => mark.selected ? { stroke: selectionColor, strokeWidth: Math.max(2, mark.strokeWidth ?? 0) } : { stroke: mark.stroke, strokeWidth: mark.strokeWidth };
2583
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
2669
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2584
2670
  "svg",
2585
2671
  {
2586
2672
  className: `pixerate-diagram-scene ${className}`.trim(),
@@ -2593,15 +2679,15 @@ function MermaidFamilyScene({
2593
2679
  style: { display: "block", maxWidth: "100%", height: "auto", overflow: "visible", ...style },
2594
2680
  onClick: interactive ? (event) => onSelect?.(null, event) : void 0,
2595
2681
  children: [
2596
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("defs", { children: [
2597
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("marker", { id: `${uid}-arrowclosed`, viewBox: "0 0 10 10", refX: "9", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto-start-reverse", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M0,0 L10,5 L0,10 Z", style: { fill: markerColor } }) }),
2598
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("marker", { id: `${uid}-arrow`, viewBox: "0 0 10 10", refX: "9", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto-start-reverse", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M0,0 L10,5 L0,10", style: { fill: "none", stroke: markerColor, strokeWidth: 1.5 } }) })
2682
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("defs", { children: [
2683
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("marker", { id: `${uid}-arrowclosed`, viewBox: "0 0 10 10", refX: "9", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto-start-reverse", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M0,0 L10,5 L0,10 Z", style: { fill: markerColor } }) }),
2684
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("marker", { id: `${uid}-arrow`, viewBox: "0 0 10 10", refX: "9", refY: "5", markerWidth: "8", markerHeight: "8", orient: "auto-start-reverse", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M0,0 L10,5 L0,10", style: { fill: "none", stroke: markerColor, strokeWidth: 1.5 } }) })
2599
2685
  ] }),
2600
2686
  scene.marks.map((mark) => {
2601
2687
  const common = { "data-role": mark.role, "data-target": mark.target, "data-selected": mark.selected ? "" : void 0, opacity: mark.opacity, ...handlers(mark) };
2602
2688
  switch (mark.kind) {
2603
2689
  case "rect":
2604
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2690
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2605
2691
  "rect",
2606
2692
  {
2607
2693
  ...common,
@@ -2616,9 +2702,9 @@ function MermaidFamilyScene({
2616
2702
  mark.key
2617
2703
  );
2618
2704
  case "circle":
2619
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("circle", { ...common, cx: mark.cx, cy: mark.cy, r: mark.r, style: { fill: mark.fill, ...stroke(mark) } }, mark.key);
2705
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { ...common, cx: mark.cx, cy: mark.cy, r: mark.r, style: { fill: mark.fill, ...stroke(mark) } }, mark.key);
2620
2706
  case "line":
2621
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2707
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2622
2708
  "line",
2623
2709
  {
2624
2710
  ...common,
@@ -2634,7 +2720,7 @@ function MermaidFamilyScene({
2634
2720
  mark.key
2635
2721
  );
2636
2722
  case "path":
2637
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2723
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2638
2724
  "path",
2639
2725
  {
2640
2726
  ...common,
@@ -2648,14 +2734,14 @@ function MermaidFamilyScene({
2648
2734
  mark.key
2649
2735
  );
2650
2736
  case "text":
2651
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2737
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2652
2738
  "text",
2653
2739
  {
2654
2740
  ...common,
2655
2741
  x: mark.x,
2656
2742
  y: mark.y,
2657
2743
  textAnchor: mark.anchor,
2658
- dominantBaseline: (0, import_canvas20.diagramTextBaseline)(mark.baseline),
2744
+ dominantBaseline: (0, import_canvas21.diagramTextBaseline)(mark.baseline),
2659
2745
  transform: mark.rotate ? `rotate(${mark.rotate} ${mark.x} ${mark.y})` : void 0,
2660
2746
  style: {
2661
2747
  fill: mark.selected ? selectionColor : mark.fill,
@@ -2676,14 +2762,14 @@ function MermaidFamilyScene({
2676
2762
  }
2677
2763
 
2678
2764
  // src/canvas/useMermaidDiagram.ts
2679
- var import_react21 = require("react");
2765
+ var import_react22 = require("react");
2680
2766
  var import_diagram = require("@pixerate/editor/diagram");
2681
- var import_canvas21 = require("@pixerate/editor/canvas");
2767
+ var import_canvas22 = require("@pixerate/editor/canvas");
2682
2768
  function useDiagramState(controller) {
2683
- return (0, import_react21.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
2769
+ return (0, import_react22.useSyncExternalStore)(controller.subscribe, controller.getState, controller.getState);
2684
2770
  }
2685
2771
  function useMermaidDiagram(controllerOrOptions = {}, view = {}) {
2686
- const own = (0, import_react21.useRef)(null);
2772
+ const own = (0, import_react22.useRef)(null);
2687
2773
  let controller;
2688
2774
  if (controllerOrOptions instanceof import_diagram.DiagramController) controller = controllerOrOptions;
2689
2775
  else {
@@ -2693,24 +2779,24 @@ function useMermaidDiagram(controllerOrOptions = {}, view = {}) {
2693
2779
  const layoutOptions = (controllerOrOptions instanceof import_diagram.DiagramController ? void 0 : controllerOrOptions.layoutOptions) ?? view.layoutOptions;
2694
2780
  const sceneTheme = (controllerOrOptions instanceof import_diagram.DiagramController ? void 0 : controllerOrOptions.sceneTheme) ?? view.sceneTheme;
2695
2781
  const state = useDiagramState(controller);
2696
- const canvas = (0, import_react21.useMemo)(
2697
- () => (0, import_canvas21.mermaidToCanvas)(state.document, { ...layoutOptions, editable: state.editable }),
2782
+ const canvas = (0, import_react22.useMemo)(
2783
+ () => (0, import_canvas22.mermaidToCanvas)(state.document, { ...layoutOptions, editable: state.editable }),
2698
2784
  // eslint-disable-next-line react-hooks/exhaustive-deps
2699
2785
  [state.document, state.editable]
2700
2786
  );
2701
- const scene = (0, import_react21.useMemo)(
2702
- () => state.document.tier === "editable" ? (0, import_canvas21.familySceneFromLayout)(state.document.family, state.document.graph, canvas.layout, { theme: { ...import_canvas21.CSS_VARIABLE_DIAGRAM_SCENE_THEME, ...sceneTheme }, selection: state.selection }) : null,
2787
+ const scene = (0, import_react22.useMemo)(
2788
+ () => state.document.tier === "editable" ? (0, import_canvas22.familySceneFromLayout)(state.document.family, state.document.graph, canvas.layout, { theme: { ...import_canvas22.CSS_VARIABLE_DIAGRAM_SCENE_THEME, ...sceneTheme }, selection: state.selection }) : null,
2703
2789
  // eslint-disable-next-line react-hooks/exhaustive-deps
2704
2790
  [state.document, canvas.layout, state.selection]
2705
2791
  );
2706
- const layoutRef = (0, import_react21.useRef)(canvas.layout);
2792
+ const layoutRef = (0, import_react22.useRef)(canvas.layout);
2707
2793
  layoutRef.current = canvas.layout;
2708
- const actions = (0, import_react21.useMemo)(
2794
+ const actions = (0, import_react22.useMemo)(
2709
2795
  () => ({
2710
2796
  apply: (ops, label) => controller.apply(ops, label),
2711
2797
  load: (source, options) => controller.load(source, options),
2712
2798
  moveNodes: (moved, all = moved) => {
2713
- const op = (0, import_canvas21.mermaidMovesFromCanvas)(layoutRef.current, moved, all, { stored: controller.getDocument().meta.layout ?? {} });
2799
+ const op = (0, import_canvas22.mermaidMovesFromCanvas)(layoutRef.current, moved, all, { stored: controller.getDocument().meta.layout ?? {} });
2714
2800
  return op ? controller.apply(op, "Move") : null;
2715
2801
  },
2716
2802
  connect: (source, target, label) => controller.apply({ type: "addEdge", edge: { source, target, ...label ? { label } : {} } }, "Connect"),
@@ -2729,7 +2815,7 @@ function useMermaidDiagram(controllerOrOptions = {}, view = {}) {
2729
2815
  "Rename"
2730
2816
  ),
2731
2817
  renameTarget: (target, label) => {
2732
- const op = (0, import_canvas21.diagramRenameOp)(controller.getDocument(), target, label);
2818
+ const op = (0, import_canvas22.diagramRenameOp)(controller.getDocument(), target, label);
2733
2819
  return op ? controller.apply(op, "Rename") : null;
2734
2820
  },
2735
2821
  select: (ids) => controller.select(ids),
@@ -2742,13 +2828,13 @@ function useMermaidDiagram(controllerOrOptions = {}, view = {}) {
2742
2828
  }
2743
2829
  function useMermaidStream(source, options = {}) {
2744
2830
  const { complete = false, duration = 300, ...layoutOptions } = options;
2745
- const stream = (0, import_react21.useRef)(null);
2746
- if (!stream.current) stream.current = new import_canvas21.DiagramStream(layoutOptions);
2747
- const result = (0, import_react21.useMemo)(() => stream.current.update(source, complete), [source, complete]);
2748
- const [shown, setShown] = (0, import_react21.useState)({ layout: result.layout, settled: true });
2749
- const shownRef = (0, import_react21.useRef)(shown.layout);
2831
+ const stream = (0, import_react22.useRef)(null);
2832
+ if (!stream.current) stream.current = new import_canvas22.DiagramStream(layoutOptions);
2833
+ const result = (0, import_react22.useMemo)(() => stream.current.update(source, complete), [source, complete]);
2834
+ const [shown, setShown] = (0, import_react22.useState)({ layout: result.layout, settled: true });
2835
+ const shownRef = (0, import_react22.useRef)(shown.layout);
2750
2836
  shownRef.current = shown.layout;
2751
- (0, import_react21.useEffect)(() => {
2837
+ (0, import_react22.useEffect)(() => {
2752
2838
  const target = result.layout;
2753
2839
  if (!target) return setShown({ layout: null, settled: true });
2754
2840
  const from = shownRef.current;
@@ -2758,14 +2844,14 @@ function useMermaidStream(source, options = {}) {
2758
2844
  const start = performance.now();
2759
2845
  const step = () => {
2760
2846
  const t = Math.min(1, (performance.now() - start) / duration);
2761
- setShown({ layout: (0, import_canvas21.blendDiagramLayout)(from, target, (0, import_canvas21.easeDiagramTween)(t)), settled: t >= 1 });
2847
+ setShown({ layout: (0, import_canvas22.blendDiagramLayout)(from, target, (0, import_canvas22.easeDiagramTween)(t)), settled: t >= 1 });
2762
2848
  if (t < 1) frame = requestAnimationFrame(step);
2763
2849
  };
2764
2850
  frame = requestAnimationFrame(step);
2765
2851
  return () => cancelAnimationFrame(frame);
2766
2852
  }, [result.layout, duration]);
2767
2853
  const doc = result.document.tier === "editable" ? result.document : null;
2768
- const canvas = (0, import_react21.useMemo)(() => {
2854
+ const canvas = (0, import_react22.useMemo)(() => {
2769
2855
  if (!doc || !shown.layout) return { nodes: [], edges: [] };
2770
2856
  const placed = new Set(Object.keys(shown.layout.positions));
2771
2857
  const graph = {
@@ -2774,24 +2860,24 @@ function useMermaidStream(source, options = {}) {
2774
2860
  groups: doc.graph.groups.filter((g) => placed.has(g.id)),
2775
2861
  edges: doc.graph.edges.filter((e) => placed.has(e.source) && placed.has(e.target))
2776
2862
  };
2777
- return (0, import_canvas21.mermaidToCanvas)({ ...doc, graph }, { layout: shown.layout });
2863
+ return (0, import_canvas22.mermaidToCanvas)({ ...doc, graph }, { layout: shown.layout });
2778
2864
  }, [doc, shown.layout]);
2779
2865
  return { document: doc, ...canvas, layout: shown.layout, settled: shown.settled };
2780
2866
  }
2781
2867
 
2782
2868
  // src/canvas/MermaidDiagramNode.tsx
2783
- var import_canvas22 = require("@pixerate/editor/canvas");
2784
- var import_jsx_runtime9 = require("react/jsx-runtime");
2869
+ var import_canvas23 = require("@pixerate/editor/canvas");
2870
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2785
2871
  function mermaidNodeStyle(styles = {}, selected = false) {
2786
- const paint = (0, import_canvas22.mermaidNodePaint)(styles, selected);
2872
+ const paint = (0, import_canvas23.mermaidNodePaint)(styles, selected);
2787
2873
  const { color, "stroke-width": strokeWidth, "stroke-dasharray": strokeDasharray, ...vars } = paint;
2788
2874
  return { ...vars, color, strokeWidth, strokeDasharray };
2789
2875
  }
2790
2876
  function MermaidDiagramNode({ data, width = 160, height = 56, selected, className = "", children }) {
2791
2877
  const node = data.node;
2792
2878
  if (!node) return null;
2793
- const members = (0, import_canvas22.mermaidNodeMembers)(node.data);
2794
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2879
+ const members = (0, import_canvas23.mermaidNodeMembers)(node.data);
2880
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2795
2881
  "div",
2796
2882
  {
2797
2883
  className: `pixerate-diagram-node ${className}`.trim(),
@@ -2799,14 +2885,14 @@ function MermaidDiagramNode({ data, width = 160, height = 56, selected, classNam
2799
2885
  "data-selected": selected ? "true" : void 0,
2800
2886
  style: { position: "relative", width: "100%", height: "100%", ...mermaidNodeStyle(data.resolvedStyles, selected) },
2801
2887
  children: [
2802
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { viewBox: `0 0 ${width} ${height}`, preserveAspectRatio: "none", width: "100%", height: "100%", style: { position: "absolute", inset: 0, overflow: "visible" }, "aria-hidden": "true", children: (0, import_canvas22.mermaidShapePaths)(node.shape, width, height).map((path, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: path.d, style: { ...import_canvas22.MERMAID_SHAPE_PAINT[path.paint], vectorEffect: "non-scaling-stroke" } }, i)) }),
2803
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2888
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { viewBox: `0 0 ${width} ${height}`, preserveAspectRatio: "none", width: "100%", height: "100%", style: { position: "absolute", inset: 0, overflow: "visible" }, "aria-hidden": "true", children: (0, import_canvas23.mermaidShapePaths)(node.shape, width, height).map((path, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: path.d, style: { ...import_canvas23.MERMAID_SHAPE_PAINT[path.paint], vectorEffect: "non-scaling-stroke" } }, i)) }),
2889
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2804
2890
  "div",
2805
2891
  {
2806
2892
  style: { position: "relative", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: members.length ? "flex-start" : "center", height: "100%", padding: "6px 10px", boxSizing: "border-box", fontSize: 13, lineHeight: 1.3, textAlign: "center", pointerEvents: "none" },
2807
2893
  children: [
2808
- (0, import_canvas22.mermaidLabelLines)(node.label).map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { fontWeight: members.length ? 600 : void 0 }, children: line }, i)),
2809
- members.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { alignSelf: "stretch", marginTop: 4, paddingTop: 4, borderTop: "1px solid var(--pixerate-diagram-node-border)", textAlign: "left", fontSize: 12 }, children: members.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { children: m }, i)) })
2894
+ (0, import_canvas23.mermaidLabelLines)(node.label).map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { style: { fontWeight: members.length ? 600 : void 0 }, children: line }, i)),
2895
+ members.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { alignSelf: "stretch", marginTop: 4, paddingTop: 4, borderTop: "1px solid var(--pixerate-diagram-node-border)", textAlign: "left", fontSize: 12 }, children: members.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: m }, i)) })
2810
2896
  ]
2811
2897
  }
2812
2898
  ),
@@ -2818,7 +2904,7 @@ function MermaidDiagramNode({ data, width = 160, height = 56, selected, classNam
2818
2904
  function MermaidDiagramGroup({ data, selected, className = "", children }) {
2819
2905
  const group = data.group;
2820
2906
  if (!group) return null;
2821
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2907
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
2822
2908
  "div",
2823
2909
  {
2824
2910
  className: `pixerate-diagram-group ${className}`.trim(),
@@ -2833,7 +2919,7 @@ function MermaidDiagramGroup({ data, selected, className = "", children }) {
2833
2919
  color: data.resolvedStyles?.color ?? "var(--muted-foreground, #475569)"
2834
2920
  },
2835
2921
  children: [
2836
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { padding: "6px 10px", fontSize: 12, fontWeight: 600 }, children: (0, import_canvas22.mermaidLabelLines)(group.label).join(" ") }),
2922
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { style: { padding: "6px 10px", fontSize: 12, fontWeight: 600 }, children: (0, import_canvas23.mermaidLabelLines)(group.label).join(" ") }),
2837
2923
  children
2838
2924
  ]
2839
2925
  }
@@ -2841,29 +2927,29 @@ function MermaidDiagramGroup({ data, selected, className = "", children }) {
2841
2927
  }
2842
2928
 
2843
2929
  // src/canvas/MermaidThumbnail.tsx
2844
- var import_react22 = require("react");
2930
+ var import_react23 = require("react");
2845
2931
  var import_diagram2 = require("@pixerate/editor/diagram");
2846
- var import_canvas23 = require("@pixerate/editor/canvas");
2847
- var import_jsx_runtime10 = require("react/jsx-runtime");
2932
+ var import_canvas24 = require("@pixerate/editor/canvas");
2933
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2848
2934
  function MermaidThumbnail({ source, className = "", fallback = null, ...options }) {
2849
- const doc = (0, import_react22.useMemo)(() => typeof source === "string" ? (0, import_diagram2.parseMermaid)(source) : source, [source]);
2935
+ const doc = (0, import_react23.useMemo)(() => typeof source === "string" ? (0, import_diagram2.parseMermaid)(source) : source, [source]);
2850
2936
  const key = JSON.stringify(options);
2851
- const drawn = (0, import_react22.useMemo)(
2852
- () => doc.tier === "editable" && doc.graph.nodes.length ? (0, import_canvas23.mermaidThumbnailSvg)(doc, options) : null,
2937
+ const drawn = (0, import_react23.useMemo)(
2938
+ () => doc.tier === "editable" && doc.graph.nodes.length ? (0, import_canvas24.mermaidThumbnailSvg)(doc, options) : null,
2853
2939
  // eslint-disable-next-line react-hooks/exhaustive-deps
2854
2940
  [doc, key]
2855
2941
  );
2856
- if (!drawn) return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: fallback });
2857
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: `pixerate-diagram-thumbnail ${className}`.trim(), style: { display: "inline-block", lineHeight: 0 }, dangerouslySetInnerHTML: { __html: drawn.svg } });
2942
+ if (!drawn) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: fallback });
2943
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: `pixerate-diagram-thumbnail ${className}`.trim(), style: { display: "inline-block", lineHeight: 0 }, dangerouslySetInnerHTML: { __html: drawn.svg } });
2858
2944
  }
2859
2945
 
2860
2946
  // src/canvas/useDiagramDirector.ts
2861
- var import_react23 = require("react");
2947
+ var import_react24 = require("react");
2862
2948
  var import_diagram3 = require("@pixerate/editor/diagram");
2863
2949
  function useDiagramDirector(controller, options) {
2864
- const placement = (0, import_react23.useRef)(options.placement);
2950
+ const placement = (0, import_react24.useRef)(options.placement);
2865
2951
  placement.current = options.placement;
2866
- const ref = (0, import_react23.useRef)(null);
2952
+ const ref = (0, import_react24.useRef)(null);
2867
2953
  if (!ref.current) {
2868
2954
  const presence = new import_diagram3.PresenceStore();
2869
2955
  ref.current = {
@@ -2874,17 +2960,17 @@ function useDiagramDirector(controller, options) {
2874
2960
  return ref.current;
2875
2961
  }
2876
2962
  function usePresenceState(presence) {
2877
- return (0, import_react23.useSyncExternalStore)(presence.subscribe, presence.getState, presence.getState);
2963
+ return (0, import_react24.useSyncExternalStore)(presence.subscribe, presence.getState, presence.getState);
2878
2964
  }
2879
2965
 
2880
2966
  // src/canvas/DiagramPresenceLayer.tsx
2881
- var import_jsx_runtime11 = require("react/jsx-runtime");
2967
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2882
2968
  function DiagramPresenceLayer({ presence, viewport, className = "" }) {
2883
2969
  const { actors } = usePresenceState(presence);
2884
2970
  if (!actors.length) return null;
2885
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: `pixerate-diagram-presence ${className}`.trim(), "aria-hidden": "true", style: { position: "absolute", inset: 0, pointerEvents: "none", overflow: "hidden", zIndex: 50 }, children: actors.map((a) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { "data-actor": a.id, style: { position: "absolute", left: 0, top: 0, transform: `translate(${a.x * viewport.zoom + viewport.x}px, ${a.y * viewport.zoom + viewport.y}px)` }, children: [
2886
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { width: "18", height: "20", viewBox: "0 0 12 18", style: { display: "block", transform: a.pressed ? "scale(0.85)" : void 0, transformOrigin: "0 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M0,0 L0,14 L4,10.5 L7,17 L9.5,16 L6.5,9.5 L11.5,9.5 Z", style: { fill: a.color, stroke: "#ffffff", strokeWidth: 1 } }) }),
2887
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { position: "absolute", left: 14, top: 16, whiteSpace: "nowrap", borderRadius: 4, padding: "1px 6px", fontSize: 11, fontWeight: 600, color: "#ffffff", background: a.color }, children: a.message ?? a.name })
2971
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: `pixerate-diagram-presence ${className}`.trim(), "aria-hidden": "true", style: { position: "absolute", inset: 0, pointerEvents: "none", overflow: "hidden", zIndex: 50 }, children: actors.map((a) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { "data-actor": a.id, style: { position: "absolute", left: 0, top: 0, transform: `translate(${a.x * viewport.zoom + viewport.x}px, ${a.y * viewport.zoom + viewport.y}px)` }, children: [
2972
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { width: "18", height: "20", viewBox: "0 0 12 18", style: { display: "block", transform: a.pressed ? "scale(0.85)" : void 0, transformOrigin: "0 0" }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M0,0 L0,14 L4,10.5 L7,17 L9.5,16 L6.5,9.5 L11.5,9.5 Z", style: { fill: a.color, stroke: "#ffffff", strokeWidth: 1 } }) }),
2973
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { style: { position: "absolute", left: 14, top: 16, whiteSpace: "nowrap", borderRadius: 4, padding: "1px 6px", fontSize: 11, fontWeight: 600, color: "#ffffff", background: a.color }, children: a.message ?? a.name })
2888
2974
  ] }, a.id)) });
2889
2975
  }
2890
2976
  // Annotate the CommonJS export names for ESM import in node:
@@ -2925,6 +3011,8 @@ function DiagramPresenceLayer({ presence, viewport, className = "" }) {
2925
3011
  SHAPE_NODE_TYPE,
2926
3012
  SHAPE_OPERATIONS,
2927
3013
  ShapeNode,
3014
+ ShapeNodeZoomContext,
3015
+ ShapeNodeZoomProvider,
2928
3016
  TOKEN_BINDINGS_DATA_KEY,
2929
3017
  TOKEN_MODES_DATA_KEY,
2930
3018
  TokenBindingPicker,
@@ -2950,6 +3038,7 @@ function DiagramPresenceLayer({ presence, viewport, className = "" }) {
2950
3038
  bindCanvasToken,
2951
3039
  blendLayout,
2952
3040
  boundsOf,
3041
+ brushstrokeScaleBucket,
2953
3042
  calculateDagreReflowDisplacement,
2954
3043
  calculateDirectionalDisplacement,
2955
3044
  canCombineShapeNodes,
@@ -3015,6 +3104,7 @@ function DiagramPresenceLayer({ presence, viewport, className = "" }) {
3015
3104
  flowSide,
3016
3105
  formatAnimationTime,
3017
3106
  formatOklab,
3107
+ freehandBrushstroke,
3018
3108
  getAbsolutePosition,
3019
3109
  getAnimatableProperty,
3020
3110
  getAnimatedProperties,
@@ -3025,6 +3115,7 @@ function DiagramPresenceLayer({ presence, viewport, className = "" }) {
3025
3115
  getAutoLayoutGrid,
3026
3116
  getAutoLayoutInsertTarget,
3027
3117
  getBindableTokenProperties,
3118
+ getBrushedShapeSvg,
3028
3119
  getCanvasComponentDragId,
3029
3120
  getCanvasTokenProperty,
3030
3121
  getCenteredNodePosition,
@@ -3067,6 +3158,7 @@ function DiagramPresenceLayer({ presence, viewport, className = "" }) {
3067
3158
  isAnimationEasing,
3068
3159
  isAnimationKeyframe,
3069
3160
  isAutoLayoutFrame,
3161
+ isBrushedShape,
3070
3162
  isCanvasComponent,
3071
3163
  isCanvasComponentSet,
3072
3164
  isCanvasGradient,
@@ -3089,7 +3181,9 @@ function DiagramPresenceLayer({ presence, viewport, className = "" }) {
3089
3181
  layoutUpMany,
3090
3182
  linearPositionTrajectory,
3091
3183
  linearTrajectory,
3184
+ listCanvasBrushes,
3092
3185
  listCanvasComponents,
3186
+ loadCanvasBrushstrokeRenderer,
3093
3187
  lockNodes,
3094
3188
  makeSizingCoherent,
3095
3189
  matchArrangeShortcut,
@@ -3124,15 +3218,18 @@ function DiagramPresenceLayer({ presence, viewport, className = "" }) {
3124
3218
  parseSvgPath,
3125
3219
  pasteKeyframes,
3126
3220
  pathBoolean,
3221
+ pathDataToPolyline,
3127
3222
  placeBeside,
3128
3223
  playWebAnimations,
3129
3224
  pointInBezierPath,
3130
3225
  pointInMultiPolygon,
3131
3226
  pointInRings,
3227
+ pointerPenSample,
3132
3228
  polygonArea,
3133
3229
  polygonBoolean,
3134
3230
  polygonToSvgPath,
3135
3231
  positionToSide,
3232
+ profileAlongPolyline,
3136
3233
  pruneCanvasTokenModes,
3137
3234
  pushCanvasInstanceOverrides,
3138
3235
  readAnimatableValue,
@@ -3146,6 +3243,7 @@ function DiagramPresenceLayer({ presence, viewport, className = "" }) {
3146
3243
  removeTrack,
3147
3244
  renameCanvasVariantProperty,
3148
3245
  renameCanvasVariantValue,
3246
+ renderShapeBrushstroke,
3149
3247
  reorderNodes,
3150
3248
  repositionNodesTo,
3151
3249
  resetCanvasInstanceOverrides,
@@ -3206,6 +3304,7 @@ function DiagramPresenceLayer({ presence, viewport, className = "" }) {
3206
3304
  useCanvasArrange,
3207
3305
  useCanvasArrangeShortcuts,
3208
3306
  useCanvasAutoLayout,
3307
+ useCanvasBrushes,
3209
3308
  useCanvasCapture,
3210
3309
  useCanvasClipboard,
3211
3310
  useCanvasComponents,
@@ -3223,7 +3322,9 @@ function DiagramPresenceLayer({ presence, viewport, className = "" }) {
3223
3322
  useMermaidDiagram,
3224
3323
  useMermaidStream,
3225
3324
  usePresenceState,
3325
+ useShapeBrushstroke,
3226
3326
  useStreamingCanvas,
3327
+ validateCanvasBrush,
3227
3328
  withNodeAnimation,
3228
3329
  withStyleSize,
3229
3330
  wouldCreateComponentCycle,