@pixerate/editor 0.127.0 → 0.128.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/agent/index.cjs +2 -2
  2. package/dist/agent/index.d.cts +3 -3
  3. package/dist/agent/index.d.ts +3 -3
  4. package/dist/agent/index.js +1 -1
  5. package/dist/animation-editor/index.d.cts +3 -3
  6. package/dist/animation-editor/index.d.ts +3 -3
  7. package/dist/{arrange-BlfgJ_wt.d.ts → arrange-BUREmgD9.d.ts} +1 -1
  8. package/dist/{arrange-CD6Gh-pd.d.cts → arrange-CKXK_hf7.d.cts} +1 -1
  9. package/dist/{bezier-DBz0IgEt.d.cts → bezier-CvgQiYRg.d.cts} +1 -1
  10. package/dist/{bezier-DWI5MEkI.d.ts → bezier-DP4NnJp3.d.ts} +1 -1
  11. package/dist/{brushTypes-IG7ZZjIN.d.cts → brushTypes-C7N3EBK7.d.cts} +56 -1
  12. package/dist/{brushTypes-IG7ZZjIN.d.ts → brushTypes-C7N3EBK7.d.ts} +56 -1
  13. package/dist/{brushstrokeRender-OW6ENCZG.cjs → brushstrokeRender-JNHVEUFG.cjs} +25 -6
  14. package/dist/brushstrokeRender-JNHVEUFG.cjs.map +1 -0
  15. package/dist/{brushstrokeRender-7RUITO42.js → brushstrokeRender-SII6MG4R.js} +24 -5
  16. package/dist/brushstrokeRender-SII6MG4R.js.map +1 -0
  17. package/dist/{builtins-DMIsnNst.d.cts → builtins-Cc-bH-3U.d.cts} +3 -2
  18. package/dist/{builtins-B5-ipm5u.d.ts → builtins-ZU1GJnUA.d.ts} +3 -2
  19. package/dist/canvas/index.cjs +18 -7
  20. package/dist/canvas/index.cjs.map +1 -1
  21. package/dist/canvas/index.d.cts +22 -10
  22. package/dist/canvas/index.d.ts +22 -10
  23. package/dist/canvas/index.js +14 -3
  24. package/dist/canvas/index.js.map +1 -1
  25. package/dist/{chunk-33SO3QWP.cjs → chunk-DDSO4HS7.cjs} +7 -3
  26. package/dist/chunk-DDSO4HS7.cjs.map +1 -0
  27. package/dist/{chunk-AKU2KQ47.cjs → chunk-DFSZO2B5.cjs} +70 -3
  28. package/dist/chunk-DFSZO2B5.cjs.map +1 -0
  29. package/dist/{chunk-2SDGZAJR.js → chunk-LSXXAJG3.js} +70 -3
  30. package/dist/chunk-LSXXAJG3.js.map +1 -0
  31. package/dist/{chunk-UABQTYQF.js → chunk-SVYE5HIM.js} +6 -2
  32. package/dist/chunk-SVYE5HIM.js.map +1 -0
  33. package/dist/commands/index.cjs +2 -2
  34. package/dist/commands/index.d.cts +3 -3
  35. package/dist/commands/index.d.ts +3 -3
  36. package/dist/commands/index.js +1 -1
  37. package/dist/{export-CcldobdN.d.cts → export-BkYQvV56.d.cts} +3 -3
  38. package/dist/{export-PGhOpDmz.d.ts → export-DHrFJ8r_.d.ts} +3 -3
  39. package/dist/image-editor/index.d.cts +9 -9
  40. package/dist/image-editor/index.d.ts +9 -9
  41. package/dist/{opentype-BgqvmGT-.d.cts → opentype-BOewaGQx.d.cts} +1 -1
  42. package/dist/{opentype-01rMIuQR.d.ts → opentype-sQrF3Ry1.d.ts} +1 -1
  43. package/dist/paint/index.d.cts +2 -2
  44. package/dist/paint/index.d.ts +2 -2
  45. package/dist/paint-editor/index.d.cts +6 -6
  46. package/dist/paint-editor/index.d.ts +6 -6
  47. package/dist/{pathfinder-D-h0Imus.d.ts → pathfinder-BwJx0_zM.d.ts} +2 -2
  48. package/dist/{pathfinder-DgG0Z9Lr.d.cts → pathfinder-CnkW7zLI.d.cts} +2 -2
  49. package/dist/{rand-CfinE-1c.d.cts → rand-DTXAssW1.d.cts} +4 -4
  50. package/dist/{rand-DtazXGOB.d.ts → rand-pQQ2sJTk.d.ts} +4 -4
  51. package/dist/{svg-DLBBPQP9.d.cts → svg-C4LlFnEw.d.cts} +1 -1
  52. package/dist/{svg-BRLwcibA.d.ts → svg-CUzZa0EO.d.ts} +1 -1
  53. package/dist/vector/index.d.cts +8 -8
  54. package/dist/vector/index.d.ts +8 -8
  55. package/dist/{warp-q8FK5HHi.d.ts → warp-CIsO617e.d.ts} +1 -1
  56. package/dist/{warp-C13L_GRn.d.cts → warp-D62N_5VK.d.cts} +1 -1
  57. package/package.json +1 -1
  58. package/skills/pixerate-canvas/SKILL.md +11 -2
  59. package/dist/brushstrokeRender-7RUITO42.js.map +0 -1
  60. package/dist/brushstrokeRender-OW6ENCZG.cjs.map +0 -1
  61. package/dist/chunk-2SDGZAJR.js.map +0 -1
  62. package/dist/chunk-33SO3QWP.cjs.map +0 -1
  63. package/dist/chunk-AKU2KQ47.cjs.map +0 -1
  64. package/dist/chunk-UABQTYQF.js.map +0 -1
@@ -5,7 +5,7 @@
5
5
  var _chunkDK6QBGCScjs = require('../chunk-DK6QBGCS.cjs');
6
6
 
7
7
 
8
- var _chunkAKU2KQ47cjs = require('../chunk-AKU2KQ47.cjs');
8
+ var _chunkDFSZO2B5cjs = require('../chunk-DFSZO2B5.cjs');
9
9
 
10
10
 
11
11
 
@@ -1593,7 +1593,7 @@ function createCanvasComponentToolProvider(controller, options = { id: "canvas-c
1593
1593
  ({ id }) => check(controller.restoreMainComponent(id))
1594
1594
  )
1595
1595
  ];
1596
- if (_chunkAKU2KQ47cjs.hasVariantCommands.call(void 0, controller)) {
1596
+ if (_chunkDFSZO2B5cjs.hasVariantCommands.call(void 0, controller)) {
1597
1597
  const SET = { type: "string", description: "Component set, or one of its variants (default: the selection\u2019s set)." };
1598
1598
  const VARIANT = { type: "string", description: "Variant id (default: the first selected variant)." };
1599
1599
  const VALUES = { type: "object", additionalProperties: { type: "string" }, description: 'Variant property \u2192 value, e.g. { "Size": "Medium" }.' };
@@ -1,4 +1,4 @@
1
- import { b as CanvasNode, e as CanvasEdge, X as XYPosition, S as Side } from '../brushTypes-IG7ZZjIN.cjs';
1
+ import { c as CanvasNode, f as CanvasEdge, X as XYPosition, S as Side } from '../brushTypes-C7N3EBK7.cjs';
2
2
  export { J as JsonSchema, a as JsonSchemaType, S as SchemaValidationError, v as validateJsonSchema } from '../schema-Di0CS6Pe.cjs';
3
3
  import { a as AgentToolProvider, A as AgentTool } from '../registry-BqA1AZt0.cjs';
4
4
  export { c as AgentToolHandler, d as McpListToolsResult, e as McpToolContent, M as McpToolDefinition, b as McpToolResult, f as TOOL_NAMESPACE_SEPARATOR, g as ToolCallContext, h as ToolCallError, i as ToolErrorCode, T as ToolRegistry, j as ToolRegistryError, k as ToolRegistryOptions, l as createToolRegistry, t as toToolResult } from '../registry-BqA1AZt0.cjs';
@@ -9,11 +9,11 @@ export { C as CAPTURE_EXCLUDE_SELECTOR, a as CAPTURE_OVERLAY_SELECTORS, E as Ele
9
9
  import { Editor } from '@tiptap/core';
10
10
  import { S as SpreadsheetController } from '../controller-w6eRTjF8.cjs';
11
11
  import { A as AgentTypingOptions } from '../agent-caret-BmYhQF7L.cjs';
12
- import { b as ComponentCommandTarget } from '../builtins-DMIsnNst.cjs';
12
+ import { b as ComponentCommandTarget } from '../builtins-Cc-bH-3U.cjs';
13
13
  import '@tiptap/pm/state';
14
14
  import '@tiptap/pm/view';
15
15
  import '../types-DsiXGmjo.cjs';
16
- import '../arrange-CD6Gh-pd.cjs';
16
+ import '../arrange-CKXK_hf7.cjs';
17
17
  import '../registry-CaR7LC6W.cjs';
18
18
 
19
19
  /**
@@ -1,4 +1,4 @@
1
- import { b as CanvasNode, e as CanvasEdge, X as XYPosition, S as Side } from '../brushTypes-IG7ZZjIN.js';
1
+ import { c as CanvasNode, f as CanvasEdge, X as XYPosition, S as Side } from '../brushTypes-C7N3EBK7.js';
2
2
  export { J as JsonSchema, a as JsonSchemaType, S as SchemaValidationError, v as validateJsonSchema } from '../schema-Di0CS6Pe.js';
3
3
  import { a as AgentToolProvider, A as AgentTool } from '../registry-D-4fit9C.js';
4
4
  export { c as AgentToolHandler, d as McpListToolsResult, e as McpToolContent, M as McpToolDefinition, b as McpToolResult, f as TOOL_NAMESPACE_SEPARATOR, g as ToolCallContext, h as ToolCallError, i as ToolErrorCode, T as ToolRegistry, j as ToolRegistryError, k as ToolRegistryOptions, l as createToolRegistry, t as toToolResult } from '../registry-D-4fit9C.js';
@@ -9,11 +9,11 @@ export { C as CAPTURE_EXCLUDE_SELECTOR, a as CAPTURE_OVERLAY_SELECTORS, E as Ele
9
9
  import { Editor } from '@tiptap/core';
10
10
  import { S as SpreadsheetController } from '../controller-w6eRTjF8.js';
11
11
  import { A as AgentTypingOptions } from '../agent-caret-BmYhQF7L.js';
12
- import { b as ComponentCommandTarget } from '../builtins-B5-ipm5u.js';
12
+ import { b as ComponentCommandTarget } from '../builtins-ZU1GJnUA.js';
13
13
  import '@tiptap/pm/state';
14
14
  import '@tiptap/pm/view';
15
15
  import '../types-DsiXGmjo.js';
16
- import '../arrange-BlfgJ_wt.js';
16
+ import '../arrange-BUREmgD9.js';
17
17
  import '../registry-rVtFJjRM.js';
18
18
 
19
19
  /**
@@ -5,7 +5,7 @@ import {
5
5
  } from "../chunk-47WWV3LI.js";
6
6
  import {
7
7
  hasVariantCommands
8
- } from "../chunk-2SDGZAJR.js";
8
+ } from "../chunk-LSXXAJG3.js";
9
9
  import {
10
10
  ensureLayout,
11
11
  getLayoutedNodes,
@@ -2,15 +2,15 @@ import { a6 as MotionCommand, a7 as MotionShot, a8 as MotionScene, L as VectorNo
2
2
  export { az as FLAIR_EASES, aA as FLAIR_EXPORT_VERSION, aB as FlairEase, aC as FlairEaseName, aD as FlairSpringEase, aE as FlairSvgAnimation, aF as MOTION_BLENDS, aG as MOTION_CAMERA_MS, aH as MOTION_CASCADES, aI as MOTION_CLIP_TARGET, aJ as MOTION_COMMAND_TYPES, aK as MOTION_DEFAULT_DURATIONS, aL as MOTION_DEFAULT_HOLD, aM as MOTION_DIRECTIONS, aN as MOTION_DRAW_MS_PER_UNIT, aO as MOTION_DRAW_RANGE, aP as MOTION_DRIVEN_PROPERTIES, aQ as MOTION_ENTER_STYLES, aR as MOTION_EXIT_STYLES, aS as MOTION_IRIS_SHAPES, aT as MOTION_REPEAT_MODES, aU as MOTION_SPLIT_ORIENTATIONS, aV as MOTION_TEXT_UNITS, aW as MOTION_TRIGGERS, aX as MotionColorPulseCommand, aY as MotionCommandBase, aZ as MotionDrawCommand, a_ as MotionDrawOrder, a$ as MotionEffectCommand, b0 as MotionEnterCommand, b1 as MotionExitCommand, b2 as MotionFadeCommand, b3 as MotionFollowCommand, b4 as MotionMatchCommand, b5 as MotionMorphCommand, b6 as MotionMoveCommand, b7 as MotionPlayCommand, b8 as MotionPulseCommand, b9 as MotionRotateCommand, ba as MotionScaleCommand, bb as MotionShakeCommand, bc as MotionStyleCommand, bd as MotionTeeterCommand, be as MotionTrigger, bf as MotionWaitCommand, bg as MotionWaveCommand, bh as MotionWiggleCommand, bi as flairAtLeast, bj as flairCurveFor, bk as flairEaseFor, bl as motionFlairPrimitive, bm as toFlairEffectDocument, bn as toFlairSvgMotion, bo as toFlairVectorEffect } from '../helpers-C5aAd44p.cjs';
3
3
  import { f as MotionBehavior, b as AnimationLoopMode } from '../evaluate-BsxYieLN.cjs';
4
4
  import { b as AnimationEasing } from '../easing-lM0Xo9Ni.cjs';
5
- import { A as AffineMatrix, B as BezierPath } from '../bezier-DBz0IgEt.cjs';
6
- import { V as VectorSvgExportOptions } from '../svg-DLBBPQP9.cjs';
5
+ import { A as AffineMatrix, B as BezierPath } from '../bezier-CvgQiYRg.cjs';
6
+ import { V as VectorSvgExportOptions } from '../svg-C4LlFnEw.cjs';
7
7
  import { Z as ZipReadOptions } from '../zip-4nG0YAH7.cjs';
8
8
  import { A as AnimationPlayer, C as Clock } from '../player-CmbY3218.cjs';
9
9
  import { H as HistoryManager } from '../HistoryManager-DeQQMBCj.cjs';
10
10
  import { a as AgentToolProvider } from '../registry-BqA1AZt0.cjs';
11
11
  import { J as JsonSchema } from '../schema-Di0CS6Pe.cjs';
12
12
  import '../types-CwMPoRMU.cjs';
13
- import '../brushTypes-IG7ZZjIN.cjs';
13
+ import '../brushTypes-C7N3EBK7.cjs';
14
14
  import '../types-DsiXGmjo.cjs';
15
15
 
16
16
  /**
@@ -2,15 +2,15 @@ import { a6 as MotionCommand, a7 as MotionShot, a8 as MotionScene, L as VectorNo
2
2
  export { az as FLAIR_EASES, aA as FLAIR_EXPORT_VERSION, aB as FlairEase, aC as FlairEaseName, aD as FlairSpringEase, aE as FlairSvgAnimation, aF as MOTION_BLENDS, aG as MOTION_CAMERA_MS, aH as MOTION_CASCADES, aI as MOTION_CLIP_TARGET, aJ as MOTION_COMMAND_TYPES, aK as MOTION_DEFAULT_DURATIONS, aL as MOTION_DEFAULT_HOLD, aM as MOTION_DIRECTIONS, aN as MOTION_DRAW_MS_PER_UNIT, aO as MOTION_DRAW_RANGE, aP as MOTION_DRIVEN_PROPERTIES, aQ as MOTION_ENTER_STYLES, aR as MOTION_EXIT_STYLES, aS as MOTION_IRIS_SHAPES, aT as MOTION_REPEAT_MODES, aU as MOTION_SPLIT_ORIENTATIONS, aV as MOTION_TEXT_UNITS, aW as MOTION_TRIGGERS, aX as MotionColorPulseCommand, aY as MotionCommandBase, aZ as MotionDrawCommand, a_ as MotionDrawOrder, a$ as MotionEffectCommand, b0 as MotionEnterCommand, b1 as MotionExitCommand, b2 as MotionFadeCommand, b3 as MotionFollowCommand, b4 as MotionMatchCommand, b5 as MotionMorphCommand, b6 as MotionMoveCommand, b7 as MotionPlayCommand, b8 as MotionPulseCommand, b9 as MotionRotateCommand, ba as MotionScaleCommand, bb as MotionShakeCommand, bc as MotionStyleCommand, bd as MotionTeeterCommand, be as MotionTrigger, bf as MotionWaitCommand, bg as MotionWaveCommand, bh as MotionWiggleCommand, bi as flairAtLeast, bj as flairCurveFor, bk as flairEaseFor, bl as motionFlairPrimitive, bm as toFlairEffectDocument, bn as toFlairSvgMotion, bo as toFlairVectorEffect } from '../helpers-CPWcK504.js';
3
3
  import { f as MotionBehavior, b as AnimationLoopMode } from '../evaluate-BbCeF6pt.js';
4
4
  import { b as AnimationEasing } from '../easing-lM0Xo9Ni.js';
5
- import { A as AffineMatrix, B as BezierPath } from '../bezier-DWI5MEkI.js';
6
- import { V as VectorSvgExportOptions } from '../svg-BRLwcibA.js';
5
+ import { A as AffineMatrix, B as BezierPath } from '../bezier-DP4NnJp3.js';
6
+ import { V as VectorSvgExportOptions } from '../svg-CUzZa0EO.js';
7
7
  import { Z as ZipReadOptions } from '../zip-4nG0YAH7.js';
8
8
  import { A as AnimationPlayer, C as Clock } from '../player-BK2kKbfd.js';
9
9
  import { H as HistoryManager } from '../HistoryManager-DWSLd6Tf.js';
10
10
  import { a as AgentToolProvider } from '../registry-D-4fit9C.js';
11
11
  import { J as JsonSchema } from '../schema-Di0CS6Pe.js';
12
12
  import '../types-CwMPoRMU.js';
13
- import '../brushTypes-IG7ZZjIN.js';
13
+ import '../brushTypes-C7N3EBK7.js';
14
14
  import '../types-DsiXGmjo.js';
15
15
 
16
16
  /**
@@ -1,4 +1,4 @@
1
- import { R as Rect, X as XYPosition, b as CanvasNode, c as CanvasNodeStyle } from './brushTypes-IG7ZZjIN.js';
1
+ import { R as Rect, X as XYPosition, c as CanvasNode, d as CanvasNodeStyle } from './brushTypes-C7N3EBK7.js';
2
2
 
3
3
  /**
4
4
  * Canvas arrangement actions that have keyboard shortcuts.
@@ -1,4 +1,4 @@
1
- import { R as Rect, X as XYPosition, b as CanvasNode, c as CanvasNodeStyle } from './brushTypes-IG7ZZjIN.cjs';
1
+ import { R as Rect, X as XYPosition, c as CanvasNode, d as CanvasNodeStyle } from './brushTypes-C7N3EBK7.cjs';
2
2
 
3
3
  /**
4
4
  * Canvas arrangement actions that have keyboard shortcuts.
@@ -1,4 +1,4 @@
1
- import { P as Point, d as CanvasBrushstroke } from './brushTypes-IG7ZZjIN.cjs';
1
+ import { P as Point, e as CanvasBrushstroke } from './brushTypes-C7N3EBK7.cjs';
2
2
  import { C as CanvasGradientDef, S as SvgGradientDef } from './helpers-C5aAd44p.cjs';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { P as Point, d as CanvasBrushstroke } from './brushTypes-IG7ZZjIN.js';
1
+ import { P as Point, e as CanvasBrushstroke } from './brushTypes-C7N3EBK7.js';
2
2
  import { C as CanvasGradientDef, S as SvgGradientDef } from './helpers-CPWcK504.js';
3
3
 
4
4
  /**
@@ -245,12 +245,67 @@ interface CanvasBrushSettings {
245
245
  * tip settings give one.
246
246
  */
247
247
  type CanvasBrush = string | CanvasBrushSettings;
248
+ /** A gradient stop of brushed stroke paint (the paint engine's `PaintGradientStop`). */
249
+ interface CanvasBrushPaintStop {
250
+ /** 0..1 along the gradient. */
251
+ offset: number;
252
+ /** `#rrggbb`, or `paint` (the stroke colour) / `secondary` (white). */
253
+ color: string;
254
+ /** 0..1 (default 1): multiplies the brush's flow where this colour is laid. */
255
+ opacity?: number;
256
+ /** Where between this stop and the next (0.05..0.95) the colours are half mixed (default 0.5). */
257
+ midpoint?: number;
258
+ }
259
+ /**
260
+ * What moves a brushed stroke along its gradient. `distance` is in canvas units of the path
261
+ * (default 300, mirrored), so the colours keep their place at every zoom. Canvas strokes carry no
262
+ * timing, so the paint engine's `velocity` and `time` mappings are refused.
263
+ */
264
+ type CanvasBrushPaintMapping = {
265
+ by: 'distance';
266
+ length?: number;
267
+ repeat?: 'clamp' | 'repeat' | 'mirror';
268
+ unit?: 'px' | 'dabs';
269
+ } | {
270
+ by: 'pressure';
271
+ } | {
272
+ by: 'tilt';
273
+ } | {
274
+ by: 'direction';
275
+ } | {
276
+ by: 'across-tip';
277
+ } | {
278
+ by: 'random';
279
+ every?: number;
280
+ };
281
+ /**
282
+ * What a brushed stroke paints with, instead of its stroke colour (the paint engine's
283
+ * `PaintSource`, described structurally so the canvas types never import the paint engine): one
284
+ * colour, or gradient paint sampled dab by dab. The stroke colour still gives the alpha and fills
285
+ * `paint` stops.
286
+ */
287
+ type CanvasBrushPaint = {
288
+ type: 'color';
289
+ color: string;
290
+ } | {
291
+ type: 'gradient';
292
+ /** 2..16 stops sorted by offset. */
293
+ stops: CanvasBrushPaintStop[];
294
+ /** How neighbouring stops mix (default `pigment`). */
295
+ space?: 'pigment' | 'oklab' | 'srgb';
296
+ /** Default: distance, 300 canvas units, mirror. */
297
+ map?: CanvasBrushPaintMapping;
298
+ /** 0 (hard steps) .. 1 (smooth, default). */
299
+ softness?: number;
300
+ };
248
301
  /**
249
302
  * What makes a path shape a brushed stroke: the brush, plus pen profiles spread evenly along the
250
303
  * path's length (first value at the start, last at the end).
251
304
  */
252
305
  interface CanvasBrushstroke {
253
306
  brush: CanvasBrush;
307
+ /** Gradient paint (or one colour) instead of the stroke colour. */
308
+ paint?: CanvasBrushPaint;
254
309
  /** Pressure 0..1 along the length (default full pressure). */
255
310
  pressure?: number[];
256
311
  /** Pointer Events pen tilt in degrees (−90..90) along the length. */
@@ -266,4 +321,4 @@ interface CanvasBrushPreset {
266
321
  size: number;
267
322
  }
268
323
 
269
- export type { CanvasBrush as C, DirectionalDisplacementOptions as D, ExplodeNodeOptions as E, FanOutTrajectoryOptions as F, GraphDifferences as G, IncrementalLayoutOptions as I, NodeTransition as N, Point as P, Rect as R, Side as S, TrajectoryFunction as T, XYPosition as X, CanvasBrushPreset as a, CanvasNode as b, CanvasNodeStyle as c, CanvasBrushstroke as d, CanvasEdge as e, CanvasLayoutOptions as f, PlaceBesideOptions as g, ReflowDisplacementOptions as h, CanvasClipboardPayload as i, Position as j, CanvasBrushSettings as k, CanvasDockingCallbacks as l, CollapseNodeOptions as m, DisplacementDirection as n, DockStrategy as o, ExplosionSnapshot as p, TrajectoryPoint as q };
324
+ export type { CanvasBrush as C, DirectionalDisplacementOptions as D, ExplodeNodeOptions as E, FanOutTrajectoryOptions as F, GraphDifferences as G, IncrementalLayoutOptions as I, NodeTransition as N, Point as P, Rect as R, Side as S, TrajectoryFunction as T, XYPosition as X, CanvasBrushPaint as a, CanvasBrushPreset as b, CanvasNode as c, CanvasNodeStyle as d, CanvasBrushstroke as e, CanvasEdge as f, CanvasLayoutOptions as g, PlaceBesideOptions as h, ReflowDisplacementOptions as i, CanvasClipboardPayload as j, Position as k, CanvasBrushPaintMapping as l, CanvasBrushPaintStop as m, CanvasBrushSettings as n, CanvasDockingCallbacks as o, CollapseNodeOptions as p, DisplacementDirection as q, DockStrategy as r, ExplosionSnapshot as s, TrajectoryPoint as t };
@@ -245,12 +245,67 @@ interface CanvasBrushSettings {
245
245
  * tip settings give one.
246
246
  */
247
247
  type CanvasBrush = string | CanvasBrushSettings;
248
+ /** A gradient stop of brushed stroke paint (the paint engine's `PaintGradientStop`). */
249
+ interface CanvasBrushPaintStop {
250
+ /** 0..1 along the gradient. */
251
+ offset: number;
252
+ /** `#rrggbb`, or `paint` (the stroke colour) / `secondary` (white). */
253
+ color: string;
254
+ /** 0..1 (default 1): multiplies the brush's flow where this colour is laid. */
255
+ opacity?: number;
256
+ /** Where between this stop and the next (0.05..0.95) the colours are half mixed (default 0.5). */
257
+ midpoint?: number;
258
+ }
259
+ /**
260
+ * What moves a brushed stroke along its gradient. `distance` is in canvas units of the path
261
+ * (default 300, mirrored), so the colours keep their place at every zoom. Canvas strokes carry no
262
+ * timing, so the paint engine's `velocity` and `time` mappings are refused.
263
+ */
264
+ type CanvasBrushPaintMapping = {
265
+ by: 'distance';
266
+ length?: number;
267
+ repeat?: 'clamp' | 'repeat' | 'mirror';
268
+ unit?: 'px' | 'dabs';
269
+ } | {
270
+ by: 'pressure';
271
+ } | {
272
+ by: 'tilt';
273
+ } | {
274
+ by: 'direction';
275
+ } | {
276
+ by: 'across-tip';
277
+ } | {
278
+ by: 'random';
279
+ every?: number;
280
+ };
281
+ /**
282
+ * What a brushed stroke paints with, instead of its stroke colour (the paint engine's
283
+ * `PaintSource`, described structurally so the canvas types never import the paint engine): one
284
+ * colour, or gradient paint sampled dab by dab. The stroke colour still gives the alpha and fills
285
+ * `paint` stops.
286
+ */
287
+ type CanvasBrushPaint = {
288
+ type: 'color';
289
+ color: string;
290
+ } | {
291
+ type: 'gradient';
292
+ /** 2..16 stops sorted by offset. */
293
+ stops: CanvasBrushPaintStop[];
294
+ /** How neighbouring stops mix (default `pigment`). */
295
+ space?: 'pigment' | 'oklab' | 'srgb';
296
+ /** Default: distance, 300 canvas units, mirror. */
297
+ map?: CanvasBrushPaintMapping;
298
+ /** 0 (hard steps) .. 1 (smooth, default). */
299
+ softness?: number;
300
+ };
248
301
  /**
249
302
  * What makes a path shape a brushed stroke: the brush, plus pen profiles spread evenly along the
250
303
  * path's length (first value at the start, last at the end).
251
304
  */
252
305
  interface CanvasBrushstroke {
253
306
  brush: CanvasBrush;
307
+ /** Gradient paint (or one colour) instead of the stroke colour. */
308
+ paint?: CanvasBrushPaint;
254
309
  /** Pressure 0..1 along the length (default full pressure). */
255
310
  pressure?: number[];
256
311
  /** Pointer Events pen tilt in degrees (−90..90) along the length. */
@@ -266,4 +321,4 @@ interface CanvasBrushPreset {
266
321
  size: number;
267
322
  }
268
323
 
269
- export type { CanvasBrush as C, DirectionalDisplacementOptions as D, ExplodeNodeOptions as E, FanOutTrajectoryOptions as F, GraphDifferences as G, IncrementalLayoutOptions as I, NodeTransition as N, Point as P, Rect as R, Side as S, TrajectoryFunction as T, XYPosition as X, CanvasBrushPreset as a, CanvasNode as b, CanvasNodeStyle as c, CanvasBrushstroke as d, CanvasEdge as e, CanvasLayoutOptions as f, PlaceBesideOptions as g, ReflowDisplacementOptions as h, CanvasClipboardPayload as i, Position as j, CanvasBrushSettings as k, CanvasDockingCallbacks as l, CollapseNodeOptions as m, DisplacementDirection as n, DockStrategy as o, ExplosionSnapshot as p, TrajectoryPoint as q };
324
+ export type { CanvasBrush as C, DirectionalDisplacementOptions as D, ExplodeNodeOptions as E, FanOutTrajectoryOptions as F, GraphDifferences as G, IncrementalLayoutOptions as I, NodeTransition as N, Point as P, Rect as R, Side as S, TrajectoryFunction as T, XYPosition as X, CanvasBrushPaint as a, CanvasBrushPreset as b, CanvasNode as c, CanvasNodeStyle as d, CanvasBrushstroke as e, CanvasEdge as f, CanvasLayoutOptions as g, PlaceBesideOptions as h, ReflowDisplacementOptions as i, CanvasClipboardPayload as j, Position as k, CanvasBrushPaintMapping as l, CanvasBrushPaintStop as m, CanvasBrushSettings as n, CanvasDockingCallbacks as o, CollapseNodeOptions as p, DisplacementDirection as q, DockStrategy as r, ExplosionSnapshot as s, TrajectoryPoint as t };
@@ -3,7 +3,7 @@
3
3
  var _chunkW4LNKTHTcjs = require('./chunk-W4LNKTHT.cjs');
4
4
 
5
5
 
6
- var _chunk33SO3QWPcjs = require('./chunk-33SO3QWP.cjs');
6
+ var _chunkDDSO4HS7cjs = require('./chunk-DDSO4HS7.cjs');
7
7
 
8
8
 
9
9
  var _chunk2YQONY6Gcjs = require('./chunk-2YQONY6G.cjs');
@@ -12,7 +12,9 @@ var _chunk2YQONY6Gcjs = require('./chunk-2YQONY6G.cjs');
12
12
 
13
13
 
14
14
  var _chunkZ6OUCS2Kcjs = require('./chunk-Z6OUCS2K.cjs');
15
- require('./chunk-6GFRKLLS.cjs');
15
+
16
+
17
+ var _chunk6GFRKLLScjs = require('./chunk-6GFRKLLS.cjs');
16
18
  require('./chunk-SYPFUL5B.cjs');
17
19
  require('./chunk-J5BA3BQ6.cjs');
18
20
  require('./chunk-DCLJNVZS.cjs');
@@ -44,6 +46,21 @@ function resolveCanvasBrush(brush, width) {
44
46
  }
45
47
  return { size, ...brush };
46
48
  }
49
+ function resolveCanvasPaint(paint) {
50
+ const source = _chunk6GFRKLLScjs.parsePaintSource.call(void 0, paint, "paint");
51
+ if (source.type === "gradient" && (source.map.by === "velocity" || source.map.by === "time")) {
52
+ throw new Error(`paint.map.by "${source.map.by}" needs timed samples, which canvas strokes do not record; use distance, pressure, tilt, direction, across-tip or random.`);
53
+ }
54
+ return source;
55
+ }
56
+ function shapePaint(shape) {
57
+ if (shape.brush.paint === void 0 || shape.brush.paint === null) return null;
58
+ try {
59
+ return resolveCanvasPaint(shape.brush.paint);
60
+ } catch (e) {
61
+ return null;
62
+ }
63
+ }
47
64
  function strokeColor(shape) {
48
65
  const gradient = _chunkIZ4WRXZAcjs.resolveCanvasGradient.call(void 0, _nullishCoalesce(shape.strokeGradient, () => ( shape.stroke)));
49
66
  const css = gradient ? _nullishCoalesce(_optionalChain([gradient, 'access', _ => _.stops, 'access', _2 => _2[0], 'optionalAccess', _3 => _3.color]), () => ( "#000")) : typeof shape.stroke === "string" && shape.stroke !== "none" ? shape.stroke : "#000";
@@ -55,7 +72,7 @@ var cache = new (0, _chunkZ6OUCS2Kcjs.BrushstrokeCache)(128);
55
72
  var urls = /* @__PURE__ */ new WeakMap();
56
73
  function renderShapeBrushstrokeNow(shape, scale) {
57
74
  const brush = resolveCanvasBrush(shape.brush.brush, _nullishCoalesce(shape.strokeWidth, () => ( 3)));
58
- const points = _chunk33SO3QWPcjs.pathDataToPolyline.call(void 0, shape.d);
75
+ const points = _chunkDDSO4HS7cjs.pathDataToPolyline.call(void 0, shape.d);
59
76
  if (!points.length) return null;
60
77
  const { pressure, tiltX, tiltY } = shape.brush;
61
78
  const input = {
@@ -64,7 +81,8 @@ function renderShapeBrushstrokeNow(shape, scale) {
64
81
  ..._optionalChain([tiltX, 'optionalAccess', _5 => _5.length]) ? { tiltX } : {},
65
82
  ..._optionalChain([tiltY, 'optionalAccess', _6 => _6.length]) ? { tiltY } : {}
66
83
  };
67
- const stroke = cache.render(input, brush, { scale, color: strokeColor(shape) });
84
+ const paint = shapePaint(shape);
85
+ const stroke = cache.render(input, brush, { scale, color: strokeColor(shape), ...paint ? { paint } : {} });
68
86
  if (!stroke.bounds) return null;
69
87
  let href = urls.get(stroke);
70
88
  if (href === void 0) {
@@ -87,5 +105,6 @@ function brushedShapeSvgNow(shape, size, scale) {
87
105
 
88
106
 
89
107
 
90
- exports.brushedShapeSvgNow = brushedShapeSvgNow; exports.listCanvasBrushes = listCanvasBrushes; exports.renderShapeBrushstrokeNow = renderShapeBrushstrokeNow; exports.resolveCanvasBrush = resolveCanvasBrush;
91
- //# sourceMappingURL=brushstrokeRender-OW6ENCZG.cjs.map
108
+
109
+ exports.brushedShapeSvgNow = brushedShapeSvgNow; exports.listCanvasBrushes = listCanvasBrushes; exports.renderShapeBrushstrokeNow = renderShapeBrushstrokeNow; exports.resolveCanvasBrush = resolveCanvasBrush; exports.resolveCanvasPaint = resolveCanvasPaint;
110
+ //# sourceMappingURL=brushstrokeRender-JNHVEUFG.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/editor/editor/packages/core/dist/brushstrokeRender-JNHVEUFG.cjs","../src/canvas/brushstrokeRender.ts"],"names":[],"mappings":"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","file":"/home/runner/work/editor/editor/packages/core/dist/brushstrokeRender-JNHVEUFG.cjs","sourcesContent":[null,"/**\n * The lazily loaded half of brushed freehand strokes (`./brushstroke.ts` imports it on first use):\n * the paint engine's dry brushstroke renderer, the paint presets and a CSS colour parser. Keep\n * every import of the paint engine in this file, so the canvas entry never reaches it statically.\n */\nimport { BrushstrokeCache, brushstrokeDataUrl, isBrushstrokeBrush, type BrushstrokeBrush, type BrushstrokeImage } from '../paint/brushstroke.js';\nimport { parsePaintSource, type PaintSource } from '../paint/gradient-paint.js';\nimport { BUILTIN_BRUSHES } from '../paint-editor/brushes.js';\nimport { parseCssColor } from '../image-editor/layers/css-color.js';\nimport { resolveCanvasGradient } from './gradient.js';\nimport { formatNumber, getShapeSvg, type ShapeSize } from './shapeGeometry.js';\nimport { pathDataToPolyline, type BrushedPathShape, type CanvasBrush, type CanvasBrushPaint, type CanvasBrushPreset, type CanvasBrushstrokeImage } from './brushstroke.js';\n\nconst DRY = BUILTIN_BRUSHES.filter((b) => isBrushstrokeBrush(b));\n\nexport function listCanvasBrushes(): CanvasBrushPreset[] {\n\treturn DRY.map((b) => ({ id: b.id, name: b.name, category: b.category, size: b.tip.size }));\n}\n\n/** The paint engine brush for a canvas brush at stroke width `width`; throws with the usable ids. */\nexport function resolveCanvasBrush(brush: CanvasBrush, width: number): BrushstrokeBrush {\n\tconst size = Math.max(1, Number.isFinite(width) ? width : 1);\n\tif (typeof brush === 'string') {\n\t\tconst preset = BUILTIN_BRUSHES.find((b) => b.id === brush);\n\t\tconst ids = DRY.map((b) => b.id).join(', ');\n\t\tif (!preset) throw new Error(`Unknown brush '${brush}'. Use one of the dry paint presets (${ids}) or tip settings ({ hardness, spacing, flow, … }).`);\n\t\tif (!isBrushstrokeBrush(preset)) {\n\t\t\tthrow new Error(`Brush '${brush}' (${preset.name}) is not a dry brush: brushed canvas strokes use dry media only (wet paint needs an area to flow in; mixer, blender, smudge and eraser brushes need paint under them). Use one of: ${ids}.`);\n\t\t}\n\t\treturn { ...preset, tip: { ...preset.tip, size } };\n\t}\n\tif (!brush || typeof brush !== 'object' || Array.isArray(brush)) {\n\t\tthrow new Error('A brush is a dry paint preset id (see listCanvasBrushes / canvas.listBrushes) or an object of tip settings.');\n\t}\n\treturn { size, ...brush };\n}\n\n/**\n * The paint engine's `PaintSource` for a brushed stroke's `paint`; throws with what is wrong.\n * Mappings that need timed samples (`velocity`, `time`) are refused: canvas strokes carry no timing.\n */\nexport function resolveCanvasPaint(paint: CanvasBrushPaint | unknown): PaintSource {\n\tconst source = parsePaintSource(paint, 'paint');\n\tif (source.type === 'gradient' && (source.map.by === 'velocity' || source.map.by === 'time')) {\n\t\tthrow new Error(`paint.map.by \"${source.map.by}\" needs timed samples, which canvas strokes do not record; use distance, pressure, tilt, direction, across-tip or random.`);\n\t}\n\treturn source;\n}\n\n/** A stored stroke's paint, or null when it has none or it is not valid paint (the stroke colour is used then). */\nfunction shapePaint(shape: BrushedPathShape): PaintSource | null {\n\tif (shape.brush.paint === undefined || shape.brush.paint === null) return null;\n\ttry {\n\t\treturn resolveCanvasPaint(shape.brush.paint);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * RGBA of a shape's stroke paint: with `brush.paint` its alpha and the colour of `paint` stops.\n * A canvas gradient stroke without `brush.paint` uses its first stop.\n */\nfunction strokeColor(shape: BrushedPathShape): [number, number, number, number] {\n\tconst gradient = resolveCanvasGradient(shape.strokeGradient ?? shape.stroke);\n\tconst css = gradient ? (gradient.stops[0]?.color ?? '#000') : typeof shape.stroke === 'string' && shape.stroke !== 'none' ? shape.stroke : '#000';\n\tconst parsed = parseCssColor(css) ?? { hex: '#000000', alpha: 1 };\n\tconst n = parseInt(parsed.hex.slice(1), 16);\n\treturn [(n >> 16) & 255, (n >> 8) & 255, n & 255, Math.round(parsed.alpha * 255)];\n}\n\nconst cache = new BrushstrokeCache(128);\nconst urls = new WeakMap<BrushstrokeImage, string>();\n\nexport function renderShapeBrushstrokeNow(shape: BrushedPathShape, scale: number): CanvasBrushstrokeImage | null {\n\tconst brush = resolveCanvasBrush(shape.brush.brush, shape.strokeWidth ?? 3);\n\tconst points = pathDataToPolyline(shape.d);\n\tif (!points.length) return null;\n\tconst { pressure, tiltX, tiltY } = shape.brush;\n\tconst input = {\n\t\tpoints: points.map(([x, y]) => ({ x, y })),\n\t\t...(pressure?.length ? { pressure } : {}),\n\t\t...(tiltX?.length ? { tiltX } : {}),\n\t\t...(tiltY?.length ? { tiltY } : {})\n\t};\n\tconst paint = shapePaint(shape);\n\tconst stroke = cache.render(input, brush, { scale, color: strokeColor(shape), ...(paint ? { paint } : {}) });\n\tif (!stroke.bounds) return null;\n\tlet href = urls.get(stroke);\n\tif (href === undefined) {\n\t\thref = brushstrokeDataUrl(stroke);\n\t\turls.set(stroke, href);\n\t}\n\treturn { href, ...stroke.bounds, scale: stroke.scale };\n}\n\nconst escapeAttr = (s: string) => s.replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/</g, '&lt;');\n\nexport function brushedShapeSvgNow(shape: BrushedPathShape, size: ShapeSize, scale: number): string {\n\tconst f = (n: number) => formatNumber(n, 3);\n\tconst image = renderShapeBrushstrokeNow(shape, scale);\n\tconst svg = getShapeSvg(shape, size);\n\tconst body = image\n\t\t? `<image href=\"${escapeAttr(image.href)}\" x=\"${f(image.x)}\" y=\"${f(image.y)}\" width=\"${f(image.width)}\" height=\"${f(image.height)}\" preserveAspectRatio=\"none\"${shape.opacity !== undefined ? ` opacity=\"${f(shape.opacity)}\"` : ''}/>`\n\t\t: '';\n\tconst content = svg.transform && body ? `<g transform=\"${svg.transform}\">${body}</g>` : body;\n\treturn `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${f(size.width)}\" height=\"${f(size.height)}\" viewBox=\"0 0 ${f(size.width)} ${f(size.height)}\">${content}</svg>`;\n}\n"]}
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-UYQUPUR6.js";
4
4
  import {
5
5
  pathDataToPolyline
6
- } from "./chunk-UABQTYQF.js";
6
+ } from "./chunk-SVYE5HIM.js";
7
7
  import {
8
8
  parseCssColor
9
9
  } from "./chunk-CTTF4KYV.js";
@@ -12,7 +12,9 @@ import {
12
12
  brushstrokeDataUrl,
13
13
  isBrushstrokeBrush
14
14
  } from "./chunk-64PYNEHJ.js";
15
- import "./chunk-EM3FMJWE.js";
15
+ import {
16
+ parsePaintSource
17
+ } from "./chunk-EM3FMJWE.js";
16
18
  import "./chunk-63AZAUSN.js";
17
19
  import "./chunk-BR7EKQUP.js";
18
20
  import "./chunk-7QN76ESJ.js";
@@ -44,6 +46,21 @@ function resolveCanvasBrush(brush, width) {
44
46
  }
45
47
  return { size, ...brush };
46
48
  }
49
+ function resolveCanvasPaint(paint) {
50
+ const source = parsePaintSource(paint, "paint");
51
+ if (source.type === "gradient" && (source.map.by === "velocity" || source.map.by === "time")) {
52
+ throw new Error(`paint.map.by "${source.map.by}" needs timed samples, which canvas strokes do not record; use distance, pressure, tilt, direction, across-tip or random.`);
53
+ }
54
+ return source;
55
+ }
56
+ function shapePaint(shape) {
57
+ if (shape.brush.paint === void 0 || shape.brush.paint === null) return null;
58
+ try {
59
+ return resolveCanvasPaint(shape.brush.paint);
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
47
64
  function strokeColor(shape) {
48
65
  const gradient = resolveCanvasGradient(shape.strokeGradient ?? shape.stroke);
49
66
  const css = gradient ? gradient.stops[0]?.color ?? "#000" : typeof shape.stroke === "string" && shape.stroke !== "none" ? shape.stroke : "#000";
@@ -64,7 +81,8 @@ function renderShapeBrushstrokeNow(shape, scale) {
64
81
  ...tiltX?.length ? { tiltX } : {},
65
82
  ...tiltY?.length ? { tiltY } : {}
66
83
  };
67
- const stroke = cache.render(input, brush, { scale, color: strokeColor(shape) });
84
+ const paint = shapePaint(shape);
85
+ const stroke = cache.render(input, brush, { scale, color: strokeColor(shape), ...paint ? { paint } : {} });
68
86
  if (!stroke.bounds) return null;
69
87
  let href = urls.get(stroke);
70
88
  if (href === void 0) {
@@ -86,6 +104,7 @@ export {
86
104
  brushedShapeSvgNow,
87
105
  listCanvasBrushes,
88
106
  renderShapeBrushstrokeNow,
89
- resolveCanvasBrush
107
+ resolveCanvasBrush,
108
+ resolveCanvasPaint
90
109
  };
91
- //# sourceMappingURL=brushstrokeRender-7RUITO42.js.map
110
+ //# sourceMappingURL=brushstrokeRender-SII6MG4R.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/canvas/brushstrokeRender.ts"],"sourcesContent":["/**\n * The lazily loaded half of brushed freehand strokes (`./brushstroke.ts` imports it on first use):\n * the paint engine's dry brushstroke renderer, the paint presets and a CSS colour parser. Keep\n * every import of the paint engine in this file, so the canvas entry never reaches it statically.\n */\nimport { BrushstrokeCache, brushstrokeDataUrl, isBrushstrokeBrush, type BrushstrokeBrush, type BrushstrokeImage } from '../paint/brushstroke.js';\nimport { parsePaintSource, type PaintSource } from '../paint/gradient-paint.js';\nimport { BUILTIN_BRUSHES } from '../paint-editor/brushes.js';\nimport { parseCssColor } from '../image-editor/layers/css-color.js';\nimport { resolveCanvasGradient } from './gradient.js';\nimport { formatNumber, getShapeSvg, type ShapeSize } from './shapeGeometry.js';\nimport { pathDataToPolyline, type BrushedPathShape, type CanvasBrush, type CanvasBrushPaint, type CanvasBrushPreset, type CanvasBrushstrokeImage } from './brushstroke.js';\n\nconst DRY = BUILTIN_BRUSHES.filter((b) => isBrushstrokeBrush(b));\n\nexport function listCanvasBrushes(): CanvasBrushPreset[] {\n\treturn DRY.map((b) => ({ id: b.id, name: b.name, category: b.category, size: b.tip.size }));\n}\n\n/** The paint engine brush for a canvas brush at stroke width `width`; throws with the usable ids. */\nexport function resolveCanvasBrush(brush: CanvasBrush, width: number): BrushstrokeBrush {\n\tconst size = Math.max(1, Number.isFinite(width) ? width : 1);\n\tif (typeof brush === 'string') {\n\t\tconst preset = BUILTIN_BRUSHES.find((b) => b.id === brush);\n\t\tconst ids = DRY.map((b) => b.id).join(', ');\n\t\tif (!preset) throw new Error(`Unknown brush '${brush}'. Use one of the dry paint presets (${ids}) or tip settings ({ hardness, spacing, flow, … }).`);\n\t\tif (!isBrushstrokeBrush(preset)) {\n\t\t\tthrow new Error(`Brush '${brush}' (${preset.name}) is not a dry brush: brushed canvas strokes use dry media only (wet paint needs an area to flow in; mixer, blender, smudge and eraser brushes need paint under them). Use one of: ${ids}.`);\n\t\t}\n\t\treturn { ...preset, tip: { ...preset.tip, size } };\n\t}\n\tif (!brush || typeof brush !== 'object' || Array.isArray(brush)) {\n\t\tthrow new Error('A brush is a dry paint preset id (see listCanvasBrushes / canvas.listBrushes) or an object of tip settings.');\n\t}\n\treturn { size, ...brush };\n}\n\n/**\n * The paint engine's `PaintSource` for a brushed stroke's `paint`; throws with what is wrong.\n * Mappings that need timed samples (`velocity`, `time`) are refused: canvas strokes carry no timing.\n */\nexport function resolveCanvasPaint(paint: CanvasBrushPaint | unknown): PaintSource {\n\tconst source = parsePaintSource(paint, 'paint');\n\tif (source.type === 'gradient' && (source.map.by === 'velocity' || source.map.by === 'time')) {\n\t\tthrow new Error(`paint.map.by \"${source.map.by}\" needs timed samples, which canvas strokes do not record; use distance, pressure, tilt, direction, across-tip or random.`);\n\t}\n\treturn source;\n}\n\n/** A stored stroke's paint, or null when it has none or it is not valid paint (the stroke colour is used then). */\nfunction shapePaint(shape: BrushedPathShape): PaintSource | null {\n\tif (shape.brush.paint === undefined || shape.brush.paint === null) return null;\n\ttry {\n\t\treturn resolveCanvasPaint(shape.brush.paint);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * RGBA of a shape's stroke paint: with `brush.paint` its alpha and the colour of `paint` stops.\n * A canvas gradient stroke without `brush.paint` uses its first stop.\n */\nfunction strokeColor(shape: BrushedPathShape): [number, number, number, number] {\n\tconst gradient = resolveCanvasGradient(shape.strokeGradient ?? shape.stroke);\n\tconst css = gradient ? (gradient.stops[0]?.color ?? '#000') : typeof shape.stroke === 'string' && shape.stroke !== 'none' ? shape.stroke : '#000';\n\tconst parsed = parseCssColor(css) ?? { hex: '#000000', alpha: 1 };\n\tconst n = parseInt(parsed.hex.slice(1), 16);\n\treturn [(n >> 16) & 255, (n >> 8) & 255, n & 255, Math.round(parsed.alpha * 255)];\n}\n\nconst cache = new BrushstrokeCache(128);\nconst urls = new WeakMap<BrushstrokeImage, string>();\n\nexport function renderShapeBrushstrokeNow(shape: BrushedPathShape, scale: number): CanvasBrushstrokeImage | null {\n\tconst brush = resolveCanvasBrush(shape.brush.brush, shape.strokeWidth ?? 3);\n\tconst points = pathDataToPolyline(shape.d);\n\tif (!points.length) return null;\n\tconst { pressure, tiltX, tiltY } = shape.brush;\n\tconst input = {\n\t\tpoints: points.map(([x, y]) => ({ x, y })),\n\t\t...(pressure?.length ? { pressure } : {}),\n\t\t...(tiltX?.length ? { tiltX } : {}),\n\t\t...(tiltY?.length ? { tiltY } : {})\n\t};\n\tconst paint = shapePaint(shape);\n\tconst stroke = cache.render(input, brush, { scale, color: strokeColor(shape), ...(paint ? { paint } : {}) });\n\tif (!stroke.bounds) return null;\n\tlet href = urls.get(stroke);\n\tif (href === undefined) {\n\t\thref = brushstrokeDataUrl(stroke);\n\t\turls.set(stroke, href);\n\t}\n\treturn { href, ...stroke.bounds, scale: stroke.scale };\n}\n\nconst escapeAttr = (s: string) => s.replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/</g, '&lt;');\n\nexport function brushedShapeSvgNow(shape: BrushedPathShape, size: ShapeSize, scale: number): string {\n\tconst f = (n: number) => formatNumber(n, 3);\n\tconst image = renderShapeBrushstrokeNow(shape, scale);\n\tconst svg = getShapeSvg(shape, size);\n\tconst body = image\n\t\t? `<image href=\"${escapeAttr(image.href)}\" x=\"${f(image.x)}\" y=\"${f(image.y)}\" width=\"${f(image.width)}\" height=\"${f(image.height)}\" preserveAspectRatio=\"none\"${shape.opacity !== undefined ? ` opacity=\"${f(shape.opacity)}\"` : ''}/>`\n\t\t: '';\n\tconst content = svg.transform && body ? `<g transform=\"${svg.transform}\">${body}</g>` : body;\n\treturn `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${f(size.width)}\" height=\"${f(size.height)}\" viewBox=\"0 0 ${f(size.width)} ${f(size.height)}\">${content}</svg>`;\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import { H as HistoryState } from './types-DsiXGmjo.cjs';
2
- import { C as CanvasArrangeAction, A as AlignEdge, D as DistributeAxis, a as DistributeMode, Z as ZOrderOperation } from './arrange-CD6Gh-pd.cjs';
3
- import { C as CanvasBrush, a as CanvasBrushPreset } from './brushTypes-IG7ZZjIN.cjs';
2
+ import { C as CanvasArrangeAction, A as AlignEdge, D as DistributeAxis, a as DistributeMode, Z as ZOrderOperation } from './arrange-CKXK_hf7.cjs';
3
+ import { C as CanvasBrush, a as CanvasBrushPaint, b as CanvasBrushPreset } from './brushTypes-C7N3EBK7.cjs';
4
4
  import { S as ShortcutBinding, C as CommandSpec, K as KeyboardEventLike, P as Platform } from './registry-CaR7LC6W.cjs';
5
5
 
6
6
  /** Minimal history surface (`HistoryManager` satisfies it). */
@@ -104,6 +104,7 @@ interface DrawCommandTarget {
104
104
  width?: number;
105
105
  opacity?: number;
106
106
  brush?: CanvasBrush;
107
+ paint?: CanvasBrushPaint;
107
108
  };
108
109
  pressure?: readonly number[];
109
110
  tiltX?: readonly number[];
@@ -1,6 +1,6 @@
1
1
  import { H as HistoryState } from './types-DsiXGmjo.js';
2
- import { C as CanvasArrangeAction, A as AlignEdge, D as DistributeAxis, a as DistributeMode, Z as ZOrderOperation } from './arrange-BlfgJ_wt.js';
3
- import { C as CanvasBrush, a as CanvasBrushPreset } from './brushTypes-IG7ZZjIN.js';
2
+ import { C as CanvasArrangeAction, A as AlignEdge, D as DistributeAxis, a as DistributeMode, Z as ZOrderOperation } from './arrange-BUREmgD9.js';
3
+ import { C as CanvasBrush, a as CanvasBrushPaint, b as CanvasBrushPreset } from './brushTypes-C7N3EBK7.js';
4
4
  import { S as ShortcutBinding, C as CommandSpec, K as KeyboardEventLike, P as Platform } from './registry-rVtFJjRM.js';
5
5
 
6
6
  /** Minimal history surface (`HistoryManager` satisfies it). */
@@ -104,6 +104,7 @@ interface DrawCommandTarget {
104
104
  width?: number;
105
105
  opacity?: number;
106
106
  brush?: CanvasBrush;
107
+ paint?: CanvasBrushPaint;
107
108
  };
108
109
  pressure?: readonly number[];
109
110
  tiltX?: readonly number[];