@pixerate/editor 0.135.0 → 0.137.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 (164) hide show
  1. package/dist/animation-editor/index.cjs +63 -55
  2. package/dist/animation-editor/index.cjs.map +1 -1
  3. package/dist/animation-editor/index.d.cts +8 -5
  4. package/dist/animation-editor/index.d.ts +8 -5
  5. package/dist/animation-editor/index.js +10 -2
  6. package/dist/animation-editor/index.js.map +1 -1
  7. package/dist/{bezier-J8i4uqSH.d.cts → bezier-CZ2AhjID.d.cts} +1 -1
  8. package/dist/{bezier-lNEOp0Jx.d.ts → bezier-Dywv3Bw8.d.ts} +1 -1
  9. package/dist/blending-D7jCmjO6.d.cts +1026 -0
  10. package/dist/blending-NgF3qo3d.d.ts +1026 -0
  11. package/dist/brushes-CnvZSYYU.d.cts +744 -0
  12. package/dist/brushes-DJmUbIgz.d.ts +744 -0
  13. package/dist/{brushstrokeRender-SII6MG4R.js → brushstrokeRender-2FAXA3XC.js} +13 -16
  14. package/dist/{brushstrokeRender-SII6MG4R.js.map → brushstrokeRender-2FAXA3XC.js.map} +1 -1
  15. package/dist/{brushstrokeRender-JNHVEUFG.cjs → brushstrokeRender-IMFY3FF6.cjs} +16 -19
  16. package/dist/brushstrokeRender-IMFY3FF6.cjs.map +1 -0
  17. package/dist/canvas/index.cjs +10 -10
  18. package/dist/canvas/index.cjs.map +1 -1
  19. package/dist/canvas/index.d.cts +10 -7
  20. package/dist/canvas/index.d.ts +10 -7
  21. package/dist/canvas/index.js +4 -4
  22. package/dist/{chunk-W4LNKTHT.cjs → chunk-2XS6LTUP.cjs} +63 -63
  23. package/dist/{chunk-W4LNKTHT.cjs.map → chunk-2XS6LTUP.cjs.map} +1 -1
  24. package/dist/{chunk-HHTCDFZC.js → chunk-3D77LOBM.js} +234 -136
  25. package/dist/chunk-3D77LOBM.js.map +1 -0
  26. package/dist/{chunk-BR7EKQUP.js → chunk-3G6J7UFV.js} +322 -2
  27. package/dist/chunk-3G6J7UFV.js.map +1 -0
  28. package/dist/{chunk-62XUO5LB.js → chunk-3X6IAJUQ.js} +2 -2
  29. package/dist/{chunk-EM3FMJWE.js → chunk-5FSRTP6E.js} +320 -3
  30. package/dist/chunk-5FSRTP6E.js.map +1 -0
  31. package/dist/{chunk-Z2H7KECK.cjs → chunk-5OOIUXNJ.cjs} +345 -247
  32. package/dist/chunk-5OOIUXNJ.cjs.map +1 -0
  33. package/dist/{chunk-7RJ6P7MI.js → chunk-6S6362D2.js} +2 -2
  34. package/dist/chunk-A3BVTI3G.js +150 -0
  35. package/dist/chunk-A3BVTI3G.js.map +1 -0
  36. package/dist/{chunk-24ATT2PE.cjs → chunk-AEAAN4AD.cjs} +120 -120
  37. package/dist/{chunk-24ATT2PE.cjs.map → chunk-AEAAN4AD.cjs.map} +1 -1
  38. package/dist/chunk-ECCXGELC.cjs +727 -0
  39. package/dist/chunk-ECCXGELC.cjs.map +1 -0
  40. package/dist/{chunk-SVYE5HIM.js → chunk-EQQMGO42.js} +2 -2
  41. package/dist/{chunk-FHPVDTI2.cjs → chunk-F2Y4E4GU.cjs} +22 -22
  42. package/dist/{chunk-FHPVDTI2.cjs.map → chunk-F2Y4E4GU.cjs.map} +1 -1
  43. package/dist/{chunk-OXSV64JX.js → chunk-G6IKY6PL.js} +4 -4
  44. package/dist/{chunk-UYQUPUR6.js → chunk-HUO3TI4C.js} +3 -3
  45. package/dist/chunk-I52DRGGJ.js +727 -0
  46. package/dist/chunk-I52DRGGJ.js.map +1 -0
  47. package/dist/{chunk-DDSO4HS7.cjs → chunk-KEENUAFN.cjs} +2 -2
  48. package/dist/{chunk-DDSO4HS7.cjs.map → chunk-KEENUAFN.cjs.map} +1 -1
  49. package/dist/{chunk-2HC4DRF4.js → chunk-LLFHCSU2.js} +2 -2
  50. package/dist/{chunk-J5BA3BQ6.cjs → chunk-O7LUD7MH.cjs} +323 -3
  51. package/dist/chunk-O7LUD7MH.cjs.map +1 -0
  52. package/dist/{chunk-ILYFOJUN.js → chunk-OIBIRXRG.js} +3 -3
  53. package/dist/{chunk-FWEO3HSL.js → chunk-PQQF5KOW.js} +8 -8
  54. package/dist/{chunk-T6TV6HY6.cjs → chunk-PRSRYHQD.cjs} +36 -36
  55. package/dist/{chunk-T6TV6HY6.cjs.map → chunk-PRSRYHQD.cjs.map} +1 -1
  56. package/dist/chunk-Q6OUXEK3.cjs +150 -0
  57. package/dist/chunk-Q6OUXEK3.cjs.map +1 -0
  58. package/dist/{chunk-6GFRKLLS.cjs → chunk-QBWEH3IM.cjs} +429 -112
  59. package/dist/chunk-QBWEH3IM.cjs.map +1 -0
  60. package/dist/{chunk-ESIWZMMK.js → chunk-SYT2TLQF.js} +35 -37
  61. package/dist/{chunk-ESIWZMMK.js.map → chunk-SYT2TLQF.js.map} +1 -1
  62. package/dist/{chunk-YT3JL7YM.cjs → chunk-TLCTTQFF.cjs} +53 -53
  63. package/dist/{chunk-YT3JL7YM.cjs.map → chunk-TLCTTQFF.cjs.map} +1 -1
  64. package/dist/{chunk-P3RQ5UJE.cjs → chunk-UTQKC66X.cjs} +4 -4
  65. package/dist/{chunk-P3RQ5UJE.cjs.map → chunk-UTQKC66X.cjs.map} +1 -1
  66. package/dist/{chunk-J3B45HTA.cjs → chunk-XB25WOC2.cjs} +6 -6
  67. package/dist/{chunk-J3B45HTA.cjs.map → chunk-XB25WOC2.cjs.map} +1 -1
  68. package/dist/{chunk-YAFS2QFZ.cjs → chunk-XN2NBLV5.cjs} +313 -315
  69. package/dist/chunk-XN2NBLV5.cjs.map +1 -0
  70. package/dist/effects/index.d.cts +7 -4
  71. package/dist/effects/index.d.ts +7 -4
  72. package/dist/{export-DMeG6E06.d.ts → export-41rL6Cne.d.ts} +1 -1
  73. package/dist/{export-AZSwX087.d.cts → export-CyJdfP_Z.d.cts} +5 -4
  74. package/dist/{export-KzubBKo7.d.cts → export-D9mXp05Q.d.cts} +1 -1
  75. package/dist/{export-BDkyDNM8.d.ts → export-DwnZ_hvQ.d.ts} +5 -4
  76. package/dist/extensions/index.cjs +3 -3
  77. package/dist/extensions/index.cjs.map +1 -1
  78. package/dist/extensions/index.js +2 -2
  79. package/dist/generation/index.cjs +150 -945
  80. package/dist/generation/index.cjs.map +1 -1
  81. package/dist/generation/index.d.cts +3 -423
  82. package/dist/generation/index.d.ts +3 -423
  83. package/dist/generation/index.js +59 -854
  84. package/dist/generation/index.js.map +1 -1
  85. package/dist/grammar/index.cjs +3 -3
  86. package/dist/grammar/index.cjs.map +1 -1
  87. package/dist/grammar/index.js +2 -2
  88. package/dist/{helpers-Coa4e2j_.d.ts → helpers-C-RgeyvH.d.ts} +25 -8
  89. package/dist/{helpers-DHl28yLO.d.cts → helpers-v6GMazzg.d.cts} +25 -8
  90. package/dist/image-editor/index.cjs +986 -986
  91. package/dist/image-editor/index.cjs.map +1 -1
  92. package/dist/image-editor/index.d.cts +15 -11
  93. package/dist/image-editor/index.d.ts +15 -11
  94. package/dist/image-editor/index.js +94 -94
  95. package/dist/index.cjs +28 -28
  96. package/dist/index.cjs.map +1 -1
  97. package/dist/index.js +36 -36
  98. package/dist/{opentype-BWR7Qv8W.d.cts → opentype-KR_jj6b_.d.cts} +1 -1
  99. package/dist/{opentype-Dfcx6wFx.d.ts → opentype-a1KAW-qs.d.ts} +1 -1
  100. package/dist/paint/index.cjs +5 -8
  101. package/dist/paint/index.cjs.map +1 -1
  102. package/dist/paint/index.d.cts +4 -2
  103. package/dist/paint/index.d.ts +4 -2
  104. package/dist/paint/index.js +15 -18
  105. package/dist/paint-editor/index.cjs +405 -403
  106. package/dist/paint-editor/index.cjs.map +1 -1
  107. package/dist/paint-editor/index.d.cts +15 -748
  108. package/dist/paint-editor/index.d.ts +15 -748
  109. package/dist/paint-editor/index.js +79 -77
  110. package/dist/paint-editor/index.js.map +1 -1
  111. package/dist/{pathfinder-D8KQ6blQ.d.cts → pathfinder-BHS4vQNm.d.cts} +1 -1
  112. package/dist/{pathfinder-Celbi3e6.d.ts → pathfinder-BVvTIBMo.d.ts} +1 -1
  113. package/dist/{pool-8JZGWHvR.d.ts → pool-CZQOrSXZ.d.ts} +1 -1
  114. package/dist/{pool-BfuxBKTd.d.cts → pool-FjZZmZ80.d.cts} +1 -1
  115. package/dist/provenance-DmlcgdzT.d.cts +426 -0
  116. package/dist/provenance-uh5r2TQ8.d.ts +426 -0
  117. package/dist/rand-8xbUb6ur.d.ts +1118 -0
  118. package/dist/rand-Cw9VLrVC.d.cts +1118 -0
  119. package/dist/raster/index.cjs +17 -19
  120. package/dist/raster/index.cjs.map +1 -1
  121. package/dist/raster/index.js +9 -11
  122. package/dist/raster/index.js.map +1 -1
  123. package/dist/{svg-CxxqG3_W.d.ts → svg-CSz3mzkw.d.ts} +2 -2
  124. package/dist/{svg-pwXWq6s2.d.cts → svg-DTb40ICU.d.cts} +2 -2
  125. package/dist/{tools-y1M6O3UT.d.ts → tools-B0wXP5cF.d.ts} +1 -1
  126. package/dist/{tools-3EBjR91b.d.cts → tools-Ca0kI1qo.d.cts} +1 -1
  127. package/dist/vector/index.cjs +2698 -1674
  128. package/dist/vector/index.cjs.map +1 -1
  129. package/dist/vector/index.d.cts +390 -72
  130. package/dist/vector/index.d.ts +390 -72
  131. package/dist/vector/index.js +1665 -641
  132. package/dist/vector/index.js.map +1 -1
  133. package/dist/video-editor/index.d.cts +7 -4
  134. package/dist/video-editor/index.d.ts +7 -4
  135. package/dist/{warp-Ceqdz7kj.d.cts → warp-DTOp0lON.d.cts} +1 -1
  136. package/dist/{warp-C1gwu2G_.d.ts → warp-pd7hrH4T.d.ts} +1 -1
  137. package/package.json +1 -1
  138. package/skills/pixerate-vector/SKILL.md +22 -0
  139. package/dist/brushstrokeRender-JNHVEUFG.cjs.map +0 -1
  140. package/dist/chunk-64PYNEHJ.js +0 -340
  141. package/dist/chunk-64PYNEHJ.js.map +0 -1
  142. package/dist/chunk-6GFRKLLS.cjs.map +0 -1
  143. package/dist/chunk-7QN76ESJ.js +0 -323
  144. package/dist/chunk-7QN76ESJ.js.map +0 -1
  145. package/dist/chunk-BR7EKQUP.js.map +0 -1
  146. package/dist/chunk-DCLJNVZS.cjs +0 -323
  147. package/dist/chunk-DCLJNVZS.cjs.map +0 -1
  148. package/dist/chunk-EM3FMJWE.js.map +0 -1
  149. package/dist/chunk-HHTCDFZC.js.map +0 -1
  150. package/dist/chunk-J5BA3BQ6.cjs.map +0 -1
  151. package/dist/chunk-YAFS2QFZ.cjs.map +0 -1
  152. package/dist/chunk-Z2H7KECK.cjs.map +0 -1
  153. package/dist/chunk-Z6OUCS2K.cjs +0 -340
  154. package/dist/chunk-Z6OUCS2K.cjs.map +0 -1
  155. package/dist/rand-BszBST4s.d.ts +0 -2140
  156. package/dist/rand-DOH_aMvm.d.cts +0 -2140
  157. /package/dist/{chunk-62XUO5LB.js.map → chunk-3X6IAJUQ.js.map} +0 -0
  158. /package/dist/{chunk-7RJ6P7MI.js.map → chunk-6S6362D2.js.map} +0 -0
  159. /package/dist/{chunk-SVYE5HIM.js.map → chunk-EQQMGO42.js.map} +0 -0
  160. /package/dist/{chunk-OXSV64JX.js.map → chunk-G6IKY6PL.js.map} +0 -0
  161. /package/dist/{chunk-UYQUPUR6.js.map → chunk-HUO3TI4C.js.map} +0 -0
  162. /package/dist/{chunk-2HC4DRF4.js.map → chunk-LLFHCSU2.js.map} +0 -0
  163. /package/dist/{chunk-ILYFOJUN.js.map → chunk-OIBIRXRG.js.map} +0 -0
  164. /package/dist/{chunk-FWEO3HSL.js.map → chunk-PQQF5KOW.js.map} +0 -0
@@ -1,3 +1,9 @@
1
+ import {
2
+ BUILTIN_BRUSHES
3
+ } from "./chunk-HUO3TI4C.js";
4
+ import {
5
+ parseProvenance
6
+ } from "./chunk-A3BVTI3G.js";
1
7
  import {
2
8
  bezierPathBounds,
3
9
  bezierPathToSvg,
@@ -36,6 +42,11 @@ import {
36
42
  formatNumber,
37
43
  isStraightCubic
38
44
  } from "./chunk-KHNZ6MOU.js";
45
+ import {
46
+ BrushstrokeCache,
47
+ brushstrokeDataUrl,
48
+ isBrushstrokeBrush
49
+ } from "./chunk-5FSRTP6E.js";
39
50
  import {
40
51
  oklabToRgb,
41
52
  rgbToOklab
@@ -123,7 +134,8 @@ var VECTOR_TOOLS = [
123
134
  "type",
124
135
  "typePath",
125
136
  "frame",
126
- "connector"
137
+ "connector",
138
+ "distort"
127
139
  ];
128
140
  var VECTOR_TRANSFORM_HANDLES = ["nw", "n", "ne", "e", "se", "s", "sw", "w", "rotate"];
129
141
  var VECTOR_PATHFINDER_OPERATIONS = ["divide", "trim", "merge", "crop", "outline", "minusBack"];
@@ -2383,6 +2395,193 @@ function vectorStrokeReach(style) {
2383
2395
  return reach;
2384
2396
  }
2385
2397
 
2398
+ // src/vector/extrude.ts
2399
+ function vectorPaintSolid(paint) {
2400
+ if (paint == null || paint === "none") return null;
2401
+ if (typeof paint === "string") return paint;
2402
+ const stops = paint.stops;
2403
+ if (stops?.length) return stops.reduce((a, b) => Math.abs(b.offset - 0.5) < Math.abs(a.offset - 0.5) ? b : a).color;
2404
+ const colors = paint.colors;
2405
+ if (colors?.length) return colors[0];
2406
+ const points = paint.points;
2407
+ return points?.find((p) => typeof p.color === "string")?.color ?? null;
2408
+ }
2409
+ function shadeVectorColor(color2, amount) {
2410
+ const c = parseVectorColor(color2);
2411
+ if (!c) return color2;
2412
+ const a = Math.min(1, Math.max(-1, amount));
2413
+ const target = a >= 0 ? 1 : 0;
2414
+ const h = (v2) => Math.round(Math.min(1, Math.max(0, v2)) * 255).toString(16).padStart(2, "0");
2415
+ const m = [0, 1, 2].map((k) => c[k] + (target - c[k]) * Math.abs(a));
2416
+ return `#${h(m[0])}${h(m[1])}${h(m[2])}`;
2417
+ }
2418
+ function vectorPathRings(path, tolerance = 0.5) {
2419
+ const rings = [];
2420
+ for (const contour of pathToContours(path)) {
2421
+ const ring = flattenChain(closeContour(contour, true), Math.max(1e-3, tolerance));
2422
+ if (ring.length >= 2) rings.push(ring);
2423
+ }
2424
+ return rings;
2425
+ }
2426
+ function vectorExtrudeFaces(path, params) {
2427
+ const box = bezierPathBounds(path);
2428
+ if (!box || !path.length) return [];
2429
+ const perspective = params.mode === "perspective";
2430
+ const rad2 = params.angle * Math.PI / 180;
2431
+ const d = [Math.cos(rad2) * Math.max(0, params.depth), Math.sin(rad2) * Math.max(0, params.depth)];
2432
+ const vp = [(box.minX + box.maxX) / 2 + params.vanishingPoint.x, (box.minY + box.maxY) / 2 + params.vanishingPoint.y];
2433
+ const pull = Math.min(1, Math.max(0, params.toward / 100));
2434
+ const back = (p) => perspective ? [p[0] + (vp[0] - p[0]) * pull, p[1] + (vp[1] - p[1]) * pull] : [p[0] + d[0], p[1] + d[1]];
2435
+ if (perspective ? pull <= 0 : Math.hypot(d[0], d[1]) < 1e-9) return [];
2436
+ const lr = params.lightAngle * Math.PI / 180;
2437
+ const light = [Math.cos(lr), Math.sin(lr)];
2438
+ const strength = Math.min(1, Math.max(0, params.shading / 100));
2439
+ const u = perspective ? [0, 0] : [d[0] / Math.hypot(d[0], d[1]), d[1] / Math.hypot(d[0], d[1])];
2440
+ const centre = [(box.minX + box.maxX) / 2, (box.minY + box.maxY) / 2];
2441
+ const aim = Math.atan2(centre[1] - vp[1], centre[0] - vp[0]);
2442
+ const across = (p) => {
2443
+ if (!perspective) return -p[0] * u[1] + p[1] * u[0];
2444
+ let a = Math.atan2(p[1] - vp[1], p[0] - vp[0]) - aim;
2445
+ while (a > Math.PI) a -= 2 * Math.PI;
2446
+ while (a <= -Math.PI) a += 2 * Math.PI;
2447
+ return a;
2448
+ };
2449
+ const towardBack = (p, q, l) => {
2450
+ const lp = across(p);
2451
+ const lq = across(q);
2452
+ const t = Math.abs(lq - lp) < 1e-12 ? 0.5 : Math.min(1, Math.max(0, (l - lp) / (lq - lp)));
2453
+ const x = [p[0] + (q[0] - p[0]) * t, p[1] + (q[1] - p[1]) * t];
2454
+ return perspective ? -Math.hypot(vp[0] - x[0], vp[1] - x[1]) : x[0] * u[0] + x[1] * u[1];
2455
+ };
2456
+ const faces = [];
2457
+ for (const ring of vectorPathRings(path, 0.25)) {
2458
+ for (let i = 0; i < ring.length; i++) {
2459
+ const p = ring[i];
2460
+ const q = ring[(i + 1) % ring.length];
2461
+ const ex = q[0] - p[0];
2462
+ const ey = q[1] - p[1];
2463
+ const len2 = Math.hypot(ex, ey);
2464
+ if (len2 < 1e-9) continue;
2465
+ const pb = back(p);
2466
+ const qb = back(q);
2467
+ const mid = [(p[0] + q[0]) / 2, (p[1] + q[1]) / 2];
2468
+ const away = perspective ? [vp[0] - mid[0], vp[1] - mid[1]] : d;
2469
+ let n2 = [ey / len2, -ex / len2];
2470
+ if (n2[0] * away[0] + n2[1] * away[1] < 0) n2 = [-n2[0], -n2[1]];
2471
+ const shade = (n2[0] * light[0] + n2[1] * light[1]) * strength;
2472
+ const lp = across(p);
2473
+ const lq = across(q);
2474
+ faces.push({
2475
+ p,
2476
+ q,
2477
+ lo: Math.min(lp, lq),
2478
+ hi: Math.max(lp, lq),
2479
+ key: towardBack(p, q, (lp + lq) / 2),
2480
+ face: {
2481
+ shade,
2482
+ path: [{ type: "M", x: p[0], y: p[1] }, { type: "L", x: q[0], y: q[1] }, { type: "L", x: qb[0], y: qb[1] }, { type: "L", x: pb[0], y: pb[1] }, { type: "Z" }]
2483
+ }
2484
+ });
2485
+ }
2486
+ }
2487
+ faces.sort((a, b) => a.key - b.key);
2488
+ const n = faces.length;
2489
+ const after = faces.map(() => []);
2490
+ const before = new Array(n).fill(0);
2491
+ const eps = 1e-9;
2492
+ for (let i = 0; i < n; i++) {
2493
+ for (let j = i + 1; j < n; j++) {
2494
+ const lo = Math.max(faces[i].lo, faces[j].lo);
2495
+ const hi = Math.min(faces[i].hi, faces[j].hi);
2496
+ if (hi - lo <= eps * Math.max(1, Math.abs(hi))) continue;
2497
+ const l = (lo + hi) / 2;
2498
+ const di = towardBack(faces[i].p, faces[i].q, l);
2499
+ const dj = towardBack(faces[j].p, faces[j].q, l);
2500
+ if (Math.abs(di - dj) < 1e-9) continue;
2501
+ const [back0, front] = di < dj ? [i, j] : [j, i];
2502
+ after[back0].push(front);
2503
+ before[front]++;
2504
+ }
2505
+ }
2506
+ const order = [];
2507
+ const done = new Array(n).fill(false);
2508
+ let next = 0;
2509
+ while (order.length < n) {
2510
+ let pick = -1;
2511
+ for (let i = next; i < n; i++) {
2512
+ if (!done[i] && before[i] === 0) {
2513
+ pick = i;
2514
+ break;
2515
+ }
2516
+ }
2517
+ if (pick < 0) pick = done.indexOf(false);
2518
+ done[pick] = true;
2519
+ order.push(pick);
2520
+ for (const k of after[pick]) before[k]--;
2521
+ while (next < n && done[next]) next++;
2522
+ }
2523
+ return order.map((i) => faces[i].face);
2524
+ }
2525
+
2526
+ // src/vector/brushstroke.ts
2527
+ var VECTOR_BRUSHSTROKE_SCALE = 2;
2528
+ function vectorBrushstrokeBrushes() {
2529
+ return BUILTIN_BRUSHES.filter((b) => isBrushstrokeBrush(b));
2530
+ }
2531
+ function vectorBrushstrokeBrush(id) {
2532
+ return vectorBrushstrokeBrushes().find((b) => b.id === id) ?? null;
2533
+ }
2534
+ function sanitizeVectorBrushstroke(value) {
2535
+ if (!value || typeof value !== "object") return null;
2536
+ const r = value;
2537
+ if (typeof r.brushId !== "string" || !vectorBrushstrokeBrush(r.brushId)) return null;
2538
+ const out = { brushId: r.brushId };
2539
+ if (typeof r.size === "number" && Number.isFinite(r.size) && r.size > 0) out.size = Math.min(500, r.size);
2540
+ if (Array.isArray(r.pressure)) {
2541
+ const p = r.pressure.filter((v2) => typeof v2 === "number" && Number.isFinite(v2)).map((v2) => Math.min(1, Math.max(0, v2)));
2542
+ if (p.length) out.pressure = p.slice(0, 64);
2543
+ }
2544
+ return out;
2545
+ }
2546
+ function isVectorBrushstrokeLayer(layer) {
2547
+ return layer.kind === "brushstroke" && !!layer.brush && !!vectorBrushstrokeBrush(layer.brush.brushId);
2548
+ }
2549
+ function vectorBrushstrokeReach(layer) {
2550
+ if (!isVectorBrushstrokeLayer(layer)) return 0;
2551
+ return (layer.brush.size ?? vectorBrushstrokeBrush(layer.brush.brushId).tip.size) / 2;
2552
+ }
2553
+ var cache = new BrushstrokeCache(256);
2554
+ var urls = /* @__PURE__ */ new WeakMap();
2555
+ var layerCache = /* @__PURE__ */ new WeakMap();
2556
+ function vectorBrushstrokeImages(node, layer) {
2557
+ if (!isVectorBrushstrokeLayer(layer)) return [];
2558
+ let byLayer = layerCache.get(node);
2559
+ const hit = byLayer?.get(layer);
2560
+ if (hit) return hit;
2561
+ const preset = vectorBrushstrokeBrush(layer.brush.brushId);
2562
+ const brush = layer.brush.size ? { ...preset, tip: { ...preset.tip, size: layer.brush.size } } : preset;
2563
+ const solid = vectorPaintSolid(layer.paint) ?? "#000000";
2564
+ const c = parseVectorColor(solid) ?? [0, 0, 0, 1];
2565
+ const color2 = [c[0] * 255, c[1] * 255, c[2] * 255, c[3] * 255].map(Math.round);
2566
+ const out = [];
2567
+ for (const sp of node.subpaths) {
2568
+ if (sp.anchors.length < 2) continue;
2569
+ for (const contour of pathToContours(subpathsToBezier([sp]))) {
2570
+ const ring = flattenChain(closeContour(contour, contour.closed), 0.25);
2571
+ if (contour.closed && ring.length > 2) ring.push(ring[0]);
2572
+ if (ring.length < 2) continue;
2573
+ const stroke = cache.render({ points: ring.map(([x, y]) => ({ x, y })), ...layer.brush.pressure ? { pressure: layer.brush.pressure } : {} }, brush, { scale: VECTOR_BRUSHSTROKE_SCALE, color: color2, maxPixels: 2048 * 2048 });
2574
+ if (!stroke.bounds) continue;
2575
+ let href = urls.get(stroke);
2576
+ if (!href) urls.set(stroke, href = brushstrokeDataUrl(stroke));
2577
+ out.push({ href, ...stroke.bounds });
2578
+ }
2579
+ }
2580
+ if (!byLayer) layerCache.set(node, byLayer = /* @__PURE__ */ new Map());
2581
+ byLayer.set(layer, out);
2582
+ return out;
2583
+ }
2584
+
2386
2585
  // src/vector/paintLayers.ts
2387
2586
  var VECTOR_STROKE_SETTING_KEYS = [
2388
2587
  "strokeWidth",
@@ -2582,6 +2781,10 @@ function sanitizeVectorStrokeSettings(raw) {
2582
2781
  function sanitizeVectorStrokes(value) {
2583
2782
  if (!Array.isArray(value)) return [];
2584
2783
  return value.filter((l) => !!l && typeof l === "object").map((raw) => {
2784
+ if (raw.kind === "brushstroke") {
2785
+ const brush = sanitizeVectorBrushstroke(raw.brush);
2786
+ if (brush) return { ...sanitizeLayerBase(raw), kind: "brushstroke", brush };
2787
+ }
2585
2788
  if (raw.kind !== void 0 && raw.kind !== "paint") return { ...raw };
2586
2789
  return { ...sanitizeLayerBase(raw), ...sanitizeVectorStrokeSettings(raw) };
2587
2790
  });
@@ -2612,7 +2815,10 @@ function needsVectorPaintLayers(node) {
2612
2815
  }
2613
2816
  function vectorStrokeStackReach(node) {
2614
2817
  let reach = 0;
2615
- for (const l of vectorPaintLayerNodes(node)) if (l.kind === "stroke" && l.drawn) reach = Math.max(reach, vectorStrokeReach(l.node));
2818
+ for (const l of vectorPaintLayerNodes(node)) {
2819
+ if (l.kind === "stroke" && l.drawn) reach = Math.max(reach, vectorStrokeReach(l.node));
2820
+ else if (l.kind === "stroke" && l.layer.visible !== false) reach = Math.max(reach, vectorBrushstrokeReach(l.layer));
2821
+ }
2616
2822
  return reach;
2617
2823
  }
2618
2824
  function hitTestVectorPaintLayer(node, path, p, tolerance = 0) {
@@ -5556,134 +5762,6 @@ function vectorInstanceGroup(node, bake) {
5556
5762
  }
5557
5763
  var composeVectorMatrices = (a, b) => multiplyMatrices(a, b);
5558
5764
 
5559
- // src/vector/extrude.ts
5560
- function vectorPaintSolid(paint) {
5561
- if (paint == null || paint === "none") return null;
5562
- if (typeof paint === "string") return paint;
5563
- const stops = paint.stops;
5564
- if (stops?.length) return stops.reduce((a, b) => Math.abs(b.offset - 0.5) < Math.abs(a.offset - 0.5) ? b : a).color;
5565
- const colors = paint.colors;
5566
- if (colors?.length) return colors[0];
5567
- const points = paint.points;
5568
- return points?.find((p) => typeof p.color === "string")?.color ?? null;
5569
- }
5570
- function shadeVectorColor(color2, amount) {
5571
- const c = parseVectorColor(color2);
5572
- if (!c) return color2;
5573
- const a = Math.min(1, Math.max(-1, amount));
5574
- const target = a >= 0 ? 1 : 0;
5575
- const h = (v2) => Math.round(Math.min(1, Math.max(0, v2)) * 255).toString(16).padStart(2, "0");
5576
- const m = [0, 1, 2].map((k) => c[k] + (target - c[k]) * Math.abs(a));
5577
- return `#${h(m[0])}${h(m[1])}${h(m[2])}`;
5578
- }
5579
- function vectorPathRings(path, tolerance = 0.5) {
5580
- const rings = [];
5581
- for (const contour of pathToContours(path)) {
5582
- const ring = flattenChain(closeContour(contour, true), Math.max(1e-3, tolerance));
5583
- if (ring.length >= 2) rings.push(ring);
5584
- }
5585
- return rings;
5586
- }
5587
- function vectorExtrudeFaces(path, params) {
5588
- const box = bezierPathBounds(path);
5589
- if (!box || !path.length) return [];
5590
- const perspective = params.mode === "perspective";
5591
- const rad2 = params.angle * Math.PI / 180;
5592
- const d = [Math.cos(rad2) * Math.max(0, params.depth), Math.sin(rad2) * Math.max(0, params.depth)];
5593
- const vp = [(box.minX + box.maxX) / 2 + params.vanishingPoint.x, (box.minY + box.maxY) / 2 + params.vanishingPoint.y];
5594
- const pull = Math.min(1, Math.max(0, params.toward / 100));
5595
- const back = (p) => perspective ? [p[0] + (vp[0] - p[0]) * pull, p[1] + (vp[1] - p[1]) * pull] : [p[0] + d[0], p[1] + d[1]];
5596
- if (perspective ? pull <= 0 : Math.hypot(d[0], d[1]) < 1e-9) return [];
5597
- const lr = params.lightAngle * Math.PI / 180;
5598
- const light = [Math.cos(lr), Math.sin(lr)];
5599
- const strength = Math.min(1, Math.max(0, params.shading / 100));
5600
- const u = perspective ? [0, 0] : [d[0] / Math.hypot(d[0], d[1]), d[1] / Math.hypot(d[0], d[1])];
5601
- const centre = [(box.minX + box.maxX) / 2, (box.minY + box.maxY) / 2];
5602
- const aim = Math.atan2(centre[1] - vp[1], centre[0] - vp[0]);
5603
- const across = (p) => {
5604
- if (!perspective) return -p[0] * u[1] + p[1] * u[0];
5605
- let a = Math.atan2(p[1] - vp[1], p[0] - vp[0]) - aim;
5606
- while (a > Math.PI) a -= 2 * Math.PI;
5607
- while (a <= -Math.PI) a += 2 * Math.PI;
5608
- return a;
5609
- };
5610
- const towardBack = (p, q, l) => {
5611
- const lp = across(p);
5612
- const lq = across(q);
5613
- const t = Math.abs(lq - lp) < 1e-12 ? 0.5 : Math.min(1, Math.max(0, (l - lp) / (lq - lp)));
5614
- const x = [p[0] + (q[0] - p[0]) * t, p[1] + (q[1] - p[1]) * t];
5615
- return perspective ? -Math.hypot(vp[0] - x[0], vp[1] - x[1]) : x[0] * u[0] + x[1] * u[1];
5616
- };
5617
- const faces = [];
5618
- for (const ring of vectorPathRings(path, 0.25)) {
5619
- for (let i = 0; i < ring.length; i++) {
5620
- const p = ring[i];
5621
- const q = ring[(i + 1) % ring.length];
5622
- const ex = q[0] - p[0];
5623
- const ey = q[1] - p[1];
5624
- const len2 = Math.hypot(ex, ey);
5625
- if (len2 < 1e-9) continue;
5626
- const pb = back(p);
5627
- const qb = back(q);
5628
- const mid = [(p[0] + q[0]) / 2, (p[1] + q[1]) / 2];
5629
- const away = perspective ? [vp[0] - mid[0], vp[1] - mid[1]] : d;
5630
- let n2 = [ey / len2, -ex / len2];
5631
- if (n2[0] * away[0] + n2[1] * away[1] < 0) n2 = [-n2[0], -n2[1]];
5632
- const shade = (n2[0] * light[0] + n2[1] * light[1]) * strength;
5633
- const lp = across(p);
5634
- const lq = across(q);
5635
- faces.push({
5636
- p,
5637
- q,
5638
- lo: Math.min(lp, lq),
5639
- hi: Math.max(lp, lq),
5640
- key: towardBack(p, q, (lp + lq) / 2),
5641
- face: {
5642
- shade,
5643
- path: [{ type: "M", x: p[0], y: p[1] }, { type: "L", x: q[0], y: q[1] }, { type: "L", x: qb[0], y: qb[1] }, { type: "L", x: pb[0], y: pb[1] }, { type: "Z" }]
5644
- }
5645
- });
5646
- }
5647
- }
5648
- faces.sort((a, b) => a.key - b.key);
5649
- const n = faces.length;
5650
- const after = faces.map(() => []);
5651
- const before = new Array(n).fill(0);
5652
- const eps = 1e-9;
5653
- for (let i = 0; i < n; i++) {
5654
- for (let j = i + 1; j < n; j++) {
5655
- const lo = Math.max(faces[i].lo, faces[j].lo);
5656
- const hi = Math.min(faces[i].hi, faces[j].hi);
5657
- if (hi - lo <= eps * Math.max(1, Math.abs(hi))) continue;
5658
- const l = (lo + hi) / 2;
5659
- const di = towardBack(faces[i].p, faces[i].q, l);
5660
- const dj = towardBack(faces[j].p, faces[j].q, l);
5661
- if (Math.abs(di - dj) < 1e-9) continue;
5662
- const [back0, front] = di < dj ? [i, j] : [j, i];
5663
- after[back0].push(front);
5664
- before[front]++;
5665
- }
5666
- }
5667
- const order = [];
5668
- const done = new Array(n).fill(false);
5669
- let next = 0;
5670
- while (order.length < n) {
5671
- let pick = -1;
5672
- for (let i = next; i < n; i++) {
5673
- if (!done[i] && before[i] === 0) {
5674
- pick = i;
5675
- break;
5676
- }
5677
- }
5678
- if (pick < 0) pick = done.indexOf(false);
5679
- done[pick] = true;
5680
- order.push(pick);
5681
- for (const k of after[pick]) before[k]--;
5682
- while (next < n && done[next]) next++;
5683
- }
5684
- return order.map((i) => faces[i].face);
5685
- }
5686
-
5687
5765
  // src/vector/bevel.ts
5688
5766
  var MITER_LIMIT = 4;
5689
5767
  function crossing2(a, b, c, d) {
@@ -8245,6 +8323,7 @@ function vectorDocumentToSvg(doc, options = {}) {
8245
8323
  if (node.resizing) out2 += ` data-vector-resizing="${escapeAttr2(JSON.stringify(node.resizing))}"`;
8246
8324
  if (node.type === "path" && isVectorShadedPaint(node.fill)) out2 += ` data-vector-shading="${escapeAttr2(JSON.stringify(node.fill))}"`;
8247
8325
  if (node.type === "path" && node.connector) out2 += ` data-vector-connector="${escapeAttr2(JSON.stringify(node.connector))}"`;
8326
+ if (node.type === "group" && node.generation) out2 += ` data-vector-generation="${escapeAttr2(JSON.stringify(node.generation))}"`;
8248
8327
  if (node.type === "path" && node.lens) out2 += ` data-vector-lens="${escapeAttr2(JSON.stringify(node.lens))}"`;
8249
8328
  const blend = vectorBlendModeCss(node.blendMode);
8250
8329
  if (blend) out2 += ` style="mix-blend-mode:${blend}"`;
@@ -8308,13 +8387,19 @@ function vectorDocumentToSvg(doc, options = {}) {
8308
8387
  let data = ` data-vector-path="" data-vector-fills="${escapeAttr2(JSON.stringify(vectorFills(node)))}" data-vector-strokes="${escapeAttr2(JSON.stringify(vectorStrokes(node)))}"`;
8309
8388
  if (node.fillRule === "evenodd") data += ` data-vector-fill-rule="evenodd"`;
8310
8389
  lines.push(`${indent(depth)}<g${common(node)}${data}>`);
8311
- const layers = vectorPaintLayerNodes(node).filter((l) => l.drawn);
8390
+ const layers = vectorPaintLayerNodes(node).filter((l) => l.drawn || l.kind === "stroke" && isVectorBrushstrokeLayer(l.layer) && l.layer.visible !== false);
8312
8391
  let geometry = liveCorners(node);
8313
8392
  if (!layers.some((l) => l.kind === "fill")) {
8314
8393
  lines.push(`${indent(depth + 1)}<path data-vector-part="fill" d="${d}" fill="none"${rule}${geometry}/>`);
8315
8394
  geometry = "";
8316
8395
  }
8317
8396
  for (const l of layers) {
8397
+ if (l.kind === "stroke" && isVectorBrushstrokeLayer(l.layer)) {
8398
+ lines.push(`${indent(depth + 1)}<g data-vector-part="brushstroke" data-vector-layer="${l.index}"${layerAttrs(l.layer)}>`);
8399
+ for (const im of vectorBrushstrokeImages(node, l.layer)) lines.push(`${indent(depth + 2)}<image href="${im.href}" x="${num3(im.x)}" y="${num3(im.y)}" width="${num3(im.width)}" height="${num3(im.height)}" preserveAspectRatio="none"/>`);
8400
+ lines.push(`${indent(depth + 1)}</g>`);
8401
+ continue;
8402
+ }
8318
8403
  const id = `${prefix}${l.kind}-${node.id}-${l.index}`;
8319
8404
  const paint = vectorPaintToSvg(l.layer.paint, id, { node: l.node, precision, ...l.kind === "stroke" ? { role: "stroke" } : {} });
8320
8405
  defs.push(...paintMarkup(l.layer.paint, paint.defs));
@@ -9353,6 +9438,12 @@ function parseVectorSvg(svg, options = {}) {
9353
9438
  if (resizing) meta.resizing = resizing;
9354
9439
  const connector = child.attrs["data-vector-connector"] !== void 0 ? sanitizeVectorConnector(parseJson(child.attrs["data-vector-connector"])) : null;
9355
9440
  if (connector) meta.connector = connector;
9441
+ if (child.attrs["data-vector-generation"] !== void 0) {
9442
+ try {
9443
+ meta.generation = parseProvenance(parseJson(child.attrs["data-vector-generation"]));
9444
+ } catch {
9445
+ }
9446
+ }
9356
9447
  const lens = child.attrs["data-vector-lens"] !== void 0 ? sanitizeVectorLens(parseJson(child.attrs["data-vector-lens"])) : null;
9357
9448
  if (lens) meta.lens = lens;
9358
9449
  if (child.name === "g" && child.attrs["data-vector-frame"] !== void 0) {
@@ -10363,6 +10454,17 @@ export {
10363
10454
  vectorStrokeOutlinePath,
10364
10455
  hitTestVectorStroke,
10365
10456
  vectorStrokeReach,
10457
+ vectorPaintSolid,
10458
+ shadeVectorColor,
10459
+ vectorPathRings,
10460
+ vectorExtrudeFaces,
10461
+ VECTOR_BRUSHSTROKE_SCALE,
10462
+ vectorBrushstrokeBrushes,
10463
+ vectorBrushstrokeBrush,
10464
+ sanitizeVectorBrushstroke,
10465
+ isVectorBrushstrokeLayer,
10466
+ vectorBrushstrokeReach,
10467
+ vectorBrushstrokeImages,
10366
10468
  VECTOR_STROKE_SETTING_KEYS,
10367
10469
  VECTOR_BLEND_MODE_LABELS,
10368
10470
  isVectorBlendMode,
@@ -10526,10 +10628,6 @@ export {
10526
10628
  prefixVectorIds,
10527
10629
  vectorInstanceGroup,
10528
10630
  composeVectorMatrices,
10529
- vectorPaintSolid,
10530
- shadeVectorColor,
10531
- vectorPathRings,
10532
- vectorExtrudeFaces,
10533
10631
  vectorBevelFaces,
10534
10632
  isVectorLens,
10535
10633
  VECTOR_LENS_LABELS,
@@ -10674,4 +10772,4 @@ export {
10674
10772
  lineSubpath,
10675
10773
  roundSubpaths
10676
10774
  };
10677
- //# sourceMappingURL=chunk-HHTCDFZC.js.map
10775
+ //# sourceMappingURL=chunk-3D77LOBM.js.map