@pixerate/editor 0.228.2 → 0.230.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/animation-editor/camera-tools.d.cts +10 -0
  2. package/dist/animation-editor/camera-tools.d.ts +10 -0
  3. package/dist/animation-editor/camera.d.cts +67 -0
  4. package/dist/animation-editor/camera.d.ts +67 -0
  5. package/dist/animation-editor/compile.d.cts +4 -0
  6. package/dist/animation-editor/compile.d.ts +4 -0
  7. package/dist/animation-editor/controller.d.cts +34 -2
  8. package/dist/animation-editor/controller.d.ts +34 -2
  9. package/dist/animation-editor/effect-tools.d.cts +2 -1
  10. package/dist/animation-editor/effect-tools.d.ts +2 -1
  11. package/dist/animation-editor/evaluate.d.cts +9 -0
  12. package/dist/animation-editor/evaluate.d.ts +9 -0
  13. package/dist/animation-editor/flair.d.cts +8 -0
  14. package/dist/animation-editor/flair.d.ts +8 -0
  15. package/dist/animation-editor/index.cjs +603 -217
  16. package/dist/animation-editor/index.d.cts +2 -0
  17. package/dist/animation-editor/index.d.ts +2 -0
  18. package/dist/animation-editor/index.js +454 -68
  19. package/dist/animation-editor/issues.d.cts +16 -0
  20. package/dist/animation-editor/issues.d.ts +16 -0
  21. package/dist/animation-editor/tools.d.cts +1 -1
  22. package/dist/animation-editor/tools.d.ts +1 -1
  23. package/dist/animation-editor/types.d.cts +21 -3
  24. package/dist/animation-editor/types.d.ts +21 -3
  25. package/dist/canvas/index.cjs +7 -7
  26. package/dist/canvas/index.js +1 -1
  27. package/dist/{chunk-2XGW6DKL.cjs → chunk-5VQXSS2S.cjs} +8 -2
  28. package/dist/{chunk-IGPEBXUD.cjs → chunk-A57ZQDNN.cjs} +7 -7
  29. package/dist/{chunk-K5GXW5TR.cjs → chunk-C73U5UI3.cjs} +14 -14
  30. package/dist/{chunk-EBDZWIOP.cjs → chunk-ERJA5CGT.cjs} +5 -1
  31. package/dist/{chunk-SWKXPAJC.js → chunk-JVNGCS26.js} +7 -1
  32. package/dist/{chunk-LPTFDCJO.js → chunk-ONNNNGNS.js} +1 -1
  33. package/dist/{chunk-5MQOBTNP.cjs → chunk-OPSK22DL.cjs} +80 -9
  34. package/dist/{chunk-PB6JV62G.js → chunk-SBPGIZQN.js} +1 -1
  35. package/dist/{chunk-UGYUGZE2.js → chunk-TCZ2J7PR.js} +71 -0
  36. package/dist/{chunk-W4KFNAWC.js → chunk-TYCJGFCF.js} +5 -1
  37. package/dist/effects/helpers.d.cts +35 -1
  38. package/dist/effects/helpers.d.ts +35 -1
  39. package/dist/effects/index.cjs +60 -44
  40. package/dist/effects/index.js +18 -2
  41. package/dist/effects/types.d.cts +15 -0
  42. package/dist/effects/types.d.ts +15 -0
  43. package/dist/image-editor/controller.d.cts +12 -0
  44. package/dist/image-editor/controller.d.ts +12 -0
  45. package/dist/image-editor/geometry.d.cts +6 -0
  46. package/dist/image-editor/geometry.d.ts +6 -0
  47. package/dist/image-editor/index.cjs +837 -738
  48. package/dist/image-editor/index.js +117 -18
  49. package/dist/image-editor/tool-groups.d.cts +57 -9
  50. package/dist/image-editor/tool-groups.d.ts +57 -9
  51. package/dist/image-editor/types.d.cts +3 -1
  52. package/dist/image-editor/types.d.ts +3 -1
  53. package/dist/paint-editor/index.cjs +13 -13
  54. package/dist/paint-editor/index.js +3 -3
  55. package/dist/vector/index.cjs +6 -6
  56. package/dist/vector/index.js +1 -1
  57. package/dist/video-editor/index.cjs +318 -318
  58. package/dist/video-editor/index.js +4 -4
  59. package/package.json +1 -1
  60. package/skills/pixerate-animation-editor/SKILL.md +28 -1
  61. package/skills/pixerate-animation-motion-graphics/SKILL.md +3 -0
  62. package/skills/pixerate-image-editor/SKILL.md +1 -0
  63. package/skills/pixerate-video-editor/SKILL.md +16 -1
  64. package/skills/pixerate-video-montage/SKILL.md +2 -1
@@ -72,6 +72,7 @@ import {
72
72
  LUMA_709,
73
73
  LayerCompositor,
74
74
  LayerOperationError,
75
+ MARGIN_FIT_MIN_GUTTER,
75
76
  MAX_EFFECT_ANIMATION_MS,
76
77
  MAX_KELVIN,
77
78
  MIN_KELVIN,
@@ -405,7 +406,7 @@ import {
405
406
  writePsd,
406
407
  xyToTempTint,
407
408
  xyToUv
408
- } from "../chunk-SWKXPAJC.js";
409
+ } from "../chunk-JVNGCS26.js";
409
410
  import {
410
411
  parseCssColor
411
412
  } from "../chunk-3CI7FRMK.js";
@@ -743,7 +744,7 @@ import {
743
744
  createEffectToolProvider,
744
745
  linearToSrgb,
745
746
  resolveEffectValues
746
- } from "../chunk-UGYUGZE2.js";
747
+ } from "../chunk-TCZ2J7PR.js";
747
748
  import "../chunk-V2ZCJRDM.js";
748
749
  import {
749
750
  BrushstrokeCache,
@@ -7156,6 +7157,35 @@ var ImageEditorController = class {
7156
7157
  const data = this.compositor.composite(layers, r, this.compositorSources());
7157
7158
  return { width: r.width, height: r.height, data };
7158
7159
  }
7160
+ /**
7161
+ * The Eyedropper: the colour (#rrggbb) of the composite at a document point, or the average of
7162
+ * the `size` × `size` square round it (1, 3 or 5…), or null outside the canvas or where every
7163
+ * layer is transparent. With `setForeground` it also becomes the paint foreground.
7164
+ */
7165
+ sampleColor(point2, options = {}) {
7166
+ const { width, height } = this.naturalSize;
7167
+ const size = Math.max(1, Math.floor(options.size ?? 1));
7168
+ const cx = Math.floor(point2.x);
7169
+ const cy = Math.floor(point2.y);
7170
+ if (cx < 0 || cy < 0 || cx >= width || cy >= height) return null;
7171
+ const half = Math.floor(size / 2);
7172
+ const x = Math.max(0, cx - half);
7173
+ const y = Math.max(0, cy - half);
7174
+ const rect3 = { x, y, width: Math.min(width, cx + half + 1) - x, height: Math.min(height, cy + half + 1) - y };
7175
+ const { data } = this.compositePixels(rect3);
7176
+ let r = 0, g = 0, b = 0, a = 0;
7177
+ for (let i = 0; i < data.length; i += 4) {
7178
+ const w = data[i + 3];
7179
+ r += data[i] * w;
7180
+ g += data[i + 1] * w;
7181
+ b += data[i + 2] * w;
7182
+ a += w;
7183
+ }
7184
+ if (a === 0) return null;
7185
+ const hex = toHex([r / a, g / a, b / a]);
7186
+ if (options.setForeground) this.setPaintOptions({ foreground: hex });
7187
+ return hex;
7188
+ }
7159
7189
  compositorSources() {
7160
7190
  const { width, height } = this.naturalSize;
7161
7191
  return {
@@ -13523,7 +13553,7 @@ var DEPTH_MASK_CONTROLS = [
13523
13553
 
13524
13554
  // src/image-editor/playback.ts
13525
13555
  var IMAGE_PLAYBACK_KIND = "layer";
13526
- var PAINT = /^(paint_stroke|clone_stamp|heal_brush|spot_heal|dodge|burn|sponge|smudge|blur_stroke|sharpen_stroke|history_brush|set_clone_source|set_clone_transform|fill_pixels|clear_pixels|set_paint|set_retouch_options|load_mixer_brush|clean_mixer_brush)$/;
13556
+ var PAINT = /^(paint_stroke|clone_stamp|heal_brush|spot_heal|dodge|burn|sponge|smudge|blur_stroke|sharpen_stroke|history_brush|set_clone_source|set_clone_transform|fill_pixels|clear_pixels|set_paint|sample_color|set_retouch_options|load_mixer_brush|clean_mixer_brush)$/;
13527
13557
  var SELECT = /^(make_work_path|add_path|set_path_geometry|rename_path|duplicate_path|delete_path|fill_path|stroke_path|select_region|select_subject|select_by_color|select_all|deselect|invert_selection|select_rect|select_ellipse|select_polygon|quick_select|select_object|select_focus_area|select_sky|select_line|magic_wand|grow_selection|select_similar|reselect|select_layer_transparency|select_color_range|load_selection_from_image|load_selection_from_mask|set_selection_display|modify_selection|refine_selection|transform_selection|apply_selection_as_mask|layer_via_copy|stroke_selection|content_aware_fill|copy_pixels|cut_pixels|paste_pixels|save_selection|load_selection_from_channel|set_channel_properties|duplicate_channel|delete_channel|load_channel_from_image|set_quick_mask|path_to_selection|select_text_shape|compare_selections|edit_selection_step|insert_selection_step|remove_selection_step|freeze_selection|separate_subject)$/;
13528
13558
  var ANNOTATE = /^(add_shape_layer|update_shape|add_shape_component|set_shape_component|remove_shape_component|merge_shape_components|add_text_layer|set_text|set_text_style|set_paragraph_style|set_text_frame|set_text_orientation|convert_text_to_shape)$/;
13529
13559
  var CROP = /^(set_crop|crop_to_selection|reset_crop|set_rotation|flip_image|transform_layer|warp_layer|flip_layer|offset_layer)$/;
@@ -17441,7 +17471,29 @@ function createImagePaintTools(controller) {
17441
17471
  annotations: { title: "Get the paint", ...READ4 },
17442
17472
  handler: () => paintView()
17443
17473
  };
17444
- return [paintStroke, fill, clear, getMixer, loadMixerTool, cleanMixerTool, setPaint, getPaint];
17474
+ const sampleColor2 = {
17475
+ name: "sample_color",
17476
+ title: "Sample a colour (Eyedropper)",
17477
+ description: "The Eyedropper: reads the composite colour at a point in document pixels, averaged over a size \xD7 size square (default 1), and by default makes it the paint foreground. Fails outside the canvas or where every layer is transparent. View state, not an undo step. Returns the colour (#rrggbb) and the foreground.",
17478
+ inputSchema: {
17479
+ type: "object",
17480
+ properties: {
17481
+ x: { type: "number", description: "Document x in pixels." },
17482
+ y: { type: "number", description: "Document y in pixels." },
17483
+ size: { type: "integer", minimum: 1, maximum: 101, description: "Sample square in pixels (odd values centre on the point). Default 1." },
17484
+ setForeground: { type: "boolean", description: "Make the colour the paint foreground (default true)." }
17485
+ },
17486
+ required: ["x", "y"],
17487
+ additionalProperties: false
17488
+ },
17489
+ annotations: { title: "Sample a colour (Eyedropper)", ...SET },
17490
+ handler: (args) => {
17491
+ const color = controller.sampleColor({ x: args.x, y: args.y }, { size: args.size, setForeground: args.setForeground !== false });
17492
+ if (!color) throw new LayerOperationError(`Nothing to sample at (${args.x}, ${args.y}): the point is outside the canvas or transparent. Read the canvas size with get_image_info, then sample inside it.`);
17493
+ return { color, foreground: controller.getState().paint.foreground };
17494
+ }
17495
+ };
17496
+ return [paintStroke, fill, clear, getMixer, loadMixerTool, cleanMixerTool, setPaint, getPaint, sampleColor2];
17445
17497
  }
17446
17498
 
17447
17499
  // src/image-editor/color-tools.ts
@@ -20902,6 +20954,7 @@ function layerPanels(layer, options = {}) {
20902
20954
  };
20903
20955
  if (layer.type === "pixel") {
20904
20956
  effects();
20957
+ panels.push({ id: "color", title: "Color Adjustments" });
20905
20958
  panels.push({ id: "paint", title: "Brush Options" });
20906
20959
  } else if (layer.type === "adjustment") {
20907
20960
  panels.push({ id: "adjustment", title: adjustmentKindLabel(layer.kind) });
@@ -20911,7 +20964,10 @@ function layerPanels(layer, options = {}) {
20911
20964
  } else if (layer.type === "shape") {
20912
20965
  panels.push({ id: "shape", title: "Shape Options" });
20913
20966
  effects();
20914
- } else if (layer.type === "smart" || layer.type === "group") {
20967
+ } else if (layer.type === "smart") {
20968
+ effects();
20969
+ panels.push({ id: "color", title: "Color Adjustments" });
20970
+ } else if (layer.type === "group") {
20915
20971
  effects();
20916
20972
  }
20917
20973
  if (layer.mask || layer.vectorMask) {
@@ -21935,18 +21991,28 @@ var IMAGE_TOOL_GROUPS = [
21935
21991
  { id: "move", label: "Move", tools: ["move"] },
21936
21992
  { id: "select", label: "Select", tools: ["select"] },
21937
21993
  { id: "crop", label: "Crop", tools: ["crop"] },
21938
- { id: "brush", label: "Brush", tools: ["brush", "mixer"] },
21939
- { id: "eraser", label: "Eraser", tools: ["eraser"] },
21940
- { id: "repair", label: "Repair", tools: ["spot-heal", "heal", "clone"] },
21941
- { id: "history", label: "History Brush", tools: ["history"] },
21942
- { id: "focus", label: "Blur & Sharpen", tools: ["blur", "sharpen", "smudge"] },
21943
- { id: "tone", label: "Dodge & Burn", tools: ["dodge", "burn", "sponge"] },
21994
+ { id: "draw", label: "Draw", tools: ["brush", "pen", "mixer"] },
21995
+ { id: "erase", label: "Erase", tools: ["eraser", "history"] },
21996
+ {
21997
+ id: "retouch",
21998
+ label: "Retouch",
21999
+ tools: ["spot-heal", "heal", "clone", "dodge", "burn", "sponge", "blur", "sharpen", "smudge"],
22000
+ sections: [
22001
+ { label: "Fix", tools: ["spot-heal", "heal", "clone"] },
22002
+ { label: "Tone", tools: ["dodge", "burn", "sponge"] },
22003
+ { label: "Detail", tools: ["blur", "sharpen", "smudge"] }
22004
+ ]
22005
+ },
21944
22006
  { id: "shape", label: "Shape", tools: ["shape"] },
21945
- { id: "pen", label: "Pen", tools: ["path-pen"] },
22007
+ { id: "paths", label: "Paths", tools: ["path-pen", "path-select", "direct-select"] },
21946
22008
  { id: "type", label: "Type", tools: ["type"] },
21947
- { id: "path-select", label: "Path Selection", tools: ["path-select", "direct-select"] },
21948
- { id: "annotate", label: "Annotate", tools: ["pen", "line", "arrow", "rect", "circle"] }
22009
+ { id: "eyedropper", label: "Eyedropper", tools: ["eyedropper"] }
21949
22010
  ];
22011
+ function imageToolVariants(tool) {
22012
+ if (tool === "select") return SELECTION_TOOLS.map((t) => ({ tool: "select", id: t.id, label: t.label }));
22013
+ if (tool === "shape") return LIVE_SHAPE_KINDS.map((kind) => ({ tool: "shape", id: kind, label: SHAPE_KIND_LABELS[kind] }));
22014
+ return [];
22015
+ }
21950
22016
  function imageToolGroup(tool) {
21951
22017
  return IMAGE_TOOL_GROUPS.find((group) => group.tools.includes(tool)) ?? IMAGE_TOOL_GROUPS[0];
21952
22018
  }
@@ -21958,13 +22024,14 @@ var OTHER_TOOL_LABELS = {
21958
22024
  "path-pen": "Pen",
21959
22025
  "path-select": "Path Selection",
21960
22026
  "direct-select": "Direct Selection",
21961
- pen: "Freehand",
22027
+ pen: "Pencil",
21962
22028
  line: "Line",
21963
22029
  arrow: "Arrow",
21964
22030
  rect: "Rectangle",
21965
22031
  circle: "Ellipse",
21966
22032
  text: "Text",
21967
- watermark: "Watermark"
22033
+ watermark: "Watermark",
22034
+ eyedropper: "Eyedropper"
21968
22035
  };
21969
22036
  function imageToolLabel(tool) {
21970
22037
  return PAINT_TOOLS.find((t) => t.id === tool)?.label ?? OTHER_TOOL_LABELS[tool] ?? tool;
@@ -21977,7 +22044,8 @@ var IMAGE_TOOL_SHORTCUTS = {
21977
22044
  type: "T",
21978
22045
  "path-pen": "P",
21979
22046
  "path-select": "A",
21980
- "direct-select": "Shift+A"
22047
+ "direct-select": "Shift+A",
22048
+ eyedropper: "I"
21981
22049
  };
21982
22050
  function imageToolForShortcut(key2, shift = false) {
21983
22051
  const shortcut = `${shift ? "Shift+" : ""}${key2.toUpperCase()}`;
@@ -21991,6 +22059,7 @@ function imageToolCanvasMode(tool) {
21991
22059
  if (isPaintTool(tool)) return "paint";
21992
22060
  if (tool === "select") return "select";
21993
22061
  if (tool === "crop") return "crop";
22062
+ if (tool === "eyedropper") return "sample";
21994
22063
  return "annotate";
21995
22064
  }
21996
22065
  function imageToolPanel(tool) {
@@ -22002,12 +22071,37 @@ function imageToolPanel(tool) {
22002
22071
  if (tool === "shape" || tool === "type") return tool;
22003
22072
  return null;
22004
22073
  }
22074
+ function imageToolPanelIds(tool) {
22075
+ const own = imageToolPanel(tool);
22076
+ if (!own) return [];
22077
+ return own === "selection" ? [own, "channels"] : [own];
22078
+ }
22005
22079
  function imagePanelTool(panel) {
22006
22080
  for (const group of IMAGE_TOOL_GROUPS) {
22007
- for (const tool of group.tools) if (imageToolPanel(tool) === panel) return tool;
22081
+ for (const tool of group.tools) if (imageToolPanelIds(tool).includes(panel)) return tool;
22008
22082
  }
22009
22083
  return null;
22010
22084
  }
22085
+ var TOOL_ONLY_PANELS = /* @__PURE__ */ new Set(["paint", "selection", "canvas-size", "channels", "paths"]);
22086
+ var TOOL_PANEL_TITLES = {
22087
+ paint: "Brush Options",
22088
+ selection: "Selection",
22089
+ "canvas-size": "Composition Size",
22090
+ channels: "Channels",
22091
+ paths: "Paths",
22092
+ shape: "Shape Options",
22093
+ type: "Typography"
22094
+ };
22095
+ function imageToolPanels(tool, layer, options = {}) {
22096
+ const own = imageToolPanelIds(tool);
22097
+ const listed = layerPanels(layer, options);
22098
+ const first = own.map((id) => listed.find((p) => p.id === id) ?? { id, title: TOOL_PANEL_TITLES[id] ?? id });
22099
+ const rest = listed.filter((p) => !own.includes(p.id) && !TOOL_ONLY_PANELS.has(p.id));
22100
+ return [...first, ...rest];
22101
+ }
22102
+ function imageToolUsesColor(tool) {
22103
+ return tool === "brush" || tool === "mixer" || tool === "pen" || tool === "line" || tool === "arrow" || tool === "rect" || tool === "circle" || tool === "shape" || tool === "type" || tool === "eyedropper";
22104
+ }
22011
22105
 
22012
22106
  // src/image-editor/editorDocument.ts
22013
22107
  function createImageEditorDocument(controller, options = {}) {
@@ -22905,6 +22999,7 @@ export {
22905
22999
  LayerEffectError,
22906
23000
  LayerOperationError,
22907
23001
  MARCHING_ANTS_STEP_MS,
23002
+ MARGIN_FIT_MIN_GUTTER,
22908
23003
  MASK_EDGE_THRESHOLDS,
22909
23004
  MASK_FILE_ACCEPT,
22910
23005
  MAX_BATCH,
@@ -23406,6 +23501,10 @@ export {
23406
23501
  imageToolGroup,
23407
23502
  imageToolLabel,
23408
23503
  imageToolPanel,
23504
+ imageToolPanelIds,
23505
+ imageToolPanels,
23506
+ imageToolUsesColor,
23507
+ imageToolVariants,
23409
23508
  importPsd,
23410
23509
  inflate,
23411
23510
  inflateRaw,
@@ -1,20 +1,49 @@
1
1
  /**
2
- * The image editor's tools as a toolbar shows them: grouped like Photoshop's (a slot per group, the
3
- * rest of the group in a flyout), with labels and shortcuts, the canvas mode each tool draws in and
4
- * the layer panel (`layerPanels`) holding its options. Hosts build their toolbar from these instead
5
- * of listing tools themselves, so new tools show up without host changes.
2
+ * The image editor's tools as a toolbar shows them: grouped by what each tool is for (a slot per
3
+ * group, the rest of the group in a flyout or the host's tool options), with labels and shortcuts,
4
+ * the canvas mode each tool draws in and the layer panel (`layerPanels`) holding its options. Hosts
5
+ * build their toolbar from these instead of listing tools themselves, so new tools show up without
6
+ * host changes.
6
7
  */
7
8
  import type { ImageEditorTool } from './types.cjs';
9
+ import { type SelectionToolKind } from './selection/tool-options.cjs';
10
+ import { type ImageLayer, type LiveShapeKind } from './layers/model.cjs';
11
+ import { type LayerPanelDescriptor, type LayerPanelsOptions } from './layers/panel.cjs';
12
+ /** Tools of a group shown together under a heading (Retouch's Fix, Tone and Detail). */
13
+ export interface ImageToolSection {
14
+ label: string;
15
+ tools: readonly ImageEditorTool[];
16
+ }
8
17
  export interface ImageToolGroup {
9
18
  id: string;
10
19
  label: string;
11
20
  tools: readonly ImageEditorTool[];
21
+ /** The group's tools split by purpose, in `tools` order; absent when the group is one set. */
22
+ sections?: readonly ImageToolSection[];
12
23
  }
13
24
  /**
14
- * Every tool a toolbar offers, in toolbar order. The `text` and `watermark` annotations are left
15
- * out: they are added through the API (`addAnnotation`), not drawn.
25
+ * Every tool a toolbar offers, in toolbar order, grouped by intent: choose (Move, Select, Crop),
26
+ * put paint down (Draw), take it away (Erase), retouch (Fix, Tone, Detail), build shapes, paths and
27
+ * type, and pick colours (Eyedropper). The `text` and `watermark` annotations are left out: they
28
+ * are added through the API (`addAnnotation`), not drawn. So are the `line`, `arrow`, `rect` and
29
+ * `circle` annotations, which the Shape tool's live shapes cover (they still draw for API callers).
16
30
  */
17
31
  export declare const IMAGE_TOOL_GROUPS: readonly ImageToolGroup[];
32
+ /**
33
+ * One way of using a tool that a toolbar offers as a tool of its own: a selection tool (`select`
34
+ * with `SelectionToolOptions.tool`) or a shape kind (`shape` with `ShapeToolOptions.kind`).
35
+ */
36
+ export type ImageToolVariant = {
37
+ tool: 'select';
38
+ id: SelectionToolKind;
39
+ label: string;
40
+ } | {
41
+ tool: 'shape';
42
+ id: LiveShapeKind;
43
+ label: string;
44
+ };
45
+ /** The variants a tool offers (the selection tools, the shape kinds), or none. */
46
+ export declare function imageToolVariants(tool: ImageEditorTool): readonly ImageToolVariant[];
18
47
  /** The group a tool is in (the first group for a tool no group holds). */
19
48
  export declare function imageToolGroup(tool: ImageEditorTool): ImageToolGroup;
20
49
  export declare function imageToolLabel(tool: ImageEditorTool): string;
@@ -23,13 +52,32 @@ export declare const IMAGE_TOOL_SHORTCUTS: Partial<Record<ImageEditorTool, strin
23
52
  /** The tool a shortcut picks (the first tool listed for a shared key), or null. */
24
53
  export declare function imageToolForShortcut(key: string, shift?: boolean): ImageEditorTool | null;
25
54
  /** How a canvas handles pointer gestures for a tool (the Svelte and React canvases' `mode`). */
26
- export type ImageToolCanvasMode = 'transform' | 'crop' | 'select' | 'paint' | 'annotate';
55
+ export type ImageToolCanvasMode = 'transform' | 'crop' | 'select' | 'paint' | 'annotate' | 'sample';
27
56
  /**
28
57
  * The canvas mode a tool works in. Move picks and transforms layers; shapes, type, the path tools
29
- * and the annotations draw in `annotate`.
58
+ * and the annotations draw in `annotate`; the Eyedropper picks colours in `sample`.
30
59
  */
31
60
  export declare function imageToolCanvasMode(tool: ImageEditorTool): ImageToolCanvasMode;
32
61
  /** The `layerPanels` panel holding a tool's options, or null when it has none. */
33
62
  export declare function imageToolPanel(tool: ImageEditorTool): string | null;
34
- /** The first tool whose options are in a panel (in toolbar order), or null. */
63
+ /**
64
+ * The panels that work with a tool: the one holding its options (`imageToolPanel`) and, for the
65
+ * selection tools, Channels (where a selection is saved and loaded).
66
+ */
67
+ export declare function imageToolPanelIds(tool: ImageEditorTool): string[];
68
+ /** The first tool whose panels include `panel` (in toolbar order), or null. */
35
69
  export declare function imagePanelTool(panel: string): ImageEditorTool | null;
70
+ /**
71
+ * The panels a sidebar shows for the active tool and layer: the tool's own panels first
72
+ * (`imageToolPanelIds`: Brush Options only with a paint tool, Selection and Channels with Select,
73
+ * Composition Size with Crop, Paths with the path tools, Shape Options or Typography with Shape or
74
+ * Type), then the active layer's (`layerPanels`: its properties, effects, colour adjustments, mask,
75
+ * and its shape or type options when it is a shape or type layer). Move shows the layer's panels only.
76
+ */
77
+ export declare function imageToolPanels(tool: ImageEditorTool, layer: ImageLayer | null, options?: LayerPanelsOptions): LayerPanelDescriptor[];
78
+ /**
79
+ * Tools that put down a colour the host chooses: the brush and mixer (the paint foreground), the
80
+ * pencil and annotations, shapes and type (their fill or colour), and the Eyedropper that picks it.
81
+ * Hosts show their colour picker or palette for these.
82
+ */
83
+ export declare function imageToolUsesColor(tool: ImageEditorTool): boolean;
@@ -1,20 +1,49 @@
1
1
  /**
2
- * The image editor's tools as a toolbar shows them: grouped like Photoshop's (a slot per group, the
3
- * rest of the group in a flyout), with labels and shortcuts, the canvas mode each tool draws in and
4
- * the layer panel (`layerPanels`) holding its options. Hosts build their toolbar from these instead
5
- * of listing tools themselves, so new tools show up without host changes.
2
+ * The image editor's tools as a toolbar shows them: grouped by what each tool is for (a slot per
3
+ * group, the rest of the group in a flyout or the host's tool options), with labels and shortcuts,
4
+ * the canvas mode each tool draws in and the layer panel (`layerPanels`) holding its options. Hosts
5
+ * build their toolbar from these instead of listing tools themselves, so new tools show up without
6
+ * host changes.
6
7
  */
7
8
  import type { ImageEditorTool } from './types.js';
9
+ import { type SelectionToolKind } from './selection/tool-options.js';
10
+ import { type ImageLayer, type LiveShapeKind } from './layers/model.js';
11
+ import { type LayerPanelDescriptor, type LayerPanelsOptions } from './layers/panel.js';
12
+ /** Tools of a group shown together under a heading (Retouch's Fix, Tone and Detail). */
13
+ export interface ImageToolSection {
14
+ label: string;
15
+ tools: readonly ImageEditorTool[];
16
+ }
8
17
  export interface ImageToolGroup {
9
18
  id: string;
10
19
  label: string;
11
20
  tools: readonly ImageEditorTool[];
21
+ /** The group's tools split by purpose, in `tools` order; absent when the group is one set. */
22
+ sections?: readonly ImageToolSection[];
12
23
  }
13
24
  /**
14
- * Every tool a toolbar offers, in toolbar order. The `text` and `watermark` annotations are left
15
- * out: they are added through the API (`addAnnotation`), not drawn.
25
+ * Every tool a toolbar offers, in toolbar order, grouped by intent: choose (Move, Select, Crop),
26
+ * put paint down (Draw), take it away (Erase), retouch (Fix, Tone, Detail), build shapes, paths and
27
+ * type, and pick colours (Eyedropper). The `text` and `watermark` annotations are left out: they
28
+ * are added through the API (`addAnnotation`), not drawn. So are the `line`, `arrow`, `rect` and
29
+ * `circle` annotations, which the Shape tool's live shapes cover (they still draw for API callers).
16
30
  */
17
31
  export declare const IMAGE_TOOL_GROUPS: readonly ImageToolGroup[];
32
+ /**
33
+ * One way of using a tool that a toolbar offers as a tool of its own: a selection tool (`select`
34
+ * with `SelectionToolOptions.tool`) or a shape kind (`shape` with `ShapeToolOptions.kind`).
35
+ */
36
+ export type ImageToolVariant = {
37
+ tool: 'select';
38
+ id: SelectionToolKind;
39
+ label: string;
40
+ } | {
41
+ tool: 'shape';
42
+ id: LiveShapeKind;
43
+ label: string;
44
+ };
45
+ /** The variants a tool offers (the selection tools, the shape kinds), or none. */
46
+ export declare function imageToolVariants(tool: ImageEditorTool): readonly ImageToolVariant[];
18
47
  /** The group a tool is in (the first group for a tool no group holds). */
19
48
  export declare function imageToolGroup(tool: ImageEditorTool): ImageToolGroup;
20
49
  export declare function imageToolLabel(tool: ImageEditorTool): string;
@@ -23,13 +52,32 @@ export declare const IMAGE_TOOL_SHORTCUTS: Partial<Record<ImageEditorTool, strin
23
52
  /** The tool a shortcut picks (the first tool listed for a shared key), or null. */
24
53
  export declare function imageToolForShortcut(key: string, shift?: boolean): ImageEditorTool | null;
25
54
  /** How a canvas handles pointer gestures for a tool (the Svelte and React canvases' `mode`). */
26
- export type ImageToolCanvasMode = 'transform' | 'crop' | 'select' | 'paint' | 'annotate';
55
+ export type ImageToolCanvasMode = 'transform' | 'crop' | 'select' | 'paint' | 'annotate' | 'sample';
27
56
  /**
28
57
  * The canvas mode a tool works in. Move picks and transforms layers; shapes, type, the path tools
29
- * and the annotations draw in `annotate`.
58
+ * and the annotations draw in `annotate`; the Eyedropper picks colours in `sample`.
30
59
  */
31
60
  export declare function imageToolCanvasMode(tool: ImageEditorTool): ImageToolCanvasMode;
32
61
  /** The `layerPanels` panel holding a tool's options, or null when it has none. */
33
62
  export declare function imageToolPanel(tool: ImageEditorTool): string | null;
34
- /** The first tool whose options are in a panel (in toolbar order), or null. */
63
+ /**
64
+ * The panels that work with a tool: the one holding its options (`imageToolPanel`) and, for the
65
+ * selection tools, Channels (where a selection is saved and loaded).
66
+ */
67
+ export declare function imageToolPanelIds(tool: ImageEditorTool): string[];
68
+ /** The first tool whose panels include `panel` (in toolbar order), or null. */
35
69
  export declare function imagePanelTool(panel: string): ImageEditorTool | null;
70
+ /**
71
+ * The panels a sidebar shows for the active tool and layer: the tool's own panels first
72
+ * (`imageToolPanelIds`: Brush Options only with a paint tool, Selection and Channels with Select,
73
+ * Composition Size with Crop, Paths with the path tools, Shape Options or Typography with Shape or
74
+ * Type), then the active layer's (`layerPanels`: its properties, effects, colour adjustments, mask,
75
+ * and its shape or type options when it is a shape or type layer). Move shows the layer's panels only.
76
+ */
77
+ export declare function imageToolPanels(tool: ImageEditorTool, layer: ImageLayer | null, options?: LayerPanelsOptions): LayerPanelDescriptor[];
78
+ /**
79
+ * Tools that put down a colour the host chooses: the brush and mixer (the paint foreground), the
80
+ * pencil and annotations, shapes and type (their fill or colour), and the Eyedropper that picks it.
81
+ * Hosts show their colour picker or palette for these.
82
+ */
83
+ export declare function imageToolUsesColor(tool: ImageEditorTool): boolean;
@@ -282,7 +282,9 @@ export type ImageEditorTool = 'select' | 'crop' | 'pen' | 'rect' | 'circle' | 'a
282
282
  /** Live type layers, edited on the canvas (see `TypeToolGesture`). */
283
283
  | 'type'
284
284
  /** The path tools (see `PathEditGesture`): Path Selection, Direct Selection and the Pen for paths. */
285
- | 'path-select' | 'direct-select' | 'path-pen';
285
+ | 'path-select' | 'direct-select' | 'path-pen'
286
+ /** The Eyedropper: clicking the canvas picks the composite's colour as the paint foreground. */
287
+ | 'eyedropper';
286
288
  export type ImageEditorFit = 'contain' | 'margin';
287
289
  import type { DocumentColorMode, DocumentColorProfile, ProofSetup } from './color-management.cjs';
288
290
  import type { SelectionRecipeStep } from './selection/recipe.cjs';
@@ -282,7 +282,9 @@ export type ImageEditorTool = 'select' | 'crop' | 'pen' | 'rect' | 'circle' | 'a
282
282
  /** Live type layers, edited on the canvas (see `TypeToolGesture`). */
283
283
  | 'type'
284
284
  /** The path tools (see `PathEditGesture`): Path Selection, Direct Selection and the Pen for paths. */
285
- | 'path-select' | 'direct-select' | 'path-pen';
285
+ | 'path-select' | 'direct-select' | 'path-pen'
286
+ /** The Eyedropper: clicking the canvas picks the composite's colour as the paint foreground. */
287
+ | 'eyedropper';
286
288
  export type ImageEditorFit = 'contain' | 'margin';
287
289
  import type { DocumentColorMode, DocumentColorProfile, ProofSetup } from './color-management.js';
288
290
  import type { SelectionRecipeStep } from './selection/recipe.js';
@@ -1,13 +1,13 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12;
2
2
 
3
- var _chunkIGPEBXUDcjs = require('../chunk-IGPEBXUD.cjs');
3
+ var _chunkA57ZQDNNcjs = require('../chunk-A57ZQDNN.cjs');
4
4
 
5
5
 
6
6
 
7
7
 
8
8
 
9
9
 
10
- var _chunk2XGW6DKLcjs = require('../chunk-2XGW6DKL.cjs');
10
+ var _chunk5VQXSS2Scjs = require('../chunk-5VQXSS2S.cjs');
11
11
  require('../chunk-A2IS7EHE.cjs');
12
12
  require('../chunk-SS53NNZO.cjs');
13
13
 
@@ -137,7 +137,7 @@ require('../chunk-NM3G4VQT.cjs');
137
137
 
138
138
 
139
139
 
140
- var _chunk5MQOBTNPcjs = require('../chunk-5MQOBTNP.cjs');
140
+ var _chunkOPSK22DLcjs = require('../chunk-OPSK22DL.cjs');
141
141
  require('../chunk-WOFXZ3XU.cjs');
142
142
 
143
143
 
@@ -1673,11 +1673,11 @@ function header(state, options) {
1673
1673
  return out;
1674
1674
  }
1675
1675
  function serializePaintDocument(state, options = {}) {
1676
- const { layers, assets } = _chunk2XGW6DKLcjs.serializeLayers.call(void 0, state.layers);
1676
+ const { layers, assets } = _chunk5VQXSS2Scjs.serializeLayers.call(void 0, state.layers);
1677
1677
  return { ...header(state, options), layers, assets };
1678
1678
  }
1679
1679
  async function serializePaintDocumentExternal(state, store, options = {}) {
1680
- const { layers, assets } = await _chunk2XGW6DKLcjs.serializeLayersExternal.call(void 0, state.layers, store);
1680
+ const { layers, assets } = await _chunk5VQXSS2Scjs.serializeLayersExternal.call(void 0, state.layers, store);
1681
1681
  return { ...header(state, options), layers, assets };
1682
1682
  }
1683
1683
  function paintLayersOnly(layers, problems) {
@@ -1714,7 +1714,7 @@ function deserializePaintDocument(raw) {
1714
1714
  const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
1715
1715
  const paper = _chunkGNZI3KYKcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
1716
1716
  const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
1717
- const layers = paintLayersOnly(_chunk2XGW6DKLcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
1717
+ const layers = paintLayersOnly(_chunk5VQXSS2Scjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
1718
1718
  const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
1719
1719
  const activeLayerId = wanted && _chunkHB4ICNNAcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.flattenLayers.call(void 0, layers), 'access', _74 => _74.filter, 'call', _75 => _75((l) => l.type === "pixel"), 'access', _76 => _76.pop, 'call', _77 => _77(), 'optionalAccess', _78 => _78.id]), () => ( null));
1720
1720
  const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
@@ -1730,7 +1730,7 @@ async function deserializePaintDocumentAsync(raw, store) {
1730
1730
  if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
1731
1731
  const r = raw;
1732
1732
  const problems = [];
1733
- const assets = await _chunk2XGW6DKLcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
1733
+ const assets = await _chunk5VQXSS2Scjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
1734
1734
  const loaded = deserializePaintDocument({ ...r, assets });
1735
1735
  return { ...loaded, problems: [...problems, ...loaded.problems] };
1736
1736
  }
@@ -3213,7 +3213,7 @@ function timeLapseVideo(frameCount, width, height, fps, holdMs, name = "Time-lap
3213
3213
  }
3214
3214
  const video = { version: 1, name, width: w, height: h, fps, background: "#000000", assets, tracks: [{ id: "v1", kind: "video", clips }] };
3215
3215
  const durationMs = frameCount ? clips[clips.length - 1].start + clips[clips.length - 1].duration : 0;
3216
- return { video, ffmpeg: _chunkIGPEBXUDcjs.toVideoFfmpeg.call(void 0, video, { output: "timelapse.mp4" }), durationMs };
3216
+ return { video, ffmpeg: _chunkA57ZQDNNcjs.toVideoFfmpeg.call(void 0, video, { output: "timelapse.mp4" }), durationMs };
3217
3217
  }
3218
3218
  async function buildTimeLapse(source, target, options = {}) {
3219
3219
  const maxSide = Math.max(32, Math.min(4096, Math.round(_nullishCoalesce(options.maxSide, () => ( 720)))));
@@ -3296,7 +3296,7 @@ function checkPaintEffectPlace(d, place) {
3296
3296
  else if (d.uses.includes("filter") && place !== "light") instead = "; run it on a layer's dried paint with apply_effect instead";
3297
3297
  else if (place === "light" && d.uses.some((u) => PAINT_EFFECT_PLACES.layer.includes(u))) instead = "; add it as an effect layer (add_effect_layer) or fill a layer with it (fill_layer_with_effect) instead";
3298
3298
  else if (place === "paper" && d.uses.some((u) => u === "overlay" || u === "title")) instead = "; add it as an effect layer with add_effect_layer instead";
3299
- throw new (0, _chunk5MQOBTNPcjs.EffectUnsupportedError)(`"${d.id}" (${d.name}) is a ${d.uses.join(" / ") || d.kind} effect, and ${PLACE_WORDS[place]}${instead}.`, d.id);
3299
+ throw new (0, _chunkOPSK22DLcjs.EffectUnsupportedError)(`"${d.id}" (${d.name}) is a ${d.uses.join(" / ") || d.kind} effect, and ${PLACE_WORDS[place]}${instead}.`, d.id);
3300
3300
  }
3301
3301
  var PAPER_EFFECT_BLENDS = ["multiply", "normal", "overlay", "soft-light", "screen", "color"];
3302
3302
  var paperVersion = 1;
@@ -3479,7 +3479,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3479
3479
  /** Set while an operation that changes wet paint runs: the simulation before it (for undo). */
3480
3480
  __init106() {this.wetOp = null}
3481
3481
  /** The effects provider slot (see `setEffectsProvider`). */
3482
- __init107() {this.effects = new (0, _chunk5MQOBTNPcjs.EffectsSlot)()}
3482
+ __init107() {this.effects = new (0, _chunkOPSK22DLcjs.EffectsSlot)()}
3483
3483
  __init108() {this.effectsRenderer = new PaintEffectsRenderer()}
3484
3484
  __init109() {this.paperEffectNodeCache = null}
3485
3485
  constructor(options = {}) {;_class10.prototype.__init72.call(this);_class10.prototype.__init73.call(this);_class10.prototype.__init74.call(this);_class10.prototype.__init75.call(this);_class10.prototype.__init76.call(this);_class10.prototype.__init77.call(this);_class10.prototype.__init78.call(this);_class10.prototype.__init79.call(this);_class10.prototype.__init80.call(this);_class10.prototype.__init81.call(this);_class10.prototype.__init82.call(this);_class10.prototype.__init83.call(this);_class10.prototype.__init84.call(this);_class10.prototype.__init85.call(this);_class10.prototype.__init86.call(this);_class10.prototype.__init87.call(this);_class10.prototype.__init88.call(this);_class10.prototype.__init89.call(this);_class10.prototype.__init90.call(this);_class10.prototype.__init91.call(this);_class10.prototype.__init92.call(this);_class10.prototype.__init93.call(this);_class10.prototype.__init94.call(this);_class10.prototype.__init95.call(this);_class10.prototype.__init96.call(this);_class10.prototype.__init97.call(this);_class10.prototype.__init98.call(this);_class10.prototype.__init99.call(this);_class10.prototype.__init100.call(this);_class10.prototype.__init101.call(this);_class10.prototype.__init102.call(this);_class10.prototype.__init103.call(this);_class10.prototype.__init104.call(this);_class10.prototype.__init105.call(this);_class10.prototype.__init106.call(this);_class10.prototype.__init107.call(this);_class10.prototype.__init108.call(this);_class10.prototype.__init109.call(this);_class10.prototype.__init110.call(this);_class10.prototype.__init111.call(this);_class10.prototype.__init112.call(this);_class10.prototype.__init113.call(this);
@@ -4154,7 +4154,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4154
4154
  if (v === null) merged[k] = d.defaults[k];
4155
4155
  else given[k] = v;
4156
4156
  }
4157
- return { ...merged, ..._chunk5MQOBTNPcjs.resolveEffectValues.call(void 0, { ...d, defaults: merged }, given) };
4157
+ return { ...merged, ..._chunkOPSK22DLcjs.resolveEffectValues.call(void 0, { ...d, defaults: merged }, given) };
4158
4158
  }
4159
4159
  /** Renders a generator, overlay or title effect at the canvas size. */
4160
4160
  renderEffectCanvas(d, values, time = 0) {
@@ -5649,7 +5649,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
5649
5649
  return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
5650
5650
  });
5651
5651
  const layers = toStandard(dried);
5652
- const result = _chunk2XGW6DKLcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
5652
+ const result = _chunk5VQXSS2Scjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
5653
5653
  for (const [mode, names] of changed) {
5654
5654
  const label = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access', _289 => _289.find, 'call', _290 => _290((m) => m.id === mode), 'optionalAccess', _291 => _291.label]), () => ( mode));
5655
5655
  const std = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access', _292 => _292.find, 'call', _293 => _293((m) => m.id === _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _294 => _294.label]), () => ( _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, mode)));
@@ -8917,7 +8917,7 @@ function createPaintEffectsToolProvider(controller, options = {}) {
8917
8917
  if (changes.enabled !== void 0) throw new Error("enabled does not apply here: hide an effect layer with update_layer visible false, or remove the effect paper.");
8918
8918
  };
8919
8919
  const values = (v) => v;
8920
- return withPaintPlayback(_chunk5MQOBTNPcjs.createEffectToolProvider.call(void 0, {
8920
+ return withPaintPlayback(_chunkOPSK22DLcjs.createEffectToolProvider.call(void 0, {
8921
8921
  id: _nullishCoalesce(options.id, () => ( "paint-effects")),
8922
8922
  namespace: options.namespace,
8923
8923
  title: "Paint effects",
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  toVideoFfmpeg
3
- } from "../chunk-LPTFDCJO.js";
3
+ } from "../chunk-ONNNNGNS.js";
4
4
  import {
5
5
  deserializeLayers,
6
6
  exportPsd,
7
7
  resolveExternalAssets,
8
8
  serializeLayers,
9
9
  serializeLayersExternal
10
- } from "../chunk-SWKXPAJC.js";
10
+ } from "../chunk-JVNGCS26.js";
11
11
  import "../chunk-3CI7FRMK.js";
12
12
  import "../chunk-ZNA3IQZF.js";
13
13
  import {
@@ -137,7 +137,7 @@ import {
137
137
  EffectsSlot,
138
138
  createEffectToolProvider,
139
139
  resolveEffectValues
140
- } from "../chunk-UGYUGZE2.js";
140
+ } from "../chunk-TCZ2J7PR.js";
141
141
  import "../chunk-V2ZCJRDM.js";
142
142
  import {
143
143
  CoverageMap,
@@ -558,7 +558,7 @@ var _chunkNM3G4VQTcjs = require('../chunk-NM3G4VQT.cjs');
558
558
 
559
559
 
560
560
 
561
- var _chunk5MQOBTNPcjs = require('../chunk-5MQOBTNP.cjs');
561
+ var _chunkOPSK22DLcjs = require('../chunk-OPSK22DL.cjs');
562
562
  require('../chunk-WOFXZ3XU.cjs');
563
563
 
564
564
 
@@ -7328,7 +7328,7 @@ var VectorEditorController = (_class7 = class _VectorEditorController {
7328
7328
  }
7329
7329
  // --- Provider effects ---
7330
7330
  /** The effects provider slot (see `setEffectsProvider`). */
7331
- __init59() {this.effects = new (0, _chunk5MQOBTNPcjs.EffectsSlot)()}
7331
+ __init59() {this.effects = new (0, _chunkOPSK22DLcjs.EffectsSlot)()}
7332
7332
  /** The registered effects provider, or `null`. */
7333
7333
  get effectsProvider() {
7334
7334
  return this.effects.provider;
@@ -7352,10 +7352,10 @@ var VectorEditorController = (_class7 = class _VectorEditorController {
7352
7352
  /** The effect's picture as group children, scaled into `box` (an affine fit). */
7353
7353
  async vectorEffectPicture(effect, values) {
7354
7354
  const provider = this.effects.require();
7355
- if (!provider.applyVectorEffect) throw new (0, _chunk5MQOBTNPcjs.EffectUnsupportedError)(`${provider.name} has no vector effects.`);
7355
+ if (!provider.applyVectorEffect) throw new (0, _chunkOPSK22DLcjs.EffectUnsupportedError)(`${provider.name} has no vector effects.`);
7356
7356
  const d = await provider.describe(effect);
7357
- if (d.kind !== "vector") throw new (0, _chunk5MQOBTNPcjs.EffectUnsupportedError)(`"${d.id}" (${d.name}) is a ${d.kind} effect; the vector editor adds vector effects, which bring their own picture${d.kind === "motion" ? " (apply motion in the animation editor)" : ""}.`, d.id);
7358
- const resolved = _chunk5MQOBTNPcjs.resolveEffectValues.call(void 0, d, values);
7357
+ if (d.kind !== "vector") throw new (0, _chunkOPSK22DLcjs.EffectUnsupportedError)(`"${d.id}" (${d.name}) is a ${d.kind} effect; the vector editor adds vector effects, which bring their own picture${d.kind === "motion" ? " (apply motion in the animation editor)" : ""}.`, d.id);
7358
+ const resolved = _chunkOPSK22DLcjs.resolveEffectValues.call(void 0, d, values);
7359
7359
  const motion = await provider.applyVectorEffect(d.id, this.toSvg(), resolved);
7360
7360
  const parsed = _chunkBQE3Y6ZOcjs.parseVectorSvg.call(void 0, motion.svg);
7361
7361
  if (!parsed.nodes.length) throw new Error(`"${d.name}" drew no shapes the editor can read.`);
@@ -18172,7 +18172,7 @@ function createVectorEffectsToolProvider(controller, options = {}) {
18172
18172
  const effects = _optionalChain([g, 'optionalAccess', _765 => _765.providerEffect]) ? [info(g)] : [];
18173
18173
  return { target: id, effect: _nullishCoalesce(removed, () => ( effects[0])), effects };
18174
18174
  };
18175
- return _chunk5MQOBTNPcjs.createEffectToolProvider.call(void 0, {
18175
+ return _chunkOPSK22DLcjs.createEffectToolProvider.call(void 0, {
18176
18176
  id: _nullishCoalesce(options.id, () => ( "vector-effects")),
18177
18177
  namespace: options.namespace,
18178
18178
  title: "Vector effects",