@pixerate/editor 0.223.9 → 0.224.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.
@@ -9,8 +9,11 @@
9
9
  import type { JsonSchema } from '../tools/schema.js';
10
10
  import type { FlairSvgAnimation } from '../animation-editor/flair.js';
11
11
  import type { EffectAuthoringSession, EffectAuthoringSource } from './authoring.js';
12
- /** How an effect is drawn: a pixel shader, an animated vector picture, or motion applied to someone else's vector art. */
13
- export type EffectKind = 'shader' | 'vector' | 'motion';
12
+ /**
13
+ * How an effect is drawn: a pixel shader, an animated vector picture, motion applied to someone
14
+ * else's vector art, or a camera move, which moves a scene's camera and draws no pixels.
15
+ */
16
+ export type EffectKind = 'shader' | 'vector' | 'motion' | 'camera';
14
17
  /**
15
18
  * What an effect is for. An effect may have several uses.
16
19
  *
@@ -21,10 +24,33 @@ export type EffectKind = 'shader' | 'vector' | 'motion';
21
24
  * - `title`: draws type or a graphic meant as a title.
22
25
  * - `motion`: animates vector art (`applyVectorEffect`).
23
26
  * - `interactive`: reacts to pointer, scroll or audio input at run time.
27
+ * - `camera`: moves a scene's camera (`cameraView`). Only `camera` effects have it, and they have
28
+ * no other use, so editors that draw pixels never offer them.
24
29
  */
25
- export type EffectUse = 'filter' | 'transition' | 'generator' | 'overlay' | 'title' | 'motion' | 'interactive';
30
+ export type EffectUse = 'filter' | 'transition' | 'generator' | 'overlay' | 'title' | 'motion' | 'interactive' | 'camera';
26
31
  export declare const EFFECT_KINDS: readonly EffectKind[];
27
32
  export declare const EFFECT_USES: readonly EffectUse[];
33
+ /**
34
+ * What a camera move does to a shot.
35
+ *
36
+ * - `transition`: moves the camera from one framing (`from`) to the next (`to`): a glide, a whip
37
+ * pan, a punch zoom, a cut.
38
+ * - `hold`: moves the camera within one framing while the shot holds (`from` and `to` are the
39
+ * same): a Ken Burns drift, a crash zoom.
40
+ */
41
+ export type CameraMoveRole = 'transition' | 'hold';
42
+ export declare const CAMERA_MOVE_ROLES: readonly CameraMoveRole[];
43
+ /** How a `camera` effect moves (`EffectSummary.camera`). */
44
+ export interface EffectCameraMove {
45
+ role: CameraMoveRole;
46
+ /** Length of the move at its default values (ms); 0 for a cut. A hold plays across the shot's hold instead. */
47
+ durationMs: number;
48
+ /**
49
+ * Where the view jumps, 0–1 through the move (0.5 for a whip pan or punch zoom that cuts
50
+ * halfway). Keyframes either side of it must not be tweened across. Absent for a smooth move.
51
+ */
52
+ cut?: number;
53
+ }
28
54
  /** One entry of a provider's catalog. */
29
55
  export interface EffectSummary {
30
56
  /** Stable id, saved in documents. Never reused for a different effect. */
@@ -48,6 +74,8 @@ export interface EffectSummary {
48
74
  * background of its own to fade (an overlay is already transparent).
49
75
  */
50
76
  backgroundOpacity?: string;
77
+ /** How a `camera` effect moves. Present exactly when `kind` is `camera`. */
78
+ camera?: EffectCameraMove;
51
79
  }
52
80
  export interface EffectSearchOptions {
53
81
  kind?: EffectKind;
@@ -161,6 +189,77 @@ export type EffectVectorTarget = string | {
161
189
  svg: string;
162
190
  nodeIds?: readonly string[];
163
191
  };
192
+ /**
193
+ * Where a scene's camera looks (the shape of Flair's `View`). The scene is drawn at
194
+ * (point + scroll) × zoom, then turned by `tilt`, `turn` and `roll` round the middle of the stage
195
+ * and seen in perspective, then blurred by `blur` while the camera moves. Positions are in the
196
+ * scene's own units, so a framing is `stage.width / zoom` wide.
197
+ */
198
+ export interface CameraView {
199
+ /** Scale of the scene on the stage; > 0. */
200
+ zoom: number;
201
+ /** Scene offset before scaling, in scene units. */
202
+ scrollX: number;
203
+ scrollY: number;
204
+ /** Tips the scene back round its horizontal axis (CSS `rotateX`), degrees, −75 to 75. Default 0. */
205
+ tilt?: number;
206
+ /** Swings the scene round its vertical axis (CSS `rotateY`), degrees, −75 to 75. Default 0. */
207
+ turn?: number;
208
+ /** Rolls the scene round the line of sight (CSS `rotateZ`), degrees clockwise, −180 to 180. Default 0. */
209
+ roll?: number;
210
+ /** Distance of the lens from the scene as a multiple of the stage width; smaller is more dramatic. Default the provider's own. */
211
+ perspective?: number;
212
+ /** Motion blur in stage pixels while the camera moves; 0 or absent when still. */
213
+ blur?: number;
214
+ /** Direction the blur streaks, degrees on screen (0 horizontal, 90 vertical); absent when it blurs every way (a zoom or a turn). */
215
+ blurAngle?: number;
216
+ }
217
+ /** The stage a camera looks at, in pixels. */
218
+ export interface CameraStage {
219
+ width: number;
220
+ height: number;
221
+ }
222
+ /** Where a camera move is: what `cameraView` takes. */
223
+ export interface CameraMoveContext {
224
+ /** The framing the move leaves; for a hold, the framing it moves within (the same as `to`). */
225
+ from: CameraView;
226
+ /** The framing the move arrives at. */
227
+ to: CameraView;
228
+ /** How far through the move, 0–1. */
229
+ u: number;
230
+ /** Length of the whole move (ms): its `durationMs`, the editor's override, or for a hold the shot's hold. */
231
+ ms: number;
232
+ stage: CameraStage;
233
+ }
234
+ /** What `sampleCameraMove` takes: the move's framings, length and stage, and how often to key it. */
235
+ export interface CameraMoveSampleRequest {
236
+ from: CameraView;
237
+ to: CameraView;
238
+ /** Length of the move (ms). */
239
+ ms: number;
240
+ stage: CameraStage;
241
+ /** Keys per second; > 0. */
242
+ fps: number;
243
+ /** Control values; missing controls take their defaults. */
244
+ values?: EffectValues;
245
+ }
246
+ /** One key of a sampled camera move. */
247
+ export interface CameraKeyframe {
248
+ /** Ms from the start of the move. */
249
+ t: number;
250
+ view: CameraView;
251
+ }
252
+ /**
253
+ * A camera move as keyframes, so an editor can bake it without calling `cameraView` each frame.
254
+ * Keys are in time order from `t` 0 to `ms`, one per frame. At a cut two keys share the cut's
255
+ * `t`: the view just before it, then the view after; tweening between consecutive keys never
256
+ * crosses the jump.
257
+ */
258
+ export interface CameraMoveSample {
259
+ keys: readonly CameraKeyframe[];
260
+ /** Ms of the cut, when the move has one. */
261
+ cut?: number;
262
+ }
164
263
  /** What a provider can do, so editors can degrade cleanly. */
165
264
  export interface EffectProviderCapabilities {
166
265
  /** Renders off the main thread. */
@@ -177,6 +276,8 @@ export interface EffectProviderCapabilities {
177
276
  maxSize?: number;
178
277
  /** Implements `openAuthoring`: effects can be edited, not only used. */
179
278
  supportsAuthoring?: boolean;
279
+ /** Lists `camera` effects and implements `cameraView` (and maybe `sampleCameraMove`). */
280
+ supportsCamera?: boolean;
180
281
  }
181
282
  export type MaybePromise<T> = T | Promise<T>;
182
283
  /**
@@ -196,7 +297,10 @@ export interface EffectProvider {
196
297
  /** Effects matching every word of `query` (in name, id, category, tags or description), best first. */
197
298
  search(query: string, options?: EffectSearchOptions): MaybePromise<readonly EffectSummary[]>;
198
299
  describe(id: string): MaybePromise<EffectDescription>;
199
- /** A pixel renderer. A `vector` effect may refuse with `EffectUnsupportedError` where it cannot lay out SVG (a Worker). */
300
+ /**
301
+ * A pixel renderer. A `vector` effect may refuse with `EffectUnsupportedError` where it cannot
302
+ * lay out SVG (a Worker); a `camera` effect draws no pixels and may refuse with one saying so.
303
+ */
200
304
  createRenderer(id: string, options: EffectRendererOptions): MaybePromise<EffectRenderer>;
201
305
  /**
202
306
  * Vector and motion effects as an animated SVG. Present when `capabilities.supportsVector`. A
@@ -210,4 +314,17 @@ export interface EffectProvider {
210
314
  * `UnknownEffectError`; an effect the provider cannot edit throws `EffectUnsupportedError`.
211
315
  */
212
316
  openAuthoring?(from: EffectAuthoringSource): MaybePromise<EffectAuthoringSession>;
317
+ /**
318
+ * Where a camera move puts the camera `ctx.u` of the way through it, with its motion blur.
319
+ * Present when `capabilities.supportsCamera`. Synchronous and pure: the same id, context and
320
+ * values always give the same view, so editors may call it per frame or cache it. Unknown ids
321
+ * throw `UnknownEffectError`, invalid values `EffectControlError`, and an effect that is not a
322
+ * camera move (or a `u` outside 0–1) `EffectUnsupportedError`.
323
+ */
324
+ cameraView?(id: string, ctx: CameraMoveContext, values?: EffectValues): CameraView;
325
+ /**
326
+ * A camera move as keyframes (see `CameraMoveSample`). Optional even with `supportsCamera`;
327
+ * `sampleEffectCameraMove` falls back to `cameraView` per frame. Errors as for `cameraView`.
328
+ */
329
+ sampleCameraMove?(id: string, request: CameraMoveSampleRequest): MaybePromise<CameraMoveSample>;
213
330
  }
@@ -743,7 +743,7 @@ require('../chunk-NM3G4VQT.cjs');
743
743
 
744
744
 
745
745
 
746
- var _chunkA3A5TI6Rcjs = require('../chunk-A3A5TI6R.cjs');
746
+ var _chunkNTWR5TQBcjs = require('../chunk-NTWR5TQB.cjs');
747
747
  require('../chunk-WOFXZ3XU.cjs');
748
748
 
749
749
 
@@ -4831,7 +4831,7 @@ function checkImageEffectPlace(d, place) {
4831
4831
  const allowed = IMAGE_EFFECT_PLACES[place];
4832
4832
  if (d.kind === "motion" || !d.uses.some((u) => allowed.includes(u))) {
4833
4833
  const instead = place === "filter" && d.uses.some((u) => IMAGE_EFFECT_PLACES.layer.includes(u)) ? "; add it as an effect layer with add_effect_layer instead" : place === "layer" && d.uses.includes("filter") ? "; apply it to a layer as a smart filter with apply_effect instead" : "";
4834
- throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(
4834
+ throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(
4835
4835
  `"${d.id}" (${d.name}) is a ${d.uses.join(" / ")} effect, and ${place === "filter" ? "a smart filter takes filter effects" : "an effect layer takes generator, overlay or title effects"}${instead}.`,
4836
4836
  d.id
4837
4837
  );
@@ -4855,9 +4855,9 @@ function effectPixelsToSurface(p, depth) {
4855
4855
  const d = new Uint16Array(f.length);
4856
4856
  const code = (v) => v > 0 ? v < 1 ? Math.round(v * 65535) : 65535 : 0;
4857
4857
  for (let i = 0; i < f.length; i += 4) {
4858
- d[i] = code(_chunkA3A5TI6Rcjs.linearToSrgb.call(void 0, f[i]));
4859
- d[i + 1] = code(_chunkA3A5TI6Rcjs.linearToSrgb.call(void 0, f[i + 1]));
4860
- d[i + 2] = code(_chunkA3A5TI6Rcjs.linearToSrgb.call(void 0, f[i + 2]));
4858
+ d[i] = code(_chunkNTWR5TQBcjs.linearToSrgb.call(void 0, f[i]));
4859
+ d[i + 1] = code(_chunkNTWR5TQBcjs.linearToSrgb.call(void 0, f[i + 1]));
4860
+ d[i + 2] = code(_chunkNTWR5TQBcjs.linearToSrgb.call(void 0, f[i + 2]));
4861
4861
  d[i + 3] = code(f[i + 3]);
4862
4862
  }
4863
4863
  return _chunkOLNIPTB3cjs.surfaceFromDeepPixels.call(void 0, { width: p.width, height: p.height, data: d }, 4);
@@ -4874,7 +4874,7 @@ var ImageEffectsEngine = (_class9 = class {
4874
4874
  __init49() {this.generation = 0}
4875
4875
 
4876
4876
  constructor(options = {}) {;_class9.prototype.__init44.call(this);_class9.prototype.__init45.call(this);_class9.prototype.__init46.call(this);_class9.prototype.__init47.call(this);_class9.prototype.__init48.call(this);_class9.prototype.__init49.call(this);
4877
- this.slot = _nullishCoalesce(options.slot, () => ( new (0, _chunkA3A5TI6Rcjs.EffectsSlot)()));
4877
+ this.slot = _nullishCoalesce(options.slot, () => ( new (0, _chunkNTWR5TQBcjs.EffectsSlot)()));
4878
4878
  this.maxEntries = _nullishCoalesce(options.maxEntries, () => ( 24));
4879
4879
  this.pool = new (0, _chunkPY4GWSE2cjs.EffectRendererPool)({ maxRenderers: options.maxRenderers });
4880
4880
  this.detach = this.slot.subscribe(() => {
@@ -4934,7 +4934,7 @@ var ImageEffectsEngine = (_class9 = class {
4934
4934
  const provider = this.slot.require();
4935
4935
  const depth = _nullishCoalesce(size.depth, () => ( 8));
4936
4936
  const out = await this.render(provider, effect, size.width, size.height, depth, { time: _nullishCoalesce(size.time, () => ( 0)), values });
4937
- return out.width === size.width && out.height === size.height ? out : _chunkA3A5TI6Rcjs.createEffectPixels.call(void 0, size.width, size.height);
4937
+ return out.width === size.width && out.height === size.height ? out : _chunkNTWR5TQBcjs.createEffectPixels.call(void 0, size.width, size.height);
4938
4938
  }
4939
4939
  /** Why the result for `key` failed, if it did. */
4940
4940
  failure(key2) {
@@ -6196,7 +6196,7 @@ var ImageEditorController = (_class12 = class {
6196
6196
  __init84() {this.selectionWorker = null}
6197
6197
  __init85() {this.documentOpener = null}
6198
6198
  /** The effects provider slot (see `setEffectsProvider`). */
6199
- __init86() {this.effects = new (0, _chunkA3A5TI6Rcjs.EffectsSlot)()}
6199
+ __init86() {this.effects = new (0, _chunkNTWR5TQBcjs.EffectsSlot)()}
6200
6200
  /** Renders provider effects: effect smart filter results and effect layers. */
6201
6201
  __init87() {this.effectsEngine = new ImageEffectsEngine({ slot: this.effects })}
6202
6202
  __init88() {this.effectRefresh = "none"}
@@ -6532,7 +6532,7 @@ var ImageEditorController = (_class12 = class {
6532
6532
  */
6533
6533
  async applyEffectFilter(layerId, effect, options = {}) {
6534
6534
  const d = await this.describeEffect(effect, "filter");
6535
- const values = _chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, d, options.values);
6535
+ const values = _chunkNTWR5TQBcjs.resolveEffectValues.call(void 0, d, options.values);
6536
6536
  const found = _chunkB46UQUDCcjs.findLayer.call(void 0, this.state.layers, layerId);
6537
6537
  if (!found) throw new (0, _chunkR35YOUP2cjs.LayerOperationError)(`There is no layer "${layerId}"; call list_layers for the layer ids.`);
6538
6538
  let layers = this.state.layers;
@@ -6573,7 +6573,7 @@ var ImageEditorController = (_class12 = class {
6573
6573
  else if (k in d.controls.properties) base[k] = d.defaults[k];
6574
6574
  else throw new (0, _chunkR35YOUP2cjs.LayerOperationError)(`"${k}" is not a control of "${d.id}"; its controls are ${Object.keys(d.controls.properties).join(", ")}.`);
6575
6575
  }
6576
- update.values = { ...base, ..._chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, { ...d, defaults: base }, given) };
6576
+ update.values = { ...base, ..._chunkNTWR5TQBcjs.resolveEffectValues.call(void 0, { ...d, defaults: base }, given) };
6577
6577
  }
6578
6578
  for (const k of ["enabled", "blend", "opacity"]) if (changes[k] !== void 0) update[k] = changes[k];
6579
6579
  let res = _chunkR35YOUP2cjs.updateSmartFilter.call(void 0, this.state.layers, layerId, filterId, update, this.canvasSize);
@@ -6598,7 +6598,7 @@ var ImageEditorController = (_class12 = class {
6598
6598
  const ids = new Set(_chunkB46UQUDCcjs.flattenLayers.call(void 0, this.state.layers).map((l) => l.id));
6599
6599
  const id = options.id && !ids.has(options.id) ? options.id : _chunkR35YOUP2cjs.newLayerId.call(void 0, );
6600
6600
  const placed = _chunkR35YOUP2cjs.placeLayer.call(void 0, this.state.layers, { type: "pixel", id, name: "", visible: true, opacity: 1, blend: "normal", surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4), offset: { x: 0, y: 0 } }, this.newLayerPlacement(options));
6601
- const values = _chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, d, withBackgroundOpacity(d, options.values, hasLayersBelow(placed, id)));
6601
+ const values = _chunkNTWR5TQBcjs.resolveEffectValues.call(void 0, d, withBackgroundOpacity(d, options.values, hasLayersBelow(placed, id)));
6602
6602
  const { width, height } = this.naturalSize;
6603
6603
  const pixels = await this.effectsEngine.renderLayer(d.id, values, { width, height, depth: this.bitDepth, time });
6604
6604
  const layer = {
@@ -6642,7 +6642,7 @@ var ImageEditorController = (_class12 = class {
6642
6642
  else if (k in d.controls.properties) base[k] = d.defaults[k];
6643
6643
  else throw new (0, _chunkR35YOUP2cjs.LayerOperationError)(`"${k}" is not a control of "${d.id}"; its controls are ${Object.keys(d.controls.properties).join(", ")}.`);
6644
6644
  }
6645
- const values = { ...base, ..._chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, { ...d, defaults: base }, given) };
6645
+ const values = { ...base, ..._chunkNTWR5TQBcjs.resolveEffectValues.call(void 0, { ...d, defaults: base }, given) };
6646
6646
  const time = changes.time === void 0 ? _nullishCoalesce(g.time, () => ( 0)) : checkEffectTime(changes.time);
6647
6647
  const animate = changes.animate === void 0 ? g.animate : changes.animate === null ? void 0 : checkEffectAnimation(changes.animate);
6648
6648
  const { width, height } = this.naturalSize;
@@ -21811,7 +21811,7 @@ function createImageEffectsToolProvider(controller, options = {}) {
21811
21811
  return { target, effect: _nullishCoalesce(effects.find((e) => e.id === instance), () => ( effects[effects.length - 1])), effects, ...extra };
21812
21812
  };
21813
21813
  const plainValues = (v) => v;
21814
- return withImagePlayback(_chunkA3A5TI6Rcjs.createEffectToolProvider.call(void 0, {
21814
+ return withImagePlayback(_chunkNTWR5TQBcjs.createEffectToolProvider.call(void 0, {
21815
21815
  id: _nullishCoalesce(options.id, () => ( "image-effects")),
21816
21816
  namespace: options.namespace,
21817
21817
  title: "Image effects",
@@ -743,7 +743,7 @@ import {
743
743
  createEffectToolProvider,
744
744
  linearToSrgb,
745
745
  resolveEffectValues
746
- } from "../chunk-6G2NLMVK.js";
746
+ } from "../chunk-HKPLKISO.js";
747
747
  import "../chunk-V2ZCJRDM.js";
748
748
  import {
749
749
  BrushstrokeCache,
@@ -1,6 +1,6 @@
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 _chunkZ64NRDEHcjs = require('../chunk-Z64NRDEH.cjs');
3
+ var _chunkMDNYYOBZcjs = require('../chunk-MDNYYOBZ.cjs');
4
4
 
5
5
 
6
6
 
@@ -132,7 +132,7 @@ require('../chunk-NM3G4VQT.cjs');
132
132
 
133
133
 
134
134
 
135
- var _chunkA3A5TI6Rcjs = require('../chunk-A3A5TI6R.cjs');
135
+ var _chunkNTWR5TQBcjs = require('../chunk-NTWR5TQB.cjs');
136
136
  require('../chunk-WOFXZ3XU.cjs');
137
137
 
138
138
 
@@ -3198,7 +3198,7 @@ function timeLapseVideo(frameCount, width, height, fps, holdMs, name = "Time-lap
3198
3198
  }
3199
3199
  const video = { version: 1, name, width: w, height: h, fps, background: "#000000", assets, tracks: [{ id: "v1", kind: "video", clips }] };
3200
3200
  const durationMs = frameCount ? clips[clips.length - 1].start + clips[clips.length - 1].duration : 0;
3201
- return { video, ffmpeg: _chunkZ64NRDEHcjs.toVideoFfmpeg.call(void 0, video, { output: "timelapse.mp4" }), durationMs };
3201
+ return { video, ffmpeg: _chunkMDNYYOBZcjs.toVideoFfmpeg.call(void 0, video, { output: "timelapse.mp4" }), durationMs };
3202
3202
  }
3203
3203
  async function buildTimeLapse(source, target, options = {}) {
3204
3204
  const maxSide = Math.max(32, Math.min(4096, Math.round(_nullishCoalesce(options.maxSide, () => ( 720)))));
@@ -3277,7 +3277,7 @@ function checkPaintEffectPlace(d, place) {
3277
3277
  if (d.uses.includes("filter") && place !== "light") instead = "; run it on a layer's dried paint with apply_effect instead";
3278
3278
  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";
3279
3279
  else if (place === "paper" && d.uses.some((u) => u === "overlay" || u === "title")) instead = "; add it as an effect layer with add_effect_layer instead";
3280
- throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`"${d.id}" (${d.name}) is a ${d.uses.join(" / ") || d.kind} effect, and ${PLACE_WORDS[place]}${instead}.`, d.id);
3280
+ throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`"${d.id}" (${d.name}) is a ${d.uses.join(" / ") || d.kind} effect, and ${PLACE_WORDS[place]}${instead}.`, d.id);
3281
3281
  }
3282
3282
  var PAPER_EFFECT_BLENDS = ["multiply", "normal", "overlay", "soft-light", "screen", "color"];
3283
3283
  var paperVersion = 1;
@@ -3453,7 +3453,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
3453
3453
  /** Set while an operation that changes wet paint runs: the simulation before it (for undo). */
3454
3454
  __init102() {this.wetOp = null}
3455
3455
  /** The effects provider slot (see `setEffectsProvider`). */
3456
- __init103() {this.effects = new (0, _chunkA3A5TI6Rcjs.EffectsSlot)()}
3456
+ __init103() {this.effects = new (0, _chunkNTWR5TQBcjs.EffectsSlot)()}
3457
3457
  __init104() {this.effectsRenderer = new PaintEffectsRenderer()}
3458
3458
  __init105() {this.paperEffectNodeCache = null}
3459
3459
  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);
@@ -4126,7 +4126,7 @@ var PaintEditorController = (_class10 = class _PaintEditorController {
4126
4126
  if (v === null) merged[k] = d.defaults[k];
4127
4127
  else given[k] = v;
4128
4128
  }
4129
- return { ...merged, ..._chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, { ...d, defaults: merged }, given) };
4129
+ return { ...merged, ..._chunkNTWR5TQBcjs.resolveEffectValues.call(void 0, { ...d, defaults: merged }, given) };
4130
4130
  }
4131
4131
  /** Renders a generator, overlay or title effect at the canvas size. */
4132
4132
  renderEffectCanvas(d, values, time = 0) {
@@ -8730,7 +8730,7 @@ function createPaintEffectsToolProvider(controller, options = {}) {
8730
8730
  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.");
8731
8731
  };
8732
8732
  const values = (v) => v;
8733
- return withPaintPlayback(_chunkA3A5TI6Rcjs.createEffectToolProvider.call(void 0, {
8733
+ return withPaintPlayback(_chunkNTWR5TQBcjs.createEffectToolProvider.call(void 0, {
8734
8734
  id: _nullishCoalesce(options.id, () => ( "paint-effects")),
8735
8735
  namespace: options.namespace,
8736
8736
  title: "Paint effects",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  toVideoFfmpeg
3
- } from "../chunk-OZSA5YEJ.js";
3
+ } from "../chunk-RDTCG5MS.js";
4
4
  import {
5
5
  deserializeLayers,
6
6
  exportPsd,
@@ -132,7 +132,7 @@ import {
132
132
  EffectsSlot,
133
133
  createEffectToolProvider,
134
134
  resolveEffectValues
135
- } from "../chunk-6G2NLMVK.js";
135
+ } from "../chunk-HKPLKISO.js";
136
136
  import "../chunk-V2ZCJRDM.js";
137
137
  import {
138
138
  CoverageMap,
@@ -558,7 +558,7 @@ var _chunkNM3G4VQTcjs = require('../chunk-NM3G4VQT.cjs');
558
558
 
559
559
 
560
560
 
561
- var _chunkA3A5TI6Rcjs = require('../chunk-A3A5TI6R.cjs');
561
+ var _chunkNTWR5TQBcjs = require('../chunk-NTWR5TQB.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, _chunkA3A5TI6Rcjs.EffectsSlot)()}
7331
+ __init59() {this.effects = new (0, _chunkNTWR5TQBcjs.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, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`${provider.name} has no vector effects.`);
7355
+ if (!provider.applyVectorEffect) throw new (0, _chunkNTWR5TQBcjs.EffectUnsupportedError)(`${provider.name} has no vector effects.`);
7356
7356
  const d = await provider.describe(effect);
7357
- if (d.kind !== "vector") throw new (0, _chunkA3A5TI6Rcjs.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 = _chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, d, values);
7357
+ if (d.kind !== "vector") throw new (0, _chunkNTWR5TQBcjs.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 = _chunkNTWR5TQBcjs.resolveEffectValues.call(void 0, d, values);
7359
7359
  const motion = await provider.applyVectorEffect(d.id, this.toSvg(), resolved);
7360
7360
  const parsed = _chunkQAUIZPYIcjs.parseVectorSvg.call(void 0, motion.svg);
7361
7361
  if (!parsed.nodes.length) throw new Error(`"${d.name}" drew no shapes the editor can read.`);
@@ -18159,7 +18159,7 @@ function createVectorEffectsToolProvider(controller, options = {}) {
18159
18159
  const effects = _optionalChain([g, 'optionalAccess', _765 => _765.providerEffect]) ? [info(g)] : [];
18160
18160
  return { target: id, effect: _nullishCoalesce(removed, () => ( effects[0])), effects };
18161
18161
  };
18162
- return _chunkA3A5TI6Rcjs.createEffectToolProvider.call(void 0, {
18162
+ return _chunkNTWR5TQBcjs.createEffectToolProvider.call(void 0, {
18163
18163
  id: _nullishCoalesce(options.id, () => ( "vector-effects")),
18164
18164
  namespace: options.namespace,
18165
18165
  title: "Vector effects",
@@ -558,7 +558,7 @@ import {
558
558
  EffectsSlot,
559
559
  createEffectToolProvider,
560
560
  resolveEffectValues
561
- } from "../chunk-6G2NLMVK.js";
561
+ } from "../chunk-HKPLKISO.js";
562
562
  import "../chunk-V2ZCJRDM.js";
563
563
  import {
564
564
  GRAIN_PATTERNS