@pixerate/editor 0.132.0 → 0.134.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 (90) hide show
  1. package/dist/animation-editor/index.cjs +55 -55
  2. package/dist/animation-editor/index.d.cts +4 -4
  3. package/dist/animation-editor/index.d.ts +4 -4
  4. package/dist/animation-editor/index.js +2 -2
  5. package/dist/{bezier-oCBfrGDG.d.cts → bezier-J8i4uqSH.d.cts} +1 -1
  6. package/dist/{bezier-0IHDCvv_.d.ts → bezier-lNEOp0Jx.d.ts} +1 -1
  7. package/dist/canvas/index.d.cts +7 -7
  8. package/dist/canvas/index.d.ts +7 -7
  9. package/dist/{chunk-MZXQTKUM.cjs → chunk-24ATT2PE.cjs} +10 -6
  10. package/dist/chunk-24ATT2PE.cjs.map +1 -0
  11. package/dist/{chunk-AHUYMDYW.js → chunk-2HC4DRF4.js} +10 -6
  12. package/dist/chunk-2HC4DRF4.js.map +1 -0
  13. package/dist/{chunk-YRZ6NVE3.js → chunk-6CTZAGZ2.js} +235 -4
  14. package/dist/chunk-6CTZAGZ2.js.map +1 -0
  15. package/dist/{chunk-ECVI5QRE.js → chunk-7RJ6P7MI.js} +2 -2
  16. package/dist/{chunk-G5FX56KX.js → chunk-ESIWZMMK.js} +51 -11
  17. package/dist/chunk-ESIWZMMK.js.map +1 -0
  18. package/dist/{chunk-IEYXYMRQ.js → chunk-HHTCDFZC.js} +99 -5
  19. package/dist/chunk-HHTCDFZC.js.map +1 -0
  20. package/dist/{chunk-W6M7C7R3.cjs → chunk-NVTHUPJ6.cjs} +236 -5
  21. package/dist/chunk-NVTHUPJ6.cjs.map +1 -0
  22. package/dist/{chunk-OYPJGGF3.cjs → chunk-T6TV6HY6.cjs} +36 -36
  23. package/dist/{chunk-OYPJGGF3.cjs.map → chunk-T6TV6HY6.cjs.map} +1 -1
  24. package/dist/{chunk-55UEZIU4.cjs → chunk-YAFS2QFZ.cjs} +231 -191
  25. package/dist/chunk-YAFS2QFZ.cjs.map +1 -0
  26. package/dist/{chunk-YYJKIESX.cjs → chunk-Z2H7KECK.cjs} +153 -59
  27. package/dist/chunk-Z2H7KECK.cjs.map +1 -0
  28. package/dist/effects/index.d.cts +4 -4
  29. package/dist/effects/index.d.ts +4 -4
  30. package/dist/{export-D-gkjBkB.d.cts → export-BGdT02aL.d.cts} +10 -10
  31. package/dist/{export-CfAogLEr.d.cts → export-DMeG6E06.d.ts} +1 -1
  32. package/dist/{export-ByJvAvR7.d.ts → export-Dng22YB8.d.ts} +10 -10
  33. package/dist/{export-Crl82sbE.d.ts → export-KzubBKo7.d.cts} +1 -1
  34. package/dist/{helpers-BCd2-PAR.d.ts → helpers-Coa4e2j_.d.ts} +35 -1
  35. package/dist/{helpers-CoIeXQnW.d.cts → helpers-DHl28yLO.d.cts} +35 -1
  36. package/dist/image-editor/index.cjs +983 -874
  37. package/dist/image-editor/index.cjs.map +1 -1
  38. package/dist/image-editor/index.d.cts +32 -13
  39. package/dist/image-editor/index.d.ts +32 -13
  40. package/dist/image-editor/index.js +124 -15
  41. package/dist/image-editor/index.js.map +1 -1
  42. package/dist/{opentype-BDahNRTe.d.cts → opentype-BWR7Qv8W.d.cts} +1 -1
  43. package/dist/{opentype-BQFEvy-t.d.ts → opentype-Dfcx6wFx.d.ts} +1 -1
  44. package/dist/paint/index.cjs +8 -2
  45. package/dist/paint/index.cjs.map +1 -1
  46. package/dist/paint/index.d.cts +14 -3
  47. package/dist/paint/index.d.ts +14 -3
  48. package/dist/paint/index.js +7 -1
  49. package/dist/paint-editor/index.cjs +78 -78
  50. package/dist/paint-editor/index.d.cts +7 -7
  51. package/dist/paint-editor/index.d.ts +7 -7
  52. package/dist/paint-editor/index.js +3 -3
  53. package/dist/{pathfinder-DaVdT8jq.d.ts → pathfinder-Celbi3e6.d.ts} +1 -1
  54. package/dist/{pathfinder-01ZgAwqV.d.cts → pathfinder-D8KQ6blQ.d.cts} +1 -1
  55. package/dist/{pool-D2A3WTt9.d.ts → pool-8JZGWHvR.d.ts} +1 -1
  56. package/dist/{pool-D6a45MoE.d.cts → pool-BfuxBKTd.d.cts} +1 -1
  57. package/dist/{rand-pQQ2sJTk.d.ts → rand-BaqEOs1Y.d.ts} +17 -4
  58. package/dist/{rand-DTXAssW1.d.cts → rand-DdpFzCo6.d.cts} +17 -4
  59. package/dist/raster/index.cjs +2 -2
  60. package/dist/raster/index.d.cts +4 -4
  61. package/dist/raster/index.d.ts +4 -4
  62. package/dist/raster/index.js +1 -1
  63. package/dist/{svg-DELNVerw.d.ts → svg-CxxqG3_W.d.ts} +2 -2
  64. package/dist/{svg-CcDz7Zq2.d.cts → svg-pwXWq6s2.d.cts} +2 -2
  65. package/dist/{tools-BFvkFnRj.d.cts → tools-3EBjR91b.d.cts} +1 -1
  66. package/dist/{tools-D7ws-OKL.d.ts → tools-y1M6O3UT.d.ts} +1 -1
  67. package/dist/vector/index.cjs +1642 -1046
  68. package/dist/vector/index.cjs.map +1 -1
  69. package/dist/vector/index.d.cts +275 -93
  70. package/dist/vector/index.d.ts +275 -93
  71. package/dist/vector/index.js +607 -11
  72. package/dist/vector/index.js.map +1 -1
  73. package/dist/video-editor/index.d.cts +4 -4
  74. package/dist/video-editor/index.d.ts +4 -4
  75. package/dist/{warp-2N9wkOkL.d.ts → warp-C1gwu2G_.d.ts} +1 -1
  76. package/dist/{warp-DErXW5rz.d.cts → warp-Ceqdz7kj.d.cts} +1 -1
  77. package/package.json +1 -1
  78. package/skills/pixerate-image-editor/SKILL.md +1 -1
  79. package/skills/pixerate-image-editor/references/retouching.md +3 -2
  80. package/skills/pixerate-vector/SKILL.md +12 -53
  81. package/skills/pixerate-vector/references/pitfalls.md +62 -0
  82. package/dist/chunk-55UEZIU4.cjs.map +0 -1
  83. package/dist/chunk-AHUYMDYW.js.map +0 -1
  84. package/dist/chunk-G5FX56KX.js.map +0 -1
  85. package/dist/chunk-IEYXYMRQ.js.map +0 -1
  86. package/dist/chunk-MZXQTKUM.cjs.map +0 -1
  87. package/dist/chunk-W6M7C7R3.cjs.map +0 -1
  88. package/dist/chunk-YRZ6NVE3.js.map +0 -1
  89. package/dist/chunk-YYJKIESX.cjs.map +0 -1
  90. /package/dist/{chunk-ECVI5QRE.js.map → chunk-7RJ6P7MI.js.map} +0 -0
@@ -75,6 +75,7 @@ import {
75
75
  applyDepthMask,
76
76
  applyImageProjectionToContext,
77
77
  applyLegacyAdjustments,
78
+ applyLegacyFloat,
78
79
  applyMatrix3,
79
80
  applyParams,
80
81
  applyProcess2Adjustments,
@@ -362,7 +363,7 @@ import {
362
363
  writePsd,
363
364
  xyToTempTint,
364
365
  xyToUv
365
- } from "../chunk-G5FX56KX.js";
366
+ } from "../chunk-ESIWZMMK.js";
366
367
  import {
367
368
  parseCssColor
368
369
  } from "../chunk-CTTF4KYV.js";
@@ -426,7 +427,7 @@ import {
426
427
  validateLayerEffects,
427
428
  warpSurface,
428
429
  workingToSamples
429
- } from "../chunk-AHUYMDYW.js";
430
+ } from "../chunk-2HC4DRF4.js";
430
431
  import {
431
432
  applyHomography,
432
433
  boxQuad,
@@ -447,6 +448,8 @@ import {
447
448
  applyRetouchToTile,
448
449
  applyToneToDeepTile,
449
450
  bestOffset,
451
+ boxBlurPixels,
452
+ contentAwareFill,
450
453
  dilateMask,
451
454
  dodgeBurn,
452
455
  dodgeBurnCurve,
@@ -457,6 +460,7 @@ import {
457
460
  normalizeRetouch,
458
461
  perDabStrength,
459
462
  readSourceRegion,
463
+ retouchFilter,
460
464
  rgbaViewOfGrey,
461
465
  saturationOf,
462
466
  seamlessClone,
@@ -467,7 +471,7 @@ import {
467
471
  spotHealPixels,
468
472
  spotHealWindow,
469
473
  toneOf
470
- } from "../chunk-YRZ6NVE3.js";
474
+ } from "../chunk-6CTZAGZ2.js";
471
475
  import {
472
476
  BrushstrokeCache,
473
477
  brushstrokeDataUrl,
@@ -802,7 +806,7 @@ import {
802
806
  warpMeshParamAt,
803
807
  warpMeshRows,
804
808
  warpPresetMesh
805
- } from "../chunk-IEYXYMRQ.js";
809
+ } from "../chunk-HHTCDFZC.js";
806
810
  import "../chunk-YGJIER2R.js";
807
811
  import "../chunk-KHNZ6MOU.js";
808
812
  import {
@@ -3685,7 +3689,7 @@ function convertSurfaceColors(surface, t) {
3685
3689
 
3686
3690
  // src/image-editor/controller.ts
3687
3691
  var IMAGE_EDITOR_SCHEMA_VERSION = LAYERED_SCHEMA_VERSION;
3688
- var RETOUCH_TOOLS = ["clone", "heal", "spot-heal", "smudge", "dodge", "burn", "sponge"];
3692
+ var RETOUCH_TOOLS = ["clone", "heal", "spot-heal", "smudge", "dodge", "burn", "sponge", "blur", "sharpen", "history"];
3689
3693
  var isRetouchTool = (tool) => RETOUCH_TOOLS.includes(tool);
3690
3694
  var STROKE_TOOLS = ["brush", "eraser", "mixer", ...RETOUCH_TOOLS];
3691
3695
  function paintCoverageInto(base, coverage, apply, rects, depth = null) {
@@ -3959,6 +3963,18 @@ var PaintStrokeSession = class {
3959
3963
  this.controller._strokeCommit(this.before, this.target.id, this.target.channel, null);
3960
3964
  }
3961
3965
  };
3966
+ function workRegionOf(surface, rect, depth) {
3967
+ if (!depth) return Float32Array.from(readRegion(surface, rect));
3968
+ const d = readDeepRegion(surface, rect, depth);
3969
+ const out = new Float32Array(d.length);
3970
+ if (d instanceof Uint16Array) {
3971
+ for (let i = 0; i < d.length; i++) out[i] = d[i] / 257;
3972
+ return out;
3973
+ }
3974
+ const ch = surface.channels;
3975
+ for (let i = 0; i < d.length; i++) out[i] = (ch === 4 && (i & 3) !== 3 ? srgbEncode(d[i]) : d[i]) * 255;
3976
+ return out;
3977
+ }
3962
3978
  function workTileOf(tile) {
3963
3979
  if (!tile) return null;
3964
3980
  const d = tile.deep;
@@ -6158,7 +6174,7 @@ var ImageEditorController = class {
6158
6174
  if (tool === "smudge") return { kind: "dabs", create: (pixels) => new RetouchDabStroke(brush, pixels, smudgeEffect(brush, settings.strength)) };
6159
6175
  if (tool === "sponge") return { kind: "dabs", create: (pixels) => new RetouchDabStroke(brush, pixels, spongeEffect(brush, settings.spongeMode === "saturate", settings.vibrance)) };
6160
6176
  const retouchApply = {
6161
- opacity: tool === "clone" || tool === "heal" ? brush.opacity : 1,
6177
+ opacity: tool === "clone" || tool === "heal" || tool === "history" ? brush.opacity : tool === "blur" || tool === "sharpen" ? brush.opacity * settings.strength : 1,
6162
6178
  blend: tool === "clone" && !mask ? brush.blend : "normal",
6163
6179
  lockTransparency: target.lockTransparency,
6164
6180
  selection: apply.selection,
@@ -6170,6 +6186,41 @@ var ImageEditorController = class {
6170
6186
  return { kind: "coverage", coverage, apply: retouchApply, start: () => {
6171
6187
  }, paint: () => paint2 };
6172
6188
  }
6189
+ if (tool === "blur" || tool === "sharpen") {
6190
+ const n = target.surface.channels;
6191
+ const depth = !mask && this.bitDepth !== 8 ? this.bitDepth : null;
6192
+ const m = 6;
6193
+ const filtered = new TilePixelSource(
6194
+ (tx, ty) => {
6195
+ const r = { x: tx * TILE - m, y: ty * TILE - m, width: TILE + 2 * m, height: TILE + 2 * m };
6196
+ const d = workRegionOf(target.surface, r, depth);
6197
+ retouchFilter(d, r.width, r.height, n, tool, 2, 1.2);
6198
+ const out = new Float32Array(TILE * TILE * n);
6199
+ for (let y = 0; y < TILE; y++) out.set(d.subarray(((y + m) * r.width + m) * n, ((y + m) * r.width + m + TILE) * n), y * TILE * n);
6200
+ return out;
6201
+ },
6202
+ n,
6203
+ target.offset
6204
+ );
6205
+ const paint2 = { kind: "source", source: filtered, dx: 0, dy: 0 };
6206
+ return { kind: "coverage", coverage, apply: retouchApply, start: () => {
6207
+ }, paint: () => paint2 };
6208
+ }
6209
+ if (tool === "history") {
6210
+ const steps = settings.historySteps;
6211
+ const entry = steps > 0 ? this.undoStack[this.undoStack.length - steps] ?? this.undoStack[0] : this.undoStack[0];
6212
+ if (!entry) throw new LayerOperationError("There is no earlier state to paint from yet: the History Brush paints a layer as it was some undo steps back. Make a change first.");
6213
+ const then = findLayer(entry.layers, target.id)?.layer;
6214
+ if (!then) throw new LayerOperationError(`Layer "${target.id}" did not exist ${steps > 0 ? `${steps} steps back` : "in the oldest state"}; choose fewer history steps (historySteps).`);
6215
+ const surface = target.channel === "mask" ? then.mask?.surface : then.type === "pixel" ? then.surface : void 0;
6216
+ if (!surface) throw new LayerOperationError(`Layer "${target.id}" had no ${target.channel === "mask" ? "mask" : "pixels"} in that state.`);
6217
+ const offset2 = then.type === "pixel" ? then.offset : { x: 0, y: 0 };
6218
+ const depth = !mask && this.bitDepth !== 8 ? this.bitDepth : null;
6219
+ const source2 = depth ? new TilePixelSource((tx, ty) => workTileOf(surface.tiles.get(tileKey(tx, ty))), 4, offset2) : this.surfaceSource(surface, offset2);
6220
+ const paint2 = { kind: "source", source: source2, dx: 0, dy: 0 };
6221
+ return { kind: "coverage", coverage, apply: retouchApply, start: () => {
6222
+ }, paint: () => paint2 };
6223
+ }
6173
6224
  const sample = mask ? "current" : settings.sample;
6174
6225
  const deep = !mask && this.bitDepth !== 8 ? this.bitDepth : null;
6175
6226
  const own = deep ? new TilePixelSource((tx, ty) => workTileOf(target.surface.tiles.get(tileKey(tx, ty))), 4, target.offset) : this.surfaceSource(target.surface, target.offset);
@@ -10656,13 +10707,17 @@ var PAINT_TOOLS = [
10656
10707
  { id: "smudge", label: "Smudge", shortcut: "" },
10657
10708
  { id: "dodge", label: "Dodge", shortcut: "O" },
10658
10709
  { id: "burn", label: "Burn", shortcut: "Shift+O" },
10659
- { id: "sponge", label: "Sponge", shortcut: "Shift+O" }
10710
+ { id: "sponge", label: "Sponge", shortcut: "Shift+O" },
10711
+ { id: "blur", label: "Blur", shortcut: "" },
10712
+ { id: "sharpen", label: "Sharpen", shortcut: "" },
10713
+ { id: "history", label: "History", shortcut: "Y" }
10660
10714
  ];
10661
10715
  var isPaintTool = (tool) => PAINT_TOOLS.some((t) => t.id === tool);
10662
- var isRetouchPaintTool = (tool) => tool === "clone" || tool === "heal" || tool === "spot-heal" || tool === "smudge" || tool === "dodge" || tool === "burn" || tool === "sponge";
10716
+ var isRetouchPaintTool = (tool) => tool === "clone" || tool === "heal" || tool === "spot-heal" || tool === "smudge" || tool === "dodge" || tool === "burn" || tool === "sponge" || tool === "blur" || tool === "sharpen" || tool === "history";
10663
10717
  var RETOUCH_OPTION_CONTROLS = [
10664
10718
  { id: "exposure", label: "Exposure", section: "layer", min: 0, max: 1, step: 0.01, default: 0.5, decimals: 0, track: plain2, displayScale: 100, unit: "%", tools: ["dodge", "burn"] },
10665
- { id: "strength", label: "Strength", section: "layer", min: 0, max: 1, step: 0.01, default: 0.5, decimals: 0, track: plain2, displayScale: 100, unit: "%", tools: ["smudge"] }
10719
+ { id: "strength", label: "Strength", section: "layer", min: 0, max: 1, step: 0.01, default: 0.5, decimals: 0, track: plain2, displayScale: 100, unit: "%", tools: ["smudge", "blur", "sharpen"] },
10720
+ { id: "historySteps", label: "Steps back", section: "layer", min: 0, max: 50, step: 1, default: 0, decimals: 0, track: plain2, unit: "", tools: ["history"] }
10666
10721
  ];
10667
10722
  var RETOUCH_CHOICES = [
10668
10723
  {
@@ -10681,6 +10736,7 @@ var RETOUCH_CHOICES = [
10681
10736
  tools: ["spot-heal"],
10682
10737
  options: [
10683
10738
  { id: "proximity-match", label: "Proximity Match", title: "Copy the best matching patch nearby" },
10739
+ { id: "content-aware", label: "Content-Aware", title: "Synthesise texture and edges from patches around the spot" },
10684
10740
  { id: "smooth", label: "Smooth", title: "Fill smoothly from the edges" }
10685
10741
  ]
10686
10742
  },
@@ -10753,6 +10809,9 @@ function handlePaintShortcut(controller, e) {
10753
10809
  controller.setTool(next);
10754
10810
  return true;
10755
10811
  }
10812
+ case "y":
10813
+ controller.setTool("history");
10814
+ return true;
10756
10815
  case "d":
10757
10816
  controller.resetPaintColors();
10758
10817
  return true;
@@ -11337,12 +11396,12 @@ function createImageRetouchTools(controller) {
11337
11396
  const spotHeal = {
11338
11397
  name: "spot_heal",
11339
11398
  title: "Spot Healing stroke",
11340
- description: "Removes what a stroke covers without a source point (Photoshop's Spot Healing Brush): proximity-match copies the best matching patch nearby and blends it in; smooth fills from the edges inwards (for spots on smooth areas). Paint just over the spot with a brush a little larger than it. One undo step. Returns the layerId, channel, changed bounds, dab count and spotHeal {offset} (the patch offset copied, or null for a smooth fill).",
11399
+ description: "Removes what a stroke covers without a source point (Photoshop's Spot Healing Brush): proximity-match copies the best matching patch nearby and blends it in; content-aware synthesises texture and continues edges from patches all around (best across lines, on patterns and for larger spots, a little slower); smooth fills from the edges inwards (for spots on smooth areas). Paint just over the spot with a brush a little larger than it. One undo step. Returns the layerId, channel, changed bounds, dab count and spotHeal {offset} (the patch offset copied, or null for a smooth fill).",
11341
11400
  inputSchema: {
11342
11401
  type: "object",
11343
11402
  properties: {
11344
11403
  points: POINTS,
11345
- type: { type: "string", enum: [...SPOT_HEAL_TYPES], description: "proximity-match (default) or smooth." },
11404
+ type: { type: "string", enum: [...SPOT_HEAL_TYPES], description: "proximity-match (default the current option), content-aware or smooth." },
11346
11405
  sample: SAMPLE,
11347
11406
  brush: BRUSH2,
11348
11407
  ...TARGET2
@@ -11419,10 +11478,55 @@ function createImageRetouchTools(controller) {
11419
11478
  annotations: { title: "Sponge stroke", ...WRITE5 },
11420
11479
  handler: (args) => stroke("sponge", { ...args, channel: "pixels" }, { ...pick(args, ["vibrance"]), ...args.mode !== void 0 ? { spongeMode: args.mode } : {} })
11421
11480
  };
11481
+ const filterSchema = (verb) => ({
11482
+ type: "object",
11483
+ properties: {
11484
+ points: POINTS,
11485
+ strength: { type: "number", minimum: 0, maximum: 1, description: `How strongly to ${verb}, 0..1 (default the current option, 0.5); multiplies the brush opacity.` },
11486
+ brush: BRUSH2,
11487
+ ...TARGET2
11488
+ },
11489
+ required: ["points"],
11490
+ additionalProperties: false
11491
+ });
11492
+ const blurTool = {
11493
+ name: "blur_stroke",
11494
+ title: "Blur stroke",
11495
+ description: "Softens the pixels a stroke covers (Photoshop's Blur tool): a soft blur of the layer laid through the brush at `strength`. Overlapping dabs in one stroke do not compound; another stroke blurs further. Works on pixels and masks, at any bit depth. One undo step. Returns the layerId, channel, changed bounds and dab count.",
11496
+ inputSchema: filterSchema("blur"),
11497
+ annotations: { title: "Blur stroke", ...WRITE5 },
11498
+ handler: (args) => stroke("blur", args, pick(args, ["strength"]))
11499
+ };
11500
+ const sharpenTool = {
11501
+ name: "sharpen_stroke",
11502
+ title: "Sharpen stroke",
11503
+ description: "Crisps the pixels a stroke covers (Photoshop's Sharpen tool): an unsharp mask of the layer laid through the brush at `strength`. Keep strength low (0.2..0.5) and inspect with capture_view; strong sharpening shows halos and noise. One undo step. Returns the layerId, channel, changed bounds and dab count.",
11504
+ inputSchema: filterSchema("sharpen"),
11505
+ annotations: { title: "Sharpen stroke", ...WRITE5 },
11506
+ handler: (args) => stroke("sharpen", args, pick(args, ["strength"]))
11507
+ };
11508
+ const historyBrush = {
11509
+ name: "history_brush",
11510
+ title: "History Brush stroke",
11511
+ description: "Paints the layer back as it was earlier (Photoshop's History Brush): the same layer's pixels (or mask) from `historySteps` undo steps back, or from the oldest state history keeps (0, the default, usually the document as opened), laid through the brush. Use it to undo part of a filter, paint or retouch in one area. Fails if the layer did not exist then or there is no history yet. One undo step. Returns the layerId, channel, changed bounds and dab count.",
11512
+ inputSchema: {
11513
+ type: "object",
11514
+ properties: {
11515
+ points: POINTS,
11516
+ historySteps: { type: "integer", minimum: 0, maximum: 1e3, description: "Undo steps back to paint from; 0 (default the current option) is the oldest state history keeps." },
11517
+ brush: BRUSH2,
11518
+ ...TARGET2
11519
+ },
11520
+ required: ["points"],
11521
+ additionalProperties: false
11522
+ },
11523
+ annotations: { title: "History Brush stroke", ...WRITE5 },
11524
+ handler: (args) => stroke("history", args, pick(args, ["historySteps"]))
11525
+ };
11422
11526
  const getOptions = {
11423
11527
  name: "get_retouch_options",
11424
11528
  title: "Get retouch options",
11425
- description: "Reads the retouching tools' options (aligned, sample, spotType, range, exposure, protectTones, spongeMode, vibrance, strength) and the clone source ({x, y, offset} or null; offset is the aligned offset the last clone or heal stroke fixed: an aligned stroke samples at the brush plus offset, which the editors show as a crosshair). Call it before clone_stamp or heal_brush without a source to see where they will sample.",
11529
+ description: "Reads the retouching tools' options (aligned, sample, spotType, range, exposure, protectTones, spongeMode, vibrance, strength, historySteps) and the clone source ({x, y, offset} or null; offset is the aligned offset the last clone or heal stroke fixed: an aligned stroke samples at the brush plus offset, which the editors show as a crosshair). Call it before clone_stamp or heal_brush without a source to see where they will sample.",
11426
11530
  inputSchema: { type: "object", properties: {}, additionalProperties: false },
11427
11531
  annotations: { title: "Get retouch options", ...READ6 },
11428
11532
  handler: () => {
@@ -11439,13 +11543,14 @@ function createImageRetouchTools(controller) {
11439
11543
  properties: {
11440
11544
  aligned: { type: "boolean", description: "Clone / heal: keep the offset from stroke to stroke (default true)." },
11441
11545
  sample: SAMPLE,
11442
- spotType: { type: "string", enum: [...SPOT_HEAL_TYPES], description: "Spot heal: proximity-match (default) or smooth." },
11546
+ spotType: { type: "string", enum: [...SPOT_HEAL_TYPES], description: "Spot heal: proximity-match (default), content-aware or smooth." },
11443
11547
  range: { type: "string", enum: [...TONE_RANGES], description: "Dodge / burn: shadows, midtones (default) or highlights." },
11444
11548
  exposure: { type: "number", minimum: 0, maximum: 1, description: "Dodge / burn strength 0..1 (default 0.5)." },
11445
11549
  protectTones: { type: "boolean", description: "Dodge / burn: keep hue and saturation (default true)." },
11446
11550
  spongeMode: { type: "string", enum: ["desaturate", "saturate"], description: "Sponge: desaturate (default) or saturate." },
11447
11551
  vibrance: { type: "boolean", description: "Sponge: damp clipping (default true)." },
11448
- strength: { type: "number", minimum: 0, maximum: 1, description: "Smudge strength 0..1 (default 0.5)." }
11552
+ strength: { type: "number", minimum: 0, maximum: 1, description: "Smudge, blur and sharpen strength 0..1 (default 0.5)." },
11553
+ historySteps: { type: "integer", minimum: 0, maximum: 1e3, description: "History Brush: undo steps back it paints from; 0 is the oldest state (default 0)." }
11449
11554
  },
11450
11555
  additionalProperties: false
11451
11556
  },
@@ -11475,7 +11580,7 @@ function createImageRetouchTools(controller) {
11475
11580
  return controller.setCloneSource(checkSource(controller, { x: args.x, y: args.y }));
11476
11581
  }
11477
11582
  };
11478
- return [cloneStamp, healBrush, spotHeal, smudge, dodge, burn, spongeTool, getOptions, setOptions, setSource];
11583
+ return [cloneStamp, healBrush, spotHeal, smudge, dodge, burn, spongeTool, blurTool, sharpenTool, historyBrush, getOptions, setOptions, setSource];
11479
11584
  }
11480
11585
  function pick(args, keys) {
11481
11586
  const out = {};
@@ -15136,6 +15241,7 @@ export {
15136
15241
  applyHomography,
15137
15242
  applyImageProjectionToContext,
15138
15243
  applyLegacyAdjustments,
15244
+ applyLegacyFloat,
15139
15245
  applyMatrix3,
15140
15246
  applyOutputStage,
15141
15247
  applyParams,
@@ -15164,6 +15270,7 @@ export {
15164
15270
  blenderDab,
15165
15271
  blurFilter,
15166
15272
  borderCoverage,
15273
+ boxBlurPixels,
15167
15274
  boxMean,
15168
15275
  boxPointOf,
15169
15276
  boxQuad,
@@ -15204,6 +15311,7 @@ export {
15204
15311
  compositeSurfaceOver,
15205
15312
  computeHistogram,
15206
15313
  computeSelectionBounds,
15314
+ contentAwareFill,
15207
15315
  contentBounds,
15208
15316
  contentsBox,
15209
15317
  contentsSurface,
@@ -15644,6 +15752,7 @@ export {
15644
15752
  resolvePaintGradient,
15645
15753
  resolveProfile,
15646
15754
  restyleRange,
15755
+ retouchFilter,
15647
15756
  reversePaintGradient,
15648
15757
  rgbToGray,
15649
15758
  rgbToHsl,