@pixerate/editor 0.259.0 → 0.260.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 (74) hide show
  1. package/dist/agent/index.cjs +2 -2
  2. package/dist/agent/index.js +1 -1
  3. package/dist/animation-editor/index.cjs +61 -59
  4. package/dist/animation-editor/index.js +5 -3
  5. package/dist/brushes/index.cjs +52 -52
  6. package/dist/brushes/index.js +6 -6
  7. package/dist/{brushstrokeRender-JI4W6F2G.js → brushstrokeRender-25Q5BEY6.js} +17 -7
  8. package/dist/{brushstrokeRender-MQ6PSDM5.cjs → brushstrokeRender-N6UPZSQS.cjs} +31 -21
  9. package/dist/canvas/brushTypes.d.cts +5 -0
  10. package/dist/canvas/brushTypes.d.ts +5 -0
  11. package/dist/canvas/drawController.d.cts +15 -1
  12. package/dist/canvas/drawController.d.ts +15 -1
  13. package/dist/canvas/index.cjs +136 -102
  14. package/dist/canvas/index.js +35 -1
  15. package/dist/{chunk-3PPJRMIG.js → chunk-3O47TPGX.js} +197 -18
  16. package/dist/{chunk-5Q5MLXAD.cjs → chunk-3TQW5MPW.cjs} +23 -23
  17. package/dist/{chunk-JBBJE76O.cjs → chunk-3ZRNK3RO.cjs} +1138 -85
  18. package/dist/{chunk-YSGW7VV4.cjs → chunk-43NT242D.cjs} +1401 -228
  19. package/dist/{chunk-SMTUQWGY.js → chunk-5IW65VQ6.js} +1 -1
  20. package/dist/{chunk-YQ4PQTBB.js → chunk-6NZL24W4.js} +9 -1
  21. package/dist/{chunk-O3ZVZSNJ.cjs → chunk-7AUQ2UJ3.cjs} +137 -129
  22. package/dist/{chunk-4M4E3N6X.js → chunk-CQVTGBQI.js} +1 -1
  23. package/dist/{chunk-SSFMWJDK.js → chunk-D4TE5JNW.js} +1192 -19
  24. package/dist/{chunk-AORZ5M5C.js → chunk-EHALWBBD.js} +1 -1
  25. package/dist/{chunk-6WCQ35GI.cjs → chunk-NHA26O5X.cjs} +2 -2
  26. package/dist/{chunk-DPYAO5U6.cjs → chunk-PVJMTLPJ.cjs} +197 -18
  27. package/dist/{chunk-MQGQTKVW.cjs → chunk-PYTJBVW5.cjs} +29 -29
  28. package/dist/{chunk-IXQZHCOF.js → chunk-QAR2N7HZ.js} +1 -1
  29. package/dist/{chunk-5P4JEOIV.js → chunk-TMDDMJCR.js} +2 -2
  30. package/dist/{chunk-RSIKDWOP.cjs → chunk-TZOX7KWV.cjs} +15 -15
  31. package/dist/{chunk-IPUTIUGQ.cjs → chunk-UVZ7RQOE.cjs} +1 -1
  32. package/dist/{chunk-A7GJ6BXI.js → chunk-WJ4WQJCC.js} +1062 -9
  33. package/dist/{chunk-ICTPLVSR.js → chunk-X2EXYY4J.js} +1 -1
  34. package/dist/{chunk-WQCNC4DK.js → chunk-XC6DPRYI.js} +695 -4
  35. package/dist/{chunk-KBYB7OWB.cjs → chunk-YHDHFJUC.cjs} +776 -85
  36. package/dist/{chunk-P3PZ63M3.cjs → chunk-YLUIFXSL.cjs} +35 -35
  37. package/dist/commands/index.cjs +2 -2
  38. package/dist/commands/index.js +1 -1
  39. package/dist/image-editor/index.cjs +1385 -2484
  40. package/dist/image-editor/index.js +139 -1238
  41. package/dist/image-editor/selection-worker.cjs +3 -4
  42. package/dist/image-editor/selection-worker.js +1 -2
  43. package/dist/paint/index.cjs +3 -5
  44. package/dist/paint/index.js +40 -42
  45. package/dist/paint-editor/contract.d.cts +29 -0
  46. package/dist/paint-editor/contract.d.ts +29 -0
  47. package/dist/paint-editor/dab-stroke.d.cts +5 -0
  48. package/dist/paint-editor/dab-stroke.d.ts +5 -0
  49. package/dist/paint-editor/index.cjs +402 -258
  50. package/dist/paint-editor/index.d.cts +1 -0
  51. package/dist/paint-editor/index.d.ts +1 -0
  52. package/dist/paint-editor/index.js +197 -53
  53. package/dist/paint-editor/stamp-tip.d.cts +17 -0
  54. package/dist/paint-editor/stamp-tip.d.ts +17 -0
  55. package/dist/paint-editor/ui.d.cts +21 -1
  56. package/dist/paint-editor/ui.d.ts +21 -1
  57. package/dist/raster/index.cjs +2 -4
  58. package/dist/raster/index.js +6 -8
  59. package/dist/vector/brushstroke.d.cts +6 -0
  60. package/dist/vector/brushstroke.d.ts +6 -0
  61. package/dist/vector/controller.d.cts +11 -2
  62. package/dist/vector/controller.d.ts +11 -2
  63. package/dist/vector/index.cjs +990 -973
  64. package/dist/vector/index.js +28 -11
  65. package/package.json +1 -1
  66. package/skills/pixerate-brushes/SKILL.md +1 -1
  67. package/skills/pixerate-canvas/SKILL.md +3 -1
  68. package/skills/pixerate-vector/SKILL.md +2 -2
  69. package/dist/chunk-2VJAVXLI.js +0 -192
  70. package/dist/chunk-62Z5WLRA.js +0 -700
  71. package/dist/chunk-BOHDJJ2O.cjs +0 -192
  72. package/dist/chunk-NKGB64CW.cjs +0 -700
  73. package/dist/chunk-SS53NNZO.cjs +0 -1066
  74. package/dist/chunk-ZNA3IQZF.js +0 -1066
@@ -1,4 +1,23 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } 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;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } 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;
2
+
3
+
4
+
5
+
6
+
7
+
8
+ var _chunkBB6TR422cjs = require('./chunk-BB6TR422.cjs');
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+ var _chunkFQPUF2W2cjs = require('./chunk-FQPUF2W2.cjs');
17
+
18
+
19
+
20
+
2
21
 
3
22
 
4
23
  var _chunk2VX55NFMcjs = require('./chunk-2VX55NFM.cjs');
@@ -80,6 +99,648 @@ function createPigmentTools() {
80
99
  return [mixColors];
81
100
  }
82
101
 
102
+ // src/paint/retouch.ts
103
+ var TONE_RANGES = ["shadows", "midtones", "highlights"];
104
+ function luma(r, g, b) {
105
+ return 0.299 * r + 0.587 * g + 0.114 * b;
106
+ }
107
+ function dodgeBurnCurve(v, e, range, burn) {
108
+ const x = Math.max(0, v);
109
+ const k = Math.min(1, Math.max(0, e));
110
+ const c = Math.min(1, x);
111
+ if (range === "midtones") {
112
+ const w2 = Math.min(1, Math.max(0, 4 * x * (1 - x)));
113
+ return x + w2 * (Math.pow(c, burn ? 1 + k : 1 / (1 + k)) - x);
114
+ }
115
+ const w = range === "shadows" ? (1 - c) * (1 - c) : c * c;
116
+ return burn ? x - k * w * x : x + k * w * (1 - c);
117
+ }
118
+ function compressGamut(c, l) {
119
+ const L = Math.min(1, Math.max(0, l));
120
+ const lo = Math.min(c[0], c[1], c[2]);
121
+ const hi = Math.max(c[0], c[1], c[2]);
122
+ let t = 1;
123
+ if (hi > 1 && hi - L > 1e-9) t = Math.min(t, (1 - L) / (hi - L));
124
+ if (lo < 0 && L - lo > 1e-9) t = Math.min(t, L / (L - lo));
125
+ for (let i = 0; i < 3; i++) c[i] = L + (c[i] - L) * t;
126
+ }
127
+ function dodgeBurn(c, e, range, burn, protectTones) {
128
+ if (!(e > 0)) return c;
129
+ if (protectTones) {
130
+ const l = luma(c[0], c[1], c[2]);
131
+ const nl = dodgeBurnCurve(l, e, range, burn);
132
+ if (l > 1e-6) for (let i = 0; i < 3; i++) c[i] *= nl / l;
133
+ else c[0] = c[1] = c[2] = nl;
134
+ compressGamut(c, nl);
135
+ } else for (let i = 0; i < 3; i++) c[i] = dodgeBurnCurve(c[i], e, range, burn);
136
+ return c;
137
+ }
138
+ function saturationOf(r, g, b) {
139
+ const lo = Math.min(r, g, b);
140
+ const hi = Math.max(r, g, b);
141
+ return hi <= 1e-6 ? 0 : Math.min(1, Math.max(0, (hi - lo) / hi));
142
+ }
143
+ function sponge(c, amount, saturate, vibrance) {
144
+ let a = Math.min(1, Math.max(0, amount));
145
+ if (!(a > 0)) return c;
146
+ if (vibrance) {
147
+ const s = saturationOf(c[0], c[1], c[2]);
148
+ a *= saturate ? 1 - s : 0.25 + 0.75 * s;
149
+ }
150
+ const l = luma(c[0], c[1], c[2]);
151
+ const k = saturate ? 1 + a : 1 - a;
152
+ for (let i = 0; i < 3; i++) c[i] = l + (c[i] - l) * k;
153
+ compressGamut(c, l);
154
+ return c;
155
+ }
156
+ function perDabStrength(e, spacing) {
157
+ return 1 - Math.pow(1 - Math.min(1, Math.max(0, e)), Math.min(1, Math.max(0.01, spacing)));
158
+ }
159
+ var RETOUCH_SAMPLES = ["current", "current-below", "all"];
160
+ var SPOT_HEAL_TYPES = ["proximity-match", "content-aware", "smooth"];
161
+ var DEFAULT_RETOUCH = {
162
+ aligned: true,
163
+ sample: "current",
164
+ spotType: "proximity-match",
165
+ range: "midtones",
166
+ exposure: 0.5,
167
+ protectTones: true,
168
+ spongeMode: "desaturate",
169
+ vibrance: true,
170
+ strength: 0.5,
171
+ historySteps: 0
172
+ };
173
+ function normalizeRetouch(raw = {}, base = DEFAULT_RETOUCH) {
174
+ const unit2 = (v, d) => typeof v === "number" && Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : d;
175
+ const bool = (v, d) => typeof v === "boolean" ? v : d;
176
+ const pick = (v, all, d) => all.includes(v) ? v : d;
177
+ return {
178
+ aligned: bool(raw.aligned, base.aligned),
179
+ sample: pick(raw.sample, RETOUCH_SAMPLES, base.sample),
180
+ spotType: pick(raw.spotType, SPOT_HEAL_TYPES, base.spotType),
181
+ range: pick(raw.range, TONE_RANGES, base.range),
182
+ exposure: unit2(raw.exposure, base.exposure),
183
+ protectTones: bool(raw.protectTones, base.protectTones),
184
+ spongeMode: pick(raw.spongeMode, ["desaturate", "saturate"], base.spongeMode),
185
+ vibrance: bool(raw.vibrance, base.vibrance),
186
+ strength: unit2(raw.strength, base.strength),
187
+ historySteps: typeof raw.historySteps === "number" && Number.isFinite(raw.historySteps) ? Math.min(1e3, Math.max(0, Math.round(raw.historySteps))) : base.historySteps
188
+ };
189
+ }
190
+ function boxBlurPixels(data, w, h, n, r) {
191
+ if (r < 1) return;
192
+ if (n === 4) for (let i = 0; i < data.length; i += 4) for (let c = 0; c < 3; c++) data[i + c] *= data[i + 3] / 255;
193
+ const tmp = new Float32Array(data.length);
194
+ const k = 1 / (2 * r + 1);
195
+ for (let y = 0; y < h; y++) {
196
+ for (let x = 0; x < w; x++) {
197
+ for (let c = 0; c < n; c++) {
198
+ let s = 0;
199
+ for (let d = -r; d <= r; d++) s += data[(y * w + Math.min(w - 1, Math.max(0, x + d))) * n + c];
200
+ tmp[(y * w + x) * n + c] = s * k;
201
+ }
202
+ }
203
+ }
204
+ for (let y = 0; y < h; y++) {
205
+ for (let x = 0; x < w; x++) {
206
+ for (let c = 0; c < n; c++) {
207
+ let s = 0;
208
+ for (let d = -r; d <= r; d++) s += tmp[(Math.min(h - 1, Math.max(0, y + d)) * w + x) * n + c];
209
+ data[(y * w + x) * n + c] = s * k;
210
+ }
211
+ }
212
+ }
213
+ if (n === 4) {
214
+ for (let i = 0; i < data.length; i += 4) {
215
+ const a = data[i + 3] / 255;
216
+ for (let c = 0; c < 3; c++) data[i + c] = a > 0 ? data[i + c] / a : 0;
217
+ }
218
+ }
219
+ }
220
+ function retouchFilter(data, w, h, n, kind, radius = 2, amount = 1) {
221
+ if (kind === "blur") {
222
+ boxBlurPixels(data, w, h, n, radius);
223
+ boxBlurPixels(data, w, h, n, radius);
224
+ return;
225
+ }
226
+ const soft = data.slice();
227
+ boxBlurPixels(soft, w, h, n, 1);
228
+ for (let i = 0; i < data.length; i++) {
229
+ if (n === 4 && (i & 3) === 3) continue;
230
+ const v = data[i] + amount * (data[i] - soft[i]);
231
+ data[i] = v > 0 ? v : 0;
232
+ }
233
+ }
234
+ var IDENTITY_CLONE_TRANSFORM = { scaleX: 1, scaleY: 1, rotate: 0 };
235
+ function isIdentityCloneTransform(t) {
236
+ return t.scaleX === 1 && t.scaleY === 1 && (t.rotate % 360 + 360) % 360 === 0;
237
+ }
238
+ function cloneSamplePoint(t, source, anchor, x, y) {
239
+ const a = -t.rotate * Math.PI / 180;
240
+ const c = Math.cos(a);
241
+ const s = Math.sin(a);
242
+ const dx = x - anchor.x;
243
+ const dy = y - anchor.y;
244
+ return [source.x + (c * dx - s * dy) / t.scaleX, source.y + (s * dx + c * dy) / t.scaleY];
245
+ }
246
+ var TransformedPixelSource = (_class = class {
247
+ constructor(inner, map) {;_class.prototype.__init.call(this);
248
+ this.inner = inner;
249
+ this.map = map;
250
+ }
251
+
252
+
253
+ __init() {this.px = [0, 0, 0, 0]}
254
+ sample(x, y, out) {
255
+ const [u, v] = this.map(x, y);
256
+ const x0 = Math.floor(u);
257
+ const y0 = Math.floor(v);
258
+ const fx = u - x0;
259
+ const fy = v - y0;
260
+ let r = 0;
261
+ let g = 0;
262
+ let b = 0;
263
+ let a = 0;
264
+ for (let k = 0; k < 4; k++) {
265
+ const w = (k & 1 ? fx : 1 - fx) * (k & 2 ? fy : 1 - fy);
266
+ if (w <= 0) continue;
267
+ if (!this.inner.sample(x0 + (k & 1), y0 + (k >> 1), this.px)) continue;
268
+ const pa = this.px[3] * w;
269
+ r += this.px[0] * pa;
270
+ g += this.px[1] * pa;
271
+ b += this.px[2] * pa;
272
+ a += pa;
273
+ }
274
+ if (!(a > 0)) {
275
+ out[0] = out[1] = out[2] = out[3] = 0;
276
+ return false;
277
+ }
278
+ out[0] = r / a;
279
+ out[1] = g / a;
280
+ out[2] = b / a;
281
+ out[3] = a;
282
+ return true;
283
+ }
284
+ }, _class);
285
+ var TilePixelSource = (_class2 = class {
286
+ constructor(readTile, channels, offset = { x: 0, y: 0 }) {;_class2.prototype.__init2.call(this);_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);
287
+ this.readTile = readTile;
288
+ this.channels = channels;
289
+ this.offset = offset;
290
+ }
291
+
292
+
293
+
294
+ __init2() {this.cache = /* @__PURE__ */ new Map()}
295
+ __init3() {this.lastKey = NaN}
296
+ __init4() {this.last = null}
297
+ sample(x, y, out) {
298
+ const lx = x - this.offset.x;
299
+ const ly = y - this.offset.y;
300
+ const tx = Math.floor(lx / _chunk474IQG74cjs.TILE);
301
+ const ty = Math.floor(ly / _chunk474IQG74cjs.TILE);
302
+ const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
303
+ if (key !== this.lastKey) {
304
+ let t2 = this.cache.get(key);
305
+ if (t2 === void 0) {
306
+ t2 = this.readTile(tx, ty);
307
+ this.cache.set(key, t2);
308
+ }
309
+ this.last = t2;
310
+ this.lastKey = key;
311
+ }
312
+ const t = this.last;
313
+ if (!t) {
314
+ out[0] = out[1] = out[2] = out[3] = 0;
315
+ return false;
316
+ }
317
+ const p = (ly - ty * _chunk474IQG74cjs.TILE) * _chunk474IQG74cjs.TILE + (lx - tx * _chunk474IQG74cjs.TILE);
318
+ if (this.channels === 1) {
319
+ out[0] = out[1] = out[2] = t[p];
320
+ out[3] = 255;
321
+ return true;
322
+ }
323
+ const i = p * 4;
324
+ out[0] = t[i];
325
+ out[1] = t[i + 1];
326
+ out[2] = t[i + 2];
327
+ out[3] = t[i + 3];
328
+ return out[3] > 0;
329
+ }
330
+ }, _class2);
331
+ var RegionPixelSource = class {
332
+ constructor(rect, data) {
333
+ this.rect = rect;
334
+ this.data = data;
335
+ }
336
+
337
+
338
+ sample(x, y, out) {
339
+ const r = this.rect;
340
+ const lx = x - r.x;
341
+ const ly = y - r.y;
342
+ if (lx < 0 || ly < 0 || lx >= r.width || ly >= r.height) {
343
+ out[0] = out[1] = out[2] = out[3] = 0;
344
+ return false;
345
+ }
346
+ const i = (ly * r.width + lx) * 4;
347
+ out[0] = this.data[i];
348
+ out[1] = this.data[i + 1];
349
+ out[2] = this.data[i + 2];
350
+ out[3] = this.data[i + 3];
351
+ return out[3] > 0;
352
+ }
353
+ };
354
+ function readSourceRegion(source, rect, dx = 0, dy = 0) {
355
+ const out = new Float32Array(rect.width * rect.height * 4);
356
+ const px = [0, 0, 0, 0];
357
+ for (let y = 0; y < rect.height; y++) {
358
+ for (let x = 0; x < rect.width; x++) {
359
+ source.sample(rect.x + x + dx, rect.y + y + dy, px);
360
+ const i = (y * rect.width + x) * 4;
361
+ out[i] = px[0];
362
+ out[i + 1] = px[1];
363
+ out[i + 2] = px[2];
364
+ out[i + 3] = px[3];
365
+ }
366
+ }
367
+ return out;
368
+ }
369
+ function applyRetouchToTile(coverage, tileData, channels, tx, ty, paint, s, options = {}) {
370
+ const out = (_nullishCoalesce(options.into, () => ( tileData))).slice();
371
+ const ox = tx * _chunk474IQG74cjs.TILE + s.offset.x;
372
+ const oy = ty * _chunk474IQG74cjs.TILE + s.offset.y;
373
+ let x0 = 0;
374
+ let y0 = 0;
375
+ let x1 = _chunk474IQG74cjs.TILE;
376
+ let y1 = _chunk474IQG74cjs.TILE;
377
+ if (options.region) {
378
+ const r = options.region;
379
+ x0 = Math.max(0, Math.floor(r.x) - ox);
380
+ y0 = Math.max(0, Math.floor(r.y) - oy);
381
+ x1 = Math.min(_chunk474IQG74cjs.TILE, Math.ceil(r.x + r.width) - ox);
382
+ y1 = Math.min(_chunk474IQG74cjs.TILE, Math.ceil(r.y + r.height) - oy);
383
+ if (x1 <= x0 || y1 <= y0) return out;
384
+ if (options.into) {
385
+ for (let y = y0; y < y1; y++) out.set(tileData.subarray((y * _chunk474IQG74cjs.TILE + x0) * channels, (y * _chunk474IQG74cjs.TILE + x1) * channels), (y * _chunk474IQG74cjs.TILE + x0) * channels);
386
+ }
387
+ }
388
+ const sel = s.selection;
389
+ const blend = _nullishCoalesce(s.blend, () => ( "normal"));
390
+ const src = [0, 0, 0, 0];
391
+ const rgb = [0, 0, 0];
392
+ const cb = [0, 0, 0, 0];
393
+ const cs = [0, 0, 0, 0];
394
+ let covKey = NaN;
395
+ let covTile;
396
+ for (let y = y0; y < y1; y++) {
397
+ const dy = oy + y;
398
+ const cty = Math.floor(dy / _chunk474IQG74cjs.TILE);
399
+ for (let x = x0; x < x1; x++) {
400
+ const dx = ox + x;
401
+ const ctx = Math.floor(dx / _chunk474IQG74cjs.TILE);
402
+ const key = _chunk474IQG74cjs.tileKey.call(void 0, ctx, cty);
403
+ if (key !== covKey) {
404
+ covKey = key;
405
+ covTile = coverage.tiles.get(key);
406
+ }
407
+ if (!covTile) continue;
408
+ const c = covTile[(dy - cty * _chunk474IQG74cjs.TILE) * _chunk474IQG74cjs.TILE + (dx - ctx * _chunk474IQG74cjs.TILE)];
409
+ if (c <= 0) continue;
410
+ let k = c * s.opacity;
411
+ if (sel) {
412
+ if (dx < 0 || dy < 0 || dx >= sel.width || dy >= sel.height) continue;
413
+ k *= sel.data[dy * sel.width + dx] / 255;
414
+ }
415
+ if (k > 1) k = 1;
416
+ if (k <= 0) continue;
417
+ const p = y * _chunk474IQG74cjs.TILE + x;
418
+ if (channels === 1) {
419
+ const g = out[p];
420
+ let t;
421
+ if (paint.kind === "tone") {
422
+ rgb[0] = rgb[1] = rgb[2] = g / 255;
423
+ paint.tone(rgb);
424
+ t = luma(rgb[0], rgb[1], rgb[2]) * 255;
425
+ } else if (paint.kind === "color") t = paint.color[0];
426
+ else {
427
+ if (!paint.source.sample(dx + paint.dx, dy + paint.dy, src)) continue;
428
+ t = src[0];
429
+ k *= src[3] / 255;
430
+ }
431
+ out[p] = Math.round(g + (t - g) * k);
432
+ continue;
433
+ }
434
+ const i = p * 4;
435
+ const a = out[i + 3];
436
+ if (paint.kind === "tone") {
437
+ if (a === 0) continue;
438
+ rgb[0] = out[i] / 255;
439
+ rgb[1] = out[i + 1] / 255;
440
+ rgb[2] = out[i + 2] / 255;
441
+ const r0 = rgb[0];
442
+ const g0 = rgb[1];
443
+ const b0 = rgb[2];
444
+ paint.tone(rgb);
445
+ _chunkFQPUF2W2cjs.put255.call(void 0, out, i, r0 + (rgb[0] - r0) * k);
446
+ _chunkFQPUF2W2cjs.put255.call(void 0, out, i + 1, g0 + (rgb[1] - g0) * k);
447
+ _chunkFQPUF2W2cjs.put255.call(void 0, out, i + 2, b0 + (rgb[2] - b0) * k);
448
+ continue;
449
+ }
450
+ if (s.lockTransparency && a === 0) continue;
451
+ if (paint.kind === "color") {
452
+ src[0] = paint.color[0];
453
+ src[1] = paint.color[1];
454
+ src[2] = paint.color[2];
455
+ src[3] = paint.color[3];
456
+ } else if (!paint.source.sample(dx + paint.dx, dy + paint.dy, src)) continue;
457
+ for (let ch = 0; ch < 4; ch++) {
458
+ cb[ch] = out[i + ch] / 255;
459
+ cs[ch] = src[ch] / 255;
460
+ }
461
+ const o = _chunk2VX55NFMcjs.blendPixel.call(void 0, blend, cb, cs, k);
462
+ _chunkFQPUF2W2cjs.put255.call(void 0, out, i, o[0]);
463
+ _chunkFQPUF2W2cjs.put255.call(void 0, out, i + 1, o[1]);
464
+ _chunkFQPUF2W2cjs.put255.call(void 0, out, i + 2, o[2]);
465
+ if (!s.lockTransparency) _chunkFQPUF2W2cjs.put255.call(void 0, out, i + 3, o[3]);
466
+ }
467
+ }
468
+ return out;
469
+ }
470
+ function applyToneToDeepTile(coverage, samples, tx, ty, tone, s, options = {}) {
471
+ const linear = samples instanceof Float32Array;
472
+ const out = (_nullishCoalesce(options.into, () => ( samples))).slice();
473
+ const ox = tx * _chunk474IQG74cjs.TILE + s.offset.x;
474
+ const oy = ty * _chunk474IQG74cjs.TILE + s.offset.y;
475
+ let x0 = 0;
476
+ let y0 = 0;
477
+ let x1 = _chunk474IQG74cjs.TILE;
478
+ let y1 = _chunk474IQG74cjs.TILE;
479
+ if (options.region) {
480
+ const r = options.region;
481
+ x0 = Math.max(0, Math.floor(r.x) - ox);
482
+ y0 = Math.max(0, Math.floor(r.y) - oy);
483
+ x1 = Math.min(_chunk474IQG74cjs.TILE, Math.ceil(r.x + r.width) - ox);
484
+ y1 = Math.min(_chunk474IQG74cjs.TILE, Math.ceil(r.y + r.height) - oy);
485
+ if (x1 <= x0 || y1 <= y0) return out;
486
+ if (options.into) for (let y = y0; y < y1; y++) out.set(samples.subarray((y * _chunk474IQG74cjs.TILE + x0) * 4, (y * _chunk474IQG74cjs.TILE + x1) * 4), (y * _chunk474IQG74cjs.TILE + x0) * 4);
487
+ }
488
+ const sel = s.selection;
489
+ const rgb = [0, 0, 0];
490
+ const before = [0, 0, 0];
491
+ const excess = [0, 0, 0];
492
+ let covKey = NaN;
493
+ let covTile;
494
+ for (let y = y0; y < y1; y++) {
495
+ const dy = oy + y;
496
+ const cty = Math.floor(dy / _chunk474IQG74cjs.TILE);
497
+ for (let x = x0; x < x1; x++) {
498
+ const dx = ox + x;
499
+ const ctx = Math.floor(dx / _chunk474IQG74cjs.TILE);
500
+ const key = _chunk474IQG74cjs.tileKey.call(void 0, ctx, cty);
501
+ if (key !== covKey) {
502
+ covKey = key;
503
+ covTile = coverage.tiles.get(key);
504
+ }
505
+ if (!covTile) continue;
506
+ const c = covTile[(dy - cty * _chunk474IQG74cjs.TILE) * _chunk474IQG74cjs.TILE + (dx - ctx * _chunk474IQG74cjs.TILE)];
507
+ if (c <= 0) continue;
508
+ let k = c * s.opacity;
509
+ if (sel) {
510
+ if (dx < 0 || dy < 0 || dx >= sel.width || dy >= sel.height) continue;
511
+ k *= sel.data[dy * sel.width + dx] / 255;
512
+ }
513
+ if (k > 1) k = 1;
514
+ if (k <= 0) continue;
515
+ const i = (y * _chunk474IQG74cjs.TILE + x) * 4;
516
+ if (out[i + 3] === 0) continue;
517
+ for (let ch = 0; ch < 3; ch++) {
518
+ const v = out[i + ch];
519
+ if (linear) {
520
+ excess[ch] = v > 1 ? v - 1 : 0;
521
+ rgb[ch] = _chunk2VX55NFMcjs.srgbEncode.call(void 0, v > 1 ? 1 : v < 0 ? 0 : v);
522
+ } else rgb[ch] = v / 65535;
523
+ before[ch] = rgb[ch];
524
+ }
525
+ tone(rgb);
526
+ for (let ch = 0; ch < 3; ch++) {
527
+ const e = before[ch] + (rgb[ch] - before[ch]) * k;
528
+ if (linear) out[i + ch] = _chunk2VX55NFMcjs.srgbDecode.call(void 0, e) + excess[ch];
529
+ else out[i + ch] = e <= 0 ? 0 : e >= 1 ? 65535 : Math.round(e * 65535);
530
+ }
531
+ }
532
+ }
533
+ return out;
534
+ }
535
+ function toneOf(tool, settings) {
536
+ const burn = tool === "burn";
537
+ return (rgb) => {
538
+ dodgeBurn(rgb, settings.exposure, settings.range, burn, settings.protectTones);
539
+ };
540
+ }
541
+ function healPixels(w, h, src, dst, mask) {
542
+ const out = new Float32Array(dst);
543
+ const bb = _chunkBB6TR422cjs.maskBounds.call(void 0, w, h, mask);
544
+ if (!bb) return out;
545
+ const x0 = Math.max(0, bb[0] - 1);
546
+ const y0 = Math.max(0, bb[1] - 1);
547
+ const x1 = Math.min(w, bb[2] + 1);
548
+ const y1 = Math.min(h, bb[3] + 1);
549
+ const rw = x1 - x0;
550
+ const rh = y1 - y0;
551
+ const s = new Float32Array(rw * rh * 4);
552
+ const d = new Float32Array(rw * rh * 4);
553
+ const m = new Uint8Array(rw * rh);
554
+ for (let y = 0; y < rh; y++) {
555
+ for (let x = 0; x < rw; x++) {
556
+ const gi = (y + y0) * w + x + x0;
557
+ const li = y * rw + x;
558
+ m[li] = mask[gi] ? 1 : 0;
559
+ for (let c = 0; c < 4; c++) {
560
+ s[li * 4 + c] = src[gi * 4 + c];
561
+ d[li * 4 + c] = dst[gi * 4 + c];
562
+ }
563
+ }
564
+ }
565
+ const healed = _chunkBB6TR422cjs.seamlessClone.call(void 0, rw, rh, 4, s, d, m);
566
+ for (let y = 0; y < rh; y++) {
567
+ for (let x = 0; x < rw; x++) {
568
+ const gi = ((y + y0) * w + x + x0) * 4;
569
+ const li = (y * rw + x) * 4;
570
+ for (let c = 0; c < 4; c++) out[gi + c] = Math.min(255, Math.max(0, healed[li + c]));
571
+ }
572
+ }
573
+ return out;
574
+ }
575
+ function spotHealPixels(w, h, img, hole, size, type, onOffset) {
576
+ const domain = _chunkBB6TR422cjs.dilateMask.call(void 0, w, h, hole, 2);
577
+ const healMask = _chunkBB6TR422cjs.dilateMask.call(void 0, w, h, hole, 1);
578
+ let filled = null;
579
+ let bestFound = null;
580
+ if (type === "proximity-match") {
581
+ const ring = Math.min(16, Math.max(3, Math.floor(size / 8)));
582
+ const off2 = _chunkBB6TR422cjs.bestOffset.call(void 0, w, h, 4, img, domain, ring, Math.floor(Math.max(w, h) / 2));
583
+ if (off2) {
584
+ bestFound = off2;
585
+ filled = new Float32Array(img);
586
+ const [ddx, ddy] = off2;
587
+ for (let i = 0; i < w * h; i++) {
588
+ if (!domain[i]) continue;
589
+ const x = i % w + ddx;
590
+ const y = Math.floor(i / w) + ddy;
591
+ const j = (y * w + x) * 4;
592
+ for (let c = 0; c < 4; c++) filled[i * 4 + c] = img[j + c];
593
+ }
594
+ }
595
+ }
596
+ _optionalChain([onOffset, 'optionalCall', _ => _(filled ? bestFound : null)]);
597
+ if (!filled && type === "content-aware") filled = _chunkBB6TR422cjs.contentAwareFill.call(void 0, w, h, 4, img, domain);
598
+ if (!filled) filled = _chunkBB6TR422cjs.membraneFill.call(void 0, w, h, 4, img, domain);
599
+ return healPixels(w, h, filled, img, healMask);
600
+ }
601
+ function spotHealWindow(bounds, canvas) {
602
+ const g = Math.max(8, Math.ceil(Math.max(bounds.width, bounds.height)));
603
+ const x0 = Math.max(0, bounds.x - g);
604
+ const y0 = Math.max(0, bounds.y - g);
605
+ const x1 = Math.min(canvas.width, bounds.x + bounds.width + g);
606
+ const y1 = Math.min(canvas.height, bounds.y + bounds.height + g);
607
+ return { x: x0, y: y0, width: Math.max(0, x1 - x0), height: Math.max(0, y1 - y0) };
608
+ }
609
+ var RetouchDabStroke = (_class3 = class {
610
+ constructor(brush, target, effect) {;_class3.prototype.__init5.call(this);_class3.prototype.__init6.call(this);_class3.prototype.__init7.call(this);_class3.prototype.__init8.call(this);
611
+ this.brush = brush;
612
+ this.effect = effect;
613
+ this.walker = new (0, _chunkFQPUF2W2cjs.DabWalker)(brush);
614
+ this.medium = new (0, _chunkFQPUF2W2cjs.TileMedium)(target);
615
+ }
616
+
617
+
618
+ __init5() {this.dabCount = 0}
619
+ __init6() {this.bounds = null}
620
+
621
+
622
+ __init7() {this.smoothPos = null}
623
+ __init8() {this.buf = new Float32Array(0)}
624
+ push(points) {
625
+ const dabs = [];
626
+ for (const p of points) this.walker.push(this.smooth(p), dabs);
627
+ return this.paint(dabs);
628
+ }
629
+ finish(last) {
630
+ const dabs = [];
631
+ if (last && this.smoothPos && (this.smoothPos.x !== last.x || this.smoothPos.y !== last.y)) this.walker.push(last, dabs);
632
+ this.walker.finish(dabs);
633
+ return this.paint(dabs);
634
+ }
635
+ smooth(p) {
636
+ const a = 1 - Math.min(0.95, Math.max(0, this.brush.smoothing));
637
+ const cur = this.smoothPos;
638
+ const n = cur && a < 1 ? { ...p, x: cur.x + (p.x - cur.x) * a, y: cur.y + (p.y - cur.y) * a } : p;
639
+ this.smoothPos = n;
640
+ return n;
641
+ }
642
+ paint(dabs) {
643
+ const rects = [];
644
+ for (const d of dabs) {
645
+ const rect = _chunkFQPUF2W2cjs.dabRect.call(void 0, d, this.brush.hardness);
646
+ const n = rect.width * rect.height;
647
+ if (this.buf.length < n) this.buf = new Float32Array(n);
648
+ const cov = this.buf.subarray(0, n);
649
+ _chunkFQPUF2W2cjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.brush.hardness, rect, cov);
650
+ this.medium.reset();
651
+ this.effect(this.medium, d, rect, cov);
652
+ rects.push(rect);
653
+ this.bounds = unionRect(this.bounds, rect);
654
+ this.dabCount++;
655
+ }
656
+ return rects;
657
+ }
658
+ }, _class3);
659
+ function smudgeEffect(brush, strength, mixing = "rgb") {
660
+ const s = Math.min(1, Math.max(0, strength));
661
+ const tip = new (0, _chunkFQPUF2W2cjs.SmudgeTip)({ strength: s, length: s, mixing }, brush.size);
662
+ return (medium, d, rect, cov) => tip.dab(medium, { x: d.x, y: d.y, radius: d.radius, opacity: d.opacity * d.alpha }, rect, cov);
663
+ }
664
+ function spongeEffect(brush, saturate, vibrance) {
665
+ const rgb = [0, 0, 0];
666
+ return (medium, d, rect, cov) => {
667
+ const w = rect.width;
668
+ for (let yy = 0; yy < rect.height; yy++) {
669
+ for (let xx = 0; xx < w; xx++) {
670
+ const cv = cov[yy * w + xx];
671
+ if (cv <= 0) continue;
672
+ const dx = rect.x + xx;
673
+ const dy = rect.y + yy;
674
+ const k = perDabStrength(cv * d.alpha * d.opacity * 0.5, brush.spacing) * medium.selectionAt(dx, dy);
675
+ if (k <= 0) continue;
676
+ const ri = medium.locate(dx, dy, false);
677
+ if (ri < 0 || medium.pixels[ri + 3] === 0) continue;
678
+ const i = medium.locate(dx, dy, true);
679
+ const px = medium.pixels;
680
+ rgb[0] = px[i] / 255;
681
+ rgb[1] = px[i + 1] / 255;
682
+ rgb[2] = px[i + 2] / 255;
683
+ sponge(rgb, k, saturate, vibrance);
684
+ _chunkFQPUF2W2cjs.put255.call(void 0, px, i, rgb[0]);
685
+ _chunkFQPUF2W2cjs.put255.call(void 0, px, i + 1, rgb[1]);
686
+ _chunkFQPUF2W2cjs.put255.call(void 0, px, i + 2, rgb[2]);
687
+ }
688
+ }
689
+ };
690
+ }
691
+ function rgbaViewOfGrey(target) {
692
+ const views = /* @__PURE__ */ new Map();
693
+ const dirty = /* @__PURE__ */ new Map();
694
+ const expand = (g) => {
695
+ const out = new Uint8ClampedArray(g.length * 4);
696
+ for (let i = 0; i < g.length; i++) {
697
+ out[i * 4] = out[i * 4 + 1] = out[i * 4 + 2] = g[i];
698
+ out[i * 4 + 3] = 255;
699
+ }
700
+ return out;
701
+ };
702
+ const view = {
703
+ offset: target.offset,
704
+ lockTransparency: true,
705
+ selection: target.selection,
706
+ readTile: (tx, ty) => {
707
+ const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
708
+ let v = views.get(key);
709
+ if (!v) {
710
+ v = expand(_nullishCoalesce(target.readTile(tx, ty), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE))));
711
+ views.set(key, v);
712
+ }
713
+ return v;
714
+ },
715
+ writeTile: (tx, ty) => {
716
+ const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
717
+ let v = views.get(key);
718
+ if (!v) {
719
+ v = expand(_nullishCoalesce(target.readTile(tx, ty), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE))));
720
+ views.set(key, v);
721
+ }
722
+ dirty.set(key, { tx, ty, data: v });
723
+ return v;
724
+ }
725
+ };
726
+ return {
727
+ target: view,
728
+ flush: () => {
729
+ for (const { tx, ty, data } of dirty.values()) {
730
+ const g = target.writeTile(tx, ty);
731
+ for (let i = 0; i < g.length; i++) g[i] = data[i * 4];
732
+ }
733
+ dirty.clear();
734
+ }
735
+ };
736
+ }
737
+ function unionRect(a, b) {
738
+ if (!a) return { ...b };
739
+ const x = Math.min(a.x, b.x);
740
+ const y = Math.min(a.y, b.y);
741
+ return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
742
+ }
743
+
83
744
  // src/paint/wet/model.ts
84
745
  var WET_TILE = 256;
85
746
  var SLOT_SIDE = 258;
@@ -776,7 +1437,7 @@ function wetSupport(simd = _nullishCoalesce(simdCache, () => ( typeof WebAssembl
776
1437
  const g = globalThis;
777
1438
  const sharedMemory = canShareMemory();
778
1439
  const workers = typeof g.Worker === "function" && typeof Blob === "function" && typeof URL !== "undefined" && typeof URL.createObjectURL === "function";
779
- const cores = Math.max(1, Math.floor(_nullishCoalesce(_optionalChain([g, 'access', _ => _.navigator, 'optionalAccess', _2 => _2.hardwareConcurrency]), () => ( 1))));
1440
+ const cores = Math.max(1, Math.floor(_nullishCoalesce(_optionalChain([g, 'access', _2 => _2.navigator, 'optionalAccess', _3 => _3.hardwareConcurrency]), () => ( 1))));
780
1441
  let message = null;
781
1442
  if (!simd) message = "This browser has no WebAssembly SIMD, so wet paint runs in plain JavaScript: it flows much more slowly (the results are the same).";
782
1443
  else if (workers && !sharedMemory)
@@ -880,8 +1541,8 @@ var WetWorkerPool = class _WetWorkerPool {
880
1541
  ready.push(
881
1542
  new Promise((resolve, reject) => {
882
1543
  w.onmessage = (e) => {
883
- if (_optionalChain([e, 'access', _3 => _3.data, 'optionalAccess', _4 => _4.type]) === "ready") resolve();
884
- else if (_optionalChain([e, 'access', _5 => _5.data, 'optionalAccess', _6 => _6.type]) === "error") reject(new Error(e.data.message));
1544
+ if (_optionalChain([e, 'access', _4 => _4.data, 'optionalAccess', _5 => _5.type]) === "ready") resolve();
1545
+ else if (_optionalChain([e, 'access', _6 => _6.data, 'optionalAccess', _7 => _7.type]) === "error") reject(new Error(e.data.message));
885
1546
  };
886
1547
  w.onerror = (e) => reject(new Error(e.message || "The wet-media worker failed to start."));
887
1548
  })
@@ -903,8 +1564,8 @@ var WetWorkerPool = class _WetWorkerPool {
903
1564
  this.workers.map(
904
1565
  (w, i) => new Promise((resolve, reject) => {
905
1566
  w.onmessage = (e) => {
906
- if (_optionalChain([e, 'access', _7 => _7.data, 'optionalAccess', _8 => _8.type]) === "done") resolve();
907
- else if (_optionalChain([e, 'access', _9 => _9.data, 'optionalAccess', _10 => _10.type]) === "error") reject(new Error(e.data.message));
1567
+ if (_optionalChain([e, 'access', _8 => _8.data, 'optionalAccess', _9 => _9.type]) === "done") resolve();
1568
+ else if (_optionalChain([e, 'access', _10 => _10.data, 'optionalAccess', _11 => _11.type]) === "error") reject(new Error(e.data.message));
908
1569
  };
909
1570
  w.postMessage({ type: "run", steps, workers: n, id: i });
910
1571
  })
@@ -951,53 +1612,53 @@ function makeLayout(width, height) {
951
1612
  function quantizeHeight(v) {
952
1613
  return Math.round(Math.min(1, Math.max(0, v)) * 65536) / 65536;
953
1614
  }
954
- var WetWorld = (_class = class {
1615
+ var WetWorld = (_class4 = class {
955
1616
 
956
1617
 
957
1618
 
958
1619
  /** Steps simulated so far. */
959
- __init() {this.clock = 0}
1620
+ __init9() {this.clock = 0}
960
1621
  /** Messages for the user (slots ran out, a backend failed). */
961
- __init2() {this.warnings = []}
1622
+ __init10() {this.warnings = []}
962
1623
 
963
1624
 
964
1625
 
965
1626
 
966
1627
 
967
- __init3() {this.slotCount = 0}
968
- __init4() {this.freeSlots = []}
969
- __init5() {this.active = []}
970
- __init6() {this.parity = 0}
971
- __init7() {this.lanes = new Array(MAX_WET_LANES).fill(null)}
972
- __init8() {this.tilt = { ...FLAT }}
1628
+ __init11() {this.slotCount = 0}
1629
+ __init12() {this.freeSlots = []}
1630
+ __init13() {this.active = []}
1631
+ __init14() {this.parity = 0}
1632
+ __init15() {this.lanes = new Array(MAX_WET_LANES).fill(null)}
1633
+ __init16() {this.tilt = { ...FLAT }}
973
1634
 
974
- __init9() {this.paperBytes = new Uint8Array(3)}
975
- __init10() {this.kind = "typescript"}
976
- __init11() {this.wasm = null}
977
- __init12() {this.pool = null}
978
- __init13() {this.busyFlag = false}
979
- __init14() {this.destroyed = false}
1635
+ __init17() {this.paperBytes = new Uint8Array(3)}
1636
+ __init18() {this.kind = "typescript"}
1637
+ __init19() {this.wasm = null}
1638
+ __init20() {this.pool = null}
1639
+ __init21() {this.busyFlag = false}
1640
+ __init22() {this.destroyed = false}
980
1641
 
981
- __init15() {this.prm = new Float32Array(PARAM_FLOATS)}
1642
+ __init23() {this.prm = new Float32Array(PARAM_FLOATS)}
982
1643
  // Engine B: the GPU mirror (see `attachGpu`).
983
- __init16() {this.gpu = null}
1644
+ __init24() {this.gpu = null}
984
1645
  /** Live tiles at which the GPU takes over the display (default 16: a fully wet 1024² canvas). */
985
- __init17() {this.gpuMinTiles = 16}
986
- __init18() {this.gpuLive = false}
987
- __init19() {this.gpuFailure = null}
1646
+ __init25() {this.gpuMinTiles = 16}
1647
+ __init26() {this.gpuLive = false}
1648
+ __init27() {this.gpuFailure = null}
988
1649
  /** Slot → rows (1..256, inclusive) to upload; `[0, 257]` means the whole slot. */
989
- __init20() {this.gpuDirty = /* @__PURE__ */ new Map()}
990
- __init21() {this.gpuParamsDirty = true}
1650
+ __init28() {this.gpuDirty = /* @__PURE__ */ new Map()}
1651
+ __init29() {this.gpuParamsDirty = true}
991
1652
  /**
992
1653
  * Lead mode (between strokes): a batch is not sent to the GPU all at once; `gpuLead` steps it
993
1654
  * frame by frame while the CPU works through it, so the display moves on before the CPU is done.
994
1655
  */
995
- __init22() {this.gpuLeadMode = false}
1656
+ __init30() {this.gpuLeadMode = false}
996
1657
  /** The batch the GPU is working through in lead mode. */
997
- __init23() {this.gpuPlan = null}
1658
+ __init31() {this.gpuPlan = null}
998
1659
  /** Resolves when the fastest available kernel is running (it may stay `typescript`). */
999
1660
 
1000
- constructor(width, height, paper, options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);_class.prototype.__init11.call(this);_class.prototype.__init12.call(this);_class.prototype.__init13.call(this);_class.prototype.__init14.call(this);_class.prototype.__init15.call(this);_class.prototype.__init16.call(this);_class.prototype.__init17.call(this);_class.prototype.__init18.call(this);_class.prototype.__init19.call(this);_class.prototype.__init20.call(this);_class.prototype.__init21.call(this);_class.prototype.__init22.call(this);_class.prototype.__init23.call(this);
1661
+ constructor(width, height, paper, options = {}) {;_class4.prototype.__init9.call(this);_class4.prototype.__init10.call(this);_class4.prototype.__init11.call(this);_class4.prototype.__init12.call(this);_class4.prototype.__init13.call(this);_class4.prototype.__init14.call(this);_class4.prototype.__init15.call(this);_class4.prototype.__init16.call(this);_class4.prototype.__init17.call(this);_class4.prototype.__init18.call(this);_class4.prototype.__init19.call(this);_class4.prototype.__init20.call(this);_class4.prototype.__init21.call(this);_class4.prototype.__init22.call(this);_class4.prototype.__init23.call(this);_class4.prototype.__init24.call(this);_class4.prototype.__init25.call(this);_class4.prototype.__init26.call(this);_class4.prototype.__init27.call(this);_class4.prototype.__init28.call(this);_class4.prototype.__init29.call(this);_class4.prototype.__init30.call(this);_class4.prototype.__init31.call(this);
1001
1662
  if (!(width >= 1 && height >= 1 && width <= 16384 && height <= 16384)) throw new WetWorldError(`A wet canvas must be 1..16384 pixels per side, not ${width}\xD7${height}.`);
1002
1663
  this.width = Math.round(width);
1003
1664
  this.height = Math.round(height);
@@ -1052,7 +1713,7 @@ var WetWorld = (_class = class {
1052
1713
  }
1053
1714
  /** The kernel in use and why it is not faster. */
1054
1715
  backend() {
1055
- const threads = _nullishCoalesce(_optionalChain([this, 'access', _11 => _11.pool, 'optionalAccess', _12 => _12.size]), () => ( 1));
1716
+ const threads = _nullishCoalesce(_optionalChain([this, 'access', _12 => _12.pool, 'optionalAccess', _13 => _13.size]), () => ( 1));
1056
1717
  let message = this.support.message;
1057
1718
  if (this.kind === "typescript" && !message) message = this.wasm ? null : "Wet paint runs in plain JavaScript until the WebAssembly kernel has loaded.";
1058
1719
  if (this.kind === "wasm-threads") message = null;
@@ -1064,17 +1725,17 @@ var WetWorld = (_class = class {
1064
1725
  }
1065
1726
  destroy() {
1066
1727
  this.destroyed = true;
1067
- _optionalChain([this, 'access', _13 => _13.pool, 'optionalAccess', _14 => _14.destroy, 'call', _15 => _15()]);
1728
+ _optionalChain([this, 'access', _14 => _14.pool, 'optionalAccess', _15 => _15.destroy, 'call', _16 => _16()]);
1068
1729
  this.pool = null;
1069
1730
  }
1070
1731
  // --- Lanes ---------------------------------------------------------------------
1071
1732
  laneOf(id) {
1072
- const l = this.lanes.find((x) => _optionalChain([x, 'optionalAccess', _16 => _16.id]) === id);
1733
+ const l = this.lanes.find((x) => _optionalChain([x, 'optionalAccess', _17 => _17.id]) === id);
1073
1734
  if (!l) throw new WetWorldError(`There is no wet layer "${id}".`);
1074
1735
  return l;
1075
1736
  }
1076
1737
  hasLane(id) {
1077
- return this.lanes.some((x) => _optionalChain([x, 'optionalAccess', _17 => _17.id]) === id);
1738
+ return this.lanes.some((x) => _optionalChain([x, 'optionalAccess', _18 => _18.id]) === id);
1078
1739
  }
1079
1740
  laneIds() {
1080
1741
  return this.lanes.filter((l) => Boolean(l)).map((l) => l.id);
@@ -1082,7 +1743,7 @@ var WetWorld = (_class = class {
1082
1743
  /** Adds a wet layer (or returns it). Throws when `MAX_WET_LANES` are in use. */
1083
1744
  ensureLane(id, options = {}) {
1084
1745
  this.requireIdle();
1085
- const existing = this.lanes.find((x) => _optionalChain([x, 'optionalAccess', _18 => _18.id]) === id);
1746
+ const existing = this.lanes.find((x) => _optionalChain([x, 'optionalAccess', _19 => _19.id]) === id);
1086
1747
  if (existing) {
1087
1748
  if (options.params) this.setParams(id, options.params);
1088
1749
  if (options.base) this.setBase(id, options.base);
@@ -1776,7 +2437,7 @@ var WetWorld = (_class = class {
1776
2437
  if (!(a > 0)) return;
1777
2438
  const key = _chunk474IQG74cjs.tileKey.call(void 0, x >> 8, y >> 8);
1778
2439
  const li = (y & 255) * _chunk474IQG74cjs.TILE + (x & 255);
1779
- let lt = _optionalChain([lightTiles, 'optionalAccess', _19 => _19.get, 'call', _20 => _20(key)]);
2440
+ let lt = _optionalChain([lightTiles, 'optionalAccess', _20 => _20.get, 'call', _21 => _21(key)]);
1780
2441
  if (lt && (_nullishCoalesce(lt.uniform, () => ( 1))) !== 0) {
1781
2442
  if (!lightWritten.has(key)) {
1782
2443
  const data = lt.data.length ? new Uint8ClampedArray(lt.data) : new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE).fill(_nullishCoalesce(lt.uniform, () => ( 0)));
@@ -1849,7 +2510,7 @@ var WetWorld = (_class = class {
1849
2510
  if (x1 <= x0 || y1 <= y0) continue;
1850
2511
  const whole = x0 === tr.x && y0 === tr.y && x1 >= Math.min(tr.x + WET_TILE, this.width) && y1 >= Math.min(tr.y + WET_TILE, this.height);
1851
2512
  if (whole) {
1852
- if (this.bakeKey(key, true)) bounds = unionRect(bounds, { x: tr.x, y: tr.y, width: Math.min(WET_TILE, this.width - tr.x), height: Math.min(WET_TILE, this.height - tr.y) });
2513
+ if (this.bakeKey(key, true)) bounds = unionRect2(bounds, { x: tr.x, y: tr.y, width: Math.min(WET_TILE, this.width - tr.x), height: Math.min(WET_TILE, this.height - tr.y) });
1853
2514
  this.free(key);
1854
2515
  continue;
1855
2516
  }
@@ -1869,7 +2530,7 @@ var WetWorld = (_class = class {
1869
2530
  f[c + P_SW * PLANE] = 0;
1870
2531
  }
1871
2532
  }
1872
- bounds = unionRect(bounds, { x: x0, y: y0, width: x1 - x0, height: y1 - y0 });
2533
+ bounds = unionRect2(bounds, { x: x0, y: y0, width: x1 - x0, height: y1 - y0 });
1873
2534
  this.markEdited(lane, x0, y0, x1, y1);
1874
2535
  }
1875
2536
  this.syncList();
@@ -1897,7 +2558,7 @@ var WetWorld = (_class = class {
1897
2558
  lightChanged = true;
1898
2559
  }
1899
2560
  }
1900
- const src = _nullishCoalesce(_optionalChain([lane, 'access', _21 => _21.base, 'access', _22 => _22.tiles, 'access', _23 => _23.get, 'call', _24 => _24(tk), 'optionalAccess', _25 => _25.data]), () => ( null));
2561
+ const src = _nullishCoalesce(_optionalChain([lane, 'access', _22 => _22.base, 'access', _23 => _23.tiles, 'access', _24 => _24.get, 'call', _25 => _25(tk), 'optionalAccess', _26 => _26.data]), () => ( null));
1901
2562
  const out = this.shadeSlot(key, src, all ? "bake-all" : "bake");
1902
2563
  if (!out) return lightChanged;
1903
2564
  const tiles = new Map(lane.base.tiles);
@@ -1960,7 +2621,7 @@ var WetWorld = (_class = class {
1960
2621
  for (const key of this.active) {
1961
2622
  if (this.laneIndexOf(key) !== lane.index) continue;
1962
2623
  const tk = this.tileKeyOf(key);
1963
- const out = this.shadeSlot(key, _nullishCoalesce(_optionalChain([lane, 'access', _26 => _26.base, 'access', _27 => _27.tiles, 'access', _28 => _28.get, 'call', _29 => _29(tk), 'optionalAccess', _30 => _30.data]), () => ( null)), "bake-all");
2624
+ const out = this.shadeSlot(key, _nullishCoalesce(_optionalChain([lane, 'access', _27 => _27.base, 'access', _28 => _28.tiles, 'access', _29 => _29.get, 'call', _30 => _30(tk), 'optionalAccess', _31 => _31.data]), () => ( null)), "bake-all");
1964
2625
  if (!out) continue;
1965
2626
  const t = _chunk474IQG74cjs.finishTile.call(void 0, out, 4, 0);
1966
2627
  if (t) tiles.set(tk, t);
@@ -2083,14 +2744,14 @@ var WetWorld = (_class = class {
2083
2744
  display(id, maxTiles = Infinity) {
2084
2745
  const lane = this.laneOf(id);
2085
2746
  const keys = this.active.filter((k) => this.laneIndexOf(k) === lane.index);
2086
- const stale = keys.filter((k) => _optionalChain([lane, 'access', _31 => _31.shaded, 'access', _32 => _32.get, 'call', _33 => _33(this.tileKeyOf(k)), 'optionalAccess', _34 => _34.stamp]) !== lane.stamp);
2087
- stale.sort((a, b) => Number(lane.urgent.has(this.tileKeyOf(b))) - Number(lane.urgent.has(this.tileKeyOf(a))) || (_nullishCoalesce(_optionalChain([lane, 'access', _35 => _35.shaded, 'access', _36 => _36.get, 'call', _37 => _37(this.tileKeyOf(a)), 'optionalAccess', _38 => _38.stamp]), () => ( 0))) - (_nullishCoalesce(_optionalChain([lane, 'access', _39 => _39.shaded, 'access', _40 => _40.get, 'call', _41 => _41(this.tileKeyOf(b)), 'optionalAccess', _42 => _42.stamp]), () => ( 0))));
2747
+ const stale = keys.filter((k) => _optionalChain([lane, 'access', _32 => _32.shaded, 'access', _33 => _33.get, 'call', _34 => _34(this.tileKeyOf(k)), 'optionalAccess', _35 => _35.stamp]) !== lane.stamp);
2748
+ stale.sort((a, b) => Number(lane.urgent.has(this.tileKeyOf(b))) - Number(lane.urgent.has(this.tileKeyOf(a))) || (_nullishCoalesce(_optionalChain([lane, 'access', _36 => _36.shaded, 'access', _37 => _37.get, 'call', _38 => _38(this.tileKeyOf(a)), 'optionalAccess', _39 => _39.stamp]), () => ( 0))) - (_nullishCoalesce(_optionalChain([lane, 'access', _40 => _40.shaded, 'access', _41 => _41.get, 'call', _42 => _42(this.tileKeyOf(b)), 'optionalAccess', _43 => _43.stamp]), () => ( 0))));
2088
2749
  const changed = [];
2089
2750
  let done = 0;
2090
2751
  for (const key of stale) {
2091
2752
  if (done >= maxTiles) break;
2092
2753
  const tk = this.tileKeyOf(key);
2093
- const src = _nullishCoalesce(_optionalChain([lane, 'access', _43 => _43.base, 'access', _44 => _44.tiles, 'access', _45 => _45.get, 'call', _46 => _46(tk), 'optionalAccess', _47 => _47.data]), () => ( null));
2754
+ const src = _nullishCoalesce(_optionalChain([lane, 'access', _44 => _44.base, 'access', _45 => _45.tiles, 'access', _46 => _46.get, 'call', _47 => _47(tk), 'optionalAccess', _48 => _48.data]), () => ( null));
2094
2755
  const out = this.shadeSlot(key, src, "display");
2095
2756
  const tile = out ? _chunk474IQG74cjs.finishTile.call(void 0, out, 4, 0) : _nullishCoalesce(lane.base.tiles.get(tk), () => ( null));
2096
2757
  lane.shaded.set(tk, { stamp: lane.stamp, tile: _nullishCoalesce(tile, () => ( { data: new Uint8ClampedArray(0), uniform: 0 })) });
@@ -2127,7 +2788,7 @@ var WetWorld = (_class = class {
2127
2788
  for (const key2 of keys) {
2128
2789
  const tk = this.tileKeyOf(key2);
2129
2790
  live.add(tk);
2130
- if (_optionalChain([lane, 'access', _48 => _48.lightShaded, 'access', _49 => _49.get, 'call', _50 => _50(tk), 'optionalAccess', _51 => _51.stamp]) === lane.stamp) continue;
2791
+ if (_optionalChain([lane, 'access', _49 => _49.lightShaded, 'access', _50 => _50.get, 'call', _51 => _51(tk), 'optionalAccess', _52 => _52.stamp]) === lane.stamp) continue;
2131
2792
  const src = _nullishCoalesce(lane.light.tiles.get(tk), () => ( null));
2132
2793
  const out = this.shadeLightSlot(key2, src, "display");
2133
2794
  lane.lightShaded.set(tk, { stamp: lane.stamp, tile: out ? _chunk474IQG74cjs.finishTile.call(void 0, out, 1, 0) : src });
@@ -2325,7 +2986,7 @@ var WetWorld = (_class = class {
2325
2986
  if (!this.gpu || this.busyFlag && !plan || !plan && !this.gpuDecide()) return { ...this.display(id, maxCpuTiles), gpu: false };
2326
2987
  const lane = this.laneOf(id);
2327
2988
  const keys = this.active.filter((k) => this.laneIndexOf(k) === lane.index);
2328
- const stale = plan ? keys : keys.filter((k) => _optionalChain([lane, 'access', _52 => _52.shaded, 'access', _53 => _53.get, 'call', _54 => _54(this.tileKeyOf(k)), 'optionalAccess', _55 => _55.stamp]) !== lane.stamp);
2989
+ const stale = plan ? keys : keys.filter((k) => _optionalChain([lane, 'access', _53 => _53.shaded, 'access', _54 => _54.get, 'call', _55 => _55(this.tileKeyOf(k)), 'optionalAccess', _56 => _56.stamp]) !== lane.stamp);
2329
2990
  if (!stale.length) return { ...this.display(id, 0), gpu: true };
2330
2991
  let tiles;
2331
2992
  const stamp = lane.stamp;
@@ -2333,7 +2994,7 @@ var WetWorld = (_class = class {
2333
2994
  try {
2334
2995
  if (!plan) this.gpuSync();
2335
2996
  const parity = plan ? plan.parity + plan.done & 1 : this.parity;
2336
- tiles = await this.gpu.shade(this.gpuJobs(stale), parity, stale.map((k) => _nullishCoalesce(_optionalChain([base, 'access', _56 => _56.tiles, 'access', _57 => _57.get, 'call', _58 => _58(this.tileKeyOf(k)), 'optionalAccess', _59 => _59.data]), () => ( null))), [this.paperBytes[0], this.paperBytes[1], this.paperBytes[2]]);
2997
+ tiles = await this.gpu.shade(this.gpuJobs(stale), parity, stale.map((k) => _nullishCoalesce(_optionalChain([base, 'access', _57 => _57.tiles, 'access', _58 => _58.get, 'call', _59 => _59(this.tileKeyOf(k)), 'optionalAccess', _60 => _60.data]), () => ( null))), [this.paperBytes[0], this.paperBytes[1], this.paperBytes[2]]);
2337
2998
  } catch (e) {
2338
2999
  this.gpuStop(`Wet paint stopped using the GPU (${e.message}).`);
2339
3000
  return { ...this.display(id, maxCpuTiles), gpu: false };
@@ -2415,7 +3076,7 @@ var WetWorld = (_class = class {
2415
3076
  const slot = this.slotOf(lane.index * this.layout.perLane + ty * this.layout.tilesX + tx);
2416
3077
  return slot < 0 ? -1 : this.slotBase(slot);
2417
3078
  }
2418
- }, _class);
3079
+ }, _class4);
2419
3080
  function moveWetSnapshot(snap, from, to, dx, dy, lane = () => ({})) {
2420
3081
  if (!Number.isInteger(dx / WET_TILE) || !Number.isInteger(dy / WET_TILE)) throw new WetWorldError(`Wet paint moves by whole ${WET_TILE} px tiles, not (${dx}, ${dy}).`);
2421
3082
  const a = makeLayout(from.width, from.height);
@@ -2439,7 +3100,7 @@ function moveWetSnapshot(snap, from, to, dx, dy, lane = () => ({})) {
2439
3100
  });
2440
3101
  return { clock: snap.clock, tilt: { ...snap.tilt }, lanes, slots, bytes };
2441
3102
  }
2442
- function unionRect(a, b) {
3103
+ function unionRect2(a, b) {
2443
3104
  if (!a) return { ...b };
2444
3105
  const x = Math.min(a.x, b.x);
2445
3106
  const y = Math.min(a.y, b.y);
@@ -2512,8 +3173,8 @@ function normalizeFlow(raw = {}, base = DEFAULT_FLOW) {
2512
3173
  }
2513
3174
  function flowField(spec, width, height) {
2514
3175
  const k = FLOW_ACCEL;
2515
- const cx = _nullishCoalesce(_optionalChain([spec, 'access', _60 => _60.center, 'optionalAccess', _61 => _61.x]), () => ( width / 2));
2516
- const cy = _nullishCoalesce(_optionalChain([spec, 'access', _62 => _62.center, 'optionalAccess', _63 => _63.y]), () => ( height / 2));
3176
+ const cx = _nullishCoalesce(_optionalChain([spec, 'access', _61 => _61.center, 'optionalAccess', _62 => _62.x]), () => ( width / 2));
3177
+ const cy = _nullishCoalesce(_optionalChain([spec, 'access', _63 => _63.center, 'optionalAccess', _64 => _64.y]), () => ( height / 2));
2517
3178
  const r0 = Math.max(width, height) / 2;
2518
3179
  switch (spec.kind) {
2519
3180
  case "none":
@@ -2545,8 +3206,8 @@ function flowField(spec, width, height) {
2545
3206
 
2546
3207
  // src/paint/wet/medium.ts
2547
3208
  var SAMPLE_K = 3;
2548
- var WetMedium = (_class2 = class {
2549
- constructor(world, laneId, options) {;_class2.prototype.__init24.call(this);
3209
+ var WetMedium = (_class5 = class {
3210
+ constructor(world, laneId, options) {;_class5.prototype.__init32.call(this);
2550
3211
  this.world = world;
2551
3212
  this.laneId = laneId;
2552
3213
  this.options = options;
@@ -2554,7 +3215,7 @@ var WetMedium = (_class2 = class {
2554
3215
 
2555
3216
 
2556
3217
 
2557
- __init24() {this.pig = new Float64Array(4)}
3218
+ __init32() {this.pig = new Float64Array(4)}
2558
3219
  sample(rect, cov) {
2559
3220
  const s = this.world.sample(this.laneId, rect, cov);
2560
3221
  if (!(s.wet > 0) || !(s.weight > 0)) return null;
@@ -2587,7 +3248,7 @@ var WetMedium = (_class2 = class {
2587
3248
  const pig = [0, 1, 2, 3].map((q) => this.pig[q] * mass * dep);
2588
3249
  this.world.paint(this.laneId, rect, cov, water * dep, mass > 0 ? pig : null, null, light);
2589
3250
  }
2590
- }, _class2);
3251
+ }, _class5);
2591
3252
 
2592
3253
  // src/paint/wet/gpu-kernels.ts
2593
3254
  var GPU_JOB_WORDS = 16;
@@ -2976,7 +3637,7 @@ var UNIFORM = 64;
2976
3637
  var STORAGE = 128;
2977
3638
  function findWebGpu() {
2978
3639
  const nav = globalThis.navigator;
2979
- return _nullishCoalesce(_optionalChain([nav, 'optionalAccess', _64 => _64.gpu]), () => ( null));
3640
+ return _nullishCoalesce(_optionalChain([nav, 'optionalAccess', _65 => _65.gpu]), () => ( null));
2980
3641
  }
2981
3642
  async function createWetGpuEngine(gpu = findWebGpu()) {
2982
3643
  const no = (reason, adapter2 = null) => ({ engine: null, support: { supported: false, reason, adapter: adapter2, maxSlots: 0 } });
@@ -2988,7 +3649,7 @@ async function createWetGpuEngine(gpu = findWebGpu()) {
2988
3649
  return no(`WebGPU gave no adapter (${e.message}); wet paint runs on the CPU.`);
2989
3650
  }
2990
3651
  if (!adapter) return no("WebGPU gave no adapter (the GPU may be blocklisted); wet paint runs on the CPU.");
2991
- const name = [_optionalChain([adapter, 'access', _65 => _65.info, 'optionalAccess', _66 => _66.vendor]), _optionalChain([adapter, 'access', _67 => _67.info, 'optionalAccess', _68 => _68.architecture])].filter(Boolean).join(" ") || null;
3652
+ const name = [_optionalChain([adapter, 'access', _66 => _66.info, 'optionalAccess', _67 => _67.vendor]), _optionalChain([adapter, 'access', _68 => _68.info, 'optionalAccess', _69 => _69.architecture])].filter(Boolean).join(" ") || null;
2992
3653
  const binding = Math.min(_nullishCoalesce(adapter.limits.maxStorageBufferBindingSize, () => ( 0)), _nullishCoalesce(adapter.limits.maxBufferSize, () => ( 0)));
2993
3654
  const maxSlots = Math.min(MAX_WET_SLOTS, Math.floor(binding / SLOT_BYTES));
2994
3655
  if (maxSlots < 4) return no(`The GPU's storage buffers hold ${Math.max(0, maxSlots)} wet tiles; at least 4 are needed. Wet paint runs on the CPU.`, name);
@@ -3008,32 +3669,32 @@ async function createWetGpuEngine(gpu = findWebGpu()) {
3008
3669
  const engine = await WetGpuEngine.start(device, maxSlots, name);
3009
3670
  return { engine, support: { supported: true, reason: null, adapter: name, maxSlots } };
3010
3671
  } catch (e) {
3011
- _optionalChain([device, 'access', _69 => _69.destroy, 'optionalCall', _70 => _70()]);
3672
+ _optionalChain([device, 'access', _70 => _70.destroy, 'optionalCall', _71 => _71()]);
3012
3673
  return no(`The wet-media shaders did not compile on this GPU (${e.message}); wet paint runs on the CPU.`, name);
3013
3674
  }
3014
3675
  }
3015
3676
  async function wetGpuSupport(gpu = findWebGpu()) {
3016
3677
  const { engine, support } = await createWetGpuEngine(gpu);
3017
- _optionalChain([engine, 'optionalAccess', _71 => _71.destroy, 'call', _72 => _72()]);
3678
+ _optionalChain([engine, 'optionalAccess', _72 => _72.destroy, 'call', _73 => _73()]);
3018
3679
  return support;
3019
3680
  }
3020
3681
  async function pipeline(device, code, label) {
3021
- _optionalChain([device, 'access', _73 => _73.pushErrorScope, 'optionalCall', _74 => _74("validation")]);
3682
+ _optionalChain([device, 'access', _74 => _74.pushErrorScope, 'optionalCall', _75 => _75("validation")]);
3022
3683
  const module = device.createShaderModule({ code, label });
3023
- const info = await _optionalChain([module, 'access', _75 => _75.getCompilationInfo, 'optionalCall', _76 => _76()]);
3024
- const errors = _nullishCoalesce(_optionalChain([info, 'optionalAccess', _77 => _77.messages, 'access', _78 => _78.filter, 'call', _79 => _79((m) => m.type === "error")]), () => ( []));
3684
+ const info = await _optionalChain([module, 'access', _76 => _76.getCompilationInfo, 'optionalCall', _77 => _77()]);
3685
+ const errors = _nullishCoalesce(_optionalChain([info, 'optionalAccess', _78 => _78.messages, 'access', _79 => _79.filter, 'call', _80 => _80((m) => m.type === "error")]), () => ( []));
3025
3686
  if (errors.length) {
3026
- await _optionalChain([device, 'access', _80 => _80.popErrorScope, 'optionalCall', _81 => _81()]);
3687
+ await _optionalChain([device, 'access', _81 => _81.popErrorScope, 'optionalCall', _82 => _82()]);
3027
3688
  throw new Error(`${label}: ${errors.map((m) => `line ${m.lineNum}: ${m.message}`).join("; ")}`);
3028
3689
  }
3029
3690
  const desc = { layout: "auto", compute: { module, entryPoint: "main" }, label };
3030
3691
  const p = device.createComputePipelineAsync ? await device.createComputePipelineAsync(desc) : device.createComputePipeline(desc);
3031
- const err = await _optionalChain([device, 'access', _82 => _82.popErrorScope, 'optionalCall', _83 => _83()]);
3692
+ const err = await _optionalChain([device, 'access', _83 => _83.popErrorScope, 'optionalCall', _84 => _84()]);
3032
3693
  if (err) throw new Error(`${label}: ${err.message}`);
3033
3694
  return p;
3034
3695
  }
3035
- var WetGpuEngine = (_class3 = class _WetGpuEngine {
3036
- constructor(device, maxSlots, adapter, stepPipe, haloPipe, shadePipe) {;_class3.prototype.__init25.call(this);_class3.prototype.__init26.call(this);_class3.prototype.__init27.call(this);_class3.prototype.__init28.call(this);_class3.prototype.__init29.call(this);_class3.prototype.__init30.call(this);_class3.prototype.__init31.call(this);_class3.prototype.__init32.call(this);_class3.prototype.__init33.call(this);
3696
+ var WetGpuEngine = (_class6 = class _WetGpuEngine {
3697
+ constructor(device, maxSlots, adapter, stepPipe, haloPipe, shadePipe) {;_class6.prototype.__init33.call(this);_class6.prototype.__init34.call(this);_class6.prototype.__init35.call(this);_class6.prototype.__init36.call(this);_class6.prototype.__init37.call(this);_class6.prototype.__init38.call(this);_class6.prototype.__init39.call(this);_class6.prototype.__init40.call(this);_class6.prototype.__init41.call(this);
3037
3698
  this.device = device;
3038
3699
  this.maxSlots = maxSlots;
3039
3700
  this.adapter = adapter;
@@ -3054,8 +3715,8 @@ var WetGpuEngine = (_class3 = class _WetGpuEngine {
3054
3715
  return b;
3055
3716
  });
3056
3717
  this.shadeUni = d.createBuffer({ size: 16, usage: UNIFORM | COPY_DST, label: "wet shade" });
3057
- void _optionalChain([device, 'access', _84 => _84.lost, 'optionalAccess', _85 => _85.then, 'call', _86 => _86((info) => {
3058
- this.lostReason = _optionalChain([info, 'optionalAccess', _87 => _87.message]) || _optionalChain([info, 'optionalAccess', _88 => _88.reason]) || "the GPU device was lost";
3718
+ void _optionalChain([device, 'access', _85 => _85.lost, 'optionalAccess', _86 => _86.then, 'call', _87 => _87((info) => {
3719
+ this.lostReason = _optionalChain([info, 'optionalAccess', _88 => _88.message]) || _optionalChain([info, 'optionalAccess', _89 => _89.reason]) || "the GPU device was lost";
3059
3720
  })]);
3060
3721
  }
3061
3722
 
@@ -3065,23 +3726,23 @@ var WetGpuEngine = (_class3 = class _WetGpuEngine {
3065
3726
 
3066
3727
 
3067
3728
  /** Steps run on the GPU so far (for stats). */
3068
- __init25() {this.steps = 0}
3729
+ __init33() {this.steps = 0}
3069
3730
  /** Set once the device is lost; the engine does nothing after that. */
3070
- __init26() {this.lostReason = null}
3731
+ __init34() {this.lostReason = null}
3071
3732
 
3072
- __init27() {this.slots = 0}
3733
+ __init35() {this.slots = 0}
3073
3734
 
3074
3735
 
3075
- __init28() {this.jobCap = 0}
3736
+ __init36() {this.jobCap = 0}
3076
3737
 
3077
3738
 
3078
3739
 
3079
3740
 
3080
- __init29() {this.srcTiles = null}
3081
- __init30() {this.outTiles = null}
3082
- __init31() {this.outRead = null}
3083
- __init32() {this.tileCap = 0}
3084
- __init33() {this.groups = null}
3741
+ __init37() {this.srcTiles = null}
3742
+ __init38() {this.outTiles = null}
3743
+ __init39() {this.outRead = null}
3744
+ __init40() {this.tileCap = 0}
3745
+ __init41() {this.groups = null}
3085
3746
  /** @internal Compiles the kernels; use `createWetGpuEngine`. */
3086
3747
  static async start(device, maxSlots, adapter) {
3087
3748
  const [step, halo, shade] = await Promise.all([pipeline(device, WGSL_STEP, "wet step"), pipeline(device, WGSL_HALO, "wet halo"), pipeline(device, WGSL_SHADE, "wet shade")]);
@@ -3089,7 +3750,7 @@ var WetGpuEngine = (_class3 = class _WetGpuEngine {
3089
3750
  }
3090
3751
  /** Bytes of GPU memory in use. */
3091
3752
  memoryBytes() {
3092
- return this.state.size + this.jobs.size + (_nullishCoalesce(_optionalChain([this, 'access', _89 => _89.srcTiles, 'optionalAccess', _90 => _90.size]), () => ( 0))) + (_nullishCoalesce(_optionalChain([this, 'access', _91 => _91.outTiles, 'optionalAccess', _92 => _92.size]), () => ( 0))) * 2;
3753
+ return this.state.size + this.jobs.size + (_nullishCoalesce(_optionalChain([this, 'access', _90 => _90.srcTiles, 'optionalAccess', _91 => _91.size]), () => ( 0))) + (_nullishCoalesce(_optionalChain([this, 'access', _92 => _92.outTiles, 'optionalAccess', _93 => _93.size]), () => ( 0))) * 2;
3093
3754
  }
3094
3755
  /** Slots the state buffer holds now. */
3095
3756
  get capacity() {
@@ -3238,9 +3899,9 @@ var WetGpuEngine = (_class3 = class _WetGpuEngine {
3238
3899
  const d = this.device;
3239
3900
  const tileBytes = TILE_WORDS * 4;
3240
3901
  if (n > this.tileCap || !this.outTiles || !this.outRead || !this.srcTiles) {
3241
- _optionalChain([this, 'access', _93 => _93.srcTiles, 'optionalAccess', _94 => _94.destroy, 'call', _95 => _95()]);
3242
- _optionalChain([this, 'access', _96 => _96.outTiles, 'optionalAccess', _97 => _97.destroy, 'call', _98 => _98()]);
3243
- _optionalChain([this, 'access', _99 => _99.outRead, 'optionalAccess', _100 => _100.destroy, 'call', _101 => _101()]);
3902
+ _optionalChain([this, 'access', _94 => _94.srcTiles, 'optionalAccess', _95 => _95.destroy, 'call', _96 => _96()]);
3903
+ _optionalChain([this, 'access', _97 => _97.outTiles, 'optionalAccess', _98 => _98.destroy, 'call', _99 => _99()]);
3904
+ _optionalChain([this, 'access', _100 => _100.outRead, 'optionalAccess', _101 => _101.destroy, 'call', _102 => _102()]);
3244
3905
  this.tileCap = Math.max(n, this.tileCap * 2, 4);
3245
3906
  this.srcTiles = d.createBuffer({ size: this.tileCap * tileBytes, usage: STORAGE | COPY_DST, label: "wet base tiles" });
3246
3907
  this.outTiles = d.createBuffer({ size: this.tileCap * tileBytes, usage: STORAGE | COPY_SRC, label: "wet shaded tiles" });
@@ -3294,10 +3955,10 @@ var WetGpuEngine = (_class3 = class _WetGpuEngine {
3294
3955
  return this.device.queue.onSubmittedWorkDone();
3295
3956
  }
3296
3957
  destroy() {
3297
- for (const b of [this.state, this.params, this.jobs, this.flags, this.flagsRead, ...this.uni, this.shadeUni, this.srcTiles, this.outTiles, this.outRead]) _optionalChain([b, 'optionalAccess', _102 => _102.destroy, 'call', _103 => _103()]);
3958
+ for (const b of [this.state, this.params, this.jobs, this.flags, this.flagsRead, ...this.uni, this.shadeUni, this.srcTiles, this.outTiles, this.outRead]) _optionalChain([b, 'optionalAccess', _103 => _103.destroy, 'call', _104 => _104()]);
3298
3959
  this.device.destroy();
3299
3960
  }
3300
- }, _class3);
3961
+ }, _class6);
3301
3962
 
3302
3963
  // src/paint/pointer.ts
3303
3964
  function pointerPressure(e) {
@@ -3320,7 +3981,7 @@ function pointerStrokeSample(e, toPoint) {
3320
3981
  return s;
3321
3982
  }
3322
3983
  function pointerStrokeSamples(e, toPoint) {
3323
- const events = _nullishCoalesce(_optionalChain([e, 'access', _104 => _104.getCoalescedEvents, 'optionalCall', _105 => _105()]), () => ( []));
3984
+ const events = _nullishCoalesce(_optionalChain([e, 'access', _105 => _105.getCoalescedEvents, 'optionalCall', _106 => _106()]), () => ( []));
3324
3985
  return (events.length ? events : [e]).map((ev) => pointerStrokeSample(ev, toPoint));
3325
3986
  }
3326
3987
 
@@ -3419,4 +4080,34 @@ function pointerStrokeSamples(e, toPoint) {
3419
4080
 
3420
4081
 
3421
4082
 
3422
- exports.createPigmentTools = createPigmentTools; exports.WET_TILE = WET_TILE; exports.SLOT_SIDE = SLOT_SIDE; exports.PLANE = PLANE; exports.PLANE_BYTES = PLANE_BYTES; exports.SET_PLANES = SET_PLANES; exports.P_RHO = P_RHO; exports.P_UX = P_UX; exports.P_UY = P_UY; exports.P_SW = P_SW; exports.P_P0 = P_P0; exports.P_L = P_L; exports.P_EDGE = P_EDGE; exports.P_D0 = P_D0; exports.P_DL = P_DL; exports.P_H = P_H; exports.P_FX = P_FX; exports.P_FY = P_FY; exports.SLOT_PLANES = SLOT_PLANES; exports.SLOT_BYTES = SLOT_BYTES; exports.PIGMENT_CHANNELS = PIGMENT_CHANNELS; exports.MASS_CHANNELS = MASS_CHANNELS; exports.EX = EX; exports.EY = EY; exports.OPP = OPP; exports.W9 = W9; exports.DRY_EPS = DRY_EPS; exports.U_MAX = U_MAX; exports.STRIP = STRIP; exports.MAX_BATCH = MAX_BATCH; exports.FREE_INTERVAL = FREE_INTERVAL; exports.FLAG_ALIVE = FLAG_ALIVE; exports.FLAG_LEFT = FLAG_LEFT; exports.FLAG_RIGHT = FLAG_RIGHT; exports.FLAG_TOP = FLAG_TOP; exports.FLAG_BOTTOM = FLAG_BOTTOM; exports.FLAG_WET = FLAG_WET; exports.PARAM_FLOATS = PARAM_FLOATS; exports.PARAM = PARAM; exports.DEFAULT_WET_PARAMS = DEFAULT_WET_PARAMS; exports.WET_PARAM_KEYS = WET_PARAM_KEYS; exports.DEFAULT_WET_PAPER = DEFAULT_WET_PAPER; exports.FLAT = FLAT; exports.normalizeWetParams = normalizeWetParams; exports.normalizeTilt = normalizeTilt; exports.latticeViscosity = latticeViscosity; exports.PAPER_CAPACITY = PAPER_CAPACITY; exports.MAX_TILT_ACCEL = MAX_TILT_ACCEL; exports.packWetParams = packWetParams; exports.edgeBits = edgeBits; exports.PIGMENT_UNIT = PIGMENT_UNIT; exports.HIDE = HIDE; exports.BODY_SCATTER = BODY_SCATTER; exports.dexp = dexp; exports.dlog = dlog; exports.dpow = dpow; exports.SRGB_TO_LINEAR = SRGB_TO_LINEAR; exports.srgbByteToLinear = srgbByteToLinear; exports.linearToSrgb8 = linearToSrgb8; exports.pigmentOf = pigmentOf; exports.expNeg = expNeg; exports.filmReflectance = filmReflectance; exports.pigmentColor = pigmentColor; exports.filmPixel = filmPixel; exports.pixelPigment = pixelPigment; exports.shadeTile = shadeTile; exports.shadeLightTile = shadeLightTile; exports.stepSlotTs = stepSlotTs; exports.loadWetKernel = loadWetKernel; exports.canShareMemory = canShareMemory; exports.wetSimdSupported = wetSimdSupported; exports.wetSupport = wetSupport; exports.WetWorkerPool = WetWorkerPool; exports.MAX_WET_LANES = MAX_WET_LANES; exports.MAX_WET_SLOTS = MAX_WET_SLOTS; exports.WetWorldError = WetWorldError; exports.WetWorld = WetWorld; exports.moveWetSnapshot = moveWetSnapshot; exports.WET_FLOW_KINDS = WET_FLOW_KINDS; exports.DEFAULT_FLOW = DEFAULT_FLOW; exports.dsincos = dsincos; exports.normalizeFlow = normalizeFlow; exports.flowField = flowField; exports.WetMedium = WetMedium; exports.WGSL_STEP = WGSL_STEP; exports.WGSL_HALO = WGSL_HALO; exports.WGSL_SHADE = WGSL_SHADE; exports.findWebGpu = findWebGpu; exports.createWetGpuEngine = createWetGpuEngine; exports.wetGpuSupport = wetGpuSupport; exports.WetGpuEngine = WetGpuEngine; exports.pointerPressure = pointerPressure; exports.pointerStrokeSample = pointerStrokeSample; exports.pointerStrokeSamples = pointerStrokeSamples;
4083
+
4084
+
4085
+
4086
+
4087
+
4088
+
4089
+
4090
+
4091
+
4092
+
4093
+
4094
+
4095
+
4096
+
4097
+
4098
+
4099
+
4100
+
4101
+
4102
+
4103
+
4104
+
4105
+
4106
+
4107
+
4108
+
4109
+
4110
+
4111
+
4112
+
4113
+ exports.createPigmentTools = createPigmentTools; exports.TONE_RANGES = TONE_RANGES; exports.luma = luma; exports.dodgeBurnCurve = dodgeBurnCurve; exports.dodgeBurn = dodgeBurn; exports.saturationOf = saturationOf; exports.sponge = sponge; exports.perDabStrength = perDabStrength; exports.RETOUCH_SAMPLES = RETOUCH_SAMPLES; exports.SPOT_HEAL_TYPES = SPOT_HEAL_TYPES; exports.DEFAULT_RETOUCH = DEFAULT_RETOUCH; exports.normalizeRetouch = normalizeRetouch; exports.boxBlurPixels = boxBlurPixels; exports.retouchFilter = retouchFilter; exports.IDENTITY_CLONE_TRANSFORM = IDENTITY_CLONE_TRANSFORM; exports.isIdentityCloneTransform = isIdentityCloneTransform; exports.cloneSamplePoint = cloneSamplePoint; exports.TransformedPixelSource = TransformedPixelSource; exports.TilePixelSource = TilePixelSource; exports.RegionPixelSource = RegionPixelSource; exports.readSourceRegion = readSourceRegion; exports.applyRetouchToTile = applyRetouchToTile; exports.applyToneToDeepTile = applyToneToDeepTile; exports.toneOf = toneOf; exports.healPixels = healPixels; exports.spotHealPixels = spotHealPixels; exports.spotHealWindow = spotHealWindow; exports.RetouchDabStroke = RetouchDabStroke; exports.smudgeEffect = smudgeEffect; exports.spongeEffect = spongeEffect; exports.rgbaViewOfGrey = rgbaViewOfGrey; exports.WET_TILE = WET_TILE; exports.SLOT_SIDE = SLOT_SIDE; exports.PLANE = PLANE; exports.PLANE_BYTES = PLANE_BYTES; exports.SET_PLANES = SET_PLANES; exports.P_RHO = P_RHO; exports.P_UX = P_UX; exports.P_UY = P_UY; exports.P_SW = P_SW; exports.P_P0 = P_P0; exports.P_L = P_L; exports.P_EDGE = P_EDGE; exports.P_D0 = P_D0; exports.P_DL = P_DL; exports.P_H = P_H; exports.P_FX = P_FX; exports.P_FY = P_FY; exports.SLOT_PLANES = SLOT_PLANES; exports.SLOT_BYTES = SLOT_BYTES; exports.PIGMENT_CHANNELS = PIGMENT_CHANNELS; exports.MASS_CHANNELS = MASS_CHANNELS; exports.EX = EX; exports.EY = EY; exports.OPP = OPP; exports.W9 = W9; exports.DRY_EPS = DRY_EPS; exports.U_MAX = U_MAX; exports.STRIP = STRIP; exports.MAX_BATCH = MAX_BATCH; exports.FREE_INTERVAL = FREE_INTERVAL; exports.FLAG_ALIVE = FLAG_ALIVE; exports.FLAG_LEFT = FLAG_LEFT; exports.FLAG_RIGHT = FLAG_RIGHT; exports.FLAG_TOP = FLAG_TOP; exports.FLAG_BOTTOM = FLAG_BOTTOM; exports.FLAG_WET = FLAG_WET; exports.PARAM_FLOATS = PARAM_FLOATS; exports.PARAM = PARAM; exports.DEFAULT_WET_PARAMS = DEFAULT_WET_PARAMS; exports.WET_PARAM_KEYS = WET_PARAM_KEYS; exports.DEFAULT_WET_PAPER = DEFAULT_WET_PAPER; exports.FLAT = FLAT; exports.normalizeWetParams = normalizeWetParams; exports.normalizeTilt = normalizeTilt; exports.latticeViscosity = latticeViscosity; exports.PAPER_CAPACITY = PAPER_CAPACITY; exports.MAX_TILT_ACCEL = MAX_TILT_ACCEL; exports.packWetParams = packWetParams; exports.edgeBits = edgeBits; exports.PIGMENT_UNIT = PIGMENT_UNIT; exports.HIDE = HIDE; exports.BODY_SCATTER = BODY_SCATTER; exports.dexp = dexp; exports.dlog = dlog; exports.dpow = dpow; exports.SRGB_TO_LINEAR = SRGB_TO_LINEAR; exports.srgbByteToLinear = srgbByteToLinear; exports.linearToSrgb8 = linearToSrgb8; exports.pigmentOf = pigmentOf; exports.expNeg = expNeg; exports.filmReflectance = filmReflectance; exports.pigmentColor = pigmentColor; exports.filmPixel = filmPixel; exports.pixelPigment = pixelPigment; exports.shadeTile = shadeTile; exports.shadeLightTile = shadeLightTile; exports.stepSlotTs = stepSlotTs; exports.loadWetKernel = loadWetKernel; exports.canShareMemory = canShareMemory; exports.wetSimdSupported = wetSimdSupported; exports.wetSupport = wetSupport; exports.WetWorkerPool = WetWorkerPool; exports.MAX_WET_LANES = MAX_WET_LANES; exports.MAX_WET_SLOTS = MAX_WET_SLOTS; exports.WetWorldError = WetWorldError; exports.WetWorld = WetWorld; exports.moveWetSnapshot = moveWetSnapshot; exports.WET_FLOW_KINDS = WET_FLOW_KINDS; exports.DEFAULT_FLOW = DEFAULT_FLOW; exports.dsincos = dsincos; exports.normalizeFlow = normalizeFlow; exports.flowField = flowField; exports.WetMedium = WetMedium; exports.WGSL_STEP = WGSL_STEP; exports.WGSL_HALO = WGSL_HALO; exports.WGSL_SHADE = WGSL_SHADE; exports.findWebGpu = findWebGpu; exports.createWetGpuEngine = createWetGpuEngine; exports.wetGpuSupport = wetGpuSupport; exports.WetGpuEngine = WetGpuEngine; exports.pointerPressure = pointerPressure; exports.pointerStrokeSample = pointerStrokeSample; exports.pointerStrokeSamples = pointerStrokeSamples;