@pixerate/editor 0.275.0 → 0.276.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 (72) hide show
  1. package/dist/animation-editor/index.cjs +62 -62
  2. package/dist/animation-editor/index.js +6 -6
  3. package/dist/brushes/index.cjs +81 -70
  4. package/dist/brushes/index.js +17 -6
  5. package/dist/brushes/patch.d.cts +1 -1
  6. package/dist/brushes/patch.d.ts +1 -1
  7. package/dist/brushes/profiles.d.cts +2 -0
  8. package/dist/brushes/profiles.d.ts +2 -0
  9. package/dist/brushes/schema.d.cts +1 -0
  10. package/dist/brushes/schema.d.ts +1 -0
  11. package/dist/brushes/types.d.cts +22 -1
  12. package/dist/brushes/types.d.ts +22 -1
  13. package/dist/{brushstrokeRender-WGY4DZHF.js → brushstrokeRender-FK3ASUUJ.js} +5 -5
  14. package/dist/{brushstrokeRender-2RQL46WB.cjs → brushstrokeRender-I6MYFCOU.cjs} +21 -21
  15. package/dist/canvas/index.cjs +13 -13
  16. package/dist/canvas/index.js +1 -1
  17. package/dist/chart/contract.d.cts +3 -1
  18. package/dist/chart/contract.d.ts +3 -1
  19. package/dist/{chunk-Y2ISSVPH.js → chunk-4EM5NGCL.js} +167 -9
  20. package/dist/{chunk-Y354ETAE.cjs → chunk-5HR5CSLC.cjs} +49 -49
  21. package/dist/{chunk-LMG57L5A.js → chunk-CTHWXW5M.js} +121 -8
  22. package/dist/{chunk-43XJC3PP.js → chunk-CVBTJVRN.js} +1 -1
  23. package/dist/{chunk-RJGW3RQS.js → chunk-GHYJAMMS.js} +1 -1
  24. package/dist/{chunk-NIBFKXMD.cjs → chunk-IFWLZZCW.cjs} +619 -2
  25. package/dist/{chunk-G5TCMKX5.js → chunk-IJ6NSWKM.js} +2 -2
  26. package/dist/{chunk-C6VB7CPY.cjs → chunk-ISCAJBPQ.cjs} +1 -1
  27. package/dist/{chunk-W6JDUXP3.js → chunk-J23JOHPR.js} +1 -1
  28. package/dist/{chunk-IEEY5RJV.js → chunk-JNMNM3SL.js} +1 -1
  29. package/dist/{chunk-HVO6XCI4.js → chunk-JPB65KQ6.js} +1 -1
  30. package/dist/{chunk-ACTHSQOI.js → chunk-LDZOXESA.js} +618 -1
  31. package/dist/{chunk-DHC4E2DU.cjs → chunk-MITQGHN3.cjs} +121 -8
  32. package/dist/{chunk-STLTOISW.cjs → chunk-NPPMKMCU.cjs} +17 -17
  33. package/dist/{chunk-75SYKUOT.js → chunk-OS6OG7DN.js} +1 -1
  34. package/dist/{chunk-OLZXXAER.cjs → chunk-OY24XRYF.cjs} +408 -250
  35. package/dist/{chunk-6QNDGMK7.cjs → chunk-Q33V5PEF.cjs} +123 -42
  36. package/dist/{chunk-JDXWLCXF.cjs → chunk-QNNZA3V5.cjs} +2 -2
  37. package/dist/{chunk-T6KNJVBP.cjs → chunk-U26LUXCJ.cjs} +35 -35
  38. package/dist/{chunk-62MFUHSI.cjs → chunk-UQXULAMQ.cjs} +16 -16
  39. package/dist/{chunk-RAPNRK4R.cjs → chunk-X7XBEX3O.cjs} +88 -88
  40. package/dist/{chunk-MSWLJI4G.js → chunk-XMSH66VU.js} +2 -2
  41. package/dist/{chunk-ZM7IKQ4X.js → chunk-XVPQNX7O.js} +89 -8
  42. package/dist/{chunk-YYZC2EQO.cjs → chunk-ZIE6EJGR.cjs} +23 -23
  43. package/dist/image-editor/index.cjs +880 -852
  44. package/dist/image-editor/index.js +36 -8
  45. package/dist/paint/index.cjs +33 -5
  46. package/dist/paint/index.d.cts +1 -0
  47. package/dist/paint/index.d.ts +1 -0
  48. package/dist/paint/index.js +32 -4
  49. package/dist/paint/live-patterns.d.cts +149 -0
  50. package/dist/paint/live-patterns.d.ts +149 -0
  51. package/dist/paint/wet/world.d.cts +13 -0
  52. package/dist/paint/wet/world.d.ts +13 -0
  53. package/dist/paint-editor/brush-model.d.cts +7 -1
  54. package/dist/paint-editor/brush-model.d.ts +7 -1
  55. package/dist/paint-editor/controller.d.cts +52 -0
  56. package/dist/paint-editor/controller.d.ts +52 -0
  57. package/dist/paint-editor/index.cjs +850 -510
  58. package/dist/paint-editor/index.js +355 -15
  59. package/dist/paint-editor/ui.d.cts +5 -1
  60. package/dist/paint-editor/ui.d.ts +5 -1
  61. package/dist/paint-editor/wet-tools.d.cts +42 -0
  62. package/dist/paint-editor/wet-tools.d.ts +42 -0
  63. package/dist/paint-editor/wet.d.cts +22 -1
  64. package/dist/paint-editor/wet.d.ts +22 -1
  65. package/dist/vector/index.cjs +1002 -1002
  66. package/dist/vector/index.js +7 -7
  67. package/package.json +1 -1
  68. package/skills/pixerate-brushes/SKILL.md +1 -0
  69. package/skills/pixerate-paint-editor/SKILL.md +7 -1
  70. package/skills/pixerate-paint-editor/references/brush-facets.md +1 -0
  71. package/skills/pixerate-paint-editor/references/live-patterns.md +41 -0
  72. package/skills/pixerate-paint-watercolour/SKILL.md +8 -0
@@ -1,4 +1,4 @@
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;
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;
2
2
 
3
3
 
4
4
 
@@ -19,6 +19,8 @@ var _chunk2VX55NFMcjs = require('./chunk-2VX55NFM.cjs');
19
19
 
20
20
 
21
21
 
22
+
23
+
22
24
  var _chunk474IQG74cjs = require('./chunk-474IQG74.cjs');
23
25
 
24
26
  // src/paint/gradient-paint.ts
@@ -1866,6 +1868,621 @@ function union(a, b) {
1866
1868
  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 };
1867
1869
  }
1868
1870
 
1871
+ // src/paint/live-patterns.ts
1872
+ var PATTERN_TILE = 128;
1873
+ var PATTERN_CELLS = PATTERN_TILE * PATTERN_TILE;
1874
+ var PATTERN_SUBSTEPS = 4;
1875
+ var PATTERN_V_EPS = 0.02;
1876
+ var LIVE_PATTERN_KINDS = ["spots", "stripes", "coral", "maze", "worms"];
1877
+ var LIVE_PATTERN_PRESETS = {
1878
+ spots: {
1879
+ kind: "spots",
1880
+ label: "Spots",
1881
+ description: "Dividing Turing spots (mitosis).",
1882
+ feed: 0.035,
1883
+ kill: 0.065
1884
+ },
1885
+ stripes: {
1886
+ kind: "stripes",
1887
+ label: "Stripes",
1888
+ description: "Labyrinthine Turing stripes.",
1889
+ feed: 0.042,
1890
+ kill: 0.06
1891
+ },
1892
+ coral: {
1893
+ kind: "coral",
1894
+ label: "Coral",
1895
+ description: "Branching coral dendrites.",
1896
+ feed: 0.0545,
1897
+ kill: 0.062
1898
+ },
1899
+ maze: {
1900
+ kind: "maze",
1901
+ label: "Maze",
1902
+ description: "Winding interconnected maze channels.",
1903
+ feed: 0.029,
1904
+ kill: 0.057
1905
+ },
1906
+ worms: {
1907
+ kind: "worms",
1908
+ label: "Worms",
1909
+ description: "Wiggling vermicular tracks.",
1910
+ feed: 0.058,
1911
+ kill: 0.065
1912
+ }
1913
+ };
1914
+ var DEFAULT_LIVE_PATTERNS = {
1915
+ pattern: "spots",
1916
+ feed: LIVE_PATTERN_PRESETS.spots.feed,
1917
+ kill: LIVE_PATTERN_PRESETS.spots.kill,
1918
+ scale: 1,
1919
+ contrast: 1,
1920
+ secondColor: null,
1921
+ relief: 0
1922
+ };
1923
+ function isLivePatternKind(v) {
1924
+ return typeof v === "string" && LIVE_PATTERN_KINDS.includes(v);
1925
+ }
1926
+ function normalizePatternHexColor(v, fallback = null) {
1927
+ if (v === null) return null;
1928
+ if (typeof v !== "string") return fallback;
1929
+ const s = v.trim().toLowerCase();
1930
+ if (/^#[0-9a-f]{6}$/.test(s)) return s;
1931
+ if (/^#[0-9a-f]{3}$/.test(s)) {
1932
+ return `#${s[1]}${s[1]}${s[2]}${s[2]}${s[3]}${s[3]}`;
1933
+ }
1934
+ return fallback;
1935
+ }
1936
+ function parsePatternHexColor(hex) {
1937
+ if (!hex || !/^#[0-9a-f]{6}$/i.test(hex)) return null;
1938
+ return [
1939
+ Number.parseInt(hex.slice(1, 3), 16),
1940
+ Number.parseInt(hex.slice(3, 5), 16),
1941
+ Number.parseInt(hex.slice(5, 7), 16)
1942
+ ];
1943
+ }
1944
+ function round4(n) {
1945
+ return Math.round(n * 1e4) / 1e4;
1946
+ }
1947
+ function normalizeLivePatterns(raw = {}, base = DEFAULT_LIVE_PATTERNS) {
1948
+ const src = _nullishCoalesce(raw, () => ( {}));
1949
+ const hasExplicitPattern = isLivePatternKind(src.pattern);
1950
+ const pattern = hasExplicitPattern ? src.pattern : base.pattern;
1951
+ const preset = LIVE_PATTERN_PRESETS[pattern];
1952
+ const num = (v, d, min, max) => typeof v === "number" && Number.isFinite(v) ? Math.min(max, Math.max(min, v)) : d;
1953
+ const defaultFeed = hasExplicitPattern ? preset.feed : base.feed;
1954
+ const defaultKill = hasExplicitPattern ? preset.kill : base.kill;
1955
+ return {
1956
+ pattern,
1957
+ feed: round4(num(src.feed, defaultFeed, 0.01, 0.1)),
1958
+ kill: round4(num(src.kill, defaultKill, 0.03, 0.08)),
1959
+ scale: round4(num(src.scale, base.scale, 0.5, 4)),
1960
+ contrast: round4(num(src.contrast, base.contrast, 0, 2)),
1961
+ secondColor: src.secondColor === void 0 ? base.secondColor : normalizePatternHexColor(src.secondColor, base.secondColor),
1962
+ relief: round4(num(src.relief, base.relief, 0, 1))
1963
+ };
1964
+ }
1965
+ function patternNoise(gx, gy, seed) {
1966
+ let h = Math.imul(gx | 0, 374761393) + Math.imul(gy | 0, 668265263) + Math.imul(seed | 0, 1442695041) | 0;
1967
+ h = Math.imul(h ^ h >>> 13, 1274126177);
1968
+ return ((h ^ h >>> 16) >>> 0) / 4294967296;
1969
+ }
1970
+ var LivePatternField = (_class9 = class {
1971
+
1972
+
1973
+
1974
+
1975
+ __init40() {this.settings = { ...DEFAULT_LIVE_PATTERNS }}
1976
+ __init41() {this.enabled = false}
1977
+ __init42() {this.tiles = /* @__PURE__ */ new Map()}
1978
+ constructor(width, height, settings) {;_class9.prototype.__init40.call(this);_class9.prototype.__init41.call(this);_class9.prototype.__init42.call(this);
1979
+ this.width = Math.max(1, Math.round(width));
1980
+ this.height = Math.max(1, Math.round(height));
1981
+ this.tilesX = Math.ceil(this.width / _chunk474IQG74cjs.TILE);
1982
+ this.tilesY = Math.ceil(this.height / _chunk474IQG74cjs.TILE);
1983
+ if (settings) {
1984
+ this.settings = normalizeLivePatterns(settings, this.settings);
1985
+ this.enabled = true;
1986
+ }
1987
+ }
1988
+ resize(width, height) {
1989
+ this.width = Math.max(1, Math.round(width));
1990
+ this.height = Math.max(1, Math.round(height));
1991
+ this.tilesX = Math.ceil(this.width / _chunk474IQG74cjs.TILE);
1992
+ this.tilesY = Math.ceil(this.height / _chunk474IQG74cjs.TILE);
1993
+ }
1994
+ configure(settings) {
1995
+ this.settings = normalizeLivePatterns(settings, this.settings);
1996
+ this.enabled = true;
1997
+ return { ...this.settings };
1998
+ }
1999
+ clear() {
2000
+ this.enabled = false;
2001
+ this.tiles.clear();
2002
+ }
2003
+ ensureTile(tx, ty) {
2004
+ if (tx < 0 || ty < 0 || tx >= this.tilesX || ty >= this.tilesY) return null;
2005
+ const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
2006
+ let tile = this.tiles.get(key);
2007
+ if (!tile) {
2008
+ const u = new Float64Array(PATTERN_CELLS);
2009
+ u.fill(1);
2010
+ const v = new Float64Array(PATTERN_CELLS);
2011
+ const bakedV = new Float64Array(PATTERN_CELLS);
2012
+ tile = { u, v, bakedV };
2013
+ this.tiles.set(key, tile);
2014
+ }
2015
+ return tile;
2016
+ }
2017
+ /**
2018
+ * Seeds Gray-Scott reagent `V` inside a circle at document coordinates `(cx, cy)` with document
2019
+ * `radius` (pixels). Returns the number of half-resolution cells seeded.
2020
+ */
2021
+ seedDisc(cx, cy, radius, seed = 1, strength = 1) {
2022
+ this.enabled = true;
2023
+ const s = Math.min(1, Math.max(0.05, strength));
2024
+ const rDoc = Math.max(2, radius);
2025
+ const px = cx * 0.5;
2026
+ const py = cy * 0.5;
2027
+ const pr = Math.max(1, rDoc * 0.5);
2028
+ const maxGx = Math.ceil(this.width * 0.5);
2029
+ const maxGy = Math.ceil(this.height * 0.5);
2030
+ const gx0 = Math.max(0, Math.floor(px - pr));
2031
+ const gy0 = Math.max(0, Math.floor(py - pr));
2032
+ const gx1 = Math.min(maxGx - 1, Math.ceil(px + pr));
2033
+ const gy1 = Math.min(maxGy - 1, Math.ceil(py + pr));
2034
+ const r2 = pr * pr;
2035
+ let seeded = 0;
2036
+ for (let gy = gy0; gy <= gy1; gy++) {
2037
+ const dy = gy + 0.5 - py;
2038
+ for (let gx = gx0; gx <= gx1; gx++) {
2039
+ const dx = gx + 0.5 - px;
2040
+ const d2 = dx * dx + dy * dy;
2041
+ if (d2 > r2) continue;
2042
+ const tx = Math.floor(gx / PATTERN_TILE);
2043
+ const ty = Math.floor(gy / PATTERN_TILE);
2044
+ const tile = this.ensureTile(tx, ty);
2045
+ if (!tile) continue;
2046
+ const lx = gx - tx * PATTERN_TILE;
2047
+ const ly = gy - ty * PATTERN_TILE;
2048
+ const idx = ly * PATTERN_TILE + lx;
2049
+ const coarse = patternNoise(gx >> 1, gy >> 1, seed);
2050
+ const fine = patternNoise(gx, gy, seed + 101);
2051
+ const nearCenter = d2 <= Math.max(2.5, r2 * 0.08);
2052
+ if (nearCenter || d2 <= r2 * 0.65 && coarse > 0.72) {
2053
+ const falloff = 1 - d2 / r2 * 0.2;
2054
+ const targetV = (0.45 + 0.12 * fine) * s * falloff;
2055
+ if (targetV > tile.v[idx]) {
2056
+ tile.v[idx] = targetV;
2057
+ tile.u[idx] = Math.min(tile.u[idx], 0.5);
2058
+ }
2059
+ tile.bakedV[idx] = 0;
2060
+ seeded++;
2061
+ } else if (tile.v[idx] === 0 && tile.u[idx] === 1) {
2062
+ tile.u[idx] = 0.99 - 0.02 * fine * s;
2063
+ tile.bakedV[idx] = 0;
2064
+ }
2065
+ }
2066
+ }
2067
+ return seeded;
2068
+ }
2069
+ /**
2070
+ * Advances the Gray-Scott reaction-diffusion field for `wetSteps` wet simulation steps.
2071
+ * Only cells where `isWetCell(tx, ty, lx, ly)` is true update; dry cells have zero rate and freeze.
2072
+ * Returns whether any cell updated.
2073
+ */
2074
+ step(wetSteps, isWetCell, canWakeTile) {
2075
+ if (!this.enabled || this.tiles.size === 0 || wetSteps <= 0) return false;
2076
+ const totalSubsteps = Math.max(1, Math.floor(wetSteps)) * PATTERN_SUBSTEPS;
2077
+ const F = this.settings.feed;
2078
+ const k = this.settings.kill;
2079
+ const fk = F + k;
2080
+ const scaleClamped = Math.min(2.2, Math.max(0.4, this.settings.scale));
2081
+ const Du = 0.16 * scaleClamped;
2082
+ const Dv = 0.08 * scaleClamped;
2083
+ for (const [key, tile] of [...this.tiles.entries()]) {
2084
+ const { tx, ty } = _chunk474IQG74cjs.tileCoord.call(void 0, key);
2085
+ let top = false;
2086
+ let bottom = false;
2087
+ let left = false;
2088
+ let right = false;
2089
+ for (let i = 0; i < PATTERN_TILE; i++) {
2090
+ if (tile.v[i] > PATTERN_V_EPS || tile.v[PATTERN_TILE + i] > PATTERN_V_EPS) top = true;
2091
+ if (tile.v[(PATTERN_TILE - 1) * PATTERN_TILE + i] > PATTERN_V_EPS || tile.v[(PATTERN_TILE - 2) * PATTERN_TILE + i] > PATTERN_V_EPS) bottom = true;
2092
+ if (tile.v[i * PATTERN_TILE] > PATTERN_V_EPS || tile.v[i * PATTERN_TILE + 1] > PATTERN_V_EPS) left = true;
2093
+ if (tile.v[i * PATTERN_TILE + PATTERN_TILE - 1] > PATTERN_V_EPS || tile.v[i * PATTERN_TILE + PATTERN_TILE - 2] > PATTERN_V_EPS) right = true;
2094
+ }
2095
+ const wake = (nx, ny) => {
2096
+ if (nx < 0 || ny < 0 || nx >= this.tilesX || ny >= this.tilesY) return;
2097
+ if (canWakeTile && !canWakeTile(nx, ny)) return;
2098
+ this.ensureTile(nx, ny);
2099
+ };
2100
+ if (top) wake(tx, ty - 1);
2101
+ if (bottom) wake(tx, ty + 1);
2102
+ if (left) wake(tx - 1, ty);
2103
+ if (right) wake(tx + 1, ty);
2104
+ }
2105
+ const entries = [];
2106
+ let anyWet = false;
2107
+ for (const [key, tile] of this.tiles.entries()) {
2108
+ const { tx, ty } = _chunk474IQG74cjs.tileCoord.call(void 0, key);
2109
+ const wet = new Uint8Array(PATTERN_CELLS);
2110
+ let hasWet = false;
2111
+ const tileW = Math.min(PATTERN_TILE, Math.ceil(this.width * 0.5) - tx * PATTERN_TILE);
2112
+ const tileH = Math.min(PATTERN_TILE, Math.ceil(this.height * 0.5) - ty * PATTERN_TILE);
2113
+ for (let ly = 0; ly < tileH; ly++) {
2114
+ for (let lx = 0; lx < tileW; lx++) {
2115
+ if (isWetCell(tx, ty, lx, ly)) {
2116
+ wet[ly * PATTERN_TILE + lx] = 1;
2117
+ hasWet = true;
2118
+ anyWet = true;
2119
+ }
2120
+ }
2121
+ }
2122
+ entries.push({
2123
+ key,
2124
+ tx,
2125
+ ty,
2126
+ u: tile.u,
2127
+ v: tile.v,
2128
+ nextU: new Float64Array(tile.u),
2129
+ nextV: new Float64Array(tile.v),
2130
+ wet,
2131
+ hasWet
2132
+ });
2133
+ }
2134
+ if (!anyWet) return false;
2135
+ const byKey = /* @__PURE__ */ new Map();
2136
+ for (const e of entries) byKey.set(e.key, e);
2137
+ const sampleUV = (entry, lx, ly, out) => {
2138
+ if (lx >= 0 && lx < PATTERN_TILE && ly >= 0 && ly < PATTERN_TILE) {
2139
+ const idx2 = ly * PATTERN_TILE + lx;
2140
+ out[0] = entry.u[idx2];
2141
+ out[1] = entry.v[idx2];
2142
+ return;
2143
+ }
2144
+ let ntx = entry.tx;
2145
+ let nty = entry.ty;
2146
+ let nlx = lx;
2147
+ let nly = ly;
2148
+ if (nlx < 0) {
2149
+ ntx -= 1;
2150
+ nlx += PATTERN_TILE;
2151
+ } else if (nlx >= PATTERN_TILE) {
2152
+ ntx += 1;
2153
+ nlx -= PATTERN_TILE;
2154
+ }
2155
+ if (nly < 0) {
2156
+ nty -= 1;
2157
+ nly += PATTERN_TILE;
2158
+ } else if (nly >= PATTERN_TILE) {
2159
+ nty += 1;
2160
+ nly -= PATTERN_TILE;
2161
+ }
2162
+ const nb = byKey.get(_chunk474IQG74cjs.tileKey.call(void 0, ntx, nty));
2163
+ if (!nb) {
2164
+ const cx = Math.min(PATTERN_TILE - 1, Math.max(0, lx));
2165
+ const cy = Math.min(PATTERN_TILE - 1, Math.max(0, ly));
2166
+ const idx2 = cy * PATTERN_TILE + cx;
2167
+ out[0] = entry.u[idx2];
2168
+ out[1] = entry.v[idx2];
2169
+ return;
2170
+ }
2171
+ const idx = nly * PATTERN_TILE + nlx;
2172
+ out[0] = nb.u[idx];
2173
+ out[1] = nb.v[idx];
2174
+ };
2175
+ const nbScratch = new Float64Array(2);
2176
+ for (let s = 0; s < totalSubsteps; s++) {
2177
+ for (const e of entries) {
2178
+ if (!e.hasWet) continue;
2179
+ const { u, v, nextU, nextV, wet } = e;
2180
+ for (let ly = 0; ly < PATTERN_TILE; ly++) {
2181
+ const row = ly * PATTERN_TILE;
2182
+ const interiorY = ly > 0 && ly < PATTERN_TILE - 1;
2183
+ for (let lx = 0; lx < PATTERN_TILE; lx++) {
2184
+ const idx = row + lx;
2185
+ if (!wet[idx]) {
2186
+ nextU[idx] = u[idx];
2187
+ nextV[idx] = v[idx];
2188
+ continue;
2189
+ }
2190
+ const uc = u[idx];
2191
+ const vc = v[idx];
2192
+ let lapU = -uc;
2193
+ let lapV = -vc;
2194
+ if (interiorY && lx > 0 && lx < PATTERN_TILE - 1) {
2195
+ const n = idx - PATTERN_TILE;
2196
+ const so = idx + PATTERN_TILE;
2197
+ lapU += 0.2 * (u[idx - 1] + u[idx + 1] + u[n] + u[so]) + 0.05 * (u[n - 1] + u[n + 1] + u[so - 1] + u[so + 1]);
2198
+ lapV += 0.2 * (v[idx - 1] + v[idx + 1] + v[n] + v[so]) + 0.05 * (v[n - 1] + v[n + 1] + v[so - 1] + v[so + 1]);
2199
+ } else {
2200
+ sampleUV(e, lx - 1, ly, nbScratch);
2201
+ lapU += 0.2 * nbScratch[0];
2202
+ lapV += 0.2 * nbScratch[1];
2203
+ sampleUV(e, lx + 1, ly, nbScratch);
2204
+ lapU += 0.2 * nbScratch[0];
2205
+ lapV += 0.2 * nbScratch[1];
2206
+ sampleUV(e, lx, ly - 1, nbScratch);
2207
+ lapU += 0.2 * nbScratch[0];
2208
+ lapV += 0.2 * nbScratch[1];
2209
+ sampleUV(e, lx, ly + 1, nbScratch);
2210
+ lapU += 0.2 * nbScratch[0];
2211
+ lapV += 0.2 * nbScratch[1];
2212
+ sampleUV(e, lx - 1, ly - 1, nbScratch);
2213
+ lapU += 0.05 * nbScratch[0];
2214
+ lapV += 0.05 * nbScratch[1];
2215
+ sampleUV(e, lx + 1, ly - 1, nbScratch);
2216
+ lapU += 0.05 * nbScratch[0];
2217
+ lapV += 0.05 * nbScratch[1];
2218
+ sampleUV(e, lx - 1, ly + 1, nbScratch);
2219
+ lapU += 0.05 * nbScratch[0];
2220
+ lapV += 0.05 * nbScratch[1];
2221
+ sampleUV(e, lx + 1, ly + 1, nbScratch);
2222
+ lapU += 0.05 * nbScratch[0];
2223
+ lapV += 0.05 * nbScratch[1];
2224
+ }
2225
+ const uvv = uc * vc * vc;
2226
+ const nu = uc + Du * lapU - uvv + F * (1 - uc);
2227
+ const nv = vc + Dv * lapV + uvv - fk * vc;
2228
+ nextU[idx] = nu < 0 ? 0 : nu > 1 ? 1 : nu;
2229
+ nextV[idx] = nv < 0 ? 0 : nv > 1 ? 1 : nv;
2230
+ }
2231
+ }
2232
+ }
2233
+ for (const e of entries) {
2234
+ if (!e.hasWet) continue;
2235
+ e.u.set(e.nextU);
2236
+ e.v.set(e.nextV);
2237
+ }
2238
+ }
2239
+ return true;
2240
+ }
2241
+ /**
2242
+ * Bilinearly samples unbaked `V` (`max(0, v - bakedV)`) at document-tile pixel `(x, y)` in `0..255`.
2243
+ */
2244
+ sampleUnbakedV(tile, x, y) {
2245
+ const fx = Math.min(PATTERN_TILE - 1, Math.max(0, (x + 0.5) * 0.5 - 0.5));
2246
+ const fy = Math.min(PATTERN_TILE - 1, Math.max(0, (y + 0.5) * 0.5 - 0.5));
2247
+ const x0 = Math.floor(fx);
2248
+ const y0 = Math.floor(fy);
2249
+ const x1 = Math.min(PATTERN_TILE - 1, x0 + 1);
2250
+ const y1 = Math.min(PATTERN_TILE - 1, y0 + 1);
2251
+ const tx = fx - x0;
2252
+ const ty = fy - y0;
2253
+ const at = (ix, iy) => {
2254
+ const idx = iy * PATTERN_TILE + ix;
2255
+ const val = tile.v[idx] - tile.bakedV[idx];
2256
+ return val > 0 ? val : 0;
2257
+ };
2258
+ const v00 = at(x0, y0);
2259
+ const v10 = at(x1, y0);
2260
+ const v01 = at(x0, y1);
2261
+ const v11 = at(x1, y1);
2262
+ const top = v00 + (v10 - v00) * tx;
2263
+ const bot = v01 + (v11 - v01) * tx;
2264
+ return top + (bot - top) * ty;
2265
+ }
2266
+ /**
2267
+ * Blends the pattern's `V` concentration into a shaded `256 × 256` RGBA wet tile `out`.
2268
+ * Returns whether any pixel in `out` was modified.
2269
+ */
2270
+ shadeTile(tx, ty, out, w, h) {
2271
+ if (!this.enabled || this.settings.contrast <= 0) return false;
2272
+ const tile = this.tiles.get(_chunk474IQG74cjs.tileKey.call(void 0, tx, ty));
2273
+ if (!tile) return false;
2274
+ const second = parsePatternHexColor(this.settings.secondColor);
2275
+ const contrast = this.settings.contrast;
2276
+ let changed = false;
2277
+ for (let y = 0; y < h; y++) {
2278
+ for (let x = 0; x < w; x++) {
2279
+ const i = (y * _chunk474IQG74cjs.TILE + x) * 4;
2280
+ const a = out[i + 3];
2281
+ if (a === 0) continue;
2282
+ const vVal = this.sampleUnbakedV(tile, x, y);
2283
+ if (vVal <= 1e-4) continue;
2284
+ const t = Math.min(1, vVal * 2.2 * contrast);
2285
+ if (t <= 1e-3) continue;
2286
+ if (second) {
2287
+ out[i] = Math.round(out[i] + (second[0] - out[i]) * t);
2288
+ out[i + 1] = Math.round(out[i + 1] + (second[1] - out[i + 1]) * t);
2289
+ out[i + 2] = Math.round(out[i + 2] + (second[2] - out[i + 2]) * t);
2290
+ out[i + 3] = Math.min(255, Math.round(a + (255 - a) * t * 0.35));
2291
+ } else {
2292
+ const lum = out[i] * 77 + out[i + 1] * 150 + out[i + 2] * 29 >> 8;
2293
+ if (lum < 48) {
2294
+ out[i] = Math.round(out[i] + (220 - out[i]) * 0.4 * t);
2295
+ out[i + 1] = Math.round(out[i + 1] + (220 - out[i + 1]) * 0.4 * t);
2296
+ out[i + 2] = Math.round(out[i + 2] + (220 - out[i + 2]) * 0.4 * t);
2297
+ } else {
2298
+ const scale = 1 - 0.45 * t;
2299
+ out[i] = Math.round(out[i] * scale);
2300
+ out[i + 1] = Math.round(out[i + 1] * scale);
2301
+ out[i + 2] = Math.round(out[i + 2] * scale);
2302
+ }
2303
+ out[i + 3] = Math.min(255, Math.round(a + (255 - a) * t * 0.28));
2304
+ }
2305
+ changed = true;
2306
+ }
2307
+ }
2308
+ return changed;
2309
+ }
2310
+ /** Marks a tile's current `V` values as baked into the layer's base surface so they are not baked twice. */
2311
+ markBaked(tx, ty) {
2312
+ const tile = this.tiles.get(_chunk474IQG74cjs.tileKey.call(void 0, tx, ty));
2313
+ if (tile) tile.bakedV.set(tile.v);
2314
+ }
2315
+ /**
2316
+ * When `settings.relief > 0`, writes pattern `V` ridges into a 1-channel thick height surface.
2317
+ * Returns the updated height `TiledSurface`, or `currentHeight` when `relief <= 0` or nothing changed.
2318
+ */
2319
+ applyReliefHeight(currentHeight) {
2320
+ const relief = this.settings.relief;
2321
+ if (!this.enabled || relief <= 0 || this.tiles.size === 0) return currentHeight;
2322
+ let nextTiles = null;
2323
+ for (const [key, pTile] of this.tiles.entries()) {
2324
+ const { tx, ty } = _chunk474IQG74cjs.tileCoord.call(void 0, key);
2325
+ const w = Math.min(_chunk474IQG74cjs.TILE, this.width - tx * _chunk474IQG74cjs.TILE);
2326
+ const h = Math.min(_chunk474IQG74cjs.TILE, this.height - ty * _chunk474IQG74cjs.TILE);
2327
+ if (w <= 0 || h <= 0) continue;
2328
+ let maxTileV = 0;
2329
+ for (let i = 0; i < PATTERN_CELLS; i++) {
2330
+ if (pTile.v[i] > maxTileV) maxTileV = pTile.v[i];
2331
+ }
2332
+ if (maxTileV < PATTERN_V_EPS) continue;
2333
+ const existing = currentHeight.tiles.get(key);
2334
+ const buf = existing ? existing.data.length ? new Uint8ClampedArray(existing.data) : new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE).fill(_nullishCoalesce(existing.uniform, () => ( 0))) : new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE);
2335
+ let tileChanged = false;
2336
+ for (let y = 0; y < h; y++) {
2337
+ const ly = y >> 1;
2338
+ const row = ly * PATTERN_TILE;
2339
+ for (let x = 0; x < w; x++) {
2340
+ const vVal = pTile.v[row + (x >> 1)];
2341
+ if (vVal < PATTERN_V_EPS) continue;
2342
+ const ridge = Math.min(255, Math.round(Math.min(1, vVal * 2.2) * relief * 255));
2343
+ const p = y * _chunk474IQG74cjs.TILE + x;
2344
+ if (ridge > buf[p]) {
2345
+ buf[p] = ridge;
2346
+ tileChanged = true;
2347
+ }
2348
+ }
2349
+ }
2350
+ if (tileChanged) {
2351
+ if (!nextTiles) nextTiles = new Map(currentHeight.tiles);
2352
+ const finished = _chunk474IQG74cjs.finishTile.call(void 0, buf, 1, 0);
2353
+ if (finished) nextTiles.set(key, finished);
2354
+ else nextTiles.delete(key);
2355
+ }
2356
+ }
2357
+ return nextTiles ? new (0, _chunk474IQG74cjs.TiledSurface)(1, nextTiles, 0) : currentHeight;
2358
+ }
2359
+ /** Computes summary statistics of the layer's live pattern field. */
2360
+ stats(isWetCell) {
2361
+ if (!this.enabled || this.tiles.size === 0) {
2362
+ return {
2363
+ enabled: this.enabled,
2364
+ settings: { ...this.settings },
2365
+ activeTiles: 0,
2366
+ patternCells: 0,
2367
+ wetPatternCells: 0,
2368
+ meanV: 0,
2369
+ maxV: 0,
2370
+ bounds: null
2371
+ };
2372
+ }
2373
+ let activeTiles = 0;
2374
+ let patternCells = 0;
2375
+ let wetPatternCells = 0;
2376
+ let sumV = 0;
2377
+ let maxV = 0;
2378
+ let bx0 = Infinity;
2379
+ let by0 = Infinity;
2380
+ let bx1 = -Infinity;
2381
+ let by1 = -Infinity;
2382
+ for (const [key, tile] of this.tiles.entries()) {
2383
+ const { tx, ty } = _chunk474IQG74cjs.tileCoord.call(void 0, key);
2384
+ const tileW = Math.min(PATTERN_TILE, Math.ceil(this.width * 0.5) - tx * PATTERN_TILE);
2385
+ const tileH = Math.min(PATTERN_TILE, Math.ceil(this.height * 0.5) - ty * PATTERN_TILE);
2386
+ let tileHasCells = false;
2387
+ for (let ly = 0; ly < tileH; ly++) {
2388
+ const row = ly * PATTERN_TILE;
2389
+ for (let lx = 0; lx < tileW; lx++) {
2390
+ const val = tile.v[row + lx];
2391
+ if (val > maxV) maxV = val;
2392
+ if (val >= PATTERN_V_EPS) {
2393
+ tileHasCells = true;
2394
+ patternCells++;
2395
+ sumV += val;
2396
+ if (isWetCell && isWetCell(tx, ty, lx, ly)) wetPatternCells++;
2397
+ const gx0 = (tx * PATTERN_TILE + lx) * 2;
2398
+ const gy0 = (ty * PATTERN_TILE + ly) * 2;
2399
+ const gx1 = Math.min(this.width, gx0 + 2);
2400
+ const gy1 = Math.min(this.height, gy0 + 2);
2401
+ if (gx0 < bx0) bx0 = gx0;
2402
+ if (gy0 < by0) by0 = gy0;
2403
+ if (gx1 > bx1) bx1 = gx1;
2404
+ if (gy1 > by1) by1 = gy1;
2405
+ }
2406
+ }
2407
+ }
2408
+ if (tileHasCells) activeTiles++;
2409
+ }
2410
+ return {
2411
+ enabled: this.enabled,
2412
+ settings: { ...this.settings },
2413
+ activeTiles,
2414
+ patternCells,
2415
+ wetPatternCells,
2416
+ meanV: patternCells > 0 ? round4(sumV / patternCells) : 0,
2417
+ maxV: round4(maxV),
2418
+ bounds: patternCells > 0 ? { x: bx0, y: by0, width: bx1 - bx0, height: by1 - by0 } : null
2419
+ };
2420
+ }
2421
+ snapshot() {
2422
+ const tiles = /* @__PURE__ */ new Map();
2423
+ let bytes = 0;
2424
+ for (const [key, t] of this.tiles.entries()) {
2425
+ const u = new Float64Array(t.u);
2426
+ const v = new Float64Array(t.v);
2427
+ const bakedV = new Float64Array(t.bakedV);
2428
+ tiles.set(key, { u, v, bakedV });
2429
+ bytes += u.byteLength + v.byteLength + bakedV.byteLength;
2430
+ }
2431
+ return {
2432
+ settings: { ...this.settings },
2433
+ enabled: this.enabled,
2434
+ tiles,
2435
+ bytes
2436
+ };
2437
+ }
2438
+ restore(snap) {
2439
+ this.settings = { ...snap.settings };
2440
+ this.enabled = snap.enabled;
2441
+ this.tiles.clear();
2442
+ for (const [key, t] of snap.tiles.entries()) {
2443
+ this.tiles.set(key, {
2444
+ u: new Float64Array(t.u),
2445
+ v: new Float64Array(t.v),
2446
+ bakedV: new Float64Array(t.bakedV)
2447
+ });
2448
+ }
2449
+ }
2450
+ }, _class9);
2451
+ function moveLivePatternSnapshot(snap, to, tx0, ty0) {
2452
+ const maxTilesX = Math.ceil(to.width / _chunk474IQG74cjs.TILE);
2453
+ const maxTilesY = Math.ceil(to.height / _chunk474IQG74cjs.TILE);
2454
+ const tiles = /* @__PURE__ */ new Map();
2455
+ let bytes = 0;
2456
+ for (const [key, t] of snap.tiles.entries()) {
2457
+ const { tx, ty } = _chunk474IQG74cjs.tileCoord.call(void 0, key);
2458
+ const ntx = tx + tx0;
2459
+ const nty = ty + ty0;
2460
+ if (ntx < 0 || nty < 0 || ntx >= maxTilesX || nty >= maxTilesY) continue;
2461
+ tiles.set(_chunk474IQG74cjs.tileKey.call(void 0, ntx, nty), t);
2462
+ bytes += t.u.byteLength + t.v.byteLength + t.bakedV.byteLength;
2463
+ }
2464
+ return {
2465
+ settings: { ...snap.settings },
2466
+ enabled: snap.enabled,
2467
+ tiles,
2468
+ bytes
2469
+ };
2470
+ }
2471
+
2472
+
2473
+
2474
+
2475
+
2476
+
2477
+
2478
+
2479
+
2480
+
2481
+
2482
+
2483
+
2484
+
2485
+
1869
2486
 
1870
2487
 
1871
2488
 
@@ -1945,4 +2562,4 @@ function union(a, b) {
1945
2562
 
1946
2563
 
1947
2564
 
1948
- exports.PAINT_GRADIENT_SPACES = PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_REPEATS = PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_MAPPINGS = PAINT_GRADIENT_MAPPINGS; exports.DEFAULT_PAINT_GRADIENT_MAPPING = DEFAULT_PAINT_GRADIENT_MAPPING; exports.PAINT_GRADIENT_FULL_SPEED = PAINT_GRADIENT_FULL_SPEED; exports.PaintSourceError = PaintSourceError; exports.normalizeHexColor = normalizeHexColor; exports.hexToPaintRgb = hexToPaintRgb; exports.parsePaintSource = parsePaintSource; exports.readPaintSource = readPaintSource; exports.resolvePaintGradient = resolvePaintGradient; exports.scalePaintGradient = scalePaintGradient; exports.solidPaint = solidPaint; exports.isGradientPaint = isGradientPaint; exports.paintSourceColor = paintSourceColor; exports.paintSourceCss = paintSourceCss; exports.PaintGradientSampler = PaintGradientSampler; exports.PAINT_GRADIENT_JSON_SCHEMA = PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_COLOR_JSON_SCHEMA = PAINT_COLOR_JSON_SCHEMA; exports.PAINT_SOURCE_JSON_SCHEMA = PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_GRADIENT_MAPPING_LABELS = PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_SPACE_LABELS = PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_GRADIENT_REPEAT_LABELS = PAINT_GRADIENT_REPEAT_LABELS; exports.DEFAULT_PAINT_GRADIENT = DEFAULT_PAINT_GRADIENT; exports.PAINT_GRADIENT_PRESETS = PAINT_GRADIENT_PRESETS; exports.addPaintGradientStop = addPaintGradientStop; exports.removePaintGradientStop = removePaintGradientStop; exports.updatePaintGradientStop = updatePaintGradientStop; exports.reversePaintGradient = reversePaintGradient; exports.paintGradientMappingFor = paintGradientMappingFor; exports.PAINT_GRADIENT_KIT = PAINT_GRADIENT_KIT; exports.DEFAULT_BRUSH = DEFAULT_BRUSH; exports.MAX_BRUSH_SIZE = MAX_BRUSH_SIZE; exports.normalizeBrush = normalizeBrush; exports.tipShape = tipShape; exports.tipFalloff = tipFalloff; exports.tipReach = tipReach; exports.dabCoverage = dabCoverage; exports.smoothPoints = smoothPoints; exports.DabWalker = DabWalker; exports.walkDabs = walkDabs; exports.dabRect = dabRect; exports.rasterizeDab = rasterizeDab; exports.CoverageMap = CoverageMap; exports.StrokeCoverage = StrokeCoverage; exports.TIP_GRADIENT_STEPS = TIP_GRADIENT_STEPS; exports.gradientDabColor = gradientDabColor; exports.applyStrokeToTile = applyStrokeToTile; exports.applyStrokeToDeepTile = applyStrokeToDeepTile; exports.coverageTileCoord = coverageTileCoord; exports.GRAIN_PATTERNS = GRAIN_PATTERNS; exports.GRAIN_TILE = GRAIN_TILE; exports.grainHeights = grainHeights; exports.PaperGrain = PaperGrain; exports.grainCatch = grainCatch; exports.strokeGrainCatch = strokeGrainCatch; exports.MIXING_MODELS = MIXING_MODELS; exports.EMPTY_MIXER_LOAD = EMPTY_MIXER_LOAD; exports.MIXER_PICKUP_RATE = MIXER_PICKUP_RATE; exports.MIXER_DRAIN = MIXER_DRAIN; exports.exchangeRates = exchangeRates; exports.PaintExchange = PaintExchange; exports.put255 = put255; exports.TileMedium = TileMedium; exports.DEFAULT_BLENDER = DEFAULT_BLENDER; exports.DEFAULT_SMUDGE = DEFAULT_SMUDGE; exports.normalizeBlender = normalizeBlender; exports.normalizeSmudge = normalizeSmudge; exports.blendRadius = blendRadius; exports.createBlenderScratch = createBlenderScratch; exports.blenderDab = blenderDab; exports.SmudgeTip = SmudgeTip; exports.DEFAULT_MIXER = DEFAULT_MIXER; exports.normalizeMixer = normalizeMixer; exports.mixerRates = mixerRates; exports.loadMixer = loadMixer; exports.cleanMixer = cleanMixer; exports.MixerStroke = MixerStroke;
2565
+ exports.PAINT_GRADIENT_SPACES = PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_REPEATS = PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_MAPPINGS = PAINT_GRADIENT_MAPPINGS; exports.DEFAULT_PAINT_GRADIENT_MAPPING = DEFAULT_PAINT_GRADIENT_MAPPING; exports.PAINT_GRADIENT_FULL_SPEED = PAINT_GRADIENT_FULL_SPEED; exports.PaintSourceError = PaintSourceError; exports.normalizeHexColor = normalizeHexColor; exports.hexToPaintRgb = hexToPaintRgb; exports.parsePaintSource = parsePaintSource; exports.readPaintSource = readPaintSource; exports.resolvePaintGradient = resolvePaintGradient; exports.scalePaintGradient = scalePaintGradient; exports.solidPaint = solidPaint; exports.isGradientPaint = isGradientPaint; exports.paintSourceColor = paintSourceColor; exports.paintSourceCss = paintSourceCss; exports.PaintGradientSampler = PaintGradientSampler; exports.PAINT_GRADIENT_JSON_SCHEMA = PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_COLOR_JSON_SCHEMA = PAINT_COLOR_JSON_SCHEMA; exports.PAINT_SOURCE_JSON_SCHEMA = PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_GRADIENT_MAPPING_LABELS = PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_SPACE_LABELS = PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_GRADIENT_REPEAT_LABELS = PAINT_GRADIENT_REPEAT_LABELS; exports.DEFAULT_PAINT_GRADIENT = DEFAULT_PAINT_GRADIENT; exports.PAINT_GRADIENT_PRESETS = PAINT_GRADIENT_PRESETS; exports.addPaintGradientStop = addPaintGradientStop; exports.removePaintGradientStop = removePaintGradientStop; exports.updatePaintGradientStop = updatePaintGradientStop; exports.reversePaintGradient = reversePaintGradient; exports.paintGradientMappingFor = paintGradientMappingFor; exports.PAINT_GRADIENT_KIT = PAINT_GRADIENT_KIT; exports.DEFAULT_BRUSH = DEFAULT_BRUSH; exports.MAX_BRUSH_SIZE = MAX_BRUSH_SIZE; exports.normalizeBrush = normalizeBrush; exports.tipShape = tipShape; exports.tipFalloff = tipFalloff; exports.tipReach = tipReach; exports.dabCoverage = dabCoverage; exports.smoothPoints = smoothPoints; exports.DabWalker = DabWalker; exports.walkDabs = walkDabs; exports.dabRect = dabRect; exports.rasterizeDab = rasterizeDab; exports.CoverageMap = CoverageMap; exports.StrokeCoverage = StrokeCoverage; exports.TIP_GRADIENT_STEPS = TIP_GRADIENT_STEPS; exports.gradientDabColor = gradientDabColor; exports.applyStrokeToTile = applyStrokeToTile; exports.applyStrokeToDeepTile = applyStrokeToDeepTile; exports.coverageTileCoord = coverageTileCoord; exports.GRAIN_PATTERNS = GRAIN_PATTERNS; exports.GRAIN_TILE = GRAIN_TILE; exports.grainHeights = grainHeights; exports.PaperGrain = PaperGrain; exports.grainCatch = grainCatch; exports.strokeGrainCatch = strokeGrainCatch; exports.MIXING_MODELS = MIXING_MODELS; exports.EMPTY_MIXER_LOAD = EMPTY_MIXER_LOAD; exports.MIXER_PICKUP_RATE = MIXER_PICKUP_RATE; exports.MIXER_DRAIN = MIXER_DRAIN; exports.exchangeRates = exchangeRates; exports.PaintExchange = PaintExchange; exports.put255 = put255; exports.TileMedium = TileMedium; exports.DEFAULT_BLENDER = DEFAULT_BLENDER; exports.DEFAULT_SMUDGE = DEFAULT_SMUDGE; exports.normalizeBlender = normalizeBlender; exports.normalizeSmudge = normalizeSmudge; exports.blendRadius = blendRadius; exports.createBlenderScratch = createBlenderScratch; exports.blenderDab = blenderDab; exports.SmudgeTip = SmudgeTip; exports.DEFAULT_MIXER = DEFAULT_MIXER; exports.normalizeMixer = normalizeMixer; exports.mixerRates = mixerRates; exports.loadMixer = loadMixer; exports.cleanMixer = cleanMixer; exports.MixerStroke = MixerStroke; exports.PATTERN_TILE = PATTERN_TILE; exports.PATTERN_CELLS = PATTERN_CELLS; exports.PATTERN_SUBSTEPS = PATTERN_SUBSTEPS; exports.PATTERN_V_EPS = PATTERN_V_EPS; exports.LIVE_PATTERN_KINDS = LIVE_PATTERN_KINDS; exports.LIVE_PATTERN_PRESETS = LIVE_PATTERN_PRESETS; exports.DEFAULT_LIVE_PATTERNS = DEFAULT_LIVE_PATTERNS; exports.isLivePatternKind = isLivePatternKind; exports.normalizePatternHexColor = normalizePatternHexColor; exports.parsePatternHexColor = parsePatternHexColor; exports.normalizeLivePatterns = normalizeLivePatterns; exports.patternNoise = patternNoise; exports.LivePatternField = LivePatternField; exports.moveLivePatternSnapshot = moveLivePatternSnapshot;
@@ -27,7 +27,7 @@ import {
27
27
  resolveEngine,
28
28
  summarizeBrushSource,
29
29
  withKeptIssues
30
- } from "./chunk-ZM7IKQ4X.js";
30
+ } from "./chunk-XVPQNX7O.js";
31
31
  import {
32
32
  base64ToBytes
33
33
  } from "./chunk-OTTT5N3K.js";
@@ -44,7 +44,7 @@ var BRUSH_PATCH_PROPERTIES = (() => {
44
44
  const { required: _r, ...tip } = rest.tip;
45
45
  return { ...rest, tip: { ...tip, description: `${tip.description} In a patch, shape may be left out to keep it.` } };
46
46
  })();
47
- var UNSETTABLE_BRUSH_FACETS = ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "fluorescence", "thermochromic", "iridescence", "ghost", "mutation", "motion", "colour"];
47
+ var UNSETTABLE_BRUSH_FACETS = ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "fluorescence", "thermochromic", "iridescence", "ghost", "mutation", "motion", "livePatterns", "colour"];
48
48
  var BRUSH_UNSET_PROPERTY = {
49
49
  type: "array",
50
50
  minItems: 1,
@@ -74,7 +74,7 @@ function profileAlongPolyline(points, values, count = 32) {
74
74
  var round3 = (v) => Math.round(v * 1e3) / 1e3;
75
75
  var loading = null;
76
76
  function loadCanvasBrushstrokeRenderer() {
77
- loading ??= Promise.resolve().then(() => _interopRequireWildcard(require("./brushstrokeRender-2RQL46WB.cjs"))).catch((error) => {
77
+ loading ??= Promise.resolve().then(() => _interopRequireWildcard(require("./brushstrokeRender-I6MYFCOU.cjs"))).catch((error) => {
78
78
  loading = null;
79
79
  throw error;
80
80
  });
@@ -12,7 +12,7 @@ import {
12
12
  resolvePaintGradient,
13
13
  scalePaintGradient,
14
14
  strokeGrainCatch
15
- } from "./chunk-ACTHSQOI.js";
15
+ } from "./chunk-LDZOXESA.js";
16
16
  import {
17
17
  randSigned
18
18
  } from "./chunk-4D6KP5BV.js";