@pixerate/editor 0.24.0 → 0.26.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.
- package/README.md +101 -1
- package/THIRD_PARTY_NOTICES.md +40 -0
- package/dist/agent/index.cjs +175 -11
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +18 -4
- package/dist/agent/index.d.ts +18 -4
- package/dist/agent/index.js +168 -4
- package/dist/agent/index.js.map +1 -1
- package/dist/{arrangeShortcuts-B8O3f8-P.d.cts → arrange-BICutYPk.d.cts} +243 -29
- package/dist/{arrangeShortcuts-sLlD2rSX.d.ts → arrange-BICutYPk.d.ts} +243 -29
- package/dist/builtins-CdPcLwwF.d.cts +176 -0
- package/dist/builtins-Chj6zv_O.d.ts +176 -0
- package/dist/canvas/index.cjs +8588 -1857
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +1847 -9
- package/dist/canvas/index.d.ts +1847 -9
- package/dist/canvas/index.js +8577 -1846
- package/dist/canvas/index.js.map +1 -1
- package/dist/chunk-3CC7OPUQ.cjs +831 -0
- package/dist/chunk-3CC7OPUQ.cjs.map +1 -0
- package/dist/chunk-4BVP64JJ.cjs +1406 -0
- package/dist/chunk-4BVP64JJ.cjs.map +1 -0
- package/dist/chunk-BVP3TSLH.cjs +69 -0
- package/dist/chunk-BVP3TSLH.cjs.map +1 -0
- package/dist/{chunk-OLZJXL4R.cjs → chunk-CS6NZWWA.cjs} +59 -25
- package/dist/chunk-CS6NZWWA.cjs.map +1 -0
- package/dist/{chunk-MCSJFWAO.cjs → chunk-EWCOFSCQ.cjs} +685 -100
- package/dist/chunk-EWCOFSCQ.cjs.map +1 -0
- package/dist/chunk-HDYMLS3X.cjs +409 -0
- package/dist/chunk-HDYMLS3X.cjs.map +1 -0
- package/dist/chunk-HRMEDT2L.js +1406 -0
- package/dist/chunk-HRMEDT2L.js.map +1 -0
- package/dist/{chunk-D27YFC46.cjs → chunk-IFHKKVXH.cjs} +382 -63
- package/dist/chunk-IFHKKVXH.cjs.map +1 -0
- package/dist/{chunk-PGNZKFQS.js → chunk-JOIREKL7.js} +137 -58
- package/dist/chunk-JOIREKL7.js.map +1 -0
- package/dist/chunk-KRGXUQ2Y.js +1696 -0
- package/dist/chunk-KRGXUQ2Y.js.map +1 -0
- package/dist/{chunk-3LV6RRPH.js → chunk-MHEPLBFB.js} +2 -2
- package/dist/chunk-MR2764X2.js +831 -0
- package/dist/chunk-MR2764X2.js.map +1 -0
- package/dist/{chunk-XNORY7M6.cjs → chunk-NFVBT3UZ.cjs} +166 -87
- package/dist/chunk-NFVBT3UZ.cjs.map +1 -0
- package/dist/chunk-NQF32I6Z.cjs +6478 -0
- package/dist/chunk-NQF32I6Z.cjs.map +1 -0
- package/dist/chunk-O5RYH2PG.js +69 -0
- package/dist/chunk-O5RYH2PG.js.map +1 -0
- package/dist/{chunk-ITBSKI26.js → chunk-Q2OHWD2A.js} +1064 -360
- package/dist/chunk-Q2OHWD2A.js.map +1 -0
- package/dist/{chunk-FODNLX5N.js → chunk-QJSOZFCZ.js} +38 -4
- package/dist/chunk-QJSOZFCZ.js.map +1 -0
- package/dist/{chunk-SML64VJG.cjs → chunk-RRREAOVM.cjs} +4 -4
- package/dist/{chunk-SML64VJG.cjs.map → chunk-RRREAOVM.cjs.map} +1 -1
- package/dist/{chunk-5S3Z4PPF.js → chunk-SWE3NPOU.js} +347 -28
- package/dist/chunk-SWE3NPOU.js.map +1 -0
- package/dist/chunk-TXXNBDQX.cjs +1696 -0
- package/dist/chunk-TXXNBDQX.cjs.map +1 -0
- package/dist/chunk-UBCFIABU.js +409 -0
- package/dist/chunk-UBCFIABU.js.map +1 -0
- package/dist/chunk-X7HXL2SB.js +6478 -0
- package/dist/chunk-X7HXL2SB.js.map +1 -0
- package/dist/{chunk-SBCZ6RN5.cjs → chunk-YOMYSFJU.cjs} +1163 -459
- package/dist/chunk-YOMYSFJU.cjs.map +1 -0
- package/dist/{chunk-3CN2WD3X.js → chunk-ZRNHGAQT.js} +661 -76
- package/dist/chunk-ZRNHGAQT.js.map +1 -0
- package/dist/commands/index.cjs +425 -4
- package/dist/commands/index.cjs.map +1 -1
- package/dist/commands/index.d.cts +39 -77
- package/dist/commands/index.d.ts +39 -77
- package/dist/commands/index.js +424 -3
- package/dist/commands/index.js.map +1 -1
- package/dist/compare/index.cjs +3 -3
- package/dist/compare/index.d.cts +1 -1
- package/dist/compare/index.d.ts +1 -1
- package/dist/compare/index.js +2 -2
- package/dist/controller-CxXGOEmy.d.cts +2038 -0
- package/dist/controller-CxXGOEmy.d.ts +2038 -0
- package/dist/{documents-BQjzJNe2.d.ts → documents-CHT1U5Vs.d.ts} +10 -0
- package/dist/{documents-KRTPhvst.d.cts → documents-Gp7wb0Me.d.cts} +10 -0
- package/dist/export/index.cjs +36 -0
- package/dist/export/index.cjs.map +1 -0
- package/dist/export/index.d.cts +243 -0
- package/dist/export/index.d.ts +243 -0
- package/dist/export/index.js +36 -0
- package/dist/export/index.js.map +1 -0
- package/dist/extensions/index.cjs +101 -6
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +18 -5
- package/dist/extensions/index.d.ts +18 -5
- package/dist/extensions/index.js +101 -6
- package/dist/generation/index.cjs +1013 -69
- package/dist/generation/index.cjs.map +1 -1
- package/dist/generation/index.d.cts +474 -13
- package/dist/generation/index.d.ts +474 -13
- package/dist/generation/index.js +976 -32
- package/dist/generation/index.js.map +1 -1
- package/dist/image-editor/index.cjs +3385 -1275
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +693 -128
- package/dist/image-editor/index.d.ts +693 -128
- package/dist/image-editor/index.js +3325 -1215
- package/dist/image-editor/index.js.map +1 -1
- package/dist/{index-fJrlkJCd.d.ts → index-B273Zllk.d.ts} +500 -7
- package/dist/{index-BhJBSm2d.d.cts → index-jcJwmBYt.d.cts} +500 -7
- package/dist/index.cjs +1603 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +154 -27
- package/dist/index.d.ts +154 -27
- package/dist/index.js +1584 -26
- package/dist/index.js.map +1 -1
- package/dist/mention-text-CDnCFd3c.d.cts +53 -0
- package/dist/mention-text-CDnCFd3c.d.ts +53 -0
- package/dist/model-C1zApQM8.d.cts +219 -0
- package/dist/model-C1zApQM8.d.ts +219 -0
- package/dist/persistence/index.d.cts +3 -120
- package/dist/persistence/index.d.ts +3 -120
- package/dist/registry-CED5C0lA.d.cts +204 -0
- package/dist/registry-CED5C0lA.d.ts +204 -0
- package/dist/{registry-GJI4gToU.d.cts → registry-CEgwXED1.d.cts} +12 -1
- package/dist/{registry-GJI4gToU.d.ts → registry-CEgwXED1.d.ts} +12 -1
- package/dist/{registry-D32LpIc4.d.cts → registry-D0GADKc7.d.cts} +1 -1
- package/dist/{registry-evKTP4ls.d.ts → registry-DhVUZioj.d.ts} +1 -1
- package/dist/serializers/index.cjs +12 -4
- package/dist/serializers/index.cjs.map +1 -1
- package/dist/serializers/index.d.cts +41 -13
- package/dist/serializers/index.d.ts +41 -13
- package/dist/serializers/index.js +12 -4
- package/dist/spreadsheet/index.cjs +157 -3
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.d.cts +534 -11
- package/dist/spreadsheet/index.d.ts +534 -11
- package/dist/spreadsheet/index.js +157 -3
- package/dist/storage-BpFfspHm.d.cts +120 -0
- package/dist/storage-BpFfspHm.d.ts +120 -0
- package/dist/tokens/index.cjs +115 -0
- package/dist/tokens/index.cjs.map +1 -0
- package/dist/tokens/index.d.cts +212 -0
- package/dist/tokens/index.d.ts +212 -0
- package/dist/tokens/index.js +115 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/{track-changes-BK5sVf4_.d.cts → track-changes-D_VAPELi.d.cts} +95 -11
- package/dist/{track-changes-CDjCrwKe.d.ts → track-changes-Db_fGEvx.d.ts} +95 -11
- package/package.json +15 -1
- package/dist/chunk-3CN2WD3X.js.map +0 -1
- package/dist/chunk-5S3Z4PPF.js.map +0 -1
- package/dist/chunk-D27YFC46.cjs.map +0 -1
- package/dist/chunk-FODNLX5N.js.map +0 -1
- package/dist/chunk-ITBSKI26.js.map +0 -1
- package/dist/chunk-MA2F5KHF.cjs +0 -3223
- package/dist/chunk-MA2F5KHF.cjs.map +0 -1
- package/dist/chunk-MCSJFWAO.cjs.map +0 -1
- package/dist/chunk-OLZJXL4R.cjs.map +0 -1
- package/dist/chunk-PGNZKFQS.js.map +0 -1
- package/dist/chunk-SBCZ6RN5.cjs.map +0 -1
- package/dist/chunk-U5KWZU4X.js +0 -3223
- package/dist/chunk-U5KWZU4X.js.map +0 -1
- package/dist/chunk-XNORY7M6.cjs.map +0 -1
- package/dist/controller-BhLLAoi8.d.cts +0 -1000
- package/dist/controller-BhLLAoi8.d.ts +0 -1000
- package/dist/types-DX4Mh4SL.d.cts +0 -217
- package/dist/types-DX4Mh4SL.d.ts +0 -217
- /package/dist/{chunk-3LV6RRPH.js.map → chunk-MHEPLBFB.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/image-editor/color.ts","../../src/image-editor/blend.ts","../../src/image-editor/adjustment-layers.ts","../../src/image-editor/filters.ts","../../src/image-editor/histogram.ts","../../src/image-editor/geometry.ts","../../src/image-editor/renderer.ts","../../src/image-editor/controller.ts","../../src/image-editor/document.ts","../../src/image-editor/controls.ts","../../src/image-editor/tools.ts","../../src/image-editor/curve-editing.ts"],"sourcesContent":["// Portions ported from lightcraft-main/crates/color/src/cct.rs, lightcraft-main/crates/color/src/lib.rs,\n// lightcraft-main/crates/pipeline/src/tone.rs, lightcraft-main/crates/pipeline/src/local.rs and\n// lightcraft-main/crates/develop/src/settings.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors).\n// See THIRD_PARTY_NOTICES.md.\n\n/**\n * Colour science for the image editor's process 2 rendering: sRGB transfer functions,\n * correlated colour temperature / tint (Kim et al. Planckian locus, tint as Duv), Bradford\n * white-balance adaptation relative to \"as shot\", and the display-referred tone curve.\n */\n\n/** A CIE 1931 chromaticity. */\nexport interface Chromaticity {\n x: number;\n y: number;\n}\n\n/** A row-major 3×3 matrix (`[m00, m01, m02, m10, …, m22]`). */\nexport type Matrix3 = [number, number, number, number, number, number, number, number, number];\n\n// ---------------------------------------------------------------------------\n// Process versions\n// ---------------------------------------------------------------------------\n\n/** The rendering of adjustments from before process versions existed. Frozen. */\nexport const LEGACY_PROCESS_VERSION = 1 as const;\n/** The process new edits and Reset get. */\nexport const LATEST_PROCESS_VERSION = 2 as const;\nexport type ImageProcessVersion = 1 | 2;\n\n/**\n * Reads a stored process number leniently: a missing or damaged value (not a whole number) is\n * the legacy process, so a saved edit from before process versions renders exactly as it did. A\n * whole number newer than this build knows renders with the latest process.\n */\nexport function normalizeProcessVersion(value: unknown): ImageProcessVersion {\n if (typeof value !== 'number' || !Number.isInteger(value)) return LEGACY_PROCESS_VERSION;\n return value >= LATEST_PROCESS_VERSION ? LATEST_PROCESS_VERSION : LEGACY_PROCESS_VERSION;\n}\n\n// ---------------------------------------------------------------------------\n// sRGB transfer\n// ---------------------------------------------------------------------------\n\nexport function srgbToLinear(v: number): number {\n return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n}\n\nexport function linearToSrgb(v: number): number {\n return v <= 0.0031308 ? v * 12.92 : 1.055 * Math.pow(v, 1 / 2.4) - 0.055;\n}\n\n/** Rec.709 / sRGB luminance weights (linear light). */\nexport const LUMA_709: readonly [number, number, number] = [0.2126, 0.7152, 0.0722];\n\n// ---------------------------------------------------------------------------\n// 3×3 matrices\n// ---------------------------------------------------------------------------\n\nexport const IDENTITY_MATRIX3: Matrix3 = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n\nexport function mulMatrix3(a: Matrix3, b: Matrix3): Matrix3 {\n const out = new Array(9).fill(0) as Matrix3;\n for (let r = 0; r < 3; r++) {\n for (let c = 0; c < 3; c++) {\n out[r * 3 + c] = a[r * 3] * b[c] + a[r * 3 + 1] * b[3 + c] + a[r * 3 + 2] * b[6 + c];\n }\n }\n return out;\n}\n\nexport function applyMatrix3(m: Matrix3, v: readonly [number, number, number]): [number, number, number] {\n return [\n m[0] * v[0] + m[1] * v[1] + m[2] * v[2],\n m[3] * v[0] + m[4] * v[1] + m[5] * v[2],\n m[6] * v[0] + m[7] * v[1] + m[8] * v[2],\n ];\n}\n\nexport function invertMatrix3(m: Matrix3): Matrix3 | null {\n const [a, b, c, d, e, f, g, h, i] = m;\n const A = e * i - f * h;\n const B = -(d * i - f * g);\n const C = d * h - e * g;\n const det = a * A + b * B + c * C;\n if (!Number.isFinite(det) || Math.abs(det) < 1e-12) return null;\n const k = 1 / det;\n return [\n A * k, -(b * i - c * h) * k, (b * f - c * e) * k,\n B * k, (a * i - c * g) * k, -(a * f - c * d) * k,\n C * k, -(a * h - b * g) * k, (a * e - b * d) * k,\n ];\n}\n\nfunction diag3(x: number, y: number, z: number): Matrix3 {\n return [x, 0, 0, 0, y, 0, 0, 0, z];\n}\n\n// ---------------------------------------------------------------------------\n// Chromaticity, sRGB primaries, Bradford adaptation\n// ---------------------------------------------------------------------------\n\nexport const D65: Chromaticity = { x: 0.3127, y: 0.329 };\n\nfunction xyToXyz(p: Chromaticity): [number, number, number] {\n return [p.x / p.y, 1, (1 - p.x - p.y) / p.y];\n}\n\nfunction xyzToXy(v: readonly [number, number, number]): Chromaticity {\n const s = v[0] + v[1] + v[2];\n return s <= 0 ? { ...D65 } : { x: v[0] / s, y: v[1] / s };\n}\n\n/** Linear sRGB → XYZ (D65 white, Y = 1), derived from the primaries. */\nconst SRGB_TO_XYZ: Matrix3 = (() => {\n const p = [{ x: 0.64, y: 0.33 }, { x: 0.3, y: 0.6 }, { x: 0.15, y: 0.06 }].map(xyToXyz);\n const m: Matrix3 = [p[0][0], p[1][0], p[2][0], p[0][1], p[1][1], p[2][1], p[0][2], p[1][2], p[2][2]];\n const inv = invertMatrix3(m);\n const s = inv ? applyMatrix3(inv, xyToXyz(D65)) : [1, 1, 1];\n return mulMatrix3(m, diag3(s[0], s[1], s[2]));\n})();\nconst XYZ_TO_SRGB: Matrix3 = invertMatrix3(SRGB_TO_XYZ) ?? IDENTITY_MATRIX3;\n\n/** The Bradford cone-response matrix (XYZ → sharpened cones). */\nconst BRADFORD: Matrix3 = [0.8951, 0.2664, -0.1614, -0.7502, 1.7135, 0.0367, 0.0389, -0.0685, 1.0296];\nconst BRADFORD_INV: Matrix3 = invertMatrix3(BRADFORD) ?? IDENTITY_MATRIX3;\n\n/** Bradford chromatic adaptation (XYZ → XYZ) from white `src` to white `dst`. */\nexport function bradfordAdaptation(src: Chromaticity, dst: Chromaticity): Matrix3 {\n if (src.x === dst.x && src.y === dst.y) return [...IDENTITY_MATRIX3];\n const s = applyMatrix3(BRADFORD, xyToXyz(src));\n const d = applyMatrix3(BRADFORD, xyToXyz(dst));\n return mulMatrix3(BRADFORD_INV, mulMatrix3(diag3(d[0] / s[0], d[1] / s[1], d[2] / s[2]), BRADFORD));\n}\n\n/**\n * Matrix (linear sRGB → linear sRGB) that white-balances a scene lit by `src` so that it\n * renders as if lit by D65.\n */\nexport function wbMatrix(src: Chromaticity): Matrix3 {\n return mulMatrix3(XYZ_TO_SRGB, mulMatrix3(bradfordAdaptation(src, D65), SRGB_TO_XYZ));\n}\n\n/** The chromaticity of a linear sRGB colour. */\nexport function linearSrgbToXy(rgb: readonly [number, number, number]): Chromaticity {\n return xyzToXy(applyMatrix3(SRGB_TO_XYZ, rgb));\n}\n\n// ---------------------------------------------------------------------------\n// Correlated colour temperature and tint\n// ---------------------------------------------------------------------------\n\n/** Tint units per unit of Duv. */\nexport const TINT_SCALE = 3000;\nexport const MIN_KELVIN = 1667;\nexport const MAX_KELVIN = 25000;\n\nfunction kimXy(tIn: number): Chromaticity {\n const t = Math.min(MAX_KELVIN, Math.max(MIN_KELVIN, tIn));\n const t2 = t * t;\n const t3 = t2 * t;\n const x =\n t <= 4000\n ? -0.2661239e9 / t3 - 0.2343589e6 / t2 + 0.8776956e3 / t + 0.17991\n : -3.0258469e9 / t3 + 2.1070379e6 / t2 + 0.2226347e3 / t + 0.24039;\n const x2 = x * x;\n const x3 = x2 * x;\n const y =\n t <= 2222\n ? -1.1063814 * x3 - 1.3481102 * x2 + 2.18555832 * x - 0.20219683\n : t <= 4000\n ? -0.9549476 * x3 - 1.37418593 * x2 + 2.09137015 * x - 0.16748867\n : 3.081758 * x3 - 5.8733867 * x2 + 3.75112997 * x - 0.37001483;\n return { x, y };\n}\n\n/** CIE 1931 xy → CIE 1960 uv. */\nexport function xyToUv(p: Chromaticity): [number, number] {\n const d = -2 * p.x + 12 * p.y + 3;\n return [(4 * p.x) / d, (6 * p.y) / d];\n}\n\n/** CIE 1960 uv → CIE 1931 xy. */\nexport function uvToXy(u: number, v: number): Chromaticity {\n const d = 2 * u - 8 * v + 4;\n return { x: (3 * u) / d, y: (2 * v) / d };\n}\n\n/** Planckian locus in (u, v), extended linearly in mired space outside the approximation's range. */\nfunction locusUv(tIn: number): [number, number] {\n const t = Math.max(1000, tIn);\n if (t >= MIN_KELVIN && t <= MAX_KELVIN) return xyToUv(kimXy(t));\n const [a, b] = t < MIN_KELVIN ? [MIN_KELVIN, MIN_KELVIN + 50] : [MAX_KELVIN - 500, MAX_KELVIN];\n const [ua, va] = xyToUv(kimXy(a));\n const [ub, vb] = xyToUv(kimXy(b));\n const ma = 1e6 / a;\n const mb = 1e6 / b;\n const s = (1e6 / t - ma) / (mb - ma);\n return [ua + (ub - ua) * s, va + (vb - va) * s];\n}\n\n/** Unit normal of the locus at `t`, pointing towards green (increasing v). */\nfunction locusNormal(t: number): [number, number] {\n const m = 1e6 / t;\n const [u0, v0] = locusUv(1e6 / (m + 1));\n const [u1, v1] = locusUv(1e6 / Math.max(m - 1, 1));\n const du = u1 - u0;\n const dv = v1 - v0;\n const l = Math.max(Math.hypot(du, dv), 1e-12);\n const nx = -dv / l;\n const ny = du / l;\n return ny < 0 ? [-nx, -ny] : [nx, ny];\n}\n\n/**\n * Source illuminant chromaticity for temperature `kelvin` and correction `tint`.\n * Positive tint means a green source white, whose correction adds magenta to the image.\n */\nexport function tempTintToXy(kelvin: number, tint: number): Chromaticity {\n const [u, v] = locusUv(kelvin);\n const [nu, nv] = locusNormal(kelvin);\n const duv = tint / TINT_SCALE;\n return uvToXy(u + nu * duv, v + nv * duv);\n}\n\n/** Inverse of {@link tempTintToXy}: nearest locus temperature (searched in mired space) and tint. */\nexport function xyToTempTint(p: Chromaticity): { kelvin: number; tint: number } {\n const [u, v] = xyToUv(p);\n const dist = (m: number) => {\n const [lu, lv] = locusUv(1e6 / m);\n return (u - lu) ** 2 + (v - lv) ** 2;\n };\n // Coarse scan, then golden-section refine over mired 20..1000 (50000 K .. 1000 K).\n let best = 20;\n let bd = Infinity;\n for (let m = 20; m <= 1000; m += 5) {\n const d = dist(m);\n if (d < bd) {\n bd = d;\n best = m;\n }\n }\n let a = Math.max(best - 5, 20);\n let b = Math.min(best + 5, 1000);\n const g = 0.61803398875;\n for (let i = 0; i < 60; i++) {\n const c = b - g * (b - a);\n const d = a + g * (b - a);\n if (dist(c) < dist(d)) b = d;\n else a = c;\n }\n const kelvin = 1e6 / ((a + b) / 2);\n const [lu, lv] = locusUv(kelvin);\n const [nu, nv] = locusNormal(kelvin);\n const duv = (u - lu) * nu + (v - lv) * nv;\n return { kelvin, tint: duv * TINT_SCALE };\n}\n\n// ---------------------------------------------------------------------------\n// Relative white balance for rendered (JPEG / PNG / WebP) sources\n// ---------------------------------------------------------------------------\n\n/** Rendered images carry no as-shot white: \"as shot\" is 6500 K / tint 0 and maps to the identity. */\nexport const AS_SHOT_KELVIN = 6500;\n/** Mireds per unit of the `temperature` slider (−100…100). */\nexport const MIRED_PER_TEMPERATURE_UNIT = 1;\nconst AS_SHOT_MIRED = 1e6 / AS_SHOT_KELVIN;\n\n/**\n * Maps the `temperature` slider (−100 cool … +100 warm) to the Kelvin white-balance setting:\n * one mired per unit around 6500 K, so 0 → 6500 K, +100 → ~18 570 K (a strong warming\n * correction), −100 → ~3 940 K (a strong cooling correction). Mireds are perceptually even,\n * so equal slider steps look like equal changes.\n */\nexport function temperatureToKelvin(temperature: number): number {\n return 1e6 / (AS_SHOT_MIRED - temperature * MIRED_PER_TEMPERATURE_UNIT);\n}\n\n/** Inverse of {@link temperatureToKelvin}. */\nexport function kelvinToTemperature(kelvin: number): number {\n return (AS_SHOT_MIRED - 1e6 / kelvin) / MIRED_PER_TEMPERATURE_UNIT;\n}\n\nconst AS_SHOT_WB_INV: Matrix3 = invertMatrix3(wbMatrix(tempTintToXy(AS_SHOT_KELVIN, 0))) ?? IDENTITY_MATRIX3;\n\n/**\n * White-balance matrix (linear sRGB) for the `temperature` / `tint` sliders, relative to\n * \"as shot\": the identity at 0 / 0. Normalised so neutral luminance is preserved (white\n * balance doesn't change exposure).\n */\nexport function whiteBalanceMatrix(temperature: number, tint = 0): Matrix3 {\n if (!temperature && !tint) return [...IDENTITY_MATRIX3];\n const set = wbMatrix(tempTintToXy(temperatureToKelvin(temperature), tint));\n const m = mulMatrix3(set, AS_SHOT_WB_INV);\n const g = applyMatrix3(m, [1, 1, 1]);\n const y = g[0] * LUMA_709[0] + g[1] * LUMA_709[1] + g[2] * LUMA_709[2];\n return mulMatrix3(m, diag3(1 / y, 1 / y, 1 / y));\n}\n\n/**\n * Neutral-point eyedropper: the `temperature` / `tint` that render the sampled sRGB colour\n * (0–255 per channel, as it appears in the unadjusted image) neutral. Results are clamped to\n * the slider range −100…100.\n */\nexport function whiteBalanceFromSample(\n rgb: readonly [number, number, number] | { r: number; g: number; b: number }\n): { temperature: number; tint: number } {\n const [r, g, b] = Array.isArray(rgb) ? rgb : [(rgb as any).r, (rgb as any).g, (rgb as any).b];\n const lin: [number, number, number] = [r, g, b].map((c) => srgbToLinear(Math.min(255, Math.max(0, c)) / 255)) as [\n number,\n number,\n number,\n ];\n if (lin[0] + lin[1] + lin[2] <= 1e-6) return { temperature: 0, tint: 0 };\n // Under relative WB the matrix is wb(set) · wb(asShot)⁻¹, so the sample is neutral when the\n // chosen source white is the chromaticity of wb(asShot)⁻¹ · sample.\n const src = linearSrgbToXy(applyMatrix3(AS_SHOT_WB_INV, lin));\n const { kelvin, tint } = xyToTempTint(src);\n const clamp = (v: number) => Math.max(-100, Math.min(100, v));\n return { temperature: clamp(kelvinToTemperature(kelvin)), tint: clamp(tint) };\n}\n\n// ---------------------------------------------------------------------------\n// Tone curve (display-referred, identity at neutral)\n// ---------------------------------------------------------------------------\n\n/** Number of intervals in a tone LUT (the table has `TONE_LUT_SIZE + 1` entries). */\nexport const TONE_LUT_SIZE = 4096;\nconst GREY = 0.18;\nconst GREY_P = Math.pow(GREY, 1 / 2.2);\n/** Linear value where the highlight shoulder starts when there is headroom above 1. */\nconst SHOULDER_KNEE = 0.6;\n\n/**\n * The process 2 tone curve for one linear input value in `[0, headroom]`:\n *\n * 1. A highlight shoulder (extended Reinhard with white point `headroom`) above a knee of 0.6\n * rolls values above 1 (after exposure / white balance) back into range instead of clipping.\n * With no headroom (`headroom = 1`) it is exactly the identity.\n * 2. In a gamma-2.2 perceptual domain, contrast is an S-curve anchored at 0, middle grey and 1\n * (as `ToneMap::display`), and brightness a midtone lift anchored at 0 and 1.\n *\n * `contrast` and `brightness` are −100…100; both 0 with `headroom = 1` is the identity.\n */\nexport function toneCurve(y: number, contrast: number, brightness: number, headroom = 1): number {\n if (!(y > 0)) return 0;\n const h = Math.max(1, headroom);\n let o = Math.min(y, h);\n if (h > 1 && o > SHOULDER_KNEE) {\n const span = 1 - SHOULDER_KNEE;\n const x = (o - SHOULDER_KNEE) / span;\n const X = (h - SHOULDER_KNEE) / span;\n o = SHOULDER_KNEE + span * ((x * (1 + x / (X * X))) / (1 + x));\n }\n if (contrast === 0 && brightness === 0) return Math.min(1, o);\n let p = Math.pow(Math.min(1, o), 1 / 2.2);\n const c = contrast / 100;\n if (c !== 0) {\n p += c * 0.4 * (p - GREY_P) * (1 - (2 * p - 1) ** 2);\n }\n const b = brightness / 100;\n if (b !== 0) {\n // Smooth midtone lift that leaves black and white in place (slope stays positive).\n p += b * 0.8 * p * (1 - p);\n }\n return Math.pow(Math.min(1, Math.max(0, p)), 2.2);\n}\n\n/** Tabulates {@link toneCurve} over `[0, headroom]` in {@link TONE_LUT_SIZE} steps. */\nexport function buildToneLut(contrast: number, brightness: number, headroom = 1): Float32Array {\n const h = Math.max(1, headroom);\n const lut = new Float32Array(TONE_LUT_SIZE + 1);\n for (let i = 0; i <= TONE_LUT_SIZE; i++) {\n lut[i] = toneCurve((h * i) / TONE_LUT_SIZE, contrast, brightness, h);\n }\n return lut;\n}\n\n/** Linearly interpolated lookup into a LUT from {@link buildToneLut}. */\nexport function sampleToneLut(lut: Float32Array, headroom: number, y: number): number {\n if (!(y > 0)) return lut[0];\n const n = lut.length - 1;\n const f = (y * n) / Math.max(1, headroom);\n if (f >= n) return lut[n];\n const i = f | 0;\n return lut[i] + (lut[i + 1] - lut[i]) * (f - i);\n}\n","// Portions ported from photocraft-main/crates/color/src/blend.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\n/**\n * Photoshop blend modes on straight (non-premultiplied) 0..1 colours.\n *\n * Formulas follow the W3C Compositing / ISO 32000 definitions, with Photoshop's variants where\n * they differ (Soft Light, Vivid / Linear / Pin Light, Hard Mix, Linear Burn / Dodge, Subtract,\n * Divide, Darker / Lighter Color), and the hardened `ClipColor` for the non-separable modes.\n */\n\nexport type BlendMode =\n | 'normal'\n | 'darken'\n | 'multiply'\n | 'color-burn'\n | 'linear-burn'\n | 'darker-color'\n | 'lighten'\n | 'screen'\n | 'color-dodge'\n | 'linear-dodge'\n | 'lighter-color'\n | 'overlay'\n | 'soft-light'\n | 'hard-light'\n | 'vivid-light'\n | 'linear-light'\n | 'pin-light'\n | 'hard-mix'\n | 'difference'\n | 'exclusion'\n | 'subtract'\n | 'divide'\n | 'hue'\n | 'saturation'\n | 'color'\n | 'luminosity';\n\nexport interface BlendModeInfo {\n id: BlendMode;\n label: string;\n /** Canvas `globalCompositeOperation` with the same maths, when there is one. */\n canvas: GlobalCompositeOperation | null;\n}\n\n/** Every blend mode, in Photoshop's menu order. */\nexport const BLEND_MODES: readonly BlendModeInfo[] = [\n { id: 'normal', label: 'Normal', canvas: 'source-over' },\n { id: 'darken', label: 'Darken', canvas: 'darken' },\n { id: 'multiply', label: 'Multiply', canvas: 'multiply' },\n { id: 'color-burn', label: 'Color Burn', canvas: 'color-burn' },\n { id: 'linear-burn', label: 'Linear Burn', canvas: null },\n { id: 'darker-color', label: 'Darker Color', canvas: null },\n { id: 'lighten', label: 'Lighten', canvas: 'lighten' },\n { id: 'screen', label: 'Screen', canvas: 'screen' },\n { id: 'color-dodge', label: 'Color Dodge', canvas: 'color-dodge' },\n { id: 'linear-dodge', label: 'Linear Dodge (Add)', canvas: null },\n { id: 'lighter-color', label: 'Lighter Color', canvas: null },\n { id: 'overlay', label: 'Overlay', canvas: 'overlay' },\n // Canvas soft-light is the W3C formula, not Photoshop's: use the scalar path.\n { id: 'soft-light', label: 'Soft Light', canvas: null },\n { id: 'hard-light', label: 'Hard Light', canvas: 'hard-light' },\n { id: 'vivid-light', label: 'Vivid Light', canvas: null },\n { id: 'linear-light', label: 'Linear Light', canvas: null },\n { id: 'pin-light', label: 'Pin Light', canvas: null },\n { id: 'hard-mix', label: 'Hard Mix', canvas: null },\n { id: 'difference', label: 'Difference', canvas: 'difference' },\n { id: 'exclusion', label: 'Exclusion', canvas: 'exclusion' },\n { id: 'subtract', label: 'Subtract', canvas: null },\n { id: 'divide', label: 'Divide', canvas: null },\n { id: 'hue', label: 'Hue', canvas: 'hue' },\n { id: 'saturation', label: 'Saturation', canvas: 'saturation' },\n { id: 'color', label: 'Color', canvas: 'color' },\n { id: 'luminosity', label: 'Luminosity', canvas: 'luminosity' },\n];\n\nconst BLEND_INFO = new Map<string, BlendModeInfo>(BLEND_MODES.map((m) => [m.id, m]));\n\nexport function isBlendMode(value: unknown): value is BlendMode {\n return typeof value === 'string' && BLEND_INFO.has(value);\n}\n\n/** A stored blend mode, or `normal` for a missing / unknown value. */\nexport function normalizeBlendMode(value: unknown): BlendMode {\n return isBlendMode(value) ? value : 'normal';\n}\n\n/**\n * The canvas composite operation that implements `mode` exactly, or `null` when the canvas has\n * none (draw through {@link blendImageData} instead).\n */\nexport function canvasCompositeOperation(mode: BlendMode | undefined): GlobalCompositeOperation | null {\n return BLEND_INFO.get(mode ?? 'normal')?.canvas ?? null;\n}\n\n/** Whether a mode works on whole colours (hue, saturation, colour, luminosity, darker / lighter colour). */\nexport function isSeparableBlendMode(mode: BlendMode): boolean {\n return !(\n mode === 'hue' ||\n mode === 'saturation' ||\n mode === 'color' ||\n mode === 'luminosity' ||\n mode === 'darker-color' ||\n mode === 'lighter-color'\n );\n}\n\nfunction colorBurn(cb: number, cs: number): number {\n if (cb >= 1) return 1;\n if (cs <= 0) return 0;\n return 1 - Math.min(1, (1 - cb) / cs);\n}\n\nfunction colorDodge(cb: number, cs: number): number {\n if (cb <= 0) return 0;\n if (cs >= 1) return 1;\n return Math.min(1, cb / (1 - cs));\n}\n\nfunction hardLight(cb: number, cs: number): number {\n if (cs <= 0.5) return cb * 2 * cs;\n const s = 2 * cs - 1;\n return cb + s - cb * s;\n}\n\n/** Photoshop's Soft Light (differs from W3C in the upper half). */\nfunction softLight(cb: number, cs: number): number {\n return cs <= 0.5\n ? 2 * cb * cs + cb * cb * (1 - 2 * cs)\n : 2 * cb * (1 - cs) + Math.sqrt(Math.max(0, cb)) * (2 * cs - 1);\n}\n\nfunction vividLightHardMix(cb: number, cs: number): number {\n const EDGE = 1e-4;\n if (cs <= 0.5) {\n if (cb >= 1 - EDGE) return 1;\n if (cs <= 0) return 0;\n return 1 - Math.min(1, (1 - cb) / (2 * cs));\n }\n if (cb <= EDGE) return 0;\n if (cs >= 1) return 1;\n return Math.min(1, cb / (2 * (1 - cs)));\n}\n\n/** Separable blend function `B(cb, cs)` of one channel. Non-separable modes return `cs`. */\nexport function blendChannel(mode: BlendMode, cb: number, cs: number): number {\n switch (mode) {\n case 'normal':\n return cs;\n case 'darken':\n return Math.min(cb, cs);\n case 'multiply':\n return cb * cs;\n case 'color-burn':\n return colorBurn(cb, cs);\n case 'linear-burn':\n return Math.max(0, cb + cs - 1);\n case 'lighten':\n return Math.max(cb, cs);\n case 'screen':\n return cb + cs - cb * cs;\n case 'color-dodge':\n return colorDodge(cb, cs);\n case 'linear-dodge':\n return Math.min(1, cb + cs);\n case 'overlay':\n return hardLight(cs, cb);\n case 'soft-light':\n return softLight(cb, cs);\n case 'hard-light':\n return hardLight(cb, cs);\n case 'vivid-light':\n if (cs <= 0) return 0;\n if (cs >= 1) return 1;\n return cs <= 0.5 ? colorBurn(cb, 2 * cs) : colorDodge(cb, 2 * (cs - 0.5));\n case 'linear-light':\n return Math.min(1, Math.max(0, cb + 2 * cs - 1));\n case 'pin-light':\n return cs <= 0.5 ? Math.min(cb, 2 * cs) : Math.max(cb, 2 * cs - 1);\n case 'hard-mix':\n return vividLightHardMix(cb, cs) >= 0.5 - 1e-6 ? 1 : 0;\n case 'difference':\n return Math.abs(cb - cs);\n case 'exclusion':\n return cb + cs - 2 * cb * cs;\n case 'subtract':\n return Math.max(0, cb - cs);\n case 'divide':\n if (cs <= 0) return cb <= 0 ? 0 : 1;\n return Math.min(1, cb / cs);\n default:\n return cs;\n }\n}\n\nexport type Rgb = [number, number, number];\nexport type Rgba = [number, number, number, number];\n\n/** Luminosity of the non-separable modes (W3C / ISO 32000 weights). */\nexport function blendLum(c: readonly number[]): number {\n return 0.3 * c[0] + 0.59 * c[1] + 0.11 * c[2];\n}\n\n/**\n * ClipColor, hardened: when the luminosity itself is out of range no colour of that luminosity\n * is in gamut, so the result is its grey (the spec formula turned such colours inside out and,\n * for greys, divided by rounding noise).\n */\nfunction clipColor(c: Rgb): Rgb {\n const l = blendLum(c);\n const n = Math.min(c[0], c[1], c[2]);\n const x = Math.max(c[0], c[1], c[2]);\n let out: Rgb = [c[0], c[1], c[2]];\n if (n < 0) {\n const d = l - n;\n out = out.map((v) => (l > 0 && d > 0 ? l + ((v - l) * l) / d : l)) as Rgb;\n }\n if (x > 1) {\n const d = x - l;\n out = out.map((v) => (l < 1 && d > 0 ? l + ((v - l) * (1 - l)) / d : l)) as Rgb;\n }\n return out;\n}\n\n/** `c` with its luminosity moved to `l`, clipped back into gamut towards grey (SetLum + ClipColor). */\nexport function setLum(c: readonly number[], l: number): Rgb {\n const d = l - blendLum(c);\n return clipColor([c[0] + d, c[1] + d, c[2] + d]);\n}\n\nfunction sat(c: readonly number[]): number {\n return Math.max(c[0], c[1], c[2]) - Math.min(c[0], c[1], c[2]);\n}\n\nfunction setSat(c: readonly number[], s: number): Rgb {\n const idx = [0, 1, 2].sort((a, b) => c[a] - c[b]);\n const [imin, imid, imax] = idx;\n const out: Rgb = [0, 0, 0];\n if (c[imax] > c[imin]) {\n out[imid] = ((c[imid] - c[imin]) * s) / (c[imax] - c[imin]);\n out[imax] = s;\n }\n out[imin] = 0;\n return out;\n}\n\n/** `B(Cb, Cs)` of a whole colour, including the non-separable modes. */\nexport function blendRgb(mode: BlendMode, cb: readonly number[], cs: readonly number[]): Rgb {\n switch (mode) {\n case 'hue':\n return setLum(setSat(cs, sat(cb)), blendLum(cb));\n case 'saturation':\n return setLum(setSat(cb, sat(cs)), blendLum(cb));\n case 'color':\n return setLum(cs, blendLum(cb));\n case 'luminosity':\n return setLum(cb, blendLum(cs));\n case 'darker-color':\n return blendLum(cs) < blendLum(cb) ? [cs[0], cs[1], cs[2]] : [cb[0], cb[1], cb[2]];\n case 'lighter-color':\n return blendLum(cs) > blendLum(cb) ? [cs[0], cs[1], cs[2]] : [cb[0], cb[1], cb[2]];\n default:\n return [blendChannel(mode, cb[0], cs[0]), blendChannel(mode, cb[1], cs[1]), blendChannel(mode, cb[2], cs[2])];\n }\n}\n\n/**\n * Composites a straight-alpha `source` over a straight-alpha `backdrop` (both RGBA in 0..1) with a\n * blend mode and an extra `alpha` (opacity), using the W3C general formula:\n * `αo = αs + αb(1 − αs)`, `αo·Co = (1 − αs)·αb·Cb + (1 − αb)·αs·Cs + αs·αb·B(Cb, Cs)`.\n */\nexport function blendPixel(mode: BlendMode, backdrop: readonly number[], source: readonly number[], alpha = 1): Rgba {\n const ab = backdrop[3] ?? 1;\n const as = (source[3] ?? 1) * alpha;\n if (!(as > 0)) return [backdrop[0], backdrop[1], backdrop[2], ab];\n const b = blendRgb(mode, backdrop, source);\n const ao = as + ab * (1 - as);\n if (ao <= 0) return [0, 0, 0, 0];\n const out: Rgba = [0, 0, 0, ao];\n for (let i = 0; i < 3; i++) {\n out[i] = ((1 - as) * ab * backdrop[i] + (1 - ab) * as * source[i] + as * ab * b[i]) / ao;\n }\n return out;\n}\n\n/**\n * Blends `source` into `backdrop` in place (8-bit straight RGBA of the same size) with\n * {@link blendPixel}. The scalar fallback for modes the canvas cannot composite.\n */\nexport function blendImageData(backdrop: ImageData, source: ImageData, mode: BlendMode, alpha = 1): void {\n const d = backdrop.data;\n const s = source.data;\n const len = Math.min(d.length, s.length);\n const cb = [0, 0, 0, 0];\n const cs = [0, 0, 0, 0];\n for (let i = 0; i < len; i += 4) {\n if (s[i + 3] === 0) continue;\n for (let k = 0; k < 4; k++) {\n cb[k] = d[i + k] / 255;\n cs[k] = s[i + k] / 255;\n }\n const o = blendPixel(mode, cb, cs, alpha);\n d[i] = Math.round(o[0] * 255);\n d[i + 1] = Math.round(o[1] * 255);\n d[i + 2] = Math.round(o[2] * 255);\n d[i + 3] = Math.round(o[3] * 255);\n }\n}\n","// Portions ported from photocraft-main/crates/compose/src/adjust.rs, photocraft-main/crates/doc/src/adjust.rs and photocraft-main/crates/color/src/convert.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\nimport type {\n AdjustmentKind,\n AdjustmentLayer,\n AdjustmentLayerOf,\n AdjustmentParamsMap,\n BlackWhiteParams,\n ColorBalanceParams,\n ColorBalanceTone,\n CurvePoint,\n HueRange,\n HueSaturationParams,\n LevelsChannel,\n PhotoFilterParams,\n VibranceParams,\n} from './types';\nimport { type BlendMode, blendRgb, normalizeBlendMode, setLum } from './blend';\nimport { linearToSrgb, srgbToLinear } from './color';\n\n/**\n * Adjustment layers: Photoshop-matching evaluation on encoded sRGB colours in 0..1.\n *\n * Every layer is compiled once per parameter change into a per-pixel function (per-channel kinds\n * into three 4096-entry LUTs); {@link applyAdjustmentLayers} runs the stack on an ImageData.\n */\n\ntype Rgb = [number, number, number];\n\n/** Entries in a tone LUT (curves, levels, colour balance). */\nexport const ADJUSTMENT_LUT_SIZE = 4096;\n\nconst clamp01 = (v: number) => (v <= 0 ? 0 : v >= 1 ? 1 : v);\nconst finite = (v: unknown, fallback: number) => (typeof v === 'number' && Number.isFinite(v) ? v : fallback);\nconst clampTo = (v: unknown, lo: number, hi: number, fallback: number) => Math.min(hi, Math.max(lo, finite(v, fallback)));\nconst remEuclid = (a: number, b: number) => ((a % b) + b) % b;\n\n/** Linear interpolation into a 0..1-domain LUT. */\nexport function sampleLut(table: ArrayLike<number>, v: number): number {\n const n = table.length - 1;\n const x = clamp01(v) * n;\n const i = Math.floor(x);\n const j = Math.min(i + 1, n);\n const f = x - i;\n return table[i] * (1 - f) + table[j] * f;\n}\n\n// ---------------------------------------------------------------------------\n// Kinds, labels, defaults\n// ---------------------------------------------------------------------------\n\nexport interface AdjustmentKindInfo {\n kind: AdjustmentKind;\n label: string;\n}\n\nexport const ADJUSTMENT_KINDS: readonly AdjustmentKindInfo[] = [\n { kind: 'curves', label: 'Curves' },\n { kind: 'levels', label: 'Levels' },\n { kind: 'hueSaturation', label: 'Hue/Saturation' },\n { kind: 'vibrance', label: 'Vibrance' },\n { kind: 'colorBalance', label: 'Color Balance' },\n { kind: 'blackWhite', label: 'Black & White' },\n { kind: 'photoFilter', label: 'Photo Filter' },\n { kind: 'invert', label: 'Invert' },\n { kind: 'posterize', label: 'Posterize' },\n { kind: 'threshold', label: 'Threshold' },\n];\n\nconst KIND_LABELS = new Map(ADJUSTMENT_KINDS.map((k) => [k.kind, k.label]));\n\nexport function isAdjustmentKind(value: unknown): value is AdjustmentKind {\n return typeof value === 'string' && KIND_LABELS.has(value as AdjustmentKind);\n}\n\nexport function adjustmentKindLabel(kind: AdjustmentKind): string {\n return KIND_LABELS.get(kind) ?? kind;\n}\n\nexport const HUE_RANGE_LABELS = ['Reds', 'Yellows', 'Greens', 'Cyans', 'Blues', 'Magentas'] as const;\n\n/** The neutral range `i` (0 reds … 5 magentas): fully on for 30° around its centre, fading over 30° each side. */\nexport function neutralHueRange(i: number): HueRange {\n const c = 60 * i;\n return { hue: 0, saturation: 0, lightness: 0, bounds: [c - 45, c - 15, c + 15, c + 45] };\n}\n\nexport const identityCurve = (): CurvePoint[] => [\n { input: 0, output: 0 },\n { input: 255, output: 255 },\n];\n\nexport const identityLevels = (): LevelsChannel => ({ inBlack: 0, inWhite: 255, gamma: 1, outBlack: 0, outWhite: 255 });\n\n/** Neutral parameters of every kind (fresh objects on every call). */\nexport function defaultAdjustmentParams<K extends AdjustmentKind>(kind: K): AdjustmentParamsMap[K] {\n const defaults: { [P in AdjustmentKind]: () => AdjustmentParamsMap[P] } = {\n curves: () => ({ master: identityCurve(), red: identityCurve(), green: identityCurve(), blue: identityCurve() }),\n levels: () => ({ master: identityLevels(), red: identityLevels(), green: identityLevels(), blue: identityLevels() }),\n hueSaturation: () => ({\n hue: 0,\n saturation: 0,\n lightness: 0,\n colorize: false,\n ranges: [0, 1, 2, 3, 4, 5].map(neutralHueRange),\n }),\n vibrance: () => ({ vibrance: 0, saturation: 0 }),\n colorBalance: () => ({ shadows: [0, 0, 0], midtones: [0, 0, 0], highlights: [0, 0, 0], preserveLuminosity: true }),\n blackWhite: () => ({ reds: 40, yellows: 60, greens: 40, cyans: 60, blues: 20, magentas: 80, tint: null }),\n invert: () => ({}) as Record<string, never>,\n posterize: () => ({ levels: 4 }),\n threshold: () => ({ level: 128 }),\n photoFilter: () => ({ color: '#ec8a00', density: 25, preserveLuminosity: true }),\n };\n return defaults[kind]() as AdjustmentParamsMap[K];\n}\n\nlet layerCounter = 0;\n\n/** A new layer of `kind` with neutral (or the given) parameters, enabled, opacity 1, normal blend. */\nexport function createAdjustmentLayer<K extends AdjustmentKind>(\n kind: K,\n options: {\n id?: string;\n name?: string;\n params?: Partial<AdjustmentParamsMap[K]>;\n enabled?: boolean;\n opacity?: number;\n blend?: BlendMode;\n } = {}\n): AdjustmentLayerOf<K> {\n const raw = {\n id: options.id ?? `adj_${Date.now().toString(36)}_${(++layerCounter).toString(36)}`,\n kind,\n name: options.name,\n params: { ...defaultAdjustmentParams(kind), ...(options.params ?? {}) },\n enabled: options.enabled ?? true,\n opacity: options.opacity ?? 1,\n blend: options.blend ?? 'normal',\n };\n return normalizeAdjustmentLayer(raw) as AdjustmentLayerOf<K>;\n}\n\n// ---------------------------------------------------------------------------\n// Normalisation of stored layers\n// ---------------------------------------------------------------------------\n\nconst HEX = /^#[0-9a-f]{6}$/i;\n\nfunction normCurve(points: unknown): CurvePoint[] {\n if (!Array.isArray(points)) return identityCurve();\n const out = points\n .filter((p) => p && typeof p === 'object')\n .map((p) => ({ input: clampTo(p.input, 0, 255, 0), output: clampTo(p.output, 0, 255, 0) }))\n .sort((a, b) => a.input - b.input);\n return out.length >= 2 ? out : identityCurve();\n}\n\nfunction normLevels(ch: unknown): LevelsChannel {\n const c = (ch && typeof ch === 'object' ? ch : {}) as Partial<LevelsChannel>;\n return {\n inBlack: clampTo(c.inBlack, 0, 254, 0),\n inWhite: clampTo(c.inWhite, 1, 255, 255),\n gamma: clampTo(c.gamma, 0.1, 9.99, 1),\n outBlack: clampTo(c.outBlack, 0, 255, 0),\n outWhite: clampTo(c.outWhite, 0, 255, 255),\n };\n}\n\nfunction normTone(t: unknown): ColorBalanceTone {\n const a = Array.isArray(t) ? t : [];\n return [clampTo(a[0], -100, 100, 0), clampTo(a[1], -100, 100, 0), clampTo(a[2], -100, 100, 0)];\n}\n\nfunction normParams(kind: AdjustmentKind, raw: unknown): AdjustmentParamsMap[AdjustmentKind] {\n const p = (raw && typeof raw === 'object' ? raw : {}) as Record<string, any>;\n const d = defaultAdjustmentParams(kind) as Record<string, any>;\n switch (kind) {\n case 'curves':\n return { master: normCurve(p.master), red: normCurve(p.red), green: normCurve(p.green), blue: normCurve(p.blue) };\n case 'levels':\n return { master: normLevels(p.master), red: normLevels(p.red), green: normLevels(p.green), blue: normLevels(p.blue) };\n case 'hueSaturation': {\n const ranges: HueRange[] = [0, 1, 2, 3, 4, 5].map((i) => {\n const r = Array.isArray(p.ranges) && p.ranges[i] && typeof p.ranges[i] === 'object' ? p.ranges[i] : {};\n const n = neutralHueRange(i);\n const b = Array.isArray(r.bounds) && r.bounds.length === 4 && r.bounds.every((v: unknown) => Number.isFinite(v)) ? r.bounds : n.bounds;\n return {\n hue: clampTo(r.hue, -180, 180, 0),\n saturation: clampTo(r.saturation, -100, 100, 0),\n lightness: clampTo(r.lightness, -100, 100, 0),\n bounds: [b[0], b[1], b[2], b[3]] as [number, number, number, number],\n };\n });\n const colorize = p.colorize === true;\n return {\n hue: colorize ? clampTo(p.hue, 0, 360, 0) : clampTo(p.hue, -180, 180, 0),\n saturation: clampTo(p.saturation, -100, 100, 0),\n lightness: clampTo(p.lightness, -100, 100, 0),\n colorize,\n ranges,\n } satisfies HueSaturationParams;\n }\n case 'vibrance':\n return { vibrance: clampTo(p.vibrance, -100, 100, 0), saturation: clampTo(p.saturation, -100, 100, 0) } satisfies VibranceParams;\n case 'colorBalance':\n return {\n shadows: normTone(p.shadows),\n midtones: normTone(p.midtones),\n highlights: normTone(p.highlights),\n preserveLuminosity: p.preserveLuminosity !== false,\n } satisfies ColorBalanceParams;\n case 'blackWhite': {\n const out = {} as BlackWhiteParams;\n for (const k of ['reds', 'yellows', 'greens', 'cyans', 'blues', 'magentas'] as const) out[k] = clampTo(p[k], -200, 300, d[k]);\n out.tint = typeof p.tint === 'string' && HEX.test(p.tint) ? p.tint.toLowerCase() : null;\n return out;\n }\n case 'photoFilter':\n return {\n color: typeof p.color === 'string' && HEX.test(p.color) ? p.color.toLowerCase() : d.color,\n density: clampTo(p.density, 0, 100, d.density),\n preserveLuminosity: p.preserveLuminosity !== false,\n } satisfies PhotoFilterParams;\n case 'posterize':\n return { levels: Math.round(clampTo(p.levels, 2, 255, 4)) };\n case 'threshold':\n return { level: Math.round(clampTo(p.level, 1, 255, 128)) };\n case 'invert':\n return {} as Record<string, never>;\n }\n}\n\n/**\n * A clean, deep-copied layer from stored or hand-written data: missing fields get neutral\n * defaults, numbers are clamped to their ranges. `null` for an unknown kind.\n */\nexport function normalizeAdjustmentLayer(raw: unknown): AdjustmentLayer | null {\n if (!raw || typeof raw !== 'object') return null;\n const r = raw as Record<string, any>;\n if (!isAdjustmentKind(r.kind)) return null;\n const layer: Record<string, unknown> = {\n id: typeof r.id === 'string' && r.id ? r.id : `adj_${Date.now().toString(36)}_${(++layerCounter).toString(36)}`,\n kind: r.kind,\n enabled: r.enabled !== false,\n opacity: clampTo(r.opacity, 0, 1, 1),\n blend: normalizeBlendMode(r.blend),\n params: normParams(r.kind, r.params),\n };\n if (typeof r.name === 'string' && r.name) layer.name = r.name;\n return layer as unknown as AdjustmentLayer;\n}\n\n/** Normalises a stored layer list (drops unknown kinds, de-duplicates ids). */\nexport function normalizeAdjustmentLayers(raw: unknown): AdjustmentLayer[] {\n if (!Array.isArray(raw)) return [];\n const seen = new Set<string>();\n const out: AdjustmentLayer[] = [];\n for (const item of raw) {\n const layer = normalizeAdjustmentLayer(item);\n if (!layer) continue;\n while (seen.has(layer.id)) layer.id = `${layer.id}_${(++layerCounter).toString(36)}`;\n seen.add(layer.id);\n out.push(layer);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Curves\n// ---------------------------------------------------------------------------\n\n/**\n * Photoshop curve: a natural cubic spline through the points (0..1 in and out; it may overshoot\n * between points, as Photoshop's does), constant outside the first / last point, clamped to\n * 0..1, sampled into a LUT. Fewer than two distinct points: the identity.\n */\nexport function curveLut(points: ReadonlyArray<{ input: number; output: number }>, size = ADJUSTMENT_LUT_SIZE): Float32Array {\n const pts = points\n .filter((p) => Number.isFinite(p.input) && Number.isFinite(p.output))\n .map((p) => [p.input, p.output] as [number, number])\n .sort((a, b) => a[0] - b[0]);\n const dedup: [number, number][] = [];\n for (const p of pts) {\n if (dedup.length && Math.abs(dedup[dedup.length - 1][0] - p[0]) < 1e-6) continue;\n dedup.push(p);\n }\n const out = new Float32Array(size);\n const n = dedup.length;\n if (n < 2) {\n for (let k = 0; k < size; k++) out[k] = k / (size - 1);\n return out;\n }\n const x = dedup.map((p) => p[0]);\n const y = dedup.map((p) => p[1]);\n // Second derivatives of the natural spline (tridiagonal solve).\n const m2 = new Float64Array(n);\n if (n > 2) {\n const c = new Float64Array(n);\n const d = new Float64Array(n);\n for (let i = 1; i < n - 1; i++) {\n const h0 = x[i] - x[i - 1];\n const h1 = x[i + 1] - x[i];\n const a = h0 / 6;\n const b = (h0 + h1) / 3;\n const cc = h1 / 6;\n const r = (y[i + 1] - y[i]) / h1 - (y[i] - y[i - 1]) / h0;\n const denom = b - a * c[i - 1];\n c[i] = cc / denom;\n d[i] = (r - a * d[i - 1]) / denom;\n }\n for (let i = n - 2; i >= 1; i--) m2[i] = d[i] - c[i] * m2[i + 1];\n }\n let seg = 0;\n for (let k = 0; k < size; k++) {\n const xv = k / (size - 1);\n if (xv <= x[0]) {\n out[k] = clamp01(y[0]);\n continue;\n }\n if (xv >= x[n - 1]) {\n out[k] = clamp01(y[n - 1]);\n continue;\n }\n while (seg < n - 2 && xv > x[seg + 1]) seg++;\n const x0 = x[seg], x1 = x[seg + 1];\n const h = x1 - x0;\n const a = (x1 - xv) / h;\n const b = (xv - x0) / h;\n const v = a * y[seg] + b * y[seg + 1] + ((a * a * a - a) * m2[seg] + (b * b * b - b) * m2[seg + 1]) * (h * h) / 6;\n out[k] = clamp01(v);\n }\n return out;\n}\n\n/** {@link curveLut} for Curves points in levels (0..255). */\nexport function curveLutFromLevels(points: readonly CurvePoint[]): Float32Array {\n return curveLut(points.map((p) => ({ input: p.input / 255, output: p.output / 255 })));\n}\n\n// ---------------------------------------------------------------------------\n// Levels\n// ---------------------------------------------------------------------------\n\n/** A Levels record with values in 0..1 (as `levelsValue` takes them). */\nexport interface UnitLevels {\n inBlack: number;\n inWhite: number;\n gamma: number;\n outBlack: number;\n outWhite: number;\n}\n\nconst toUnitLevels = (c: LevelsChannel): UnitLevels => ({\n inBlack: c.inBlack / 255,\n inWhite: c.inWhite / 255,\n gamma: c.gamma,\n outBlack: c.outBlack / 255,\n outWhite: c.outWhite / 255,\n});\n\n/**\n * One Levels record on `v` (0..1). With `quantum` (8-bit: 255) Photoshop works on whole levels:\n * the input is a level and the stretch is rounded (half up) before the gamma. A gamma above 1 has\n * Photoshop's soft shadow toe: a p-norm soft-min of the power curve and a line of slope ≈ 2^gamma.\n */\nexport function levelsValue(ch: UnitLevels, v: number, quantum?: number): number {\n const range = Math.max(1e-6, ch.inWhite - ch.inBlack);\n let u: number;\n if (quantum !== undefined && Number.isFinite(quantum) && quantum >= 1) {\n const q = quantum;\n const vq = Math.round(v * q) / q;\n u = Math.floor(clamp01((vq - ch.inBlack) / range) * q + 0.5 + 1e-3) / q;\n } else {\n u = clamp01((v - ch.inBlack) / range);\n }\n const g = Math.max(0.01, ch.gamma);\n let t: number;\n if (g > 1) {\n const power = Math.pow(u, 1 / g);\n const line = 0.93 * Math.pow(2, g) * u;\n if (power <= 1e-6 || line <= 1e-6) t = Math.min(power, line);\n else {\n const p = 10;\n t = Math.pow(Math.pow(power, -p) + Math.pow(line, -p), -1 / p);\n }\n } else {\n t = Math.pow(u, 1 / g);\n }\n return ch.outBlack + t * (ch.outWhite - ch.outBlack);\n}\n\n// ---------------------------------------------------------------------------\n// HSL and Hue/Saturation\n// ---------------------------------------------------------------------------\n\n/** RGB (0..1) → HSL with hue in turns (0..1). */\nexport function rgbToHsl(c: readonly number[]): [number, number, number] {\n const max = Math.max(c[0], c[1], c[2]);\n const min = Math.min(c[0], c[1], c[2]);\n const l = (max + min) / 2;\n if (Math.abs(max - min) < 1e-7) return [0, 0, l];\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n let h: number;\n if (max === c[0]) h = remEuclid((c[1] - c[2]) / d, 6);\n else if (max === c[1]) h = (c[2] - c[0]) / d + 2;\n else h = (c[0] - c[1]) / d + 4;\n return [h / 6, s, l];\n}\n\nexport function hslToRgb(h: number, s: number, l: number): Rgb {\n if (s <= 0) return [l, l, l];\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n const f = (t: number) => {\n t = remEuclid(t, 1);\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 0.5) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n return [f(h + 1 / 3), f(h), f(h - 1 / 3)];\n}\n\n/** How much a pixel of hue `deg` belongs to `range` (0..1): a trapezoid that may wrap past 0/360. */\nexport function hueRangeWeight(range: Pick<HueRange, 'bounds'>, deg: number): number {\n const [a, b0, c0, d0] = range.bounds;\n const rel = (x: number) => (Number.isFinite(x) && Number.isFinite(a) ? remEuclid(x - a, 360) : 0);\n const b = rel(b0);\n const c = Math.max(rel(c0), b);\n const d = Math.max(rel(d0), c);\n const h = rel(deg);\n if (h <= b) return b <= 0 ? 1 : h / b;\n if (h <= c) return 1;\n if (h <= d) return d <= c ? 1 : (d - h) / (d - c);\n return 0;\n}\n\nconst isNeutralRange = (r: HueRange) => r.hue === 0 && r.saturation === 0 && r.lightness === 0;\n\n/** Range edits as three hue-indexed tables (hue shift in degrees, saturation and lightness as fractions). */\nexport function hueRangeTables(ranges: readonly HueRange[]): [Float32Array, Float32Array, Float32Array] {\n const n = ADJUSTMENT_LUT_SIZE;\n const t: [Float32Array, Float32Array, Float32Array] = [new Float32Array(n), new Float32Array(n), new Float32Array(n)];\n const active = ranges.filter((r) => !isNeutralRange(r));\n for (let k = 0; k < n; k++) {\n const deg = (k / (n - 1)) * 360;\n for (const r of active) {\n const w = hueRangeWeight(r, deg);\n t[0][k] += w * r.hue;\n t[1][k] += (w * r.saturation) / 100;\n t[2][k] += (w * r.lightness) / 100;\n }\n }\n return t;\n}\n\n/**\n * One Hue/Saturation evaluation: hue shift in degrees, saturation and lightness in -1..1.\n * Lightness first, then hue and saturation (raising divides by 1 − s, lowering multiplies by\n * 1 + s). Colorize sets hue and saturation at the lightened lightness.\n */\nexport function hueSaturation(c: readonly number[], hue: number, s: number, l: number, colorize: boolean): Rgb {\n const lighten = (v: number) => (l > 0 ? v + (1 - v) * l : v * (1 + l));\n if (colorize) {\n const ll = rgbToHsl(c)[2];\n return hslToRgb(remEuclid(hue, 360) / 360, Math.min(1, Math.abs(s)), lighten(ll));\n }\n const [hh0, ss0, ll] = rgbToHsl([lighten(c[0]), lighten(c[1]), lighten(c[2])]);\n const hh = remEuclid(hh0 + hue / 360, 1);\n const ss = Math.min(1, Math.max(0, s > 0 ? ss0 / Math.max(1 / 512, 1 - s) : ss0 * (1 + s)));\n return hslToRgb(hh, ss, ll);\n}\n\n/** A colour range's Lightness: towards the brightest channel when raised, the darkest when lowered. */\nexport function rangeLightness(c: readonly number[], l: number): Rgb {\n const k = Math.min(1, Math.max(-1, l));\n const target = k > 0 ? Math.max(c[0], c[1], c[2]) : Math.min(c[0], c[1], c[2]);\n const a = Math.abs(k);\n return [c[0] + (target - c[0]) * a, c[1] + (target - c[1]) * a, c[2] + (target - c[2]) * a];\n}\n\n// ---------------------------------------------------------------------------\n// Vibrance\n// ---------------------------------------------------------------------------\n\n/** Grey Vibrance › Saturation desaturates to (linear light; blue has no weight). */\nexport const VIBRANCE_GREY: readonly [number, number] = [0.288, 0.712];\nconst VIBRANCE_BOOST = [0.5001, 0.0887, 0.4374, 0.7573, -0.8113, 0.5154, 2.8026] as const;\n\nfunction vibranceSkin(h: number): number {\n if (h <= 30) return 1;\n if (h < 45) return (45 - h) / 15;\n if (h < 300) return 0;\n return (h - 300) / 60;\n}\n\nfunction hsvHue(c: readonly number[], mx: number, mn: number): number {\n const d = mx - mn;\n let h: number;\n if (mx === c[0]) h = remEuclid((c[1] - c[2]) / d, 6);\n else if (mx === c[1]) h = (c[2] - c[0]) / d + 2;\n else h = (c[0] - c[1]) / d + 4;\n return h * 60;\n}\n\n/** The Vibrance slider (`v` in -1..1) on a linear-light pixel: an HSV change that keeps the hue. */\nexport function vibranceLinear(c: Rgb, v: number): Rgb {\n const mx = Math.max(c[0], c[1], c[2]);\n const mn = Math.min(c[0], c[1], c[2]);\n if (mx <= 0 || mx - mn <= 1e-9) return c;\n const t = 1 - mn / mx;\n const shape = t * (1 - t) * (2 - t + t * t) * mx * Math.max(0, 1 - mx);\n let t2: number, v2: number;\n if (v < 0) {\n const a = -v;\n t2 = t * (1 - a / 4) * (1 - a + (a * t * (1 + t)) / 2);\n v2 = mx - a * shape;\n } else {\n const [c0, c1, p, q, r0, ra, rt] = VIBRANCE_BOOST;\n const w = vibranceSkin(hsvHue(c, mx, mn));\n const a = v * (1 - w) + 0.64 * Math.pow(v, 1.6) * w;\n const boost =\n (c0 * a + c1 * a * a) * Math.pow(t, p) * Math.pow(1 - t, q) * Math.exp((r0 + ra * a + rt * (1 - t)) * Math.max(0, 1 - mx));\n t2 = Math.min(1, t * (1 + boost));\n v2 = mx + (v / 4) * shape;\n }\n const m2 = v2 * (1 - t2);\n const k = (v2 - m2) / (mx - mn);\n return [m2 + (c[0] - mn) * k, m2 + (c[1] - mn) * k, m2 + (c[2] - mn) * k];\n}\n\n/** Photoshop's Vibrance on one encoded sRGB pixel (`v`, `s`: the sliders / 100). */\nexport function vibrancePixel(c: readonly number[], v: number, s: number): Rgb {\n let l: Rgb = [srgbToLinear(Math.max(0, c[0])), srgbToLinear(Math.max(0, c[1])), srgbToLinear(Math.max(0, c[2]))];\n if (v !== 0) l = vibranceLinear(l, v);\n if (s !== 0) {\n const g = VIBRANCE_GREY[0] * l[0] + VIBRANCE_GREY[1] * l[1];\n l = l.map((x) => Math.min(1, Math.max(0, g + (1 + s) * (x - g)))) as Rgb;\n }\n return l.map((x) => linearToSrgb(clamp01(x))) as Rgb;\n}\n\n// ---------------------------------------------------------------------------\n// Color Balance\n// ---------------------------------------------------------------------------\n\n/** How far one Color Balance slider at ±100 moves the black or white point. */\nconst BALANCE_LEVELS = 0.39;\n\n/**\n * Color Balance on channel `ch` (0 red, 1 green, 2 blue) of `v` (0..1); `tones` are the\n * shadows, midtones and highlights slider triples (-100..100). Highlights, shadows, then midtones.\n */\nexport function colorBalanceChannel(\n tones: readonly [readonly number[], readonly number[], readonly number[]],\n preserveLuminosity: boolean,\n ch: number,\n v: number\n): number {\n const [shadows, midtones, highlights] = tones;\n const black = (x: number, b: number) => Math.max(0, (x - b) / (1 - b));\n const white = (x: number, w: number) => Math.min(1, x / w);\n let out = clamp01(v);\n for (const [tone, sliders] of [\n [2, highlights],\n [0, shadows],\n [1, midtones],\n ] as const) {\n const a = [0, 1, 2].map((i) => Math.min(1, Math.max(-1, sliders[i] / 100)));\n if (preserveLuminosity) {\n const own = a[ch] ?? 0;\n const lo = Math.min(a[0], a[1], a[2]);\n const hi = Math.max(a[0], a[1], a[2]);\n if (tone === 0) out = black(out, BALANCE_LEVELS * (hi - own));\n else if (tone === 1) out = Math.pow(out, Math.pow(2, (hi + lo) / 2 - own));\n else out = white(out, 1 - BALANCE_LEVELS * (own - lo));\n continue;\n }\n const s = a[ch];\n if (s === 0) continue;\n if (tone === 1) out = Math.pow(out, Math.pow(2, -s));\n else if (tone === 0 && s < 0) out = Math.pow(black(out, BALANCE_LEVELS * -s), Math.pow(2, -s / 2));\n else if (tone === 2 && s > 0) out = Math.pow(white(out, 1 - BALANCE_LEVELS * s), Math.pow(2, -s / 2));\n else out = Math.pow(out, Math.pow(2, -s / 2));\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Black & White, Photo Filter, Posterize, Threshold\n// ---------------------------------------------------------------------------\n\n/**\n * Black & White grey: the smallest channel, plus the secondary part (middle − smallest) and the\n * primary part (largest − middle) weighted by the sliders (percent: reds, yellows, greens, cyans,\n * blues, magentas).\n */\nexport function blackWhiteGray(c: readonly number[], weights: readonly number[]): number {\n const [r, g, b] = c;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const mid = r + g + b - max - min;\n const primary = r >= g && r >= b ? 0 : g >= b ? 2 : 4;\n const secondary = b <= r && b <= g ? 1 : r <= g ? 3 : 5;\n return clamp01(min + ((mid - min) * weights[secondary]) / 100 + ((max - mid) * weights[primary]) / 100);\n}\n\n/** D50 white (ICC PCS). */\nconst D50 = [0.96422, 1.0, 0.82521] as const;\n/** Linear sRGB → D50 XYZ (Bradford-adapted, as in the ICC sRGB profile). */\nconst SRGB_TO_XYZ_D50 = [\n [0.436074, 0.385064, 0.14308],\n [0.222504, 0.716878, 0.060618],\n [0.013932, 0.097104, 0.714173],\n] as const;\n/** D50 XYZ → linear sRGB. */\nconst XYZ_D50_TO_SRGB = [\n [3.133856, -1.616867, -0.490615],\n [-0.978768, 1.916142, 0.033454],\n [0.071945, -0.228991, 1.405243],\n] as const;\n\n/**\n * Photo Filter's linear-light RGB matrix (row-major 3×3): the pixel's D50 XYZ, relative to white,\n * multiplied by the filter colour's mixed in by `density` (0..1). `normalizeY` keeps luminance Y.\n */\nexport function photoFilterMatrix(color: readonly number[], density: number, normalizeY = false): number[][] {\n const d = Number.isFinite(density) ? clamp01(density) : 0;\n const lin = [0, 1, 2].map((i) => srgbToLinear(clamp01(color[i])));\n const xyz = SRGB_TO_XYZ_D50.map((r) => r[0] * lin[0] + r[1] * lin[1] + r[2] * lin[2]);\n let s = [0, 1, 2].map((i) => 1 - d + (d * xyz[i]) / D50[i]);\n if (normalizeY && s[1] > 1e-6) {\n const y = s[1];\n s = s.map((v) => v / y);\n }\n return [0, 1, 2].map((r) =>\n [0, 1, 2].map((c) => XYZ_D50_TO_SRGB[r][0] * s[0] * SRGB_TO_XYZ_D50[0][c] + XYZ_D50_TO_SRGB[r][1] * s[1] * SRGB_TO_XYZ_D50[1][c] + XYZ_D50_TO_SRGB[r][2] * s[2] * SRGB_TO_XYZ_D50[2][c])\n );\n}\n\n/** Photoshop posterize: `levels` equal input bins over 0..255, outputs `floor(k·255 / (levels − 1))`. */\nexport function posterizeValue(v: number, levels: number): number {\n const n = Math.min(255, Math.max(2, Math.round(levels)));\n const x = Math.round(clamp01(v) * 255);\n const bin = Math.min(n - 1, Math.floor((x * n) / 256));\n return Math.floor((bin * 255) / (n - 1)) / 255;\n}\n\n/** Rec.601 luma (Photoshop's grey for Threshold). */\nexport const rgbToGray = (c: readonly number[]) => 0.299 * c[0] + 0.587 * c[1] + 0.114 * c[2];\n\n/** `#rrggbb` → 0..1 RGB (black for anything else). */\nexport function hexToRgb(hex: string): Rgb {\n if (!HEX.test(hex)) return [0, 0, 0];\n const n = parseInt(hex.slice(1), 16);\n return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255];\n}\n\n// ---------------------------------------------------------------------------\n// Compilation and evaluation\n// ---------------------------------------------------------------------------\n\n/** Mutates an encoded sRGB colour (0..1) in place. */\nexport type PixelOp = (c: Rgb) => void;\n\nfunction lutOp(luts: [Float32Array, Float32Array, Float32Array]): PixelOp {\n const [lr, lg, lb] = luts;\n return (c) => {\n c[0] = sampleLut(lr, c[0]);\n c[1] = sampleLut(lg, c[1]);\n c[2] = sampleLut(lb, c[2]);\n };\n}\n\nconst isIdentityCurve = (pts: readonly CurvePoint[]) =>\n pts.length === 2 && pts[0].input === 0 && pts[0].output === 0 && pts[1].input === 255 && pts[1].output === 255;\n\nconst isIdentityLevels = (c: LevelsChannel) =>\n c.inBlack === 0 && c.inWhite === 255 && c.gamma === 1 && c.outBlack === 0 && c.outWhite === 255;\n\n/** Quantum Levels works in (8-bit documents: whole levels). */\nconst LEVELS_QUANTUM = 255;\n\n/**\n * Per-channel LUTs of a Curves or Levels layer: each channel's record first, then the master.\n * `null` for any other kind.\n */\nexport function toneLuts(layer: AdjustmentLayer): [Float32Array, Float32Array, Float32Array] | null {\n const n = ADJUSTMENT_LUT_SIZE;\n if (layer.kind === 'curves') {\n const m = curveLutFromLevels(layer.params.master);\n return [layer.params.red, layer.params.green, layer.params.blue].map((pts) => {\n const ch = curveLutFromLevels(pts);\n for (let k = 0; k < n; k++) ch[k] = sampleLut(m, ch[k]);\n return ch;\n }) as [Float32Array, Float32Array, Float32Array];\n }\n if (layer.kind === 'levels') {\n const m = toUnitLevels(layer.params.master);\n return [layer.params.red, layer.params.green, layer.params.blue].map((rec) => {\n const c = toUnitLevels(rec);\n const out = new Float32Array(n);\n for (let k = 0; k < n; k++) out[k] = levelsValue(m, levelsValue(c, k / (n - 1), LEVELS_QUANTUM), LEVELS_QUANTUM);\n return out;\n }) as [Float32Array, Float32Array, Float32Array];\n }\n return null;\n}\n\n/**\n * Compiles a layer into a pixel function, or `null` when it is the identity (neutral parameters).\n * Pure: depends on `kind` and `params` only.\n */\nexport function compileAdjustmentLayer(layer: AdjustmentLayer): PixelOp | null {\n switch (layer.kind) {\n case 'curves': {\n const p = layer.params;\n if ([p.master, p.red, p.green, p.blue].every(isIdentityCurve)) return null;\n return lutOp(toneLuts(layer)!);\n }\n case 'levels': {\n const p = layer.params;\n if ([p.master, p.red, p.green, p.blue].every(isIdentityLevels)) return null;\n return lutOp(toneLuts(layer)!);\n }\n case 'hueSaturation': {\n const p = layer.params;\n const rangesActive = !p.colorize && p.ranges.some((r) => !isNeutralRange(r));\n if (!p.colorize && !rangesActive && p.hue === 0 && p.saturation === 0 && p.lightness === 0) return null;\n const tables = rangesActive ? hueRangeTables(p.ranges) : null;\n const sat = p.saturation / 100;\n const light = Math.min(1, Math.max(-1, p.lightness / 100));\n return (c) => {\n let dh = 0, ds = 0, dl = 0;\n if (tables) {\n const h0 = rgbToHsl(c)[0];\n dh = sampleLut(tables[0], h0);\n ds = sampleLut(tables[1], h0);\n dl = sampleLut(tables[2], h0);\n }\n const out = rangeLightness(hueSaturation(c, p.hue + dh, Math.min(1, Math.max(-1, sat + ds)), light, p.colorize), dl);\n c[0] = out[0];\n c[1] = out[1];\n c[2] = out[2];\n };\n }\n case 'vibrance': {\n const v = layer.params.vibrance / 100;\n const s = layer.params.saturation / 100;\n if (v === 0 && s === 0) return null;\n return (c) => {\n const out = vibrancePixel(c, v, s);\n c[0] = out[0];\n c[1] = out[1];\n c[2] = out[2];\n };\n }\n case 'colorBalance': {\n const p = layer.params;\n const tones = [p.shadows, p.midtones, p.highlights] as const;\n if (tones.every((t) => t[0] === 0 && t[1] === 0 && t[2] === 0)) return null;\n const n = ADJUSTMENT_LUT_SIZE;\n const luts = [0, 1, 2].map((ch) => {\n const out = new Float32Array(n);\n for (let k = 0; k < n; k++) out[k] = colorBalanceChannel(tones, p.preserveLuminosity, ch, k / (n - 1));\n return out;\n }) as [Float32Array, Float32Array, Float32Array];\n return lutOp(luts);\n }\n case 'blackWhite': {\n const p = layer.params;\n const weights = [p.reds, p.yellows, p.greens, p.cyans, p.blues, p.magentas];\n const tint = p.tint ? hexToRgb(p.tint) : null;\n return (c) => {\n const g = blackWhiteGray(c, weights);\n if (tint) {\n const t = setLum(tint, g);\n c[0] = clamp01(t[0]);\n c[1] = clamp01(t[1]);\n c[2] = clamp01(t[2]);\n } else {\n c[0] = c[1] = c[2] = g;\n }\n };\n }\n case 'photoFilter': {\n const p = layer.params;\n if (p.density <= 0) return null;\n const m = photoFilterMatrix(hexToRgb(p.color), p.density / 100, false);\n const preserve = p.preserveLuminosity;\n return (c) => {\n const l = [srgbToLinear(Math.max(0, c[0])), srgbToLinear(Math.max(0, c[1])), srgbToLinear(Math.max(0, c[2]))];\n let f: Rgb = [0, 1, 2].map((r) => linearToSrgb(Math.max(0, m[r][0] * l[0] + m[r][1] * l[1] + m[r][2] * l[2]))) as Rgb;\n if (preserve) {\n const target = 0.3 * c[0] + 0.59 * c[1] + 0.11 * c[2];\n f = setLum(f, target);\n }\n c[0] = clamp01(f[0]);\n c[1] = clamp01(f[1]);\n c[2] = clamp01(f[2]);\n };\n }\n case 'invert':\n return (c) => {\n c[0] = 1 - c[0];\n c[1] = 1 - c[1];\n c[2] = 1 - c[2];\n };\n case 'posterize': {\n const levels = layer.params.levels;\n return (c) => {\n c[0] = posterizeValue(c[0], levels);\n c[1] = posterizeValue(c[1], levels);\n c[2] = posterizeValue(c[2], levels);\n };\n }\n case 'threshold': {\n const t = Math.round(layer.params.level);\n return (c) => {\n const v = Math.round(rgbToGray(c) * 255) >= t ? 1 : 0;\n c[0] = c[1] = c[2] = v;\n };\n }\n }\n return null;\n}\n\n// Compiled layers keyed by kind + params, so a stack is compiled once per parameter change.\nconst COMPILE_CACHE_LIMIT = 64;\nconst compileCache = new Map<string, PixelOp | null>();\n\nfunction compiledFor(layer: AdjustmentLayer): PixelOp | null {\n const key = `${layer.kind}:${JSON.stringify(layer.params)}`;\n if (compileCache.has(key)) {\n const op = compileCache.get(key)!;\n // Refresh recency.\n compileCache.delete(key);\n compileCache.set(key, op);\n return op;\n }\n const op = compileAdjustmentLayer(layer);\n compileCache.set(key, op);\n if (compileCache.size > COMPILE_CACHE_LIMIT) compileCache.delete(compileCache.keys().next().value as string);\n return op;\n}\n\n/** Layers that change pixels: enabled, visible, not the identity. */\nexport function activeAdjustmentLayers(layers: readonly AdjustmentLayer[] | undefined): AdjustmentLayer[] {\n if (!layers?.length) return [];\n return layers.filter((l) => l.enabled !== false && (l.opacity ?? 1) > 0 && compiledFor(l) !== null);\n}\n\n/**\n * Evaluates one colour (encoded sRGB, 0..1) through a layer stack: each layer adjusts the result\n * of the layers below and is blended over it with its blend mode and opacity (an opaque\n * backdrop, so `(1 − α)·Cb + α·B(Cb, Cs)`).\n */\nexport function evaluateAdjustmentLayers(color: readonly number[], layers: readonly AdjustmentLayer[]): Rgb {\n const c: Rgb = [color[0], color[1], color[2]];\n for (const layer of layers) applyLayer(c, layer, compiledFor(layer));\n return c;\n}\n\nfunction applyLayer(c: Rgb, layer: AdjustmentLayer, op: PixelOp | null): void {\n if (!op || layer.enabled === false) return;\n const alpha = Math.min(1, Math.max(0, layer.opacity ?? 1));\n if (alpha <= 0) return;\n const blend = layer.blend ?? 'normal';\n if (blend === 'normal' && alpha >= 1) {\n op(c);\n return;\n }\n const cb0 = c[0], cb1 = c[1], cb2 = c[2];\n op(c);\n const b = blend === 'normal' ? c : blendRgb(blend, [cb0, cb1, cb2], c);\n c[0] = (1 - alpha) * cb0 + alpha * b[0];\n c[1] = (1 - alpha) * cb1 + alpha * b[1];\n c[2] = (1 - alpha) * cb2 + alpha * b[2];\n}\n\n/**\n * Applies an adjustment-layer stack to 8-bit straight RGBA pixels in place. Each pixel is\n * decoded once, run through every layer in float, and encoded once. Transparent pixels are\n * left alone; alpha is never changed.\n */\nexport function applyAdjustmentLayers(imageData: ImageData, layers: readonly AdjustmentLayer[] | undefined): void {\n const active = activeAdjustmentLayers(layers);\n if (!active.length) return;\n const ops = active.map((l) => compiledFor(l));\n const data = imageData.data;\n const len = data.length;\n const c: Rgb = [0, 0, 0];\n for (let i = 0; i < len; i += 4) {\n if (data[i + 3] === 0) continue;\n c[0] = data[i] / 255;\n c[1] = data[i + 1] / 255;\n c[2] = data[i + 2] / 255;\n for (let k = 0; k < active.length; k++) applyLayer(c, active[k], ops[k]);\n data[i] = Math.round(clamp01(c[0]) * 255);\n data[i + 1] = Math.round(clamp01(c[1]) * 255);\n data[i + 2] = Math.round(clamp01(c[2]) * 255);\n }\n}\n\n/** Stable cache key of a layer stack's pixel effect (for renderer caches). */\nexport function adjustmentLayersKey(layers: readonly AdjustmentLayer[] | undefined): string {\n if (!layers?.length) return '';\n return JSON.stringify(\n layers.map((l) => [l.kind, l.enabled !== false, l.opacity ?? 1, l.blend ?? 'normal', l.params])\n );\n}\n","import type { DepthMaskOptions, ImageAdjustments } from './types';\nimport {\n LUMA_709,\n LATEST_PROCESS_VERSION,\n TONE_LUT_SIZE,\n buildToneLut,\n linearToSrgb,\n normalizeProcessVersion,\n srgbToLinear,\n whiteBalanceMatrix,\n} from './color';\nimport { applyAdjustmentLayers } from './adjustment-layers';\n\nfunction clamp(value: number, min = 0, max = 255): number {\n return Math.max(min, Math.min(max, value));\n}\n\n/**\n * Applies color and tone adjustments (brightness, contrast, saturation, exposure, temperature, tint,\n * opacity, then any adjustment `layers`, then blur) directly to the pixel data of an ImageData buffer.\n *\n * `adjustments.process` selects the rendering: `2` is the linear-light pipeline\n * ({@link applyProcess2Adjustments}); anything else (including a missing value, as in edits saved\n * before process versions existed) is the frozen legacy rendering ({@link applyLegacyAdjustments}).\n */\nexport function applyAdjustments(imageData: ImageData, adjustments: ImageAdjustments): void {\n if (normalizeProcessVersion(adjustments.process) === LATEST_PROCESS_VERSION) {\n applyProcess2Adjustments(imageData, adjustments);\n } else {\n applyLegacyAdjustments(imageData, adjustments);\n }\n\n // Adjustment layers, bottom to top, on the encoded result (no-op without layers).\n applyAdjustmentLayers(imageData, adjustments.layers);\n\n // Apply blur if requested\n if (adjustments.blur > 0) {\n applyFastBoxBlur(imageData, Math.min(Math.round(adjustments.blur), 40));\n }\n}\n\n/**\n * Process 1: the original 8-bit gamma-space rendering, clamping after every step. Frozen so\n * that edits saved without a `process` look exactly as they always have. `tint` is ignored.\n */\nexport function applyLegacyAdjustments(imageData: ImageData, adjustments: ImageAdjustments): void {\n const { brightness, contrast, saturation, exposure, temperature, opacity } = adjustments;\n const data = imageData.data;\n const len = data.length;\n\n const hasBrightness = brightness !== 0;\n const hasContrast = contrast !== 0;\n const hasSaturation = saturation !== 0;\n const hasExposure = exposure !== 0;\n const hasTemperature = temperature !== 0;\n const hasOpacity = opacity < 1;\n\n // Pre-calculate contrast factor\n const contrastFactor = hasContrast\n ? (259 * (contrast + 255)) / (255 * (259 - contrast))\n : 1;\n\n // Pre-calculate exposure multiplier\n const exposureMultiplier = hasExposure ? Math.pow(2, exposure / 50) : 1;\n\n // Pre-calculate saturation multiplier\n const satMultiplier = hasSaturation ? 1 + saturation / 100 : 1;\n\n // Pre-calculate temperature offsets\n const tempOffset = hasTemperature ? temperature * 0.8 : 0;\n\n if (hasBrightness || hasContrast || hasSaturation || hasExposure || hasTemperature || hasOpacity) {\n for (let i = 0; i < len; i += 4) {\n let r = data[i];\n let g = data[i + 1];\n let b = data[i + 2];\n let a = data[i + 3];\n\n // Exposure\n if (hasExposure) {\n r = clamp(r * exposureMultiplier);\n g = clamp(g * exposureMultiplier);\n b = clamp(b * exposureMultiplier);\n }\n\n // Brightness\n if (hasBrightness) {\n const bOffset = brightness * 2.55;\n r = clamp(r + bOffset);\n g = clamp(g + bOffset);\n b = clamp(b + bOffset);\n }\n\n // Contrast\n if (hasContrast) {\n r = clamp(contrastFactor * (r - 128) + 128);\n g = clamp(contrastFactor * (g - 128) + 128);\n b = clamp(contrastFactor * (b - 128) + 128);\n }\n\n // Saturation\n if (hasSaturation) {\n const luminance = 0.2989 * r + 0.587 * g + 0.114 * b;\n r = clamp(luminance + (r - luminance) * satMultiplier);\n g = clamp(luminance + (g - luminance) * satMultiplier);\n b = clamp(luminance + (b - luminance) * satMultiplier);\n }\n\n // Temperature / Warmth\n if (hasTemperature) {\n r = clamp(r + tempOffset);\n b = clamp(b - tempOffset);\n }\n\n // Opacity\n if (hasOpacity) {\n a = clamp(a * opacity);\n }\n\n data[i] = r;\n data[i + 1] = g;\n data[i + 2] = b;\n data[i + 3] = a;\n }\n }\n}\n\n/** sRGB byte → linear light (exact; shared by every process 2 render). */\nconst DECODE_LUT: Float32Array = (() => {\n const lut = new Float32Array(256);\n for (let i = 0; i < 256; i++) lut[i] = srgbToLinear(i / 255);\n return lut;\n})();\n\n/** Intervals of the linear → sRGB byte encode table over [0, 1]. */\nconst ENCODE_LUT_SIZE = 65535;\nlet encodeLut: Uint8Array | null = null;\nfunction getEncodeLut(): Uint8Array {\n if (!encodeLut) {\n encodeLut = new Uint8Array(ENCODE_LUT_SIZE + 1);\n for (let i = 0; i <= ENCODE_LUT_SIZE; i++) {\n encodeLut[i] = Math.round(linearToSrgb(i / ENCODE_LUT_SIZE) * 255);\n }\n }\n return encodeLut;\n}\n\ninterface Process2Plan {\n key: string;\n /** Exposure gain folded into the white-balance matrix (row-major). */\n m: Float64Array;\n /** Per-channel tone LUTs over [0, headroom[c]]. */\n luts: [Float32Array, Float32Array, Float32Array];\n /** LUT index scale per channel: TONE_LUT_SIZE / headroom[c]. */\n scale: [number, number, number];\n saturation: number;\n}\n\nlet cachedPlan: Process2Plan | null = null;\n\n/**\n * Precomputes everything per parameter change: the 3×3 colour matrix (exposure gain × white\n * balance) and one tone LUT per channel whose domain is that channel's largest possible value,\n * so the highlight shoulder absorbs it instead of clipping.\n */\nfunction getProcess2Plan(adjustments: ImageAdjustments): Process2Plan {\n const exposure = adjustments.exposure || 0;\n const temperature = adjustments.temperature || 0;\n const tint = adjustments.tint || 0;\n const contrast = adjustments.contrast || 0;\n const brightness = adjustments.brightness || 0;\n const saturation = 1 + (adjustments.saturation || 0) / 100;\n const key = `${exposure},${temperature},${tint},${contrast},${brightness},${saturation}`;\n if (cachedPlan && cachedPlan.key === key) return cachedPlan;\n\n const gain = Math.pow(2, exposure / 50);\n const wb = whiteBalanceMatrix(temperature, tint);\n const m = new Float64Array(9);\n for (let i = 0; i < 9; i++) m[i] = wb[i] * gain;\n const luts = [] as unknown as [Float32Array, Float32Array, Float32Array];\n const scale = [0, 0, 0] as [number, number, number];\n for (let c = 0; c < 3; c++) {\n // Largest value this channel can reach from inputs in [0, 1].\n let reach = 0;\n for (let k = 0; k < 3; k++) reach += Math.max(0, m[c * 3 + k]);\n const headroom = Math.max(1, reach);\n luts[c] = buildToneLut(contrast, brightness, headroom);\n scale[c] = TONE_LUT_SIZE / headroom;\n }\n cachedPlan = { key, m, luts, scale, saturation };\n return cachedPlan;\n}\n\n/**\n * Process 2: decode sRGB to linear float once; apply exposure (gain) and white balance (a\n * Bradford matrix relative to as-shot) in linear light; a per-channel tone LUT for the\n * highlight shoulder, contrast and brightness; luminance-preserving saturation in linear light;\n * then encode back to sRGB through a LUT. Nothing is clamped between stages, only at the final\n * encode. Neutral settings are the identity.\n */\nexport function applyProcess2Adjustments(imageData: ImageData, adjustments: ImageAdjustments): void {\n const data = imageData.data;\n const len = data.length;\n const opacity = adjustments.opacity ?? 1;\n const hasOpacity = opacity < 1;\n const hasColor =\n !!adjustments.brightness ||\n !!adjustments.contrast ||\n !!adjustments.saturation ||\n !!adjustments.exposure ||\n !!adjustments.temperature ||\n !!adjustments.tint;\n\n if (!hasColor) {\n if (hasOpacity) {\n for (let i = 3; i < len; i += 4) data[i] = clamp(data[i] * opacity);\n }\n return;\n }\n\n const plan = getProcess2Plan(adjustments);\n const dec = DECODE_LUT;\n const enc = getEncodeLut();\n const { m, luts, scale, saturation } = plan;\n const m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3], m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7], m8 = m[8];\n const lutR = luts[0], lutG = luts[1], lutB = luts[2];\n const sR = scale[0], sG = scale[1], sB = scale[2];\n const N = TONE_LUT_SIZE;\n const hasSaturation = saturation !== 1;\n const wr = LUMA_709[0], wg = LUMA_709[1], wb = LUMA_709[2];\n\n for (let i = 0; i < len; i += 4) {\n const r0 = dec[data[i]];\n const g0 = dec[data[i + 1]];\n const b0 = dec[data[i + 2]];\n\n // Exposure × white balance (linear light, unclamped).\n let r = m0 * r0 + m1 * g0 + m2 * b0;\n let g = m3 * r0 + m4 * g0 + m5 * b0;\n let b = m6 * r0 + m7 * g0 + m8 * b0;\n\n // Tone LUTs (linear interpolation).\n let f: number;\n let k: number;\n if (r <= 0) r = lutR[0];\n else if ((f = r * sR) >= N) r = lutR[N];\n else { k = f | 0; r = lutR[k] + (lutR[k + 1] - lutR[k]) * (f - k); }\n if (g <= 0) g = lutG[0];\n else if ((f = g * sG) >= N) g = lutG[N];\n else { k = f | 0; g = lutG[k] + (lutG[k + 1] - lutG[k]) * (f - k); }\n if (b <= 0) b = lutB[0];\n else if ((f = b * sB) >= N) b = lutB[N];\n else { k = f | 0; b = lutB[k] + (lutB[k + 1] - lutB[k]) * (f - k); }\n\n // Luminance-preserving saturation in linear light.\n if (hasSaturation) {\n const y = wr * r + wg * g + wb * b;\n r = y + (r - y) * saturation;\n g = y + (g - y) * saturation;\n b = y + (b - y) * saturation;\n }\n\n // Encode (the only clamp).\n data[i] = enc[r <= 0 ? 0 : r >= 1 ? ENCODE_LUT_SIZE : (r * ENCODE_LUT_SIZE + 0.5) | 0];\n data[i + 1] = enc[g <= 0 ? 0 : g >= 1 ? ENCODE_LUT_SIZE : (g * ENCODE_LUT_SIZE + 0.5) | 0];\n data[i + 2] = enc[b <= 0 ? 0 : b >= 1 ? ENCODE_LUT_SIZE : (b * ENCODE_LUT_SIZE + 0.5) | 0];\n if (hasOpacity) data[i + 3] = clamp(data[i + 3] * opacity);\n }\n}\n\n/**\n * Fast separable box blur running horizontally and vertically.\n */\nfunction applyFastBoxBlur(imageData: ImageData, radius: number): void {\n if (radius < 1) return;\n const w = imageData.width;\n const h = imageData.height;\n const src = imageData.data;\n const temp = new Uint8ClampedArray(src.length);\n\n // Horizontal blur pass\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n let r = 0, g = 0, b = 0, a = 0;\n let count = 0;\n for (let k = -radius; k <= radius; k++) {\n const px = Math.min(w - 1, Math.max(0, x + k));\n const idx = (y * w + px) * 4;\n r += src[idx];\n g += src[idx + 1];\n b += src[idx + 2];\n a += src[idx + 3];\n count++;\n }\n const dstIdx = (y * w + x) * 4;\n temp[dstIdx] = Math.round(r / count);\n temp[dstIdx + 1] = Math.round(g / count);\n temp[dstIdx + 2] = Math.round(b / count);\n temp[dstIdx + 3] = Math.round(a / count);\n }\n }\n\n // Vertical blur pass back into src\n for (let x = 0; x < w; x++) {\n for (let y = 0; y < h; y++) {\n let r = 0, g = 0, b = 0, a = 0;\n let count = 0;\n for (let k = -radius; k <= radius; k++) {\n const py = Math.min(h - 1, Math.max(0, y + k));\n const idx = (py * w + x) * 4;\n r += temp[idx];\n g += temp[idx + 1];\n b += temp[idx + 2];\n a += temp[idx + 3];\n count++;\n }\n const dstIdx = (y * w + x) * 4;\n src[dstIdx] = Math.round(r / count);\n src[dstIdx + 1] = Math.round(g / count);\n src[dstIdx + 2] = Math.round(b / count);\n src[dstIdx + 3] = Math.round(a / count);\n }\n }\n}\n\n/**\n * Blends a depth/alpha mask into the main image data based on Gleamforge depth masking.\n * Supports threshold range with softness gradation, brightness mode, and optional inversion.\n */\nexport function applyDepthMask(\n mainImageData: ImageData,\n maskImageData: ImageData,\n options: DepthMaskOptions\n): void {\n const { mode, depthRange, softness, invert } = options;\n const mainData = mainImageData.data;\n const maskData = maskImageData.data;\n const len = Math.min(mainData.length, maskData.length);\n const effectiveSoftness = Math.max(1, softness || 10);\n const minDepth = depthRange[0];\n const maxDepth = depthRange[1];\n\n for (let i = 0; i < len; i += 4) {\n let maskValue = maskData[i]; // Use red channel of mask (or grayscale)\n if (invert) {\n maskValue = 255 - maskValue;\n }\n\n let alphaValue: number;\n\n if (mode === 'threshold') {\n if (maskValue >= maxDepth + effectiveSoftness) {\n alphaValue = 0;\n } else if (maskValue > maxDepth) {\n alphaValue = Math.round(((maxDepth + effectiveSoftness - maskValue) / effectiveSoftness) * 255);\n } else if (maskValue >= minDepth) {\n alphaValue = 255;\n } else if (maskValue < minDepth - effectiveSoftness) {\n alphaValue = 0;\n } else {\n alphaValue = Math.round(((maskValue - (minDepth - effectiveSoftness)) / effectiveSoftness) * 255);\n }\n } else {\n // Brightness mode\n alphaValue = clamp(maskValue + minDepth);\n }\n\n // Multiply existing alpha with mask alpha\n mainData[i + 3] = clamp((mainData[i + 3] * alphaValue) / 255);\n }\n}\n\n/**\n * Removes alpha channel by setting all alpha bytes to 255 (completely opaque).\n * From Gleamforge image-filters.ts.\n */\nexport function removeAlpha(imageData: ImageData): void {\n const data = imageData.data;\n const len = data.length;\n for (let i = 3; i < len; i += 4) {\n data[i] = 255;\n }\n}\n","// Portions ported from photocraft-main/crates/algo/src/histogram.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\n/** Display bins of a histogram. */\nexport const HISTOGRAM_BINS = 256;\n\nexport interface ImageHistogram {\n /** 256-bin counts per channel. */\n red: Uint32Array;\n green: Uint32Array;\n blue: Uint32Array;\n /** 256-bin counts of Rec.709 luma `round(0.2126 R + 0.7152 G + 0.0722 B)` of the encoded values. */\n luminance: Uint32Array;\n /** Visible pixels counted (alpha > 0). Each counts once, partially transparent ones included. */\n samples: number;\n /** Fully transparent pixels, excluded from every bin. */\n transparent: number;\n /** Per channel (R, G, B): visible pixels at exactly 0. */\n shadows: [number, number, number];\n /** Per channel (R, G, B): visible pixels at exactly 255. */\n highlights: [number, number, number];\n /** Largest bin count over R, G, B and luminance (for scaling a plot). */\n max: number;\n}\n\ninterface PixelSource {\n data: ArrayLike<number>;\n width?: number;\n height?: number;\n}\n\n/**\n * Per-channel and luminance histograms of straight 8-bit RGBA pixels (an `ImageData` or anything\n * with `data`), with clipping counts at the exact endpoints. Transparent pixels cannot add\n * phantom peaks: they are counted separately and excluded.\n */\nexport function computeHistogram(imageData: PixelSource): ImageHistogram {\n const red = new Uint32Array(HISTOGRAM_BINS);\n const green = new Uint32Array(HISTOGRAM_BINS);\n const blue = new Uint32Array(HISTOGRAM_BINS);\n const luminance = new Uint32Array(HISTOGRAM_BINS);\n const shadows: [number, number, number] = [0, 0, 0];\n const highlights: [number, number, number] = [0, 0, 0];\n let samples = 0;\n let transparent = 0;\n const data = imageData.data;\n const len = data.length - (data.length % 4);\n for (let i = 0; i < len; i += 4) {\n if (!(data[i + 3] > 0)) {\n transparent++;\n continue;\n }\n samples++;\n const r = clampByte(data[i]);\n const g = clampByte(data[i + 1]);\n const b = clampByte(data[i + 2]);\n red[r]++;\n green[g]++;\n blue[b]++;\n luminance[Math.round(0.2126 * r + 0.7152 * g + 0.0722 * b)]++;\n if (r === 0) shadows[0]++;\n if (g === 0) shadows[1]++;\n if (b === 0) shadows[2]++;\n if (r === 255) highlights[0]++;\n if (g === 255) highlights[1]++;\n if (b === 255) highlights[2]++;\n }\n let max = 0;\n for (const bins of [red, green, blue, luminance]) {\n for (let k = 0; k < HISTOGRAM_BINS; k++) if (bins[k] > max) max = bins[k];\n }\n return { red, green, blue, luminance, samples, transparent, shadows, highlights, max };\n}\n\nfunction clampByte(v: number): number {\n return v <= 0 ? 0 : v >= 255 ? 255 : Math.round(v);\n}\n\nexport type HistogramChannel = 'red' | 'green' | 'blue' | 'luminance';\n\n/**\n * An SVG path (`M … Z`) of one channel scaled into a `width` × `height` box, bins left to right,\n * counts up from the bottom. `scale: 'sqrt'` (default) keeps small populations visible.\n */\nexport function histogramPath(\n histogram: ImageHistogram,\n channel: HistogramChannel,\n width: number,\n height: number,\n options: { scale?: 'linear' | 'sqrt'; max?: number } = {}\n): string {\n const bins = histogram[channel];\n const sqrt = (options.scale ?? 'sqrt') === 'sqrt';\n const f = (v: number) => (sqrt ? Math.sqrt(v) : v);\n const top = f(options.max ?? histogram.max) || 1;\n const dx = width / (HISTOGRAM_BINS - 1);\n let d = `M0 ${height}`;\n for (let k = 0; k < HISTOGRAM_BINS; k++) {\n const y = height - (f(bins[k]) / top) * height;\n d += ` L${round2(k * dx)} ${round2(y)}`;\n }\n return `${d} L${round2(width)} ${height} Z`;\n}\n\nconst round2 = (v: number) => Math.round(v * 100) / 100;\n","import type { Annotation, CropBox, ImageEditorState, ImagePoint, ImageTransform } from './types';\n\n/*\n * Coordinate spaces\n * -----------------\n * The crop box and every annotation are stored in ONE canonical space: natural image\n * pixels of the current source image (origin top-left of the un-rotated, un-flipped,\n * un-cropped image). Rotation, flips, crop and the viewport fit/zoom/pan are pure view\n * transforms applied on top of that space by a single forward mapping:\n *\n * target = origin + scale * R(angle) * F(flipH, flipV) * (image - regionCenter)\n *\n * where `regionCenter` is the centre of the visible region (the crop box, or the whole\n * image while the crop tool is active). `projectImagePoint` / `unprojectCanvasPoint`\n * implement the mapping and its exact inverse, and `applyImageProjectionToContext`\n * applies the very same transform to a 2D context, so rendering, hit-testing, viewport\n * metrics, export and mask generation cannot drift apart.\n */\n\nexport type CropHandle = 'nw' | 'ne' | 'se' | 'sw' | 'n' | 's' | 'e' | 'w' | 'inside' | null;\n\nexport interface ViewportMetrics {\n vpWidth: number;\n vpHeight: number;\n centerX: number;\n centerY: number;\n baseW: number;\n baseH: number;\n fitScale: number;\n renderW: number;\n renderH: number;\n totalScale: number;\n imageRect: { x: number; y: number; width: number; height: number };\n cropRect: { x: number; y: number; width: number; height: number } | null;\n}\n\n/**\n * A complete description of the natural-image -> target mapping (see module comment).\n */\nexport interface ImageProjection {\n /** Visible region in natural image pixels (crop box or full image). */\n region: CropBox;\n /** Rotation in degrees, normalised to [0, 360). */\n angle: number;\n flipH: boolean;\n flipV: boolean;\n /** Uniform scale from image pixels to target pixels. */\n scale: number;\n /** Target-space point that the centre of `region` maps to. */\n originX: number;\n originY: number;\n}\n\n/** Normalises any rotation in degrees to [0, 360). */\nexport function normalizeAngle(degrees: number): number {\n const a = ((degrees % 360) + 360) % 360;\n return a === 360 ? 0 : a;\n}\n\nfunction cosSin(angle: number): [number, number] {\n // Exact values for quarter turns so 90deg steps never accumulate float noise.\n switch (angle) {\n case 0:\n return [1, 0];\n case 90:\n return [0, 1];\n case 180:\n return [-1, 0];\n case 270:\n return [0, -1];\n default: {\n const rad = (angle * Math.PI) / 180;\n return [Math.cos(rad), Math.sin(rad)];\n }\n }\n}\n\n/** Whether the rotation swaps the displayed width and height. */\nexport function isQuarterTurnSwapped(transform: Pick<ImageTransform, 'rotate'>): boolean {\n const angle = normalizeAngle(transform.rotate);\n return angle === 90 || angle === 270;\n}\n\n/** Size of a region once rotated (bounding box for arbitrary angles). */\nexport function getRotatedSize(\n width: number,\n height: number,\n transform: Pick<ImageTransform, 'rotate'>\n): { width: number; height: number } {\n const [c, s] = cosSin(normalizeAngle(transform.rotate));\n return {\n width: Math.abs(width * c) + Math.abs(height * s),\n height: Math.abs(width * s) + Math.abs(height * c),\n };\n}\n\n/** Maps a natural-image point to target space. */\nexport function projectImagePoint(pt: ImagePoint, p: ImageProjection): ImagePoint {\n const [c, s] = cosSin(p.angle);\n let x = pt.x - (p.region.x + p.region.width / 2);\n let y = pt.y - (p.region.y + p.region.height / 2);\n if (p.flipH) x = -x;\n if (p.flipV) y = -y;\n const rx = x * c - y * s;\n const ry = x * s + y * c;\n return { x: p.originX + rx * p.scale, y: p.originY + ry * p.scale };\n}\n\n/** Exact inverse of {@link projectImagePoint}. */\nexport function unprojectCanvasPoint(pt: ImagePoint, p: ImageProjection): ImagePoint {\n const [c, s] = cosSin(p.angle);\n const rx = (pt.x - p.originX) / p.scale;\n const ry = (pt.y - p.originY) / p.scale;\n let x = rx * c + ry * s;\n let y = -rx * s + ry * c;\n if (p.flipH) x = -x;\n if (p.flipV) y = -y;\n return { x: x + p.region.x + p.region.width / 2, y: y + p.region.y + p.region.height / 2 };\n}\n\n/**\n * Applies the projection to a 2D context so that subsequent drawing in natural image\n * pixels lands exactly where {@link projectImagePoint} says it does.\n */\nexport function applyImageProjectionToContext(\n ctx: Pick<CanvasRenderingContext2D, 'translate' | 'scale' | 'rotate'>,\n p: ImageProjection\n): void {\n ctx.translate(p.originX, p.originY);\n ctx.scale(p.scale, p.scale);\n if (p.angle !== 0) ctx.rotate((p.angle * Math.PI) / 180);\n if (p.flipH || p.flipV) ctx.scale(p.flipH ? -1 : 1, p.flipV ? -1 : 1);\n ctx.translate(-(p.region.x + p.region.width / 2), -(p.region.y + p.region.height / 2));\n}\n\n/** Projects an image-space rectangle and returns its target-space bounding box. */\nexport function projectImageRect(\n rect: CropBox,\n p: ImageProjection\n): { x: number; y: number; width: number; height: number } {\n const corners = [\n projectImagePoint({ x: rect.x, y: rect.y }, p),\n projectImagePoint({ x: rect.x + rect.width, y: rect.y }, p),\n projectImagePoint({ x: rect.x, y: rect.y + rect.height }, p),\n projectImagePoint({ x: rect.x + rect.width, y: rect.y + rect.height }, p),\n ];\n const xs = corners.map((c) => c.x);\n const ys = corners.map((c) => c.y);\n const minX = Math.min(...xs);\n const minY = Math.min(...ys);\n return { x: minX, y: minY, width: Math.max(...xs) - minX, height: Math.max(...ys) - minY };\n}\n\n/** Clamps a crop box to the image bounds. */\nexport function clampCropToImage(crop: CropBox, width: number, height: number): CropBox {\n const x = Math.max(0, Math.min(width - 1, crop.x));\n const y = Math.max(0, Math.min(height - 1, crop.y));\n return {\n x,\n y,\n width: Math.max(1, Math.min(width - x, crop.width)),\n height: Math.max(1, Math.min(height - y, crop.height)),\n };\n}\n\nfunction resolveViewport(\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping: boolean,\n cropOverride?: CropBox | null\n) {\n const { imageDimensions, crop: stateCrop, transform, zoom, pan } = state;\n const naturalWidth = imageDimensions.width || 800;\n const naturalHeight = imageDimensions.height || 600;\n const full: CropBox = { x: 0, y: 0, width: naturalWidth, height: naturalHeight };\n const activeCrop =\n cropOverride !== undefined && cropOverride !== null\n ? cropOverride\n : (stateCrop ?? (isActivelyCropping ? full : null));\n\n const region =\n !isActivelyCropping && activeCrop ? clampCropToImage(activeCrop, naturalWidth, naturalHeight) : full;\n const { width: baseW, height: baseH } = getRotatedSize(region.width, region.height, transform);\n\n const fitScale = Math.min((vpWidth * 0.85) / baseW, (vpHeight * 0.85) / baseH, 1);\n const centerX = vpWidth / 2 + pan.x;\n const centerY = vpHeight / 2 + pan.y;\n\n const projection: ImageProjection = {\n region,\n angle: normalizeAngle(transform.rotate),\n flipH: transform.flipH,\n flipV: transform.flipV,\n scale: zoom * fitScale,\n originX: centerX,\n originY: centerY,\n };\n\n return { activeCrop, baseW, baseH, fitScale, centerX, centerY, projection };\n}\n\n/**\n * Returns the natural-image -> canvas projection used by the interactive viewport.\n */\nexport function getViewportProjection(\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false,\n cropOverride?: CropBox | null\n): ImageProjection {\n return resolveViewport(state, vpWidth, vpHeight, isActivelyCropping, cropOverride).projection;\n}\n\n/**\n * Calculates current viewport projection metrics for canvas <-> image coordinate mapping.\n * `cropRect` is the on-screen (rotated/flipped) rectangle of the crop box.\n */\nexport function getViewportMetrics(\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false,\n cropOverride?: CropBox | null\n): ViewportMetrics {\n const { zoom } = state;\n const { activeCrop, baseW, baseH, fitScale, centerX, centerY, projection } = resolveViewport(\n state,\n vpWidth,\n vpHeight,\n isActivelyCropping,\n cropOverride\n );\n\n const renderW = baseW * fitScale;\n const renderH = baseH * fitScale;\n\n const imageRect = {\n x: centerX - (renderW * zoom) / 2,\n y: centerY - (renderH * zoom) / 2,\n width: renderW * zoom,\n height: renderH * zoom,\n };\n\n const cropRect = activeCrop ? projectImageRect(activeCrop, projection) : null;\n\n return {\n vpWidth,\n vpHeight,\n centerX,\n centerY,\n baseW,\n baseH,\n fitScale,\n renderW,\n renderH,\n totalScale: zoom * fitScale,\n imageRect,\n cropRect,\n };\n}\n\n/**\n * Converts a point on the canvas (in internal canvas pixel space) to natural image pixel\n * space, accounting for zoom, pan, fit scale, crop offset, rotation and flips.\n */\nexport function canvasToImagePoint(\n canvasPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false\n): ImagePoint {\n return unprojectCanvasPoint(canvasPt, getViewportProjection(state, vpWidth, vpHeight, isActivelyCropping));\n}\n\n/**\n * Converts a point in natural image pixel space to internal canvas pixel space.\n * Exact inverse of {@link canvasToImagePoint}.\n */\nexport function imageToCanvasPoint(\n imgPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false\n): ImagePoint {\n return projectImagePoint(imgPt, getViewportProjection(state, vpWidth, vpHeight, isActivelyCropping));\n}\n\nconst HANDLE_VECTORS: Record<Exclude<CropHandle, 'inside' | null>, [number, number]> = {\n nw: [-1, -1],\n n: [0, -1],\n ne: [1, -1],\n e: [1, 0],\n se: [1, 1],\n s: [0, 1],\n sw: [-1, 1],\n w: [-1, 0],\n};\n\nfunction vectorToHandle(x: number, y: number): CropHandle {\n const vx = Math.abs(x) < 0.38 ? 0 : Math.sign(x);\n const vy = Math.abs(y) < 0.38 ? 0 : Math.sign(y);\n for (const [name, [hx, hy]] of Object.entries(HANDLE_VECTORS)) {\n if (hx === vx && hy === vy) return name as CropHandle;\n }\n return null;\n}\n\n/**\n * Converts a crop handle in screen orientation to the equivalent edge/corner of the crop\n * box in natural image space, or the reverse with `toScreen = true`.\n */\nexport function mapCropHandle(handle: CropHandle, transform: ImageTransform, toScreen = false): CropHandle {\n if (handle === null || handle === 'inside') return handle;\n const [hx, hy] = HANDLE_VECTORS[handle];\n const [c, s] = cosSin(normalizeAngle(transform.rotate));\n const fx = transform.flipH ? -1 : 1;\n const fy = transform.flipV ? -1 : 1;\n if (toScreen) {\n const x = hx * fx;\n const y = hy * fy;\n return vectorToHandle(x * c - y * s, x * s + y * c);\n }\n const x = hx * c + hy * s;\n const y = -hx * s + hy * c;\n return vectorToHandle(x * fx, y * fy);\n}\n\n/**\n * Hit-tests the crop box and its corner/edge handles given a canvas point.\n * The returned handle names the edge/corner of the crop box in natural image space\n * (what {@link calculateCropDrag} expects); use `getCropCursor(handle, state.transform)`\n * to obtain the matching on-screen cursor.\n */\nexport function hitTestCrop(\n canvasPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n handleThreshold = 14,\n cropOverride?: CropBox | null\n): CropHandle {\n const metrics = getViewportMetrics(state, vpWidth, vpHeight, true, cropOverride);\n if (!metrics.cropRect) return null;\n\n const screenHandle = hitTestCropRect(canvasPt, metrics.cropRect, handleThreshold);\n return mapCropHandle(screenHandle, state.transform);\n}\n\nfunction hitTestCropRect(\n canvasPt: ImagePoint,\n rect: { x: number; y: number; width: number; height: number },\n handleThreshold: number\n): CropHandle {\n const { x, y, width: w, height: h } = rect;\n const px = canvasPt.x;\n const py = canvasPt.y;\n\n // 1. Corners (highest priority)\n const dist = (x1: number, y1: number, x2: number, y2: number) =>\n Math.hypot(x1 - x2, y1 - y2);\n\n if (dist(px, py, x, y) <= handleThreshold) return 'nw';\n if (dist(px, py, x + w, y) <= handleThreshold) return 'ne';\n if (dist(px, py, x + w, y + h) <= handleThreshold) return 'se';\n if (dist(px, py, x, y + h) <= handleThreshold) return 'sw';\n\n // 2. Edges\n const nearX = px >= x - handleThreshold && px <= x + w + handleThreshold;\n const nearY = py >= y - handleThreshold && py <= y + h + handleThreshold;\n\n if (nearX && Math.abs(py - y) <= handleThreshold) return 'n';\n if (nearX && Math.abs(py - (y + h)) <= handleThreshold) return 's';\n if (nearY && Math.abs(px - x) <= handleThreshold) return 'w';\n if (nearY && Math.abs(px - (x + w)) <= handleThreshold) return 'e';\n\n // 3. Inside crop region\n if (px >= x && px <= x + w && py >= y && py <= y + h) {\n return 'inside';\n }\n\n return null;\n}\n\n/**\n * Returns CSS cursor style corresponding to a crop handle. Pass the current transform when\n * the handle comes from {@link hitTestCrop} (image space) so the cursor matches the\n * on-screen orientation under rotation/flip.\n */\nexport function getCropCursor(handle: CropHandle, transform?: ImageTransform): string {\n const screenHandle = transform ? mapCropHandle(handle, transform, true) : handle;\n switch (screenHandle) {\n case 'nw':\n case 'se':\n return 'nwse-resize';\n case 'ne':\n case 'sw':\n return 'nesw-resize';\n case 'n':\n case 's':\n return 'ns-resize';\n case 'e':\n case 'w':\n return 'ew-resize';\n case 'inside':\n return 'move';\n default:\n return 'crosshair';\n }\n}\n\n/**\n * Calculates updated crop rectangle given a drag interaction.\n */\nexport function calculateCropDrag(\n startCrop: CropBox,\n handle: CropHandle,\n startImgPt: ImagePoint,\n currentImgPt: ImagePoint,\n imgWidth: number,\n imgHeight: number,\n aspectRatio?: number | null,\n transform?: ImageTransform\n): CropBox {\n // `aspectRatio` is the on-screen ratio; under a quarter turn it is inverted in image space.\n if (aspectRatio && transform && isQuarterTurnSwapped(transform)) {\n aspectRatio = 1 / aspectRatio;\n }\n const dx = currentImgPt.x - startImgPt.x;\n const dy = currentImgPt.y - startImgPt.y;\n\n // Whole crop box move\n if (handle === 'inside') {\n const maxX = Math.max(0, imgWidth - startCrop.width);\n const maxY = Math.max(0, imgHeight - startCrop.height);\n const newX = Math.max(0, Math.min(maxX, startCrop.x + dx));\n const newY = Math.max(0, Math.min(maxY, startCrop.y + dy));\n return {\n x: Math.round(newX),\n y: Math.round(newY),\n width: startCrop.width,\n height: startCrop.height,\n };\n }\n\n // Handle resizing\n let left = startCrop.x;\n let top = startCrop.y;\n let right = startCrop.x + startCrop.width;\n let bottom = startCrop.y + startCrop.height;\n\n const minSize = 20;\n\n if (handle === 'e' || handle === 'ne' || handle === 'se') {\n right = Math.min(imgWidth, Math.max(left + minSize, startCrop.x + startCrop.width + dx));\n }\n if (handle === 'w' || handle === 'nw' || handle === 'sw') {\n left = Math.max(0, Math.min(right - minSize, startCrop.x + dx));\n }\n if (handle === 's' || handle === 'se' || handle === 'sw') {\n bottom = Math.min(imgHeight, Math.max(top + minSize, startCrop.y + startCrop.height + dy));\n }\n if (handle === 'n' || handle === 'nw' || handle === 'ne') {\n top = Math.max(0, Math.min(bottom - minSize, startCrop.y + dy));\n }\n\n // Maintain aspect ratio if requested\n if (aspectRatio && aspectRatio > 0) {\n let currentW = right - left;\n let currentH = bottom - top;\n\n if (handle === 'e' || handle === 'w') {\n currentH = Math.min(imgHeight, currentW / aspectRatio);\n bottom = Math.min(imgHeight, top + currentH);\n } else if (handle === 'n' || handle === 's') {\n currentW = Math.min(imgWidth, currentH * aspectRatio);\n right = Math.min(imgWidth, left + currentW);\n } else {\n // Corner resizing\n const targetH = currentW / aspectRatio;\n if (top + targetH <= imgHeight) {\n bottom = top + targetH;\n } else {\n const targetW = currentH * aspectRatio;\n right = Math.min(imgWidth, left + targetW);\n }\n }\n }\n\n return {\n x: Math.round(left),\n y: Math.round(top),\n width: Math.round(Math.max(minSize, right - left)),\n height: Math.round(Math.max(minSize, bottom - top)),\n };\n}\n\n/**\n * Calculates bounding box of an annotation.\n */\nexport function getAnnotationBounds(ann: Annotation): { x: number; y: number; width: number; height: number } {\n switch (ann.type) {\n case 'rect':\n case 'image':\n return {\n x: Math.min(ann.x, ann.x + ann.width),\n y: Math.min(ann.y, ann.y + ann.height),\n width: Math.abs(ann.width),\n height: Math.abs(ann.height),\n };\n case 'circle':\n return {\n x: ann.x - Math.abs(ann.radiusX),\n y: ann.y - Math.abs(ann.radiusY),\n width: Math.abs(ann.radiusX) * 2,\n height: Math.abs(ann.radiusY) * 2,\n };\n case 'arrow':\n case 'line': {\n const minX = Math.min(ann.x, ann.endX);\n const minY = Math.min(ann.y, ann.endY);\n return {\n x: minX,\n y: minY,\n width: Math.max(Math.abs(ann.endX - ann.x), 10),\n height: Math.max(Math.abs(ann.endY - ann.y), 10),\n };\n }\n case 'pen': {\n if (!ann.points.length) return { x: ann.x, y: ann.y, width: 0, height: 0 };\n let minX = ann.points[0].x;\n let maxX = ann.points[0].x;\n let minY = ann.points[0].y;\n let maxY = ann.points[0].y;\n for (const pt of ann.points) {\n if (pt.x < minX) minX = pt.x;\n if (pt.x > maxX) maxX = pt.x;\n if (pt.y < minY) minY = pt.y;\n if (pt.y > maxY) maxY = pt.y;\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n }\n case 'text':\n return {\n x: ann.x,\n y: ann.y,\n width: ann.text.length * ann.fontSize * 0.6,\n height: ann.fontSize * 1.2,\n };\n }\n}\n\n/**\n * Hit tests if a point in image space is within an annotation's bounds.\n */\nexport function hitTestAnnotation(imgPt: ImagePoint, ann: Annotation, padding = 10): boolean {\n const b = getAnnotationBounds(ann);\n return (\n imgPt.x >= b.x - padding &&\n imgPt.x <= b.x + b.width + padding &&\n imgPt.y >= b.y - padding &&\n imgPt.y <= b.y + b.height + padding\n );\n}\n\n","import type {\n Annotation,\n CropBox,\n ExportOptions,\n ImageEditorState,\n ImageTransform,\n PenAnnotation,\n RectAnnotation,\n CircleAnnotation,\n ArrowAnnotation,\n LineAnnotation,\n TextAnnotation,\n ImageAnnotation,\n} from './types';\nimport { applyAdjustments, applyDepthMask } from './filters';\nimport { adjustmentLayersKey } from './adjustment-layers';\nimport { canvasCompositeOperation, blendImageData, normalizeBlendMode } from './blend';\nimport { computeHistogram, type ImageHistogram } from './histogram';\nimport { normalizeProcessVersion } from './color';\nimport {\n applyImageProjectionToContext,\n clampCropToImage,\n getAnnotationBounds,\n getRotatedSize,\n getViewportMetrics,\n getViewportProjection,\n normalizeAngle,\n type ImageProjection,\n type ViewportMetrics,\n} from './geometry';\n\nexport interface RenderOptions {\n viewportWidth?: number;\n viewportHeight?: number;\n showCropOverlay?: boolean;\n showSelectionOverlay?: boolean;\n interactive?: boolean;\n draftAnnotation?: Annotation | null;\n draftCrop?: CropBox | null;\n}\n\n/**\n * Image Cache to avoid refetching HTMLImageElement objects repeatedly during re-renders.\n */\nclass ImageCache {\n private cache = new Map<string, HTMLImageElement>();\n\n public async get(src: string): Promise<HTMLImageElement> {\n const existing = this.cache.get(src);\n if (existing && existing.complete) {\n return existing;\n }\n\n return new Promise((resolve, reject) => {\n if (typeof window === 'undefined' || typeof Image === 'undefined') {\n reject(new Error('Image loading is only supported in browser/DOM environments'));\n return;\n }\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n this.cache.set(src, img);\n resolve(img);\n };\n img.onerror = (e) => reject(new Error(`Failed to load image from: ${src}`));\n img.src = src;\n\n // In JSDOM or test environments where Image resource loading is inactive, resolve promptly\n if (typeof navigator !== 'undefined' && /jsdom/i.test(navigator.userAgent)) {\n setTimeout(() => {\n try {\n Object.defineProperty(img, 'naturalWidth', { value: 800, configurable: true });\n Object.defineProperty(img, 'naturalHeight', { value: 600, configurable: true });\n Object.defineProperty(img, 'complete', { value: true, configurable: true });\n } catch {\n // Ignore definition errors in restrictive environments\n }\n this.cache.set(src, img);\n resolve(img);\n }, 10);\n }\n });\n }\n\n public set(src: string, img: HTMLImageElement): void {\n this.cache.set(src, img);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n}\n\nexport const globalImageCache = new ImageCache();\n\n/**\n * Renders an image with all its transformations, filters, depth masks, and annotations\n * to a target HTMLCanvasElement.\n */\nexport class ImageEditorRenderer {\n public imageCache = globalImageCache;\n private cachedBaseCanvas: HTMLCanvasElement | null = null;\n private cachedBaseKey = '';\n /**\n * Histogram of the last viewport base render (after adjustments and layers, before\n * annotations); `null` until a render with pixel access has happened.\n */\n public previewHistogram: ImageHistogram | null = null;\n /** Called whenever the viewport base image is re-rendered with the new histogram. */\n public onPreviewHistogram?: (histogram: ImageHistogram | null) => void;\n private sourceIds = new WeakMap<object, number>();\n private nextSourceId = 0;\n\n /**\n * Helper to create a canvas element safely in browser/JSDOM.\n */\n public createCanvas(width: number, height: number): HTMLCanvasElement {\n if (typeof document !== 'undefined' && document.createElement) {\n const c = document.createElement('canvas');\n c.width = Math.max(1, Math.round(width));\n c.height = Math.max(1, Math.round(height));\n return c;\n }\n // Fallback for non-DOM / headless\n return {\n width: Math.max(1, Math.round(width)),\n height: Math.max(1, Math.round(height)),\n getContext: () => null,\n toDataURL: () => '',\n toBlob: () => {},\n } as unknown as HTMLCanvasElement;\n }\n\n /**\n * Renders the editor state onto a canvas (viewport or preview).\n */\n public async renderToCanvas(\n targetCanvas: HTMLCanvasElement,\n imageSource: CanvasImageSource | string,\n state: ImageEditorState,\n options: RenderOptions = {}\n ): Promise<void> {\n const ctx = targetCanvas.getContext('2d');\n if (!ctx) return;\n\n let img: CanvasImageSource;\n if (typeof imageSource === 'string') {\n img = await this.imageCache.get(imageSource);\n } else {\n img = imageSource;\n }\n\n const { width: naturalWidth, height: naturalHeight } = getSourceSize(img);\n // Geometry helpers read `imageDimensions`; make sure they see the real source size so the\n // viewport drawn here and the hit-testing done by the UI share one projection.\n const geoState: ImageEditorState =\n state.imageDimensions.width === naturalWidth && state.imageDimensions.height === naturalHeight\n ? state\n : { ...state, imageDimensions: { width: naturalWidth, height: naturalHeight } };\n\n const { crop, transform, adjustments, depthMask, annotations, selectedAnnotationId, zoom, pan, isOriginalCompared } = state;\n\n // Viewport dimensions\n const vpWidth = options.viewportWidth || targetCanvas.width;\n const vpHeight = options.viewportHeight || targetCanvas.height;\n\n targetCanvas.width = vpWidth;\n targetCanvas.height = vpHeight;\n\n ctx.clearRect(0, 0, vpWidth, vpHeight);\n\n // If in compare mode, render original image directly and exit\n if (isOriginalCompared) {\n this.drawFittedImage(ctx, img, naturalWidth, naturalHeight, vpWidth, vpHeight, zoom, pan);\n return;\n }\n\n // When actively in crop tool or overlay requested, show full image so user can adjust the crop box\n const isActivelyCropping = Boolean(options.showCropOverlay || state.activeTool === 'crop');\n const projection = getViewportProjection(geoState, vpWidth, vpHeight, isActivelyCropping);\n const { region } = projection;\n const rotated = getRotatedSize(region.width, region.height, transform);\n\n // 1. Offscreen canvas for Base Image + Transform (Flip/Rotate) + Crop + Adjustments + Depth mask\n const baseKey = [\n this.getSourceId(img),\n state.sourceUrl,\n `${naturalWidth}x${naturalHeight}`,\n `${region.x},${region.y},${region.width},${region.height}`,\n `${projection.angle},${transform.flipH},${transform.flipV}`,\n `${adjustments.brightness},${adjustments.contrast},${adjustments.saturation},${adjustments.exposure},${adjustments.temperature},${adjustments.tint ?? 0},${adjustments.blur},${adjustments.opacity},p${normalizeProcessVersion(adjustments.process)}`,\n adjustmentLayersKey(adjustments.layers),\n `${depthMask.enabled},${depthMask.maskSource},${depthMask.depthRange?.[0]}-${depthMask.depthRange?.[1]},${depthMask.softness},${depthMask.invert},${depthMask.mode}`,\n ].join('|');\n\n let baseCanvas = this.cachedBaseCanvas;\n if (!baseCanvas || this.cachedBaseKey !== baseKey) {\n let histogram: ImageHistogram | null = null;\n baseCanvas = await this.renderBaseImage(img, naturalWidth, naturalHeight, region, transform, state, (pixels) => {\n histogram = computeHistogram(pixels);\n });\n this.cachedBaseCanvas = baseCanvas;\n this.cachedBaseKey = baseKey;\n this.previewHistogram = histogram;\n this.onPreviewHistogram?.(histogram);\n }\n\n // 2. Draw the base canvas into the viewport (centred, fitted, zoomed, panned)\n const drawW = rotated.width * projection.scale;\n const drawH = rotated.height * projection.scale;\n ctx.drawImage(baseCanvas, projection.originX - drawW / 2, projection.originY - drawH / 2, drawW, drawH);\n\n // 3. Annotations live in natural image space: draw them through the same projection,\n // clipped to the visible (cropped) region.\n if (annotations.length > 0 || options.draftAnnotation) {\n ctx.save();\n applyImageProjectionToContext(ctx, projection);\n ctx.beginPath();\n ctx.rect(region.x, region.y, region.width, region.height);\n ctx.clip();\n\n for (const ann of annotations) {\n await this.drawAnnotation(ctx, ann);\n if (options.showSelectionOverlay && ann.id === selectedAnnotationId) {\n this.drawAnnotationSelection(ctx, ann);\n }\n }\n\n // Render active live draft annotation\n if (options.draftAnnotation) {\n await this.drawAnnotation(ctx, options.draftAnnotation);\n }\n\n ctx.restore();\n }\n\n // 4. Draw Crop Grid Overlay if crop overlay is requested\n if (isActivelyCropping) {\n const activeCrop =\n options.draftCrop !== undefined && options.draftCrop !== null\n ? options.draftCrop\n : (crop ?? { x: 0, y: 0, width: naturalWidth, height: naturalHeight });\n this.drawCropOverlay(ctx, getViewportMetrics(geoState, vpWidth, vpHeight, true, activeCrop));\n }\n }\n\n /**\n * Draws `region` of the source image with rotation/flip applied, then pixel adjustments\n * and the depth mask (which receives the identical transform so it stays aligned).\n */\n private async renderBaseImage(\n img: CanvasImageSource,\n naturalWidth: number,\n naturalHeight: number,\n region: CropBox,\n transform: ImageTransform,\n state: Pick<ImageEditorState, 'adjustments' | 'depthMask'>,\n onPixels?: (pixels: ImageData) => void\n ): Promise<HTMLCanvasElement> {\n const { adjustments, depthMask } = state;\n const rotated = getRotatedSize(region.width, region.height, transform);\n const baseW = Math.max(1, Math.round(rotated.width));\n const baseH = Math.max(1, Math.round(rotated.height));\n const baseCanvas = this.createCanvas(baseW, baseH);\n const baseCtx = baseCanvas.getContext('2d');\n if (!baseCtx) return baseCanvas;\n\n const projection = getBaseProjection(region, transform, baseW, baseH);\n\n baseCtx.save();\n applyImageProjectionToContext(baseCtx, projection);\n baseCtx.drawImage(\n img,\n region.x, region.y, region.width, region.height,\n region.x, region.y, region.width, region.height\n );\n baseCtx.restore();\n\n const imageData = baseCtx.getImageData(0, 0, baseW, baseH);\n if (imageData) {\n applyAdjustments(imageData, adjustments);\n\n if (depthMask.enabled && depthMask.maskSource) {\n try {\n const maskImg = await this.imageCache.get(depthMask.maskSource);\n const maskSize = getSourceSize(maskImg, naturalWidth, naturalHeight);\n const sx = maskSize.width / naturalWidth;\n const sy = maskSize.height / naturalHeight;\n const maskCanvas = this.createCanvas(baseW, baseH);\n const maskCtx = maskCanvas.getContext('2d');\n if (maskCtx) {\n // The depth map covers the whole source image; scale it to natural pixels and\n // apply the exact same rotate/flip/crop projection as the image itself.\n maskCtx.save();\n applyImageProjectionToContext(maskCtx, projection);\n maskCtx.drawImage(\n maskImg,\n region.x * sx, region.y * sy, region.width * sx, region.height * sy,\n region.x, region.y, region.width, region.height\n );\n maskCtx.restore();\n const maskData = maskCtx.getImageData(0, 0, baseW, baseH);\n if (maskData) {\n applyDepthMask(imageData, maskData, depthMask);\n }\n }\n } catch {\n // Mask failed to load; continue without crashing\n }\n }\n\n onPixels?.(imageData);\n baseCtx.putImageData(imageData, 0, 0);\n }\n\n return baseCanvas;\n }\n\n private getSourceId(img: CanvasImageSource): number {\n const key = img as unknown as object;\n let id = this.sourceIds.get(key);\n if (id === undefined) {\n id = ++this.nextSourceId;\n this.sourceIds.set(key, id);\n }\n return id;\n }\n\n /**\n * Draws an individual annotation onto the canvas.\n */\n public async drawAnnotation(ctx: CanvasRenderingContext2D, ann: Annotation): Promise<void> {\n const blend = normalizeBlendMode(ann.blend);\n if (blend === 'normal') {\n await this.drawAnnotationContent(ctx, ann);\n return;\n }\n const op = canvasCompositeOperation(blend);\n if (op) {\n ctx.save();\n ctx.globalCompositeOperation = op;\n await this.drawAnnotationContent(ctx, ann);\n ctx.restore();\n return;\n }\n if (!(await this.drawAnnotationBlended(ctx, ann))) {\n // No pixel access (e.g. a tainted or headless canvas): draw it normally.\n await this.drawAnnotationContent(ctx, ann);\n }\n }\n\n /**\n * Scalar fallback for blend modes the canvas cannot composite (Photoshop soft light, linear /\n * vivid / pin light, hard mix, subtract, divide, darker / lighter colour, linear burn / dodge):\n * draws the annotation on a same-size layer with the same transform, blends it into a copy of\n * the target's pixels with `blendImageData`, and copies the result back inside the current clip.\n */\n private async drawAnnotationBlended(ctx: CanvasRenderingContext2D, ann: Annotation): Promise<boolean> {\n const canvas = ctx.canvas as HTMLCanvasElement | undefined;\n if (!canvas || typeof ctx.getTransform !== 'function' || typeof ctx.getImageData !== 'function') return false;\n const w = canvas.width;\n const h = canvas.height;\n const layer = this.createCanvas(w, h);\n const lctx = layer.getContext('2d');\n if (!lctx) return false;\n try {\n lctx.setTransform(ctx.getTransform());\n lctx.globalAlpha = ctx.globalAlpha;\n await this.drawAnnotationContent(lctx, ann);\n const backdrop = ctx.getImageData(0, 0, w, h);\n const source = lctx.getImageData(0, 0, w, h);\n if (!backdrop || !source) return false;\n blendImageData(backdrop, source, normalizeBlendMode(ann.blend));\n lctx.setTransform(1, 0, 0, 1, 0, 0);\n lctx.putImageData(backdrop, 0, 0);\n } catch {\n return false;\n }\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.globalAlpha = 1;\n ctx.globalCompositeOperation = 'copy';\n ctx.drawImage(layer, 0, 0);\n ctx.restore();\n return true;\n }\n\n private async drawAnnotationContent(ctx: CanvasRenderingContext2D, ann: Annotation): Promise<void> {\n ctx.save();\n if (ann.opacity !== undefined) {\n ctx.globalAlpha = ann.opacity;\n }\n\n if (ann.rotation) {\n ctx.translate(ann.x, ann.y);\n ctx.rotate((ann.rotation * Math.PI) / 180);\n ctx.translate(-ann.x, -ann.y);\n }\n\n switch (ann.type) {\n case 'pen': {\n const pen = ann as PenAnnotation;\n if (pen.points.length > 0) {\n ctx.beginPath();\n ctx.strokeStyle = pen.strokeColor;\n ctx.lineWidth = pen.strokeWidth;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n ctx.moveTo(pen.points[0].x, pen.points[0].y);\n for (let i = 1; i < pen.points.length; i++) {\n ctx.lineTo(pen.points[i].x, pen.points[i].y);\n }\n ctx.stroke();\n }\n break;\n }\n\n case 'rect': {\n const rect = ann as RectAnnotation;\n ctx.strokeStyle = rect.strokeColor;\n ctx.lineWidth = rect.strokeWidth;\n if (rect.fillColor) {\n ctx.fillStyle = rect.fillColor;\n ctx.fillRect(rect.x, rect.y, rect.width, rect.height);\n }\n if (rect.strokeWidth > 0) {\n ctx.strokeRect(rect.x, rect.y, rect.width, rect.height);\n }\n break;\n }\n\n case 'circle': {\n const circle = ann as CircleAnnotation;\n ctx.beginPath();\n ctx.strokeStyle = circle.strokeColor;\n ctx.lineWidth = circle.strokeWidth;\n ctx.ellipse(circle.x, circle.y, Math.abs(circle.radiusX), Math.abs(circle.radiusY), 0, 0, 2 * Math.PI);\n if (circle.fillColor) {\n ctx.fillStyle = circle.fillColor;\n ctx.fill();\n }\n if (circle.strokeWidth > 0) {\n ctx.stroke();\n }\n break;\n }\n\n case 'arrow': {\n const arrow = ann as ArrowAnnotation;\n ctx.strokeStyle = arrow.strokeColor;\n ctx.fillStyle = arrow.strokeColor;\n ctx.lineWidth = arrow.strokeWidth;\n\n // Line body\n ctx.beginPath();\n ctx.moveTo(arrow.x, arrow.y);\n ctx.lineTo(arrow.endX, arrow.endY);\n ctx.stroke();\n\n // Arrow head\n const angle = Math.atan2(arrow.endY - arrow.y, arrow.endX - arrow.x);\n const headLen = Math.max(12, arrow.strokeWidth * 3);\n ctx.beginPath();\n ctx.moveTo(arrow.endX, arrow.endY);\n ctx.lineTo(\n arrow.endX - headLen * Math.cos(angle - Math.PI / 6),\n arrow.endY - headLen * Math.sin(angle - Math.PI / 6)\n );\n ctx.lineTo(\n arrow.endX - headLen * Math.cos(angle + Math.PI / 6),\n arrow.endY - headLen * Math.sin(angle + Math.PI / 6)\n );\n ctx.closePath();\n ctx.fill();\n break;\n }\n\n case 'line': {\n const line = ann as LineAnnotation;\n ctx.beginPath();\n ctx.strokeStyle = line.strokeColor;\n ctx.lineWidth = line.strokeWidth;\n ctx.moveTo(line.x, line.y);\n ctx.lineTo(line.endX, line.endY);\n ctx.stroke();\n break;\n }\n\n case 'text': {\n const textAnn = ann as TextAnnotation;\n ctx.font = `${textAnn.fontWeight || 'normal'} ${textAnn.fontSize}px ${textAnn.fontFamily || 'sans-serif'}`;\n ctx.fillStyle = textAnn.color;\n ctx.textBaseline = 'top';\n ctx.fillText(textAnn.text, textAnn.x, textAnn.y);\n break;\n }\n\n case 'image': {\n const imgAnn = ann as ImageAnnotation;\n try {\n const loadedImg = await this.imageCache.get(imgAnn.src);\n ctx.drawImage(loadedImg, imgAnn.x, imgAnn.y, imgAnn.width, imgAnn.height);\n } catch {\n // Skip if watermark image failed to load\n }\n break;\n }\n }\n\n ctx.restore();\n }\n\n /**\n * Draws selection box around active annotation.\n */\n private drawAnnotationSelection(ctx: CanvasRenderingContext2D, ann: Annotation): void {\n ctx.save();\n ctx.strokeStyle = '#3b82f6'; // Tailwind blue-500\n ctx.lineWidth = 1.5;\n ctx.setLineDash([4, 4]);\n\n const bounds = getAnnotationBounds(ann);\n const pad = 4;\n ctx.strokeRect(bounds.x - pad, bounds.y - pad, bounds.width + pad * 2, bounds.height + pad * 2);\n\n // Draw handles\n ctx.fillStyle = '#ffffff';\n ctx.strokeStyle = '#3b82f6';\n ctx.setLineDash([]);\n const handleSize = 6;\n const corners = [\n { x: bounds.x - pad, y: bounds.y - pad },\n { x: bounds.x + bounds.width + pad, y: bounds.y - pad },\n { x: bounds.x - pad, y: bounds.y + bounds.height + pad },\n { x: bounds.x + bounds.width + pad, y: bounds.y + bounds.height + pad },\n ];\n for (const c of corners) {\n ctx.fillRect(c.x - handleSize / 2, c.y - handleSize / 2, handleSize, handleSize);\n ctx.strokeRect(c.x - handleSize / 2, c.y - handleSize / 2, handleSize, handleSize);\n }\n\n ctx.restore();\n }\n\n /** @deprecated Use the standalone `getAnnotationBounds` from the geometry module. */\n public getAnnotationBounds(ann: Annotation): { x: number; y: number; width: number; height: number } {\n return getAnnotationBounds(ann);\n }\n\n /**\n * Draws a rule-of-thirds crop grid overlay. All rectangles come from\n * `getViewportMetrics`, i.e. the crop box projected through rotation/flip.\n */\n private drawCropOverlay(ctx: CanvasRenderingContext2D, metrics: ViewportMetrics): void {\n const { imageRect, cropRect } = metrics;\n if (!cropRect) return;\n\n const imgL = imageRect.x;\n const imgT = imageRect.y;\n const imgR = imageRect.x + imageRect.width;\n const imgB = imageRect.y + imageRect.height;\n const startX = cropRect.x;\n const startY = cropRect.y;\n const cropBoxW = cropRect.width;\n const cropBoxH = cropRect.height;\n\n ctx.save();\n\n // Dark semi-transparent scrim outside crop box (within the image)\n ctx.fillStyle = 'rgba(0, 0, 0, 0.45)';\n // Top\n ctx.fillRect(imgL, imgT, imageRect.width, Math.max(0, startY - imgT));\n // Bottom\n ctx.fillRect(imgL, startY + cropBoxH, imageRect.width, Math.max(0, imgB - (startY + cropBoxH)));\n // Left\n ctx.fillRect(imgL, startY, Math.max(0, startX - imgL), cropBoxH);\n // Right\n ctx.fillRect(startX + cropBoxW, startY, Math.max(0, imgR - (startX + cropBoxW)), cropBoxH);\n\n // Crop border\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = 2;\n ctx.strokeRect(startX, startY, cropBoxW, cropBoxH);\n\n // Rule of thirds lines\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.4)';\n ctx.lineWidth = 1;\n ctx.beginPath();\n // Vertical lines\n ctx.moveTo(startX + cropBoxW / 3, startY);\n ctx.lineTo(startX + cropBoxW / 3, startY + cropBoxH);\n ctx.moveTo(startX + (cropBoxW * 2) / 3, startY);\n ctx.lineTo(startX + (cropBoxW * 2) / 3, startY + cropBoxH);\n // Horizontal lines\n ctx.moveTo(startX, startY + cropBoxH / 3);\n ctx.lineTo(startX + cropBoxW, startY + cropBoxH / 3);\n ctx.moveTo(startX, startY + (cropBoxH * 2) / 3);\n ctx.lineTo(startX + cropBoxW, startY + (cropBoxH * 2) / 3);\n ctx.stroke();\n\n // Corner and edge handles\n ctx.fillStyle = '#ffffff';\n ctx.strokeStyle = '#0284c7';\n ctx.lineWidth = 1.5;\n const handleSize = 10;\n const handles = [\n // Corners\n { x: startX, y: startY },\n { x: startX + cropBoxW, y: startY },\n { x: startX, y: startY + cropBoxH },\n { x: startX + cropBoxW, y: startY + cropBoxH },\n // Edges\n { x: startX + cropBoxW / 2, y: startY },\n { x: startX + cropBoxW / 2, y: startY + cropBoxH },\n { x: startX, y: startY + cropBoxH / 2 },\n { x: startX + cropBoxW, y: startY + cropBoxH / 2 },\n ];\n for (const h of handles) {\n ctx.fillRect(h.x - handleSize / 2, h.y - handleSize / 2, handleSize, handleSize);\n ctx.strokeRect(h.x - handleSize / 2, h.y - handleSize / 2, handleSize, handleSize);\n }\n\n ctx.restore();\n }\n\n private drawFittedImage(\n ctx: CanvasRenderingContext2D,\n img: CanvasImageSource,\n imgW: number,\n imgH: number,\n vpW: number,\n vpH: number,\n zoom: number,\n pan: { x: number; y: number }\n ): void {\n ctx.save();\n ctx.translate(vpW / 2 + pan.x, vpH / 2 + pan.y);\n ctx.scale(zoom, zoom);\n const fitScale = Math.min((vpW * 0.85) / imgW, (vpH * 0.85) / imgH, 1);\n const renderW = imgW * fitScale;\n const renderH = imgH * fitScale;\n ctx.drawImage(img, -renderW / 2, -renderH / 2, renderW, renderH);\n ctx.restore();\n }\n\n /**\n * Performs an export render at exact pixel dimensions without zoom/pan viewport offsets.\n */\n public async renderExport(\n imageSource: CanvasImageSource | string,\n state: ImageEditorState,\n options: ExportOptions = {}\n ): Promise<HTMLCanvasElement> {\n let img: CanvasImageSource;\n if (typeof imageSource === 'string') {\n img = await this.imageCache.get(imageSource);\n } else {\n img = imageSource;\n }\n\n const { width: naturalWidth, height: naturalHeight } = getSourceSize(img);\n const { crop, transform, annotations } = state;\n\n const region = crop\n ? clampCropToImage(crop, naturalWidth, naturalHeight)\n : { x: 0, y: 0, width: naturalWidth, height: naturalHeight };\n const rotated = getRotatedSize(region.width, region.height, transform);\n const baseW = Math.max(1, Math.round(rotated.width));\n const baseH = Math.max(1, Math.round(rotated.height));\n\n const exportW = options.width || baseW;\n const exportH = options.height || baseH;\n\n const exportCanvas = this.createCanvas(exportW, exportH);\n const ctx = exportCanvas.getContext('2d');\n if (!ctx) return exportCanvas;\n\n const baseCanvas = await this.renderBaseImage(img, naturalWidth, naturalHeight, region, transform, state);\n\n // Scale to target export dimensions\n ctx.drawImage(baseCanvas, 0, 0, baseW, baseH, 0, 0, exportW, exportH);\n\n // Draw annotations (natural image space) through the same rotate/flip/crop projection\n if (options.includeAnnotations !== false && annotations.length > 0) {\n ctx.save();\n ctx.scale(exportW / baseW, exportH / baseH);\n applyImageProjectionToContext(ctx, getBaseProjection(region, transform, baseW, baseH));\n for (const ann of annotations) {\n await this.drawAnnotation(ctx, ann);\n }\n ctx.restore();\n }\n\n return exportCanvas;\n }\n\n /**\n * Generates a strictly binary mask canvas (white = area to regenerate, black = keep) in\n * natural image pixel space of the current source image — the same space the crop box\n * and annotations are stored in. Pair it with `toSourceDataURL()` for AI inpainting.\n */\n public async renderMask(\n state: ImageEditorState,\n options?: { useAnnotations?: boolean; useCrop?: boolean }\n ): Promise<HTMLCanvasElement> {\n const naturalWidth = Math.max(1, Math.round(state.imageDimensions.width));\n const naturalHeight = Math.max(1, Math.round(state.imageDimensions.height));\n const maskCanvas = this.createCanvas(naturalWidth, naturalHeight);\n const ctx = maskCanvas.getContext('2d');\n if (!ctx) return maskCanvas;\n\n // Background: unmasked (black)\n ctx.fillStyle = MASK_BLACK;\n ctx.fillRect(0, 0, naturalWidth, naturalHeight);\n\n const useCrop = options?.useCrop ?? true;\n const useAnnotations = options?.useAnnotations ?? true;\n\n // Crop box mask (if active)\n if (useCrop && state.crop) {\n ctx.fillStyle = MASK_WHITE;\n ctx.fillRect(state.crop.x, state.crop.y, state.crop.width, state.crop.height);\n }\n\n // Annotation masks (drawn in solid white, never in annotation colours)\n if (useAnnotations && state.annotations.length > 0) {\n for (const ann of state.annotations) {\n this.drawAnnotationMask(ctx, ann);\n }\n }\n\n // Anti-aliased edges produce grey pixels: threshold to pure black/white.\n const imageData = ctx.getImageData?.(0, 0, naturalWidth, naturalHeight);\n if (imageData) {\n const d = imageData.data;\n for (let i = 0; i < d.length; i += 4) {\n const v = d[i] >= 128 ? 255 : 0;\n d[i] = v;\n d[i + 1] = v;\n d[i + 2] = v;\n d[i + 3] = 255;\n }\n ctx.putImageData(imageData, 0, 0);\n }\n\n return maskCanvas;\n }\n\n private drawAnnotationMask(ctx: CanvasRenderingContext2D, ann: Annotation): void {\n ctx.save();\n ctx.globalAlpha = 1;\n ctx.fillStyle = MASK_WHITE;\n ctx.strokeStyle = MASK_WHITE;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n if (ann.rotation) {\n ctx.translate(ann.x, ann.y);\n ctx.rotate((ann.rotation * Math.PI) / 180);\n ctx.translate(-ann.x, -ann.y);\n }\n\n switch (ann.type) {\n case 'pen': {\n if (ann.points.length > 0) {\n ctx.beginPath();\n ctx.lineWidth = Math.max(ann.strokeWidth || 0, 8);\n ctx.moveTo(ann.points[0].x, ann.points[0].y);\n for (let i = 1; i < ann.points.length; i++) {\n ctx.lineTo(ann.points[i].x, ann.points[i].y);\n }\n ctx.stroke();\n }\n break;\n }\n case 'circle': {\n ctx.beginPath();\n ctx.ellipse(ann.x, ann.y, Math.abs(ann.radiusX), Math.abs(ann.radiusY), 0, 0, Math.PI * 2);\n ctx.fill();\n break;\n }\n case 'arrow':\n case 'line': {\n ctx.beginPath();\n ctx.lineWidth = Math.max(ann.strokeWidth || 0, 8);\n ctx.moveTo(ann.x, ann.y);\n ctx.lineTo(ann.endX, ann.endY);\n ctx.stroke();\n break;\n }\n case 'rect':\n case 'image':\n case 'text': {\n const b = getAnnotationBounds(ann);\n ctx.fillRect(b.x, b.y, b.width, b.height);\n break;\n }\n }\n ctx.restore();\n }\n}\n\nconst MASK_WHITE = '#ffffff';\nconst MASK_BLACK = '#000000';\n\nfunction getSourceSize(img: CanvasImageSource, fallbackW = 800, fallbackH = 600): { width: number; height: number } {\n const anyImg = img as any;\n return {\n width: anyImg.naturalWidth || anyImg.videoWidth || anyImg.width || fallbackW,\n height: anyImg.naturalHeight || anyImg.videoHeight || anyImg.height || fallbackH,\n };\n}\n\nfunction getBaseProjection(region: CropBox, transform: ImageTransform, baseW: number, baseH: number): ImageProjection {\n return {\n region,\n angle: normalizeAngle(transform.rotate),\n flipH: transform.flipH,\n flipV: transform.flipV,\n scale: 1,\n originX: baseW / 2,\n originY: baseH / 2,\n };\n}\n","import {\n AdjustmentKind,\n AdjustmentLayer,\n AdjustmentParamsMap,\n Annotation,\n CreateAnnotationPayload,\n AspectRatio,\n CropBox,\n DepthMaskOptions,\n ExportOptions,\n ImageAdjustments,\n ImageDimensions,\n ImageEditorOptions,\n ImageEditorState,\n ImageEditorTool,\n ImageTransform,\n ImagePoint,\n SerializedImageEditorState,\n} from './types';\nimport { ImageEditorRenderer, RenderOptions } from './renderer';\nimport { clampCropToImage, isQuarterTurnSwapped } from './geometry';\nimport { LATEST_PROCESS_VERSION, LEGACY_PROCESS_VERSION, normalizeProcessVersion } from './color';\nimport { createAdjustmentLayer, normalizeAdjustmentLayer, normalizeAdjustmentLayers } from './adjustment-layers';\nimport type { BlendMode } from './blend';\nimport type { ImageHistogram } from './histogram';\n\n/** Latest serialized schema version (`2`: adjustment layers). */\nexport const IMAGE_EDITOR_SCHEMA_VERSION = 2 as const;\n\n/** Changes to an adjustment layer; `params` is merged into the current parameters. */\nexport interface AdjustmentLayerUpdate<K extends AdjustmentKind = AdjustmentKind> {\n params?: Partial<AdjustmentParamsMap[K]>;\n enabled?: boolean;\n opacity?: number;\n blend?: BlendMode;\n name?: string;\n}\n\n/** A new adjustment layer: its kind plus optional initial values. */\nexport interface AdjustmentLayerInit<K extends AdjustmentKind = AdjustmentKind> extends AdjustmentLayerUpdate<K> {\n kind: K;\n id?: string;\n}\n\n/** The image a history entry was recorded against. */\ninterface SourceSnapshot {\n sourceUrl: string | null;\n element: CanvasImageSource | null;\n dimensions: ImageDimensions;\n}\n\n/**\n * Undo/redo entry: the serializable edit state plus the source image it applies to, so\n * AI edits that replace the image are restorable.\n */\ninterface HistoryEntry {\n state: SerializedImageEditorState;\n source: SourceSnapshot;\n}\n\nexport const DEFAULT_ADJUSTMENTS: ImageAdjustments = {\n brightness: 0,\n contrast: 0,\n saturation: 0,\n exposure: 0,\n temperature: 0,\n tint: 0,\n blur: 0,\n opacity: 1,\n process: LATEST_PROCESS_VERSION,\n};\n\n/**\n * Fills in defaults for stored adjustments. A stored object without `process` was saved before\n * process versions existed and keeps the legacy rendering.\n */\nexport function normalizeStoredAdjustments(stored: Partial<ImageAdjustments> | undefined | null): ImageAdjustments {\n if (!stored) return { ...DEFAULT_ADJUSTMENTS };\n const out: ImageAdjustments = {\n ...DEFAULT_ADJUSTMENTS,\n ...stored,\n process: normalizeProcessVersion(stored.process),\n };\n // Layers are deep-copied and cleaned; an empty or missing list is left out entirely.\n const layers = normalizeAdjustmentLayers(stored.layers);\n if (layers.length) out.layers = layers;\n else delete out.layers;\n return out;\n}\n\n/**\n * Brings a stored editor state of any schema version to the current shape. Version 1 (and a\n * missing version) has no adjustment layers; everything else is unchanged, so old states load\n * and render exactly as before.\n */\nexport function migrateSerializedImageEditorState(\n data: Partial<SerializedImageEditorState> & { version?: number }\n): SerializedImageEditorState {\n const adjustments = normalizeStoredAdjustments(data.adjustments);\n return {\n version: adjustments.layers?.length ? IMAGE_EDITOR_SCHEMA_VERSION : 1,\n crop: data.crop ? { ...data.crop } : null,\n transform: { ...DEFAULT_TRANSFORM, ...data.transform },\n adjustments: serializeAdjustments(adjustments),\n depthMask: {\n ...DEFAULT_DEPTH_MASK,\n ...data.depthMask,\n depthRange: [...(data.depthMask?.depthRange ?? DEFAULT_DEPTH_MASK.depthRange)] as [number, number],\n },\n annotations: JSON.parse(JSON.stringify(data.annotations ?? [])),\n };\n}\n\nexport const DEFAULT_TRANSFORM: ImageTransform = {\n rotate: 0,\n flipH: false,\n flipV: false,\n};\n\nexport const DEFAULT_DEPTH_MASK: DepthMaskOptions = {\n enabled: false,\n maskSource: null,\n mode: 'threshold',\n depthRange: [0, 255],\n softness: 10,\n invert: false,\n};\n\n/**\n * ImageEditorController manages the complete lifecycle, canvas rendering pipeline,\n * tool interaction states, undo/redo history, serialization, and image export.\n */\nexport class ImageEditorController {\n private state: ImageEditorState;\n private renderer: ImageEditorRenderer;\n private imageElement: CanvasImageSource | null = null;\n private listeners = new Set<(state: ImageEditorState) => void>();\n private histogramListeners = new Set<(histogram: ImageHistogram | null) => void>();\n private onStateChange?: (state: ImageEditorState) => void;\n\n // History stacks\n private undoStack: HistoryEntry[] = [];\n private redoStack: HistoryEntry[] = [];\n private maxHistoryDepth: number;\n private isApplyingHistory = false;\n private initialSnapshot: HistoryEntry;\n\n constructor(options: ImageEditorOptions = {}) {\n this.maxHistoryDepth = options.maxHistoryDepth ?? 50;\n this.onStateChange = options.onStateChange;\n this.renderer = new ImageEditorRenderer();\n this.renderer.onPreviewHistogram = (histogram) => {\n this.histogramListeners.forEach((l) => l(histogram));\n };\n\n const initialAdjustments = normalizeStoredAdjustments(options.initialState?.adjustments);\n\n const initialTransform: ImageTransform = {\n ...DEFAULT_TRANSFORM,\n ...options.initialState?.transform,\n };\n\n const initialDepthMask: DepthMaskOptions = {\n ...DEFAULT_DEPTH_MASK,\n ...options.initialState?.depthMask,\n };\n\n this.state = {\n sourceUrl: typeof options.image === 'string' ? options.image : null,\n imageDimensions: { width: 800, height: 600 },\n crop: options.initialState?.crop ?? null,\n transform: initialTransform,\n adjustments: initialAdjustments,\n depthMask: initialDepthMask,\n annotations: options.initialState?.annotations ?? [],\n selectedAnnotationId: null,\n activeTool: 'select',\n zoom: 1,\n pan: { x: 0, y: 0 },\n isOriginalCompared: false,\n };\n\n if (options.image instanceof Object && 'width' in options.image) {\n this.imageElement = options.image as CanvasImageSource;\n this.state.sourceUrl = (options.image as any).src || null;\n this.state.imageDimensions = {\n width: (options.image as any).naturalWidth || (options.image as any).width || 800,\n height: (options.image as any).naturalHeight || (options.image as any).height || 600,\n };\n }\n\n this.initialSnapshot = this.captureHistoryEntry();\n\n if (typeof options.image === 'string') {\n this.loadImage(options.image);\n }\n }\n\n // --- Image Loading ---\n\n /**\n * Loads a new source image and makes it the baseline that `reset()` returns to.\n * Does not record history; use `applyInpaintedImage` / `applyBackgroundRemovedImage`\n * for undoable source replacement.\n */\n public async loadImage(src: string | HTMLImageElement): Promise<void> {\n // Keep the URL visible synchronously (UI bindings compare against it while loading).\n if (typeof src === 'string') this.state.sourceUrl = src;\n const source = await this.resolveSource(src);\n this.imageElement = source.element;\n this.state.sourceUrl = source.sourceUrl;\n this.state.imageDimensions = source.dimensions;\n\n this.initialSnapshot = this.captureHistoryEntry();\n this.notify();\n }\n\n private async resolveSource(src: string | HTMLImageElement): Promise<SourceSnapshot> {\n if (typeof src === 'string') {\n try {\n const img = await this.renderer.imageCache.get(src);\n return {\n sourceUrl: src,\n element: img,\n dimensions: {\n width: img.naturalWidth || img.width || 800,\n height: img.naturalHeight || img.height || 600,\n },\n };\n } catch {\n // In SSR / non-DOM environments, retain current dimensions\n return { sourceUrl: src, element: null, dimensions: { ...this.state.imageDimensions } };\n }\n }\n return {\n sourceUrl: (src as any).src || null,\n element: src,\n dimensions: {\n width: src.naturalWidth || src.width || 800,\n height: src.naturalHeight || src.height || 600,\n },\n };\n }\n\n public getImageElement(): CanvasImageSource | null {\n return this.imageElement;\n }\n\n // --- State & Subscription ---\n\n public getState(): ImageEditorState {\n return this.state;\n }\n\n public subscribe(listener: (state: ImageEditorState) => void): () => void {\n this.listeners.add(listener);\n listener(this.state);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private notify(): void {\n const currentState = { ...this.state };\n this.onStateChange?.(currentState);\n this.listeners.forEach((l) => l(currentState));\n }\n\n // --- History (Undo / Redo / Reset) ---\n\n private captureHistoryEntry(): HistoryEntry {\n return {\n state: this.serializeState(),\n source: {\n sourceUrl: this.state.sourceUrl,\n element: this.imageElement,\n dimensions: { ...this.state.imageDimensions },\n },\n };\n }\n\n private restoreHistoryEntry(entry: HistoryEntry): void {\n this.applySerializedState(entry.state);\n this.imageElement = entry.source.element;\n this.state.sourceUrl = entry.source.sourceUrl;\n this.state.imageDimensions = { ...entry.source.dimensions };\n if (\n this.state.selectedAnnotationId &&\n !this.state.annotations.some((a) => a.id === this.state.selectedAnnotationId)\n ) {\n this.state.selectedAnnotationId = null;\n }\n }\n\n private recordHistory(): void {\n if (this.isApplyingHistory) return;\n this.undoStack.push(this.captureHistoryEntry());\n if (this.undoStack.length > this.maxHistoryDepth) {\n this.undoStack.shift();\n }\n this.redoStack = [];\n }\n\n public get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n public get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n public undo(): boolean {\n if (!this.canUndo) return false;\n this.isApplyingHistory = true;\n this.redoStack.push(this.captureHistoryEntry());\n\n const prev = this.undoStack.pop()!;\n this.restoreHistoryEntry(prev);\n this.isApplyingHistory = false;\n this.notify();\n return true;\n }\n\n public redo(): boolean {\n if (!this.canRedo) return false;\n this.isApplyingHistory = true;\n this.undoStack.push(this.captureHistoryEntry());\n\n const next = this.redoStack.pop()!;\n this.restoreHistoryEntry(next);\n this.isApplyingHistory = false;\n this.notify();\n return true;\n }\n\n public reset(): void {\n this.recordHistory();\n this.restoreHistoryEntry(this.initialSnapshot);\n this.state.zoom = 1;\n this.state.pan = { x: 0, y: 0 };\n this.state.activeTool = 'select';\n this.state.selectedAnnotationId = null;\n this.notify();\n }\n\n // --- Active Tool ---\n\n public setTool(tool: ImageEditorTool): void {\n if (this.state.activeTool === tool) return;\n this.state.activeTool = tool;\n if (tool !== 'select') {\n this.state.selectedAnnotationId = null;\n }\n // If switching to crop tool and no crop is defined, initialize crop to full image\n if (tool === 'crop' && !this.state.crop) {\n this.state.crop = {\n x: 0,\n y: 0,\n width: this.state.imageDimensions.width,\n height: this.state.imageDimensions.height,\n };\n }\n this.notify();\n }\n\n // --- Crop ---\n\n public setCrop(crop: CropBox | null, addToHistory = true): void {\n if (addToHistory) {\n this.recordHistory();\n }\n this.state.crop = crop;\n this.notify();\n }\n\n public applyCropPreset(ratio: AspectRatio): void {\n this.recordHistory();\n const { width, height } = this.state.imageDimensions;\n // `ratio` is the on-screen aspect; the crop box lives in natural image space.\n if (ratio && isQuarterTurnSwapped(this.state.transform)) {\n ratio = 1 / ratio;\n }\n if (!ratio) {\n // Freeform: full image\n this.state.crop = { x: 0, y: 0, width, height };\n } else {\n let targetW = width;\n let targetH = targetW / ratio;\n\n if (targetH > height) {\n targetH = height;\n targetW = targetH * ratio;\n }\n\n const x = Math.max(0, Math.round((width - targetW) / 2));\n const y = Math.max(0, Math.round((height - targetH) / 2));\n this.state.crop = {\n x,\n y,\n width: Math.round(targetW),\n height: Math.round(targetH),\n };\n }\n this.notify();\n }\n\n public resetCrop(): void {\n this.recordHistory();\n this.state.crop = null;\n this.notify();\n }\n\n // --- Transformations (Rotate / Flip) ---\n\n public rotate(degrees: number): void {\n this.recordHistory();\n const current = this.state.transform.rotate;\n this.state.transform = { ...this.state.transform, rotate: (current + degrees) % 360 };\n this.notify();\n }\n\n public setRotation(degrees: number): void {\n this.recordHistory();\n this.state.transform = { ...this.state.transform, rotate: degrees % 360 };\n this.notify();\n }\n\n public flipHorizontal(): void {\n this.recordHistory();\n this.state.transform = { ...this.state.transform, flipH: !this.state.transform.flipH };\n this.notify();\n }\n\n public flipVertical(): void {\n this.recordHistory();\n this.state.transform = { ...this.state.transform, flipV: !this.state.transform.flipV };\n this.notify();\n }\n\n // --- Adjustments ---\n\n public setAdjustments(partial: Partial<ImageAdjustments>, commitToHistory = true): void {\n if (commitToHistory) {\n this.recordHistory();\n }\n const next: ImageAdjustments = {\n ...this.state.adjustments,\n ...partial,\n };\n if ('layers' in partial) {\n const layers = normalizeAdjustmentLayers(partial.layers);\n if (layers.length) next.layers = layers;\n else delete next.layers;\n }\n this.state.adjustments = next;\n this.notify();\n }\n\n /** True when the adjustments use an older rendering process than {@link LATEST_PROCESS_VERSION}. */\n public get isProcessOutdated(): boolean {\n return normalizeProcessVersion(this.state.adjustments.process) < LATEST_PROCESS_VERSION;\n }\n\n /**\n * Update to Current Process: re-interprets the current adjustment values with the latest\n * rendering process (one undo step). Returns false when already current.\n */\n public upgradeProcess(): boolean {\n if (!this.isProcessOutdated) return false;\n this.setAdjustments({ process: LATEST_PROCESS_VERSION });\n return true;\n }\n\n /** Resets the base sliders (latest process). Adjustment layers are kept; see `clearAdjustmentLayers`. */\n public resetAdjustments(): void {\n this.recordHistory();\n const layers = this.state.adjustments.layers;\n this.state.adjustments = { ...DEFAULT_ADJUSTMENTS };\n if (layers?.length) this.state.adjustments.layers = layers;\n this.notify();\n }\n\n // --- Adjustment layers ---\n\n /** The adjustment layers, bottom (first) to top (last). */\n public getAdjustmentLayers(): AdjustmentLayer[] {\n return this.state.adjustments.layers ?? [];\n }\n\n public getAdjustmentLayer(id: string): AdjustmentLayer | undefined {\n return this.getAdjustmentLayers().find((l) => l.id === id);\n }\n\n private setLayers(layers: AdjustmentLayer[]): void {\n const next: ImageAdjustments = { ...this.state.adjustments };\n if (layers.length) next.layers = layers;\n else delete next.layers;\n this.state.adjustments = next;\n }\n\n /**\n * Adds an adjustment layer on top (or at `index`, 0 = bottom) as one undo step and returns\n * its id. `kind` alone gives neutral parameters.\n */\n public addAdjustmentLayer<K extends AdjustmentKind>(init: K | AdjustmentLayerInit<K>, index?: number): string {\n const spec: AdjustmentLayerInit<K> = typeof init === 'string' ? { kind: init } : init;\n const layers = [...this.getAdjustmentLayers()];\n const layer = createAdjustmentLayer(spec.kind, {\n id: spec.id && !layers.some((l) => l.id === spec.id) ? spec.id : undefined,\n name: spec.name,\n params: spec.params,\n enabled: spec.enabled,\n opacity: spec.opacity,\n blend: spec.blend,\n });\n this.recordHistory();\n const at = index === undefined ? layers.length : Math.max(0, Math.min(layers.length, Math.round(index)));\n layers.splice(at, 0, layer);\n this.setLayers(layers);\n this.notify();\n return layer.id;\n }\n\n /**\n * Updates a layer (`params` merged into the current ones, then normalised). Pass\n * `commitToHistory = false` for the moves of a drag after recording its start once.\n * Returns false for an unknown id.\n */\n public updateAdjustmentLayer(id: string, update: AdjustmentLayerUpdate, commitToHistory = true): boolean {\n const layers = this.getAdjustmentLayers();\n const index = layers.findIndex((l) => l.id === id);\n if (index === -1) return false;\n const current = layers[index];\n const merged = normalizeAdjustmentLayer({\n ...current,\n ...(update.enabled !== undefined ? { enabled: update.enabled } : {}),\n ...(update.opacity !== undefined ? { opacity: update.opacity } : {}),\n ...(update.blend !== undefined ? { blend: update.blend } : {}),\n ...(update.name !== undefined ? { name: update.name } : {}),\n params: { ...current.params, ...(update.params ?? {}) },\n });\n if (!merged) return false;\n if (commitToHistory) this.recordHistory();\n const next = [...layers];\n next[index] = merged;\n this.setLayers(next);\n this.notify();\n return true;\n }\n\n /** Removes a layer as one undo step. Returns false for an unknown id. */\n public removeAdjustmentLayer(id: string): boolean {\n const layers = this.getAdjustmentLayers();\n if (!layers.some((l) => l.id === id)) return false;\n this.recordHistory();\n this.setLayers(layers.filter((l) => l.id !== id));\n this.notify();\n return true;\n }\n\n /** Moves a layer to `toIndex` (0 = bottom) as one undo step. Returns false if nothing moved. */\n public moveAdjustmentLayer(id: string, toIndex: number): boolean {\n const layers = [...this.getAdjustmentLayers()];\n const from = layers.findIndex((l) => l.id === id);\n if (from === -1) return false;\n const to = Math.max(0, Math.min(layers.length - 1, Math.round(toIndex)));\n if (to === from) return false;\n this.recordHistory();\n const [layer] = layers.splice(from, 1);\n layers.splice(to, 0, layer);\n this.setLayers(layers);\n this.notify();\n return true;\n }\n\n /** Shows or hides a layer (flips it without `enabled`) as one undo step. */\n public toggleAdjustmentLayer(id: string, enabled?: boolean): boolean {\n const layer = this.getAdjustmentLayer(id);\n if (!layer) return false;\n const next = enabled ?? !layer.enabled;\n if (next === layer.enabled) return false;\n return this.updateAdjustmentLayer(id, { enabled: next });\n }\n\n /** Removes every adjustment layer as one undo step. */\n public clearAdjustmentLayers(): void {\n if (!this.getAdjustmentLayers().length) return;\n this.recordHistory();\n this.setLayers([]);\n this.notify();\n }\n\n // --- Histogram ---\n\n /**\n * Histogram of the last rendered preview (after adjustments and layers, before annotations),\n * or `null` before the first render or without canvas pixel access.\n */\n public getHistogram(): ImageHistogram | null {\n return this.renderer.previewHistogram;\n }\n\n /** Calls `listener` now and whenever a render produces a new preview histogram. */\n public subscribeHistogram(listener: (histogram: ImageHistogram | null) => void): () => void {\n this.histogramListeners.add(listener);\n listener(this.renderer.previewHistogram);\n return () => {\n this.histogramListeners.delete(listener);\n };\n }\n\n // --- Depth Masking (Gleamforge) ---\n\n public setDepthMask(partial: Partial<DepthMaskOptions>): void {\n this.recordHistory();\n this.state.depthMask = {\n ...this.state.depthMask,\n ...partial,\n };\n this.notify();\n }\n\n public resetDepthMask(): void {\n this.recordHistory();\n this.state.depthMask = { ...DEFAULT_DEPTH_MASK };\n this.notify();\n }\n\n // --- Annotations & Layers ---\n\n public addAnnotation(annotation: CreateAnnotationPayload): string {\n this.recordHistory();\n const id = `ann_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;\n const fullAnnotation = { ...annotation, id } as Annotation;\n this.state.annotations = [...this.state.annotations, fullAnnotation];\n this.state.selectedAnnotationId = id;\n this.notify();\n return id;\n }\n\n public updateAnnotation(id: string, partial: Partial<Annotation>, commitToHistory = true): void {\n if (commitToHistory) {\n this.recordHistory();\n }\n this.state.annotations = this.state.annotations.map((ann) => {\n if (ann.id === id) {\n return { ...ann, ...partial } as Annotation;\n }\n return ann;\n });\n this.notify();\n }\n\n public removeAnnotation(id: string): void {\n this.recordHistory();\n this.state.annotations = this.state.annotations.filter((ann) => ann.id !== id);\n if (this.state.selectedAnnotationId === id) {\n this.state.selectedAnnotationId = null;\n }\n this.notify();\n }\n\n public clearAnnotations(): void {\n this.recordHistory();\n this.state.annotations = [];\n this.state.selectedAnnotationId = null;\n this.notify();\n }\n\n public selectAnnotation(id: string | null): void {\n this.state.selectedAnnotationId = id;\n this.notify();\n }\n\n // --- Zoom & Pan ---\n\n public setZoom(zoom: number): void {\n this.state.zoom = Math.max(0.1, Math.min(10, zoom));\n this.notify();\n }\n\n public zoomIn(factor = 1.2): void {\n this.setZoom(this.state.zoom * factor);\n }\n\n public zoomOut(factor = 1.2): void {\n this.setZoom(this.state.zoom / factor);\n }\n\n public resetZoom(): void {\n this.state.zoom = 1;\n this.state.pan = { x: 0, y: 0 };\n this.notify();\n }\n\n public setPan(pan: ImagePoint): void {\n this.state.pan = pan;\n this.notify();\n }\n\n public setComparing(comparing: boolean): void {\n if (this.state.isOriginalCompared === comparing) return;\n this.state.isOriginalCompared = comparing;\n this.notify();\n }\n\n // --- Rendering & Export ---\n\n public async render(targetCanvas: HTMLCanvasElement, options?: RenderOptions): Promise<void> {\n const source = this.imageElement || this.state.sourceUrl;\n if (!source) return;\n try {\n await this.renderer.renderToCanvas(targetCanvas, source, this.state, options);\n } catch {\n // In non-DOM or test mock environments without image loading, safely ignore\n }\n }\n\n public async renderExport(options?: ExportOptions): Promise<HTMLCanvasElement> {\n const source = this.imageElement || this.state.sourceUrl;\n if (!source) {\n return this.renderer.createCanvas(1, 1);\n }\n return this.renderer.renderExport(source, this.state, options);\n }\n\n public async toDataURL(options: ExportOptions = {}): Promise<string> {\n const canvas = await this.renderExport(options);\n const format = options.format || 'image/png';\n const quality = options.quality ?? 0.92;\n return canvas.toDataURL(format, quality);\n }\n\n public async toBlob(options: ExportOptions = {}): Promise<Blob> {\n const canvas = await this.renderExport(options);\n const format = options.format || 'image/png';\n const quality = options.quality ?? 0.92;\n\n return new Promise((resolve, reject) => {\n if (canvas.toBlob) {\n canvas.toBlob((blob) => {\n if (blob) resolve(blob);\n else reject(new Error('Failed to create Blob from canvas'));\n }, format, quality);\n } else {\n // Fallback for environments lacking canvas.toBlob\n try {\n const dataUrl = canvas.toDataURL(format, quality);\n const parts = dataUrl.split(',');\n const byteStr = atob(parts[1]);\n const ab = new ArrayBuffer(byteStr.length);\n const ia = new Uint8Array(ab);\n for (let i = 0; i < byteStr.length; i++) {\n ia[i] = byteStr.charCodeAt(i);\n }\n resolve(new Blob([ab], { type: format }));\n } catch (err) {\n reject(err);\n }\n }\n });\n }\n\n // --- AI Masking & Transformation Helpers ---\n\n public async renderMask(options?: { useAnnotations?: boolean; useCrop?: boolean }): Promise<HTMLCanvasElement> {\n return this.renderer.renderMask(this.state, options);\n }\n\n public async toMaskDataURL(options?: { useAnnotations?: boolean; useCrop?: boolean }): Promise<string> {\n const canvas = await this.renderMask(options);\n return canvas.toDataURL('image/png');\n }\n\n /**\n * Renders the current source image at natural size with no crop, rotation, flip,\n * adjustments or annotations. This is the image that `toMaskDataURL()` is aligned with\n * and the space that `applyInpaintedImage` / `applyBackgroundRemovedImage` expect back.\n */\n public async renderSource(): Promise<HTMLCanvasElement> {\n const { width, height } = this.state.imageDimensions;\n const canvas = this.renderer.createCanvas(width, height);\n const source = this.imageElement || this.state.sourceUrl;\n const ctx = canvas.getContext('2d');\n if (!ctx || !source) return canvas;\n const img = typeof source === 'string' ? await this.renderer.imageCache.get(source) : source;\n ctx.drawImage(img, 0, 0, width, height);\n return canvas;\n }\n\n public async toSourceDataURL(options: Pick<ExportOptions, 'format' | 'quality'> = {}): Promise<string> {\n const canvas = await this.renderSource();\n return canvas.toDataURL(options.format || 'image/png', options.quality ?? 0.92);\n }\n\n /**\n * Replaces the source image with an inpainted result (natural image space, see\n * `toSourceDataURL`) and clears the mask annotations, as ONE undoable step.\n */\n public async applyInpaintedImage(newDataUrl: string): Promise<void> {\n await this.replaceSource(newDataUrl, true);\n }\n\n /**\n * Replaces the source image with a background-removed result as ONE undoable step.\n * Crop and annotations are kept (rescaled if the new image has different dimensions).\n */\n public async applyBackgroundRemovedImage(newDataUrl: string): Promise<void> {\n await this.replaceSource(newDataUrl, false);\n }\n\n private async replaceSource(src: string, clearAnnotations: boolean): Promise<void> {\n const next = await this.resolveSource(src);\n this.recordHistory();\n\n const prev = this.state.imageDimensions;\n const sx = next.dimensions.width / (prev.width || next.dimensions.width);\n const sy = next.dimensions.height / (prev.height || next.dimensions.height);\n\n this.imageElement = next.element;\n this.state.sourceUrl = next.sourceUrl;\n this.state.imageDimensions = next.dimensions;\n\n if (sx !== 1 || sy !== 1) {\n if (this.state.crop) {\n this.state.crop = clampCropToImage(\n {\n x: Math.round(this.state.crop.x * sx),\n y: Math.round(this.state.crop.y * sy),\n width: Math.round(this.state.crop.width * sx),\n height: Math.round(this.state.crop.height * sy),\n },\n next.dimensions.width,\n next.dimensions.height\n );\n }\n this.state.annotations = this.state.annotations.map((ann) => scaleAnnotation(ann, sx, sy));\n }\n\n if (clearAnnotations) {\n this.state.annotations = [];\n this.state.selectedAnnotationId = null;\n }\n this.notify();\n }\n\n // --- Serialization ---\n\n public toJSON(): SerializedImageEditorState {\n return this.serializeState();\n }\n\n public loadJSON(data: SerializedImageEditorState): void {\n this.recordHistory();\n this.applySerializedState(migrateSerializedImageEditorState(data));\n this.notify();\n }\n\n private serializeState(): SerializedImageEditorState {\n return {\n // States without adjustment layers keep schema 1, so they round-trip unchanged.\n version: this.state.adjustments.layers?.length ? IMAGE_EDITOR_SCHEMA_VERSION : 1,\n crop: this.state.crop ? { ...this.state.crop } : null,\n transform: { ...this.state.transform },\n adjustments: serializeAdjustments(this.state.adjustments),\n depthMask: {\n ...this.state.depthMask,\n depthRange: [...this.state.depthMask.depthRange] as [number, number],\n },\n annotations: JSON.parse(JSON.stringify(this.state.annotations)),\n };\n }\n\n private applySerializedState(data: SerializedImageEditorState): void {\n this.state.crop = data.crop ? { ...data.crop } : null;\n this.state.transform = { ...data.transform };\n this.state.adjustments = normalizeStoredAdjustments(data.adjustments);\n this.state.depthMask = {\n ...data.depthMask,\n depthRange: [...data.depthMask.depthRange] as [number, number],\n };\n this.state.annotations = JSON.parse(JSON.stringify(data.annotations || []));\n }\n}\n\n/**\n * Legacy-process adjustments are saved without `process` (and without an unused zero `tint`), so\n * they serialize exactly as they did before process versions existed.\n */\nfunction serializeAdjustments(adjustments: ImageAdjustments): ImageAdjustments {\n const out: ImageAdjustments = { ...adjustments };\n if (out.layers?.length) out.layers = JSON.parse(JSON.stringify(out.layers));\n else delete out.layers;\n if (normalizeProcessVersion(out.process) === LEGACY_PROCESS_VERSION) {\n delete out.process;\n if (!out.tint) delete out.tint;\n }\n return out;\n}\n\n/** Scales an annotation's geometry from one image size to another. */\nfunction scaleAnnotation(ann: Annotation, sx: number, sy: number): Annotation {\n const k = Math.sqrt(Math.abs(sx * sy));\n const base = { ...ann, x: ann.x * sx, y: ann.y * sy } as Annotation;\n switch (base.type) {\n case 'pen':\n return { ...base, points: base.points.map((p) => ({ x: p.x * sx, y: p.y * sy })), strokeWidth: base.strokeWidth * k };\n case 'rect':\n return { ...base, width: base.width * sx, height: base.height * sy, strokeWidth: base.strokeWidth * k };\n case 'image':\n return { ...base, width: base.width * sx, height: base.height * sy };\n case 'circle':\n return { ...base, radiusX: base.radiusX * sx, radiusY: base.radiusY * sy, strokeWidth: base.strokeWidth * k };\n case 'arrow':\n case 'line':\n return { ...base, endX: base.endX * sx, endY: base.endY * sy, strokeWidth: base.strokeWidth * k };\n case 'text':\n return { ...base, fontSize: base.fontSize * k };\n }\n}\n","import {\n loadDocument,\n type JsonObject,\n type LoadReport,\n type MigrationStep,\n} from '../persistence/migrate';\nimport { DEFAULT_DEPTH_MASK, DEFAULT_TRANSFORM, normalizeStoredAdjustments } from './controller';\nimport type {\n Annotation,\n CropBox,\n DepthMaskOptions,\n ImageAdjustments,\n ImageTransform,\n SerializedImageEditorState,\n} from './types';\n\n/** The `version` that `ImageEditorController.toJSON()` writes. */\nexport const IMAGE_EDITOR_STATE_VERSION = 1;\n\n/**\n * Migration steps for `SerializedImageEditorState`, keyed by the version they\n * start from. Empty while only version 1 exists.\n */\nexport const imageEditorStateMigrations: Record<number, MigrationStep> = {};\n\nexport interface ImageEditorDocumentLoad {\n /** State to pass to `loadJSON` / `initialState`. */\n state: SerializedImageEditorState;\n report: LoadReport;\n /** Top-level keys this build does not know; spread them into the saved JSON to keep them. */\n unknown: JsonObject;\n}\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\nconst isNumber = (value: unknown): value is number =>\n typeof value === 'number' && Number.isFinite(value);\n\nfunction expectObject(value: unknown, what: string): Record<string, unknown> {\n if (!isObject(value)) throw new Error(`${what} must be an object`);\n return value;\n}\n\nfunction checkFields(\n value: Record<string, unknown>,\n types: Record<string, (v: unknown) => boolean>,\n what: string,\n) {\n for (const [field, ok] of Object.entries(types)) {\n if (field in value && value[field] !== undefined && !ok(value[field])) {\n throw new Error(`${what}.${field} has an invalid value`);\n }\n }\n}\n\nconst isBoolean = (v: unknown) => typeof v === 'boolean';\n\nfunction parseCrop(value: unknown): CropBox | null {\n if (value === null) return null;\n const crop = expectObject(value, 'crop');\n for (const field of ['x', 'y', 'width', 'height'] as const) {\n if (!isNumber(crop[field])) throw new Error(`crop.${field} must be a number`);\n }\n return { ...(crop as unknown as CropBox) };\n}\n\nfunction parseTransform(value: unknown): ImageTransform {\n const transform = expectObject(value, 'transform');\n checkFields(transform, { rotate: isNumber, flipH: isBoolean, flipV: isBoolean }, 'transform');\n return { ...DEFAULT_TRANSFORM, ...(transform as Partial<ImageTransform>) };\n}\n\nconst ADJUSTMENT_NUMBERS = [\n 'brightness',\n 'contrast',\n 'saturation',\n 'exposure',\n 'temperature',\n 'tint',\n 'blur',\n 'opacity',\n] as const;\n\nfunction parseAdjustments(value: unknown): ImageAdjustments {\n const adjustments = expectObject(value, 'adjustments');\n checkFields(\n adjustments,\n {\n ...Object.fromEntries(ADJUSTMENT_NUMBERS.map((k) => [k, isNumber])),\n process: (v) => v === 1 || v === 2,\n },\n 'adjustments',\n );\n // Kept as stored: `loadJSON` fills defaults and keeps a missing `process` legacy.\n return { ...(adjustments as unknown as ImageAdjustments) };\n}\n\nfunction parseDepthMask(value: unknown): DepthMaskOptions {\n const mask = expectObject(value, 'depthMask');\n checkFields(\n mask,\n {\n enabled: isBoolean,\n maskSource: (v) => v === null || typeof v === 'string',\n mode: (v) => v === 'threshold' || v === 'brightness',\n depthRange: (v) => Array.isArray(v) && v.length === 2 && v.every(isNumber),\n softness: isNumber,\n invert: isBoolean,\n },\n 'depthMask',\n );\n const merged = { ...DEFAULT_DEPTH_MASK, ...(mask as Partial<DepthMaskOptions>) };\n return { ...merged, depthRange: [...merged.depthRange] as [number, number] };\n}\n\nconst ANNOTATION_TYPES = new Set(['pen', 'rect', 'circle', 'arrow', 'line', 'text', 'image']);\n\nconst isAnnotation = (value: unknown): value is Annotation =>\n isObject(value) &&\n typeof value.id === 'string' &&\n typeof value.type === 'string' &&\n ANNOTATION_TYPES.has(value.type) &&\n isNumber(value.x) &&\n isNumber(value.y);\n\n/**\n * Loads stored image editor state (a JSON string or object) with a `LoadReport`:\n *\n * - Runs `imageEditorStateMigrations` up to `IMAGE_EDITOR_STATE_VERSION`; a missing\n * `version` is taken as current.\n * - A newer `version` is still loaded but reported `readOnly`: do not save over it.\n * - Each section (`crop`, `transform`, `adjustments`, `depthMask`, `annotations`)\n * falls back to its default on its own; invalid annotations are dropped one by one.\n * - Unknown top-level keys are returned in `unknown`.\n *\n * Valid state from `toJSON()` comes back unchanged, so `loadJSON(state)` behaves\n * exactly as with the raw object.\n */\nexport function loadImageEditorDocument(input: unknown): ImageEditorDocumentLoad {\n let dropped = 0;\n const result = loadDocument<Omit<SerializedImageEditorState, 'version'>>(\n input,\n {\n crop: { parse: parseCrop, defaults: null },\n transform: { parse: parseTransform, defaults: () => ({ ...DEFAULT_TRANSFORM }) },\n adjustments: {\n parse: parseAdjustments,\n // Same as what `loadJSON` derives from missing adjustments.\n defaults: () => normalizeStoredAdjustments(undefined),\n },\n depthMask: {\n parse: parseDepthMask,\n defaults: () => ({ ...DEFAULT_DEPTH_MASK, depthRange: [...DEFAULT_DEPTH_MASK.depthRange] as [number, number] }),\n },\n annotations: {\n parse: (value) => {\n if (!Array.isArray(value)) throw new Error('annotations must be an array');\n const kept = value.filter(isAnnotation);\n dropped = value.length - kept.length;\n return JSON.parse(JSON.stringify(kept)) as Annotation[];\n },\n defaults: () => [],\n },\n },\n {\n currentVersion: IMAGE_EDITOR_STATE_VERSION,\n steps: imageEditorStateMigrations,\n },\n );\n if (dropped > 0) {\n result.report.problems.push({\n section: 'annotations',\n message: `${dropped} invalid annotation${dropped === 1 ? '' : 's'} dropped`,\n });\n }\n const state = { version: 1, ...result.value } as SerializedImageEditorState;\n return { state, report: result.report, unknown: result.unknown };\n}\n","// Portions ported from lightcraft-main/crates/develop/src/controls.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\nimport type { AdjustmentKind, ImageAdjustments } from './types';\n\n/**\n * Control specs: one table describes every numeric adjustment slider (id, label, section, range,\n * default, step, display precision and track style). The React and Svelte panels render from it,\n * the agent tools expose it as a schema, and values are addressed by id.\n */\n\nexport type ControlSection = 'light' | 'color' | 'effects' | 'layer';\n\n/** How a slider track is drawn. */\nexport type ControlTrack =\n /** Plain track, fill from the minimum. */\n | { kind: 'plain' }\n /** Zero in the middle. */\n | { kind: 'centered' }\n /** Blue → yellow (white-balance temperature). */\n | { kind: 'temp' }\n /** Green → magenta (tint). */\n | { kind: 'tint' }\n /** A two-colour gradient. */\n | { kind: 'gradient'; from: string; to: string }\n /** Full hue rainbow. */\n | { kind: 'rainbow' };\n\nexport interface ControlSpec {\n /** Dotted path of the value (`exposure`; inside a layer's params: `midtones.0`, `ranges.4.hue`). */\n id: string;\n label: string;\n section: ControlSection;\n min: number;\n max: number;\n step: number;\n default: number;\n /** Decimal places shown (after `displayScale`). */\n decimals: number;\n track: ControlTrack;\n /** Multiplier for display (opacity 0..1 shows as 0..100 %). */\n displayScale?: number;\n /** Unit suffix for display (`px`, `%`, `°`). */\n unit?: string;\n /** The rendering process the control needs (tint: process 2). */\n requiresProcess?: 1 | 2;\n}\n\nconst plain: ControlTrack = { kind: 'plain' };\nconst centered: ControlTrack = { kind: 'centered' };\n\n/** Every numeric base adjustment, in panel order. */\nexport const IMAGE_ADJUSTMENT_CONTROLS: readonly ControlSpec[] = [\n { id: 'brightness', label: 'Brightness', section: 'light', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: centered },\n { id: 'contrast', label: 'Contrast', section: 'light', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: centered },\n {\n id: 'saturation', label: 'Saturation', section: 'color', min: -100, max: 100, step: 1, default: 0, decimals: 0,\n track: { kind: 'gradient', from: '#7a7a7a', to: '#e04a3a' },\n },\n { id: 'exposure', label: 'Exposure', section: 'light', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: centered },\n { id: 'temperature', label: 'Warmth / Temperature', section: 'color', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'temp' } },\n { id: 'tint', label: 'Tint', section: 'color', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'tint' }, requiresProcess: 2 },\n { id: 'blur', label: 'Blur', section: 'effects', min: 0, max: 30, step: 1, default: 0, decimals: 0, track: plain, unit: 'px' },\n { id: 'opacity', label: 'Opacity', section: 'effects', min: 0, max: 1, step: 0.05, default: 1, decimals: 0, track: plain, displayScale: 100, unit: '%' },\n];\n\nconst tone = (prefix: string, label: string): ControlSpec[] =>\n [\n ['0', 'Cyan – Red', '#00b7c7', '#e0343a'],\n ['1', 'Magenta – Green', '#d23ad2', '#2fb34a'],\n ['2', 'Yellow – Blue', '#e0c63a', '#3a5be0'],\n ].map(([i, l, from, to]) => ({\n id: `${prefix}.${i}`, label: `${label} ${l}`, section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0,\n track: { kind: 'gradient', from, to },\n }));\n\nconst levelsRecord = (ch: string, label: string): ControlSpec[] => [\n { id: `${ch}.inBlack`, label: `${label} input black`, section: 'layer', min: 0, max: 253, step: 1, default: 0, decimals: 0, track: plain },\n { id: `${ch}.gamma`, label: `${label} gamma`, section: 'layer', min: 0.1, max: 9.99, step: 0.01, default: 1, decimals: 2, track: plain },\n { id: `${ch}.inWhite`, label: `${label} input white`, section: 'layer', min: 2, max: 255, step: 1, default: 255, decimals: 0, track: plain },\n { id: `${ch}.outBlack`, label: `${label} output black`, section: 'layer', min: 0, max: 255, step: 1, default: 0, decimals: 0, track: plain },\n { id: `${ch}.outWhite`, label: `${label} output white`, section: 'layer', min: 0, max: 255, step: 1, default: 255, decimals: 0, track: plain },\n];\n\nconst RANGE_NAMES = ['Reds', 'Yellows', 'Greens', 'Cyans', 'Blues', 'Magentas'];\n\n/**\n * Numeric parameters of each adjustment-layer kind, addressed inside `layer.params`. Curves points\n * and booleans / colours (colorize, preserve luminosity, tint, filter colour) are edited by the\n * dedicated controls, not sliders.\n */\nexport const ADJUSTMENT_LAYER_CONTROLS: Readonly<Record<AdjustmentKind, readonly ControlSpec[]>> = {\n curves: [],\n levels: [\n ...levelsRecord('master', 'RGB'),\n ...levelsRecord('red', 'Red'),\n ...levelsRecord('green', 'Green'),\n ...levelsRecord('blue', 'Blue'),\n ],\n hueSaturation: [\n { id: 'hue', label: 'Hue', section: 'layer', min: -180, max: 180, step: 1, default: 0, decimals: 0, track: { kind: 'rainbow' }, unit: '°' },\n { id: 'saturation', label: 'Saturation', section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'gradient', from: '#7a7a7a', to: '#e04a3a' } },\n { id: 'lightness', label: 'Lightness', section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'gradient', from: '#000000', to: '#ffffff' } },\n ...RANGE_NAMES.flatMap((name, i): ControlSpec[] => [\n { id: `ranges.${i}.hue`, label: `${name} hue`, section: 'layer', min: -180, max: 180, step: 1, default: 0, decimals: 0, track: { kind: 'rainbow' }, unit: '°' },\n { id: `ranges.${i}.saturation`, label: `${name} saturation`, section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: centered },\n { id: `ranges.${i}.lightness`, label: `${name} lightness`, section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: centered },\n ]),\n ],\n vibrance: [\n { id: 'vibrance', label: 'Vibrance', section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'gradient', from: '#7a7a7a', to: '#d8406a' } },\n { id: 'saturation', label: 'Saturation', section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'gradient', from: '#7a7a7a', to: '#e04a3a' } },\n ],\n colorBalance: [...tone('shadows', 'Shadows'), ...tone('midtones', 'Midtones'), ...tone('highlights', 'Highlights')],\n blackWhite: [\n ['reds', 'Reds', 40, '#e0343a'],\n ['yellows', 'Yellows', 60, '#e0c63a'],\n ['greens', 'Greens', 40, '#2fb34a'],\n ['cyans', 'Cyans', 60, '#00b7c7'],\n ['blues', 'Blues', 20, '#3a5be0'],\n ['magentas', 'Magentas', 80, '#d23ad2'],\n ].map(([id, label, def, to]) => ({\n id: id as string, label: label as string, section: 'layer' as const, min: -200, max: 300, step: 1, default: def as number, decimals: 0,\n track: { kind: 'gradient' as const, from: '#000000', to: to as string }, unit: '%',\n })),\n invert: [],\n posterize: [{ id: 'levels', label: 'Levels', section: 'layer', min: 2, max: 255, step: 1, default: 4, decimals: 0, track: plain }],\n threshold: [{ id: 'level', label: 'Threshold level', section: 'layer', min: 1, max: 255, step: 1, default: 128, decimals: 0, track: { kind: 'gradient', from: '#000000', to: '#ffffff' } }],\n photoFilter: [{ id: 'density', label: 'Density', section: 'layer', min: 0, max: 100, step: 1, default: 25, decimals: 0, track: plain, unit: '%' }],\n};\n\n/** Opacity of any adjustment layer (0..1, shown as %). */\nexport const ADJUSTMENT_LAYER_OPACITY_CONTROL: ControlSpec = {\n id: 'opacity', label: 'Opacity', section: 'layer', min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain, displayScale: 100, unit: '%',\n};\n\nconst BASE_BY_ID = new Map(IMAGE_ADJUSTMENT_CONTROLS.map((c) => [c.id, c]));\n\n/** The base-adjustment control with this id. */\nexport function findAdjustmentControl(id: string): ControlSpec | undefined {\n return BASE_BY_ID.get(id);\n}\n\n/** The control of a layer parameter (`opacity` included). */\nexport function findLayerControl(kind: AdjustmentKind, id: string): ControlSpec | undefined {\n if (id === 'opacity') return ADJUSTMENT_LAYER_OPACITY_CONTROL;\n return ADJUSTMENT_LAYER_CONTROLS[kind]?.find((c) => c.id === id);\n}\n\n/** `v` clamped to the control's range and snapped to its step; non-finite values give the default. */\nexport function clampControlValue(spec: ControlSpec, v: unknown): number {\n if (typeof v !== 'number' || !Number.isFinite(v)) return spec.default;\n const clamped = Math.min(spec.max, Math.max(spec.min, v));\n const steps = Math.round((clamped - spec.min) / spec.step);\n const snapped = spec.min + steps * spec.step;\n // Trim float noise from the step arithmetic.\n return Math.min(spec.max, Number(snapped.toFixed(6)));\n}\n\n/** A value as the slider shows it (`+12`, `35%`, `4px`). */\nexport function formatControlValue(spec: ControlSpec, v: number): string {\n const shown = (Number.isFinite(v) ? v : spec.default) * (spec.displayScale ?? 1);\n const s = shown.toFixed(spec.decimals);\n return `${s}${spec.unit ?? ''}`;\n}\n\n/** Where `v` sits on the track, 0 (left) to 1 (right). */\nexport function controlPosition(spec: ControlSpec, v: number): number {\n const p = (clampControlValue(spec, v) - spec.min) / (spec.max - spec.min || 1);\n return Math.min(1, Math.max(0, p));\n}\n\n/** CSS background for a control's track. */\nexport function controlTrackBackground(spec: ControlSpec): string | undefined {\n const t = spec.track;\n switch (t.kind) {\n case 'temp':\n return 'linear-gradient(to right, #3a7bd5, #d8d8d8, #f2c94c)';\n case 'tint':\n return 'linear-gradient(to right, #3fbf4f, #d8d8d8, #d23ad2)';\n case 'gradient':\n return `linear-gradient(to right, ${t.from}, ${t.to})`;\n case 'rainbow':\n return 'linear-gradient(to right, #00ffff, #0000ff, #ff00ff, #ff0000, #ffff00, #00ff00, #00ffff)';\n default:\n return undefined;\n }\n}\n\n/** Reads a dotted path (`ranges.2.hue`) from an object. */\nexport function getControlPath(obj: unknown, path: string): unknown {\n let cur: any = obj;\n for (const part of path.split('.')) {\n if (cur === null || cur === undefined) return undefined;\n cur = cur[part];\n }\n return cur;\n}\n\n/** A copy of `obj` with the dotted path set (arrays and objects along the path are cloned). */\nexport function setControlPath<T>(obj: T, path: string, value: unknown): T {\n const parts = path.split('.');\n const root: any = Array.isArray(obj) ? [...(obj as unknown[])] : { ...(obj as object) };\n let cur = root;\n for (let i = 0; i < parts.length - 1; i++) {\n const next = cur[parts[i]];\n cur[parts[i]] = Array.isArray(next) ? [...next] : next && typeof next === 'object' ? { ...next } : {};\n cur = cur[parts[i]];\n }\n cur[parts[parts.length - 1]] = value;\n return root as T;\n}\n\n/** The base adjustment values the control table describes. */\nexport function readAdjustmentControls(adjustments: ImageAdjustments): Record<string, number> {\n const out: Record<string, number> = {};\n for (const c of IMAGE_ADJUSTMENT_CONTROLS) {\n const v = (adjustments as unknown as Record<string, unknown>)[c.id];\n out[c.id] = typeof v === 'number' && Number.isFinite(v) ? v : c.default;\n }\n return out;\n}\n","import type { AgentTool, AgentToolProvider } from '../agent/registry';\nimport type { ImageEditorController } from './controller';\nimport type { AdjustmentKind, ImageAdjustments } from './types';\nimport { normalizeProcessVersion } from './color';\nimport {\n ADJUSTMENT_KINDS,\n isAdjustmentKind,\n} from './adjustment-layers';\nimport { BLEND_MODES, isBlendMode } from './blend';\nimport {\n ADJUSTMENT_LAYER_CONTROLS,\n ADJUSTMENT_LAYER_OPACITY_CONTROL,\n IMAGE_ADJUSTMENT_CONTROLS,\n clampControlValue,\n findAdjustmentControl,\n findLayerControl,\n readAdjustmentControls,\n setControlPath,\n} from './controls';\n\nexport interface ImageEditorToolProviderOptions {\n /** Provider id (unique per registry). Default `image-editor`. */\n id?: string;\n /** Always prefix tool names with `<namespace>__`. */\n namespace?: string;\n}\n\nconst LAYER_PATH = /^layers\\.([^.]+)\\.(.+)$/;\n\nfunction adjustmentsSummary(adjustments: ImageAdjustments) {\n return {\n process: normalizeProcessVersion(adjustments.process),\n values: readAdjustmentControls(adjustments),\n layers: (adjustments.layers ?? []).map((l) => JSON.parse(JSON.stringify(l))),\n };\n}\n\n/**\n * Agent tools for an image editor, for a `ToolRegistry`:\n *\n * - `get_adjustments`: base slider values (by control id), process version and adjustment layers.\n * - `list_controls`: the control table (ids, ranges, defaults, steps), layer kinds and blend modes.\n * - `set_adjustments {values, label}`: sets base controls (`exposure`) and layer parameters\n * (`layers.<id>.vibrance`, `layers.<id>.opacity`) in one undo step; values are clamped to the\n * control ranges and the applied values are echoed.\n * - `add_adjustment_layer {kind, params?, opacity?, blend?, name?}`.\n * - `render_preview {maxSide}`: the rendered image as a PNG, longest side at most `maxSide`.\n */\nexport function createImageEditorToolProvider(\n controller: ImageEditorController,\n options: ImageEditorToolProviderOptions = {}\n): AgentToolProvider {\n const getAdjustments: AgentTool = {\n name: 'get_adjustments',\n title: 'Read image adjustments',\n description:\n 'Returns the image editor adjustment values by control id, the rendering process version and the adjustment layers (bottom to top).',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n annotations: {\n title: 'Read image adjustments',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n handler: () => adjustmentsSummary(controller.getState().adjustments),\n };\n\n const listControls: AgentTool = {\n name: 'list_controls',\n title: 'List adjustment controls',\n description:\n 'Lists every adjustment control (id, label, section, min, max, step, default), the parameters of each adjustment-layer kind, and the blend modes.',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n annotations: {\n title: 'List adjustment controls',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n handler: () => ({\n controls: IMAGE_ADJUSTMENT_CONTROLS.map(({ id, label, section, min, max, step, default: def, requiresProcess }) => ({\n id, label, section, min, max, step, default: def, ...(requiresProcess ? { requiresProcess } : {}),\n })),\n layerKinds: ADJUSTMENT_KINDS.map(({ kind, label }) => ({\n kind,\n label,\n controls: [...ADJUSTMENT_LAYER_CONTROLS[kind], ADJUSTMENT_LAYER_OPACITY_CONTROL].map(({ id, label: l, min, max, step, default: def }) => ({\n id, label: l, min, max, step, default: def,\n })),\n })),\n blendModes: BLEND_MODES.map((m) => m.id),\n layerPathFormat: 'layers.<layerId>.<controlId>',\n }),\n };\n\n const setAdjustments: AgentTool = {\n name: 'set_adjustments',\n title: 'Set image adjustments',\n description:\n 'Sets adjustment values by control id in one undoable step. Base controls use their id (e.g. \"exposure\"); layer parameters use \"layers.<layerId>.<controlId>\" (e.g. \"layers.adj_1.vibrance\"). Values are clamped to each control range; the applied values are returned.',\n inputSchema: {\n type: 'object',\n properties: {\n values: {\n type: 'object',\n description: 'Map of control id to number. See list_controls for ids and ranges.',\n additionalProperties: { type: 'number' },\n },\n label: { type: 'string', description: 'Short description of the change (echoed back).' },\n },\n required: ['values'],\n additionalProperties: false,\n },\n annotations: {\n title: 'Set image adjustments',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n handler: ({ values, label }) => {\n const entries = Object.entries((values ?? {}) as Record<string, unknown>);\n if (!entries.length) throw new Error('No values given. Pass {\"values\": {\"<control id>\": number}}.');\n const state = controller.getState();\n const base: Partial<ImageAdjustments> = {};\n const layers = (state.adjustments.layers ?? []).map((l) => ({ ...l }));\n const applied: Record<string, number> = {};\n const clamped: string[] = [];\n const unknown: string[] = [];\n for (const [id, raw] of entries) {\n const m = LAYER_PATH.exec(id);\n if (m) {\n const layer = layers.find((l) => l.id === m[1]);\n const spec = layer ? findLayerControl(layer.kind, m[2]) : undefined;\n if (!layer || !spec) {\n unknown.push(id);\n continue;\n }\n const v = clampControlValue(spec, raw);\n if (v !== raw) clamped.push(id);\n if (spec.id === 'opacity') layer.opacity = v;\n else layer.params = setControlPath(layer.params, spec.id, v) as typeof layer.params;\n applied[id] = v;\n continue;\n }\n const spec = findAdjustmentControl(id);\n if (!spec) {\n unknown.push(id);\n continue;\n }\n const v = clampControlValue(spec, raw);\n if (v !== raw) clamped.push(id);\n (base as Record<string, number>)[id] = v;\n applied[id] = v;\n }\n if (unknown.length) {\n const accepted = IMAGE_ADJUSTMENT_CONTROLS.map((c) => c.id).join(', ');\n throw new Error(\n `Unknown control id(s): ${unknown.join(', ')}. Accepted: ${accepted}, or layers.<layerId>.<controlId> for an existing layer.`\n );\n }\n const changedLayers = Object.keys(applied).some((id) => id.startsWith('layers.'));\n controller.setAdjustments(changedLayers ? { ...base, layers } : base);\n const result: Record<string, unknown> = { applied, clamped };\n if (typeof label === 'string' && label) result.label = label;\n const notes: string[] = [];\n if ('tint' in applied && normalizeProcessVersion(controller.getState().adjustments.process) < 2) {\n notes.push('Tint has no effect on process 1 edits.');\n }\n if (notes.length) result.notes = notes;\n return result;\n },\n };\n\n const addLayer: AgentTool = {\n name: 'add_adjustment_layer',\n title: 'Add an adjustment layer',\n description:\n 'Adds a non-destructive adjustment layer on top of the stack (one undoable step) and returns it. Kinds: ' +\n ADJUSTMENT_KINDS.map((k) => k.kind).join(', ') +\n '. Omitted params are neutral.',\n inputSchema: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: ADJUSTMENT_KINDS.map((k) => k.kind) },\n params: { type: 'object', description: 'Initial parameters (see list_controls); merged with neutral defaults.' },\n opacity: { type: 'number', minimum: 0, maximum: 1 },\n blend: { type: 'string', enum: BLEND_MODES.map((m) => m.id) },\n name: { type: 'string' },\n },\n required: ['kind'],\n additionalProperties: false,\n },\n annotations: {\n title: 'Add an adjustment layer',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n handler: ({ kind, params, opacity, blend, name }) => {\n if (!isAdjustmentKind(kind)) throw new Error(`Unknown adjustment kind \"${kind}\".`);\n if (blend !== undefined && !isBlendMode(blend)) throw new Error(`Unknown blend mode \"${blend}\".`);\n const id = controller.addAdjustmentLayer({ kind: kind as AdjustmentKind, params, opacity, blend, name });\n const layer = controller.getAdjustmentLayer(id)!;\n return { layer: JSON.parse(JSON.stringify(layer)), index: controller.getAdjustmentLayers().length - 1 };\n },\n };\n\n const renderPreview: AgentTool = {\n name: 'render_preview',\n title: 'Render a preview',\n description: 'Renders the edited image (crop, adjustments, layers, annotations) as a PNG whose longest side is at most maxSide pixels.',\n inputSchema: {\n type: 'object',\n properties: {\n maxSide: { type: 'integer', minimum: 16, maximum: 2048, description: 'Longest side in pixels (default 512).' },\n },\n additionalProperties: false,\n },\n annotations: {\n title: 'Render a preview',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n handler: async ({ maxSide }) => {\n const side = Math.max(16, Math.min(2048, Math.round(typeof maxSide === 'number' ? maxSide : 512)));\n const state = controller.getState();\n const crop = state.crop ?? { x: 0, y: 0, ...state.imageDimensions };\n const quarter = Math.abs(Math.round((state.transform.rotate % 180) / 90)) % 2 === 1;\n const w = quarter ? crop.height : crop.width;\n const h = quarter ? crop.width : crop.height;\n const k = Math.min(1, side / Math.max(w, h, 1));\n const dataUrl = await controller.toDataURL({\n format: 'image/png',\n width: Math.max(1, Math.round(w * k)),\n height: Math.max(1, Math.round(h * k)),\n });\n const comma = dataUrl.indexOf(',');\n if (!dataUrl.startsWith('data:image/png') || comma < 0 || comma === dataUrl.length - 1) {\n throw new Error('Rendering is not available in this environment.');\n }\n return {\n content: [\n { type: 'image', data: dataUrl.slice(comma + 1), mimeType: 'image/png' },\n { type: 'text', text: `Preview ${Math.round(w * k)}×${Math.round(h * k)}` },\n ],\n };\n },\n };\n\n return {\n id: options.id ?? 'image-editor',\n namespace: options.namespace,\n tools: [getAdjustments, listControls, setAdjustments, addLayer, renderPreview],\n };\n}\n\n","import type { CurvePoint } from './types';\nimport { curveLutFromLevels } from './adjustment-layers';\n\n/**\n * Framework-neutral helpers for a Curves editor drawn in a `width` × `height` box (levels 0..255\n * on both axes, output up). The React and Svelte curve editors share them.\n */\n\nconst clampLevel = (v: number) => Math.min(255, Math.max(0, Math.round(v)));\n\n/** Box coordinates of a curve point. */\nexport function curvePointToBox(p: CurvePoint, width: number, height: number): { x: number; y: number } {\n return { x: (p.input / 255) * width, y: height - (p.output / 255) * height };\n}\n\n/** The curve point (whole levels, clamped) under box coordinates. */\nexport function boxToCurvePoint(x: number, y: number, width: number, height: number): CurvePoint {\n return { input: clampLevel((x / (width || 1)) * 255), output: clampLevel(((height - y) / (height || 1)) * 255) };\n}\n\n/** An SVG polyline path of the evaluated curve (spline, clamped, constant beyond the end points). */\nexport function curveSvgPath(points: readonly CurvePoint[], width: number, height: number, samples = 64): string {\n const lut = curveLutFromLevels(points);\n const n = lut.length - 1;\n let d = '';\n for (let i = 0; i <= samples; i++) {\n const t = i / samples;\n const y = lut[Math.round(t * n)];\n d += `${i === 0 ? 'M' : ' L'}${round2(t * width)} ${round2(height - y * height)}`;\n }\n return d;\n}\n\n/** Index of the point within `radius` box units of (x, y), nearest first; -1 for none. */\nexport function hitTestCurvePoint(\n points: readonly CurvePoint[],\n x: number,\n y: number,\n width: number,\n height: number,\n radius = 8\n): number {\n let best = -1;\n let bestD = radius * radius;\n points.forEach((p, i) => {\n const b = curvePointToBox(p, width, height);\n const d = (b.x - x) ** 2 + (b.y - y) ** 2;\n if (d <= bestD) {\n best = i;\n bestD = d;\n }\n });\n return best;\n}\n\n/** Inserts a point in input order (replacing one at the same input). Returns the new list and its index. */\nexport function insertCurvePoint(points: readonly CurvePoint[], p: CurvePoint): { points: CurvePoint[]; index: number } {\n const point = { input: clampLevel(p.input), output: clampLevel(p.output) };\n const out = points.filter((q) => q.input !== point.input).map((q) => ({ ...q }));\n let index = out.findIndex((q) => q.input > point.input);\n if (index === -1) index = out.length;\n out.splice(index, 0, point);\n return { points: out, index };\n}\n\n/** Moves point `index`, keeping its input strictly between its neighbours'. */\nexport function moveCurvePoint(points: readonly CurvePoint[], index: number, p: CurvePoint): CurvePoint[] {\n const out = points.map((q) => ({ ...q }));\n if (index < 0 || index >= out.length) return out;\n const lo = index > 0 ? out[index - 1].input + 1 : 0;\n const hi = index < out.length - 1 ? out[index + 1].input - 1 : 255;\n out[index] = { input: Math.min(hi, Math.max(lo, clampLevel(p.input))), output: clampLevel(p.output) };\n return out;\n}\n\n/** Removes point `index`; a curve keeps at least two points. */\nexport function removeCurvePoint(points: readonly CurvePoint[], index: number): CurvePoint[] {\n if (points.length <= 2 || index < 0 || index >= points.length) return points.map((q) => ({ ...q }));\n return points.filter((_, i) => i !== index).map((q) => ({ ...q }));\n}\n\nconst round2 = (v: number) => Math.round(v * 100) / 100;\n"],"mappings":"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","names":["lu","lv","clamp","ll","tone","sat","op","x","y","spec","v","round2"]}
|
|
1
|
+
{"version":3,"sources":["../../src/image-editor/color.ts","../../src/image-editor/blend.ts","../../src/image-editor/geometry.ts","../../src/image-editor/selection/mask.ts","../../src/image-editor/selection/modify.ts","../../src/image-editor/selection/layer-mask.ts","../../src/image-editor/adjustment-layers.ts","../../src/image-editor/filters.ts","../../src/image-editor/histogram.ts","../../src/image-editor/selection/overlay.ts","../../src/image-editor/renderer.ts","../../src/image-editor/selection/shapes.ts","../../src/image-editor/selection/wand.ts","../../src/image-editor/selection/refine.ts","../../src/image-editor/controller.ts","../../src/image-editor/document.ts","../../src/image-editor/controls.ts","../../src/image-editor/selection/tool-options.ts","../../src/image-editor/selection-tools.ts","../../src/image-editor/tools.ts","../../src/image-editor/curve-editing.ts","../../src/image-editor/selection/gesture.ts"],"sourcesContent":["// Portions ported from lightcraft-main/crates/color/src/cct.rs, lightcraft-main/crates/color/src/lib.rs,\n// lightcraft-main/crates/pipeline/src/tone.rs, lightcraft-main/crates/pipeline/src/local.rs and\n// lightcraft-main/crates/develop/src/settings.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors).\n// See THIRD_PARTY_NOTICES.md.\n\n/**\n * Colour science for the image editor's process 2 rendering: sRGB transfer functions,\n * correlated colour temperature / tint (Kim et al. Planckian locus, tint as Duv), Bradford\n * white-balance adaptation relative to \"as shot\", and the display-referred tone curve.\n */\n\n/** A CIE 1931 chromaticity. */\nexport interface Chromaticity {\n x: number;\n y: number;\n}\n\n/** A row-major 3×3 matrix (`[m00, m01, m02, m10, …, m22]`). */\nexport type Matrix3 = [number, number, number, number, number, number, number, number, number];\n\n// ---------------------------------------------------------------------------\n// Process versions\n// ---------------------------------------------------------------------------\n\n/** The rendering of adjustments from before process versions existed. Frozen. */\nexport const LEGACY_PROCESS_VERSION = 1 as const;\n/** The process new edits and Reset get. */\nexport const LATEST_PROCESS_VERSION = 2 as const;\nexport type ImageProcessVersion = 1 | 2;\n\n/**\n * Reads a stored process number leniently: a missing or damaged value (not a whole number) is\n * the legacy process, so a saved edit from before process versions renders exactly as it did. A\n * whole number newer than this build knows renders with the latest process.\n */\nexport function normalizeProcessVersion(value: unknown): ImageProcessVersion {\n if (typeof value !== 'number' || !Number.isInteger(value)) return LEGACY_PROCESS_VERSION;\n return value >= LATEST_PROCESS_VERSION ? LATEST_PROCESS_VERSION : LEGACY_PROCESS_VERSION;\n}\n\n// ---------------------------------------------------------------------------\n// sRGB transfer\n// ---------------------------------------------------------------------------\n\nexport function srgbToLinear(v: number): number {\n return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n}\n\nexport function linearToSrgb(v: number): number {\n return v <= 0.0031308 ? v * 12.92 : 1.055 * Math.pow(v, 1 / 2.4) - 0.055;\n}\n\n/** Rec.709 / sRGB luminance weights (linear light). */\nexport const LUMA_709: readonly [number, number, number] = [0.2126, 0.7152, 0.0722];\n\n// ---------------------------------------------------------------------------\n// 3×3 matrices\n// ---------------------------------------------------------------------------\n\nexport const IDENTITY_MATRIX3: Matrix3 = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n\nexport function mulMatrix3(a: Matrix3, b: Matrix3): Matrix3 {\n const out = new Array(9).fill(0) as Matrix3;\n for (let r = 0; r < 3; r++) {\n for (let c = 0; c < 3; c++) {\n out[r * 3 + c] = a[r * 3] * b[c] + a[r * 3 + 1] * b[3 + c] + a[r * 3 + 2] * b[6 + c];\n }\n }\n return out;\n}\n\nexport function applyMatrix3(m: Matrix3, v: readonly [number, number, number]): [number, number, number] {\n return [\n m[0] * v[0] + m[1] * v[1] + m[2] * v[2],\n m[3] * v[0] + m[4] * v[1] + m[5] * v[2],\n m[6] * v[0] + m[7] * v[1] + m[8] * v[2],\n ];\n}\n\nexport function invertMatrix3(m: Matrix3): Matrix3 | null {\n const [a, b, c, d, e, f, g, h, i] = m;\n const A = e * i - f * h;\n const B = -(d * i - f * g);\n const C = d * h - e * g;\n const det = a * A + b * B + c * C;\n if (!Number.isFinite(det) || Math.abs(det) < 1e-12) return null;\n const k = 1 / det;\n return [\n A * k, -(b * i - c * h) * k, (b * f - c * e) * k,\n B * k, (a * i - c * g) * k, -(a * f - c * d) * k,\n C * k, -(a * h - b * g) * k, (a * e - b * d) * k,\n ];\n}\n\nfunction diag3(x: number, y: number, z: number): Matrix3 {\n return [x, 0, 0, 0, y, 0, 0, 0, z];\n}\n\n// ---------------------------------------------------------------------------\n// Chromaticity, sRGB primaries, Bradford adaptation\n// ---------------------------------------------------------------------------\n\nexport const D65: Chromaticity = { x: 0.3127, y: 0.329 };\n\nfunction xyToXyz(p: Chromaticity): [number, number, number] {\n return [p.x / p.y, 1, (1 - p.x - p.y) / p.y];\n}\n\nfunction xyzToXy(v: readonly [number, number, number]): Chromaticity {\n const s = v[0] + v[1] + v[2];\n return s <= 0 ? { ...D65 } : { x: v[0] / s, y: v[1] / s };\n}\n\n/** Linear sRGB → XYZ (D65 white, Y = 1), derived from the primaries. */\nconst SRGB_TO_XYZ: Matrix3 = (() => {\n const p = [{ x: 0.64, y: 0.33 }, { x: 0.3, y: 0.6 }, { x: 0.15, y: 0.06 }].map(xyToXyz);\n const m: Matrix3 = [p[0][0], p[1][0], p[2][0], p[0][1], p[1][1], p[2][1], p[0][2], p[1][2], p[2][2]];\n const inv = invertMatrix3(m);\n const s = inv ? applyMatrix3(inv, xyToXyz(D65)) : [1, 1, 1];\n return mulMatrix3(m, diag3(s[0], s[1], s[2]));\n})();\nconst XYZ_TO_SRGB: Matrix3 = invertMatrix3(SRGB_TO_XYZ) ?? IDENTITY_MATRIX3;\n\n/** The Bradford cone-response matrix (XYZ → sharpened cones). */\nconst BRADFORD: Matrix3 = [0.8951, 0.2664, -0.1614, -0.7502, 1.7135, 0.0367, 0.0389, -0.0685, 1.0296];\nconst BRADFORD_INV: Matrix3 = invertMatrix3(BRADFORD) ?? IDENTITY_MATRIX3;\n\n/** Bradford chromatic adaptation (XYZ → XYZ) from white `src` to white `dst`. */\nexport function bradfordAdaptation(src: Chromaticity, dst: Chromaticity): Matrix3 {\n if (src.x === dst.x && src.y === dst.y) return [...IDENTITY_MATRIX3];\n const s = applyMatrix3(BRADFORD, xyToXyz(src));\n const d = applyMatrix3(BRADFORD, xyToXyz(dst));\n return mulMatrix3(BRADFORD_INV, mulMatrix3(diag3(d[0] / s[0], d[1] / s[1], d[2] / s[2]), BRADFORD));\n}\n\n/**\n * Matrix (linear sRGB → linear sRGB) that white-balances a scene lit by `src` so that it\n * renders as if lit by D65.\n */\nexport function wbMatrix(src: Chromaticity): Matrix3 {\n return mulMatrix3(XYZ_TO_SRGB, mulMatrix3(bradfordAdaptation(src, D65), SRGB_TO_XYZ));\n}\n\n/** The chromaticity of a linear sRGB colour. */\nexport function linearSrgbToXy(rgb: readonly [number, number, number]): Chromaticity {\n return xyzToXy(applyMatrix3(SRGB_TO_XYZ, rgb));\n}\n\n// ---------------------------------------------------------------------------\n// Correlated colour temperature and tint\n// ---------------------------------------------------------------------------\n\n/** Tint units per unit of Duv. */\nexport const TINT_SCALE = 3000;\nexport const MIN_KELVIN = 1667;\nexport const MAX_KELVIN = 25000;\n\nfunction kimXy(tIn: number): Chromaticity {\n const t = Math.min(MAX_KELVIN, Math.max(MIN_KELVIN, tIn));\n const t2 = t * t;\n const t3 = t2 * t;\n const x =\n t <= 4000\n ? -0.2661239e9 / t3 - 0.2343589e6 / t2 + 0.8776956e3 / t + 0.17991\n : -3.0258469e9 / t3 + 2.1070379e6 / t2 + 0.2226347e3 / t + 0.24039;\n const x2 = x * x;\n const x3 = x2 * x;\n const y =\n t <= 2222\n ? -1.1063814 * x3 - 1.3481102 * x2 + 2.18555832 * x - 0.20219683\n : t <= 4000\n ? -0.9549476 * x3 - 1.37418593 * x2 + 2.09137015 * x - 0.16748867\n : 3.081758 * x3 - 5.8733867 * x2 + 3.75112997 * x - 0.37001483;\n return { x, y };\n}\n\n/** CIE 1931 xy → CIE 1960 uv. */\nexport function xyToUv(p: Chromaticity): [number, number] {\n const d = -2 * p.x + 12 * p.y + 3;\n return [(4 * p.x) / d, (6 * p.y) / d];\n}\n\n/** CIE 1960 uv → CIE 1931 xy. */\nexport function uvToXy(u: number, v: number): Chromaticity {\n const d = 2 * u - 8 * v + 4;\n return { x: (3 * u) / d, y: (2 * v) / d };\n}\n\n/** Planckian locus in (u, v), extended linearly in mired space outside the approximation's range. */\nfunction locusUv(tIn: number): [number, number] {\n const t = Math.max(1000, tIn);\n if (t >= MIN_KELVIN && t <= MAX_KELVIN) return xyToUv(kimXy(t));\n const [a, b] = t < MIN_KELVIN ? [MIN_KELVIN, MIN_KELVIN + 50] : [MAX_KELVIN - 500, MAX_KELVIN];\n const [ua, va] = xyToUv(kimXy(a));\n const [ub, vb] = xyToUv(kimXy(b));\n const ma = 1e6 / a;\n const mb = 1e6 / b;\n const s = (1e6 / t - ma) / (mb - ma);\n return [ua + (ub - ua) * s, va + (vb - va) * s];\n}\n\n/** Unit normal of the locus at `t`, pointing towards green (increasing v). */\nfunction locusNormal(t: number): [number, number] {\n const m = 1e6 / t;\n const [u0, v0] = locusUv(1e6 / (m + 1));\n const [u1, v1] = locusUv(1e6 / Math.max(m - 1, 1));\n const du = u1 - u0;\n const dv = v1 - v0;\n const l = Math.max(Math.hypot(du, dv), 1e-12);\n const nx = -dv / l;\n const ny = du / l;\n return ny < 0 ? [-nx, -ny] : [nx, ny];\n}\n\n/**\n * Source illuminant chromaticity for temperature `kelvin` and correction `tint`.\n * Positive tint means a green source white, whose correction adds magenta to the image.\n */\nexport function tempTintToXy(kelvin: number, tint: number): Chromaticity {\n const [u, v] = locusUv(kelvin);\n const [nu, nv] = locusNormal(kelvin);\n const duv = tint / TINT_SCALE;\n return uvToXy(u + nu * duv, v + nv * duv);\n}\n\n/** Inverse of {@link tempTintToXy}: nearest locus temperature (searched in mired space) and tint. */\nexport function xyToTempTint(p: Chromaticity): { kelvin: number; tint: number } {\n const [u, v] = xyToUv(p);\n const dist = (m: number) => {\n const [lu, lv] = locusUv(1e6 / m);\n return (u - lu) ** 2 + (v - lv) ** 2;\n };\n // Coarse scan, then golden-section refine over mired 20..1000 (50000 K .. 1000 K).\n let best = 20;\n let bd = Infinity;\n for (let m = 20; m <= 1000; m += 5) {\n const d = dist(m);\n if (d < bd) {\n bd = d;\n best = m;\n }\n }\n let a = Math.max(best - 5, 20);\n let b = Math.min(best + 5, 1000);\n const g = 0.61803398875;\n for (let i = 0; i < 60; i++) {\n const c = b - g * (b - a);\n const d = a + g * (b - a);\n if (dist(c) < dist(d)) b = d;\n else a = c;\n }\n const kelvin = 1e6 / ((a + b) / 2);\n const [lu, lv] = locusUv(kelvin);\n const [nu, nv] = locusNormal(kelvin);\n const duv = (u - lu) * nu + (v - lv) * nv;\n return { kelvin, tint: duv * TINT_SCALE };\n}\n\n// ---------------------------------------------------------------------------\n// Relative white balance for rendered (JPEG / PNG / WebP) sources\n// ---------------------------------------------------------------------------\n\n/** Rendered images carry no as-shot white: \"as shot\" is 6500 K / tint 0 and maps to the identity. */\nexport const AS_SHOT_KELVIN = 6500;\n/** Mireds per unit of the `temperature` slider (−100…100). */\nexport const MIRED_PER_TEMPERATURE_UNIT = 1;\nconst AS_SHOT_MIRED = 1e6 / AS_SHOT_KELVIN;\n\n/**\n * Maps the `temperature` slider (−100 cool … +100 warm) to the Kelvin white-balance setting:\n * one mired per unit around 6500 K, so 0 → 6500 K, +100 → ~18 570 K (a strong warming\n * correction), −100 → ~3 940 K (a strong cooling correction). Mireds are perceptually even,\n * so equal slider steps look like equal changes.\n */\nexport function temperatureToKelvin(temperature: number): number {\n return 1e6 / (AS_SHOT_MIRED - temperature * MIRED_PER_TEMPERATURE_UNIT);\n}\n\n/** Inverse of {@link temperatureToKelvin}. */\nexport function kelvinToTemperature(kelvin: number): number {\n return (AS_SHOT_MIRED - 1e6 / kelvin) / MIRED_PER_TEMPERATURE_UNIT;\n}\n\nconst AS_SHOT_WB_INV: Matrix3 = invertMatrix3(wbMatrix(tempTintToXy(AS_SHOT_KELVIN, 0))) ?? IDENTITY_MATRIX3;\n\n/**\n * White-balance matrix (linear sRGB) for the `temperature` / `tint` sliders, relative to\n * \"as shot\": the identity at 0 / 0. Normalised so neutral luminance is preserved (white\n * balance doesn't change exposure).\n */\nexport function whiteBalanceMatrix(temperature: number, tint = 0): Matrix3 {\n if (!temperature && !tint) return [...IDENTITY_MATRIX3];\n const set = wbMatrix(tempTintToXy(temperatureToKelvin(temperature), tint));\n const m = mulMatrix3(set, AS_SHOT_WB_INV);\n const g = applyMatrix3(m, [1, 1, 1]);\n const y = g[0] * LUMA_709[0] + g[1] * LUMA_709[1] + g[2] * LUMA_709[2];\n return mulMatrix3(m, diag3(1 / y, 1 / y, 1 / y));\n}\n\n/**\n * Neutral-point eyedropper: the `temperature` / `tint` that render the sampled sRGB colour\n * (0–255 per channel, as it appears in the unadjusted image) neutral. Results are clamped to\n * the slider range −100…100.\n */\nexport function whiteBalanceFromSample(\n rgb: readonly [number, number, number] | { r: number; g: number; b: number }\n): { temperature: number; tint: number } {\n const [r, g, b] = Array.isArray(rgb) ? rgb : [(rgb as any).r, (rgb as any).g, (rgb as any).b];\n const lin: [number, number, number] = [r, g, b].map((c) => srgbToLinear(Math.min(255, Math.max(0, c)) / 255)) as [\n number,\n number,\n number,\n ];\n if (lin[0] + lin[1] + lin[2] <= 1e-6) return { temperature: 0, tint: 0 };\n // Under relative WB the matrix is wb(set) · wb(asShot)⁻¹, so the sample is neutral when the\n // chosen source white is the chromaticity of wb(asShot)⁻¹ · sample.\n const src = linearSrgbToXy(applyMatrix3(AS_SHOT_WB_INV, lin));\n const { kelvin, tint } = xyToTempTint(src);\n const clamp = (v: number) => Math.max(-100, Math.min(100, v));\n return { temperature: clamp(kelvinToTemperature(kelvin)), tint: clamp(tint) };\n}\n\n// ---------------------------------------------------------------------------\n// Tone curve (display-referred, identity at neutral)\n// ---------------------------------------------------------------------------\n\n/** Number of intervals in a tone LUT (the table has `TONE_LUT_SIZE + 1` entries). */\nexport const TONE_LUT_SIZE = 4096;\nconst GREY = 0.18;\nconst GREY_P = Math.pow(GREY, 1 / 2.2);\n/** Linear value where the highlight shoulder starts when there is headroom above 1. */\nconst SHOULDER_KNEE = 0.6;\n\n/**\n * The process 2 tone curve for one linear input value in `[0, headroom]`:\n *\n * 1. A highlight shoulder (extended Reinhard with white point `headroom`) above a knee of 0.6\n * rolls values above 1 (after exposure / white balance) back into range instead of clipping.\n * With no headroom (`headroom = 1`) it is exactly the identity.\n * 2. In a gamma-2.2 perceptual domain, contrast is an S-curve anchored at 0, middle grey and 1\n * (as `ToneMap::display`), and brightness a midtone lift anchored at 0 and 1.\n *\n * `contrast` and `brightness` are −100…100; both 0 with `headroom = 1` is the identity.\n */\nexport function toneCurve(y: number, contrast: number, brightness: number, headroom = 1): number {\n if (!(y > 0)) return 0;\n const h = Math.max(1, headroom);\n let o = Math.min(y, h);\n if (h > 1 && o > SHOULDER_KNEE) {\n const span = 1 - SHOULDER_KNEE;\n const x = (o - SHOULDER_KNEE) / span;\n const X = (h - SHOULDER_KNEE) / span;\n o = SHOULDER_KNEE + span * ((x * (1 + x / (X * X))) / (1 + x));\n }\n if (contrast === 0 && brightness === 0) return Math.min(1, o);\n let p = Math.pow(Math.min(1, o), 1 / 2.2);\n const c = contrast / 100;\n if (c !== 0) {\n p += c * 0.4 * (p - GREY_P) * (1 - (2 * p - 1) ** 2);\n }\n const b = brightness / 100;\n if (b !== 0) {\n // Smooth midtone lift that leaves black and white in place (slope stays positive).\n p += b * 0.8 * p * (1 - p);\n }\n return Math.pow(Math.min(1, Math.max(0, p)), 2.2);\n}\n\n/** Tabulates {@link toneCurve} over `[0, headroom]` in {@link TONE_LUT_SIZE} steps. */\nexport function buildToneLut(contrast: number, brightness: number, headroom = 1): Float32Array {\n const h = Math.max(1, headroom);\n const lut = new Float32Array(TONE_LUT_SIZE + 1);\n for (let i = 0; i <= TONE_LUT_SIZE; i++) {\n lut[i] = toneCurve((h * i) / TONE_LUT_SIZE, contrast, brightness, h);\n }\n return lut;\n}\n\n/** Linearly interpolated lookup into a LUT from {@link buildToneLut}. */\nexport function sampleToneLut(lut: Float32Array, headroom: number, y: number): number {\n if (!(y > 0)) return lut[0];\n const n = lut.length - 1;\n const f = (y * n) / Math.max(1, headroom);\n if (f >= n) return lut[n];\n const i = f | 0;\n return lut[i] + (lut[i + 1] - lut[i]) * (f - i);\n}\n","// Portions ported from photocraft-main/crates/color/src/blend.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\n/**\n * Photoshop blend modes on straight (non-premultiplied) 0..1 colours.\n *\n * Formulas follow the W3C Compositing / ISO 32000 definitions, with Photoshop's variants where\n * they differ (Soft Light, Vivid / Linear / Pin Light, Hard Mix, Linear Burn / Dodge, Subtract,\n * Divide, Darker / Lighter Color), and the hardened `ClipColor` for the non-separable modes.\n */\n\nexport type BlendMode =\n | 'normal'\n | 'darken'\n | 'multiply'\n | 'color-burn'\n | 'linear-burn'\n | 'darker-color'\n | 'lighten'\n | 'screen'\n | 'color-dodge'\n | 'linear-dodge'\n | 'lighter-color'\n | 'overlay'\n | 'soft-light'\n | 'hard-light'\n | 'vivid-light'\n | 'linear-light'\n | 'pin-light'\n | 'hard-mix'\n | 'difference'\n | 'exclusion'\n | 'subtract'\n | 'divide'\n | 'hue'\n | 'saturation'\n | 'color'\n | 'luminosity';\n\nexport interface BlendModeInfo {\n id: BlendMode;\n label: string;\n /** Canvas `globalCompositeOperation` with the same maths, when there is one. */\n canvas: GlobalCompositeOperation | null;\n}\n\n/** Every blend mode, in Photoshop's menu order. */\nexport const BLEND_MODES: readonly BlendModeInfo[] = [\n { id: 'normal', label: 'Normal', canvas: 'source-over' },\n { id: 'darken', label: 'Darken', canvas: 'darken' },\n { id: 'multiply', label: 'Multiply', canvas: 'multiply' },\n { id: 'color-burn', label: 'Color Burn', canvas: 'color-burn' },\n { id: 'linear-burn', label: 'Linear Burn', canvas: null },\n { id: 'darker-color', label: 'Darker Color', canvas: null },\n { id: 'lighten', label: 'Lighten', canvas: 'lighten' },\n { id: 'screen', label: 'Screen', canvas: 'screen' },\n { id: 'color-dodge', label: 'Color Dodge', canvas: 'color-dodge' },\n { id: 'linear-dodge', label: 'Linear Dodge (Add)', canvas: null },\n { id: 'lighter-color', label: 'Lighter Color', canvas: null },\n { id: 'overlay', label: 'Overlay', canvas: 'overlay' },\n // Canvas soft-light is the W3C formula, not Photoshop's: use the scalar path.\n { id: 'soft-light', label: 'Soft Light', canvas: null },\n { id: 'hard-light', label: 'Hard Light', canvas: 'hard-light' },\n { id: 'vivid-light', label: 'Vivid Light', canvas: null },\n { id: 'linear-light', label: 'Linear Light', canvas: null },\n { id: 'pin-light', label: 'Pin Light', canvas: null },\n { id: 'hard-mix', label: 'Hard Mix', canvas: null },\n { id: 'difference', label: 'Difference', canvas: 'difference' },\n { id: 'exclusion', label: 'Exclusion', canvas: 'exclusion' },\n { id: 'subtract', label: 'Subtract', canvas: null },\n { id: 'divide', label: 'Divide', canvas: null },\n { id: 'hue', label: 'Hue', canvas: 'hue' },\n { id: 'saturation', label: 'Saturation', canvas: 'saturation' },\n { id: 'color', label: 'Color', canvas: 'color' },\n { id: 'luminosity', label: 'Luminosity', canvas: 'luminosity' },\n];\n\nconst BLEND_INFO = new Map<string, BlendModeInfo>(BLEND_MODES.map((m) => [m.id, m]));\n\nexport function isBlendMode(value: unknown): value is BlendMode {\n return typeof value === 'string' && BLEND_INFO.has(value);\n}\n\n/** A stored blend mode, or `normal` for a missing / unknown value. */\nexport function normalizeBlendMode(value: unknown): BlendMode {\n return isBlendMode(value) ? value : 'normal';\n}\n\n/**\n * The canvas composite operation that implements `mode` exactly, or `null` when the canvas has\n * none (draw through {@link blendImageData} instead).\n */\nexport function canvasCompositeOperation(mode: BlendMode | undefined): GlobalCompositeOperation | null {\n return BLEND_INFO.get(mode ?? 'normal')?.canvas ?? null;\n}\n\n/** Whether a mode works on whole colours (hue, saturation, colour, luminosity, darker / lighter colour). */\nexport function isSeparableBlendMode(mode: BlendMode): boolean {\n return !(\n mode === 'hue' ||\n mode === 'saturation' ||\n mode === 'color' ||\n mode === 'luminosity' ||\n mode === 'darker-color' ||\n mode === 'lighter-color'\n );\n}\n\nfunction colorBurn(cb: number, cs: number): number {\n if (cb >= 1) return 1;\n if (cs <= 0) return 0;\n return 1 - Math.min(1, (1 - cb) / cs);\n}\n\nfunction colorDodge(cb: number, cs: number): number {\n if (cb <= 0) return 0;\n if (cs >= 1) return 1;\n return Math.min(1, cb / (1 - cs));\n}\n\nfunction hardLight(cb: number, cs: number): number {\n if (cs <= 0.5) return cb * 2 * cs;\n const s = 2 * cs - 1;\n return cb + s - cb * s;\n}\n\n/** Photoshop's Soft Light (differs from W3C in the upper half). */\nfunction softLight(cb: number, cs: number): number {\n return cs <= 0.5\n ? 2 * cb * cs + cb * cb * (1 - 2 * cs)\n : 2 * cb * (1 - cs) + Math.sqrt(Math.max(0, cb)) * (2 * cs - 1);\n}\n\nfunction vividLightHardMix(cb: number, cs: number): number {\n const EDGE = 1e-4;\n if (cs <= 0.5) {\n if (cb >= 1 - EDGE) return 1;\n if (cs <= 0) return 0;\n return 1 - Math.min(1, (1 - cb) / (2 * cs));\n }\n if (cb <= EDGE) return 0;\n if (cs >= 1) return 1;\n return Math.min(1, cb / (2 * (1 - cs)));\n}\n\n/** Separable blend function `B(cb, cs)` of one channel. Non-separable modes return `cs`. */\nexport function blendChannel(mode: BlendMode, cb: number, cs: number): number {\n switch (mode) {\n case 'normal':\n return cs;\n case 'darken':\n return Math.min(cb, cs);\n case 'multiply':\n return cb * cs;\n case 'color-burn':\n return colorBurn(cb, cs);\n case 'linear-burn':\n return Math.max(0, cb + cs - 1);\n case 'lighten':\n return Math.max(cb, cs);\n case 'screen':\n return cb + cs - cb * cs;\n case 'color-dodge':\n return colorDodge(cb, cs);\n case 'linear-dodge':\n return Math.min(1, cb + cs);\n case 'overlay':\n return hardLight(cs, cb);\n case 'soft-light':\n return softLight(cb, cs);\n case 'hard-light':\n return hardLight(cb, cs);\n case 'vivid-light':\n if (cs <= 0) return 0;\n if (cs >= 1) return 1;\n return cs <= 0.5 ? colorBurn(cb, 2 * cs) : colorDodge(cb, 2 * (cs - 0.5));\n case 'linear-light':\n return Math.min(1, Math.max(0, cb + 2 * cs - 1));\n case 'pin-light':\n return cs <= 0.5 ? Math.min(cb, 2 * cs) : Math.max(cb, 2 * cs - 1);\n case 'hard-mix':\n return vividLightHardMix(cb, cs) >= 0.5 - 1e-6 ? 1 : 0;\n case 'difference':\n return Math.abs(cb - cs);\n case 'exclusion':\n return cb + cs - 2 * cb * cs;\n case 'subtract':\n return Math.max(0, cb - cs);\n case 'divide':\n if (cs <= 0) return cb <= 0 ? 0 : 1;\n return Math.min(1, cb / cs);\n default:\n return cs;\n }\n}\n\nexport type Rgb = [number, number, number];\nexport type Rgba = [number, number, number, number];\n\n/** Luminosity of the non-separable modes (W3C / ISO 32000 weights). */\nexport function blendLum(c: readonly number[]): number {\n return 0.3 * c[0] + 0.59 * c[1] + 0.11 * c[2];\n}\n\n/**\n * ClipColor, hardened: when the luminosity itself is out of range no colour of that luminosity\n * is in gamut, so the result is its grey (the spec formula turned such colours inside out and,\n * for greys, divided by rounding noise).\n */\nfunction clipColor(c: Rgb): Rgb {\n const l = blendLum(c);\n const n = Math.min(c[0], c[1], c[2]);\n const x = Math.max(c[0], c[1], c[2]);\n let out: Rgb = [c[0], c[1], c[2]];\n if (n < 0) {\n const d = l - n;\n out = out.map((v) => (l > 0 && d > 0 ? l + ((v - l) * l) / d : l)) as Rgb;\n }\n if (x > 1) {\n const d = x - l;\n out = out.map((v) => (l < 1 && d > 0 ? l + ((v - l) * (1 - l)) / d : l)) as Rgb;\n }\n return out;\n}\n\n/** `c` with its luminosity moved to `l`, clipped back into gamut towards grey (SetLum + ClipColor). */\nexport function setLum(c: readonly number[], l: number): Rgb {\n const d = l - blendLum(c);\n return clipColor([c[0] + d, c[1] + d, c[2] + d]);\n}\n\nfunction sat(c: readonly number[]): number {\n return Math.max(c[0], c[1], c[2]) - Math.min(c[0], c[1], c[2]);\n}\n\nfunction setSat(c: readonly number[], s: number): Rgb {\n const idx = [0, 1, 2].sort((a, b) => c[a] - c[b]);\n const [imin, imid, imax] = idx;\n const out: Rgb = [0, 0, 0];\n if (c[imax] > c[imin]) {\n out[imid] = ((c[imid] - c[imin]) * s) / (c[imax] - c[imin]);\n out[imax] = s;\n }\n out[imin] = 0;\n return out;\n}\n\n/** `B(Cb, Cs)` of a whole colour, including the non-separable modes. */\nexport function blendRgb(mode: BlendMode, cb: readonly number[], cs: readonly number[]): Rgb {\n switch (mode) {\n case 'hue':\n return setLum(setSat(cs, sat(cb)), blendLum(cb));\n case 'saturation':\n return setLum(setSat(cb, sat(cs)), blendLum(cb));\n case 'color':\n return setLum(cs, blendLum(cb));\n case 'luminosity':\n return setLum(cb, blendLum(cs));\n case 'darker-color':\n return blendLum(cs) < blendLum(cb) ? [cs[0], cs[1], cs[2]] : [cb[0], cb[1], cb[2]];\n case 'lighter-color':\n return blendLum(cs) > blendLum(cb) ? [cs[0], cs[1], cs[2]] : [cb[0], cb[1], cb[2]];\n default:\n return [blendChannel(mode, cb[0], cs[0]), blendChannel(mode, cb[1], cs[1]), blendChannel(mode, cb[2], cs[2])];\n }\n}\n\n/**\n * Composites a straight-alpha `source` over a straight-alpha `backdrop` (both RGBA in 0..1) with a\n * blend mode and an extra `alpha` (opacity), using the W3C general formula:\n * `αo = αs + αb(1 − αs)`, `αo·Co = (1 − αs)·αb·Cb + (1 − αb)·αs·Cs + αs·αb·B(Cb, Cs)`.\n */\nexport function blendPixel(mode: BlendMode, backdrop: readonly number[], source: readonly number[], alpha = 1): Rgba {\n const ab = backdrop[3] ?? 1;\n const as = (source[3] ?? 1) * alpha;\n if (!(as > 0)) return [backdrop[0], backdrop[1], backdrop[2], ab];\n const b = blendRgb(mode, backdrop, source);\n const ao = as + ab * (1 - as);\n if (ao <= 0) return [0, 0, 0, 0];\n const out: Rgba = [0, 0, 0, ao];\n for (let i = 0; i < 3; i++) {\n out[i] = ((1 - as) * ab * backdrop[i] + (1 - ab) * as * source[i] + as * ab * b[i]) / ao;\n }\n return out;\n}\n\n/**\n * Blends `source` into `backdrop` in place (8-bit straight RGBA of the same size) with\n * {@link blendPixel}. The scalar fallback for modes the canvas cannot composite.\n */\nexport function blendImageData(backdrop: ImageData, source: ImageData, mode: BlendMode, alpha = 1): void {\n const d = backdrop.data;\n const s = source.data;\n const len = Math.min(d.length, s.length);\n const cb = [0, 0, 0, 0];\n const cs = [0, 0, 0, 0];\n for (let i = 0; i < len; i += 4) {\n if (s[i + 3] === 0) continue;\n for (let k = 0; k < 4; k++) {\n cb[k] = d[i + k] / 255;\n cs[k] = s[i + k] / 255;\n }\n const o = blendPixel(mode, cb, cs, alpha);\n d[i] = Math.round(o[0] * 255);\n d[i + 1] = Math.round(o[1] * 255);\n d[i + 2] = Math.round(o[2] * 255);\n d[i + 3] = Math.round(o[3] * 255);\n }\n}\n","import type { Annotation, CropBox, ImageEditorState, ImagePoint, ImageTransform } from './types';\n\n/*\n * Coordinate spaces\n * -----------------\n * The crop box and every annotation are stored in ONE canonical space: natural image\n * pixels of the current source image (origin top-left of the un-rotated, un-flipped,\n * un-cropped image). Rotation, flips, crop and the viewport fit/zoom/pan are pure view\n * transforms applied on top of that space by a single forward mapping:\n *\n * target = origin + scale * R(angle) * F(flipH, flipV) * (image - regionCenter)\n *\n * where `regionCenter` is the centre of the visible region (the crop box, or the whole\n * image while the crop tool is active). `projectImagePoint` / `unprojectCanvasPoint`\n * implement the mapping and its exact inverse, and `applyImageProjectionToContext`\n * applies the very same transform to a 2D context, so rendering, hit-testing, viewport\n * metrics, export and mask generation cannot drift apart.\n */\n\nexport type CropHandle = 'nw' | 'ne' | 'se' | 'sw' | 'n' | 's' | 'e' | 'w' | 'inside' | null;\n\nexport interface ViewportMetrics {\n vpWidth: number;\n vpHeight: number;\n centerX: number;\n centerY: number;\n baseW: number;\n baseH: number;\n fitScale: number;\n renderW: number;\n renderH: number;\n totalScale: number;\n imageRect: { x: number; y: number; width: number; height: number };\n cropRect: { x: number; y: number; width: number; height: number } | null;\n}\n\n/**\n * A complete description of the natural-image -> target mapping (see module comment).\n */\nexport interface ImageProjection {\n /** Visible region in natural image pixels (crop box or full image). */\n region: CropBox;\n /** Rotation in degrees, normalised to [0, 360). */\n angle: number;\n flipH: boolean;\n flipV: boolean;\n /** Uniform scale from image pixels to target pixels. */\n scale: number;\n /** Target-space point that the centre of `region` maps to. */\n originX: number;\n originY: number;\n}\n\n/** Normalises any rotation in degrees to [0, 360). */\nexport function normalizeAngle(degrees: number): number {\n const a = ((degrees % 360) + 360) % 360;\n return a === 360 ? 0 : a;\n}\n\nfunction cosSin(angle: number): [number, number] {\n // Exact values for quarter turns so 90deg steps never accumulate float noise.\n switch (angle) {\n case 0:\n return [1, 0];\n case 90:\n return [0, 1];\n case 180:\n return [-1, 0];\n case 270:\n return [0, -1];\n default: {\n const rad = (angle * Math.PI) / 180;\n return [Math.cos(rad), Math.sin(rad)];\n }\n }\n}\n\n/** Whether the rotation swaps the displayed width and height. */\nexport function isQuarterTurnSwapped(transform: Pick<ImageTransform, 'rotate'>): boolean {\n const angle = normalizeAngle(transform.rotate);\n return angle === 90 || angle === 270;\n}\n\n/** Size of a region once rotated (bounding box for arbitrary angles). */\nexport function getRotatedSize(\n width: number,\n height: number,\n transform: Pick<ImageTransform, 'rotate'>\n): { width: number; height: number } {\n const [c, s] = cosSin(normalizeAngle(transform.rotate));\n return {\n width: Math.abs(width * c) + Math.abs(height * s),\n height: Math.abs(width * s) + Math.abs(height * c),\n };\n}\n\n/** Maps a natural-image point to target space. */\nexport function projectImagePoint(pt: ImagePoint, p: ImageProjection): ImagePoint {\n const [c, s] = cosSin(p.angle);\n let x = pt.x - (p.region.x + p.region.width / 2);\n let y = pt.y - (p.region.y + p.region.height / 2);\n if (p.flipH) x = -x;\n if (p.flipV) y = -y;\n const rx = x * c - y * s;\n const ry = x * s + y * c;\n return { x: p.originX + rx * p.scale, y: p.originY + ry * p.scale };\n}\n\n/** Exact inverse of {@link projectImagePoint}. */\nexport function unprojectCanvasPoint(pt: ImagePoint, p: ImageProjection): ImagePoint {\n const [c, s] = cosSin(p.angle);\n const rx = (pt.x - p.originX) / p.scale;\n const ry = (pt.y - p.originY) / p.scale;\n let x = rx * c + ry * s;\n let y = -rx * s + ry * c;\n if (p.flipH) x = -x;\n if (p.flipV) y = -y;\n return { x: x + p.region.x + p.region.width / 2, y: y + p.region.y + p.region.height / 2 };\n}\n\n/**\n * Applies the projection to a 2D context so that subsequent drawing in natural image\n * pixels lands exactly where {@link projectImagePoint} says it does.\n */\nexport function applyImageProjectionToContext(\n ctx: Pick<CanvasRenderingContext2D, 'translate' | 'scale' | 'rotate'>,\n p: ImageProjection\n): void {\n ctx.translate(p.originX, p.originY);\n ctx.scale(p.scale, p.scale);\n if (p.angle !== 0) ctx.rotate((p.angle * Math.PI) / 180);\n if (p.flipH || p.flipV) ctx.scale(p.flipH ? -1 : 1, p.flipV ? -1 : 1);\n ctx.translate(-(p.region.x + p.region.width / 2), -(p.region.y + p.region.height / 2));\n}\n\n/** Projects an image-space rectangle and returns its target-space bounding box. */\nexport function projectImageRect(\n rect: CropBox,\n p: ImageProjection\n): { x: number; y: number; width: number; height: number } {\n const corners = [\n projectImagePoint({ x: rect.x, y: rect.y }, p),\n projectImagePoint({ x: rect.x + rect.width, y: rect.y }, p),\n projectImagePoint({ x: rect.x, y: rect.y + rect.height }, p),\n projectImagePoint({ x: rect.x + rect.width, y: rect.y + rect.height }, p),\n ];\n const xs = corners.map((c) => c.x);\n const ys = corners.map((c) => c.y);\n const minX = Math.min(...xs);\n const minY = Math.min(...ys);\n return { x: minX, y: minY, width: Math.max(...xs) - minX, height: Math.max(...ys) - minY };\n}\n\n/** Clamps a crop box to the image bounds. */\nexport function clampCropToImage(crop: CropBox, width: number, height: number): CropBox {\n const x = Math.max(0, Math.min(width - 1, crop.x));\n const y = Math.max(0, Math.min(height - 1, crop.y));\n return {\n x,\n y,\n width: Math.max(1, Math.min(width - x, crop.width)),\n height: Math.max(1, Math.min(height - y, crop.height)),\n };\n}\n\nfunction resolveViewport(\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping: boolean,\n cropOverride?: CropBox | null\n) {\n const { imageDimensions, crop: stateCrop, transform, zoom, pan } = state;\n const naturalWidth = imageDimensions.width || 800;\n const naturalHeight = imageDimensions.height || 600;\n const full: CropBox = { x: 0, y: 0, width: naturalWidth, height: naturalHeight };\n const activeCrop =\n cropOverride !== undefined && cropOverride !== null\n ? cropOverride\n : (stateCrop ?? (isActivelyCropping ? full : null));\n\n const region =\n !isActivelyCropping && activeCrop ? clampCropToImage(activeCrop, naturalWidth, naturalHeight) : full;\n const { width: baseW, height: baseH } = getRotatedSize(region.width, region.height, transform);\n\n const fitScale = Math.min((vpWidth * 0.85) / baseW, (vpHeight * 0.85) / baseH, 1);\n const centerX = vpWidth / 2 + pan.x;\n const centerY = vpHeight / 2 + pan.y;\n\n const projection: ImageProjection = {\n region,\n angle: normalizeAngle(transform.rotate),\n flipH: transform.flipH,\n flipV: transform.flipV,\n scale: zoom * fitScale,\n originX: centerX,\n originY: centerY,\n };\n\n return { activeCrop, baseW, baseH, fitScale, centerX, centerY, projection };\n}\n\n/**\n * Returns the natural-image -> canvas projection used by the interactive viewport.\n */\nexport function getViewportProjection(\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false,\n cropOverride?: CropBox | null\n): ImageProjection {\n return resolveViewport(state, vpWidth, vpHeight, isActivelyCropping, cropOverride).projection;\n}\n\n/**\n * Calculates current viewport projection metrics for canvas <-> image coordinate mapping.\n * `cropRect` is the on-screen (rotated/flipped) rectangle of the crop box.\n */\nexport function getViewportMetrics(\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false,\n cropOverride?: CropBox | null\n): ViewportMetrics {\n const { zoom } = state;\n const { activeCrop, baseW, baseH, fitScale, centerX, centerY, projection } = resolveViewport(\n state,\n vpWidth,\n vpHeight,\n isActivelyCropping,\n cropOverride\n );\n\n const renderW = baseW * fitScale;\n const renderH = baseH * fitScale;\n\n const imageRect = {\n x: centerX - (renderW * zoom) / 2,\n y: centerY - (renderH * zoom) / 2,\n width: renderW * zoom,\n height: renderH * zoom,\n };\n\n const cropRect = activeCrop ? projectImageRect(activeCrop, projection) : null;\n\n return {\n vpWidth,\n vpHeight,\n centerX,\n centerY,\n baseW,\n baseH,\n fitScale,\n renderW,\n renderH,\n totalScale: zoom * fitScale,\n imageRect,\n cropRect,\n };\n}\n\n/**\n * Converts a point on the canvas (in internal canvas pixel space) to natural image pixel\n * space, accounting for zoom, pan, fit scale, crop offset, rotation and flips.\n */\nexport function canvasToImagePoint(\n canvasPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false\n): ImagePoint {\n return unprojectCanvasPoint(canvasPt, getViewportProjection(state, vpWidth, vpHeight, isActivelyCropping));\n}\n\n/**\n * Converts a point in natural image pixel space to internal canvas pixel space.\n * Exact inverse of {@link canvasToImagePoint}.\n */\nexport function imageToCanvasPoint(\n imgPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n isActivelyCropping = false\n): ImagePoint {\n return projectImagePoint(imgPt, getViewportProjection(state, vpWidth, vpHeight, isActivelyCropping));\n}\n\nconst HANDLE_VECTORS: Record<Exclude<CropHandle, 'inside' | null>, [number, number]> = {\n nw: [-1, -1],\n n: [0, -1],\n ne: [1, -1],\n e: [1, 0],\n se: [1, 1],\n s: [0, 1],\n sw: [-1, 1],\n w: [-1, 0],\n};\n\nfunction vectorToHandle(x: number, y: number): CropHandle {\n const vx = Math.abs(x) < 0.38 ? 0 : Math.sign(x);\n const vy = Math.abs(y) < 0.38 ? 0 : Math.sign(y);\n for (const [name, [hx, hy]] of Object.entries(HANDLE_VECTORS)) {\n if (hx === vx && hy === vy) return name as CropHandle;\n }\n return null;\n}\n\n/**\n * Converts a crop handle in screen orientation to the equivalent edge/corner of the crop\n * box in natural image space, or the reverse with `toScreen = true`.\n */\nexport function mapCropHandle(handle: CropHandle, transform: ImageTransform, toScreen = false): CropHandle {\n if (handle === null || handle === 'inside') return handle;\n const [hx, hy] = HANDLE_VECTORS[handle];\n const [c, s] = cosSin(normalizeAngle(transform.rotate));\n const fx = transform.flipH ? -1 : 1;\n const fy = transform.flipV ? -1 : 1;\n if (toScreen) {\n const x = hx * fx;\n const y = hy * fy;\n return vectorToHandle(x * c - y * s, x * s + y * c);\n }\n const x = hx * c + hy * s;\n const y = -hx * s + hy * c;\n return vectorToHandle(x * fx, y * fy);\n}\n\n/**\n * Hit-tests the crop box and its corner/edge handles given a canvas point.\n * The returned handle names the edge/corner of the crop box in natural image space\n * (what {@link calculateCropDrag} expects); use `getCropCursor(handle, state.transform)`\n * to obtain the matching on-screen cursor.\n */\nexport function hitTestCrop(\n canvasPt: ImagePoint,\n state: ImageEditorState,\n vpWidth: number,\n vpHeight: number,\n handleThreshold = 14,\n cropOverride?: CropBox | null\n): CropHandle {\n const metrics = getViewportMetrics(state, vpWidth, vpHeight, true, cropOverride);\n if (!metrics.cropRect) return null;\n\n const screenHandle = hitTestCropRect(canvasPt, metrics.cropRect, handleThreshold);\n return mapCropHandle(screenHandle, state.transform);\n}\n\nfunction hitTestCropRect(\n canvasPt: ImagePoint,\n rect: { x: number; y: number; width: number; height: number },\n handleThreshold: number\n): CropHandle {\n const { x, y, width: w, height: h } = rect;\n const px = canvasPt.x;\n const py = canvasPt.y;\n\n // 1. Corners (highest priority)\n const dist = (x1: number, y1: number, x2: number, y2: number) =>\n Math.hypot(x1 - x2, y1 - y2);\n\n if (dist(px, py, x, y) <= handleThreshold) return 'nw';\n if (dist(px, py, x + w, y) <= handleThreshold) return 'ne';\n if (dist(px, py, x + w, y + h) <= handleThreshold) return 'se';\n if (dist(px, py, x, y + h) <= handleThreshold) return 'sw';\n\n // 2. Edges\n const nearX = px >= x - handleThreshold && px <= x + w + handleThreshold;\n const nearY = py >= y - handleThreshold && py <= y + h + handleThreshold;\n\n if (nearX && Math.abs(py - y) <= handleThreshold) return 'n';\n if (nearX && Math.abs(py - (y + h)) <= handleThreshold) return 's';\n if (nearY && Math.abs(px - x) <= handleThreshold) return 'w';\n if (nearY && Math.abs(px - (x + w)) <= handleThreshold) return 'e';\n\n // 3. Inside crop region\n if (px >= x && px <= x + w && py >= y && py <= y + h) {\n return 'inside';\n }\n\n return null;\n}\n\n/**\n * Returns CSS cursor style corresponding to a crop handle. Pass the current transform when\n * the handle comes from {@link hitTestCrop} (image space) so the cursor matches the\n * on-screen orientation under rotation/flip.\n */\nexport function getCropCursor(handle: CropHandle, transform?: ImageTransform): string {\n const screenHandle = transform ? mapCropHandle(handle, transform, true) : handle;\n switch (screenHandle) {\n case 'nw':\n case 'se':\n return 'nwse-resize';\n case 'ne':\n case 'sw':\n return 'nesw-resize';\n case 'n':\n case 's':\n return 'ns-resize';\n case 'e':\n case 'w':\n return 'ew-resize';\n case 'inside':\n return 'move';\n default:\n return 'crosshair';\n }\n}\n\n/**\n * Calculates updated crop rectangle given a drag interaction.\n */\nexport function calculateCropDrag(\n startCrop: CropBox,\n handle: CropHandle,\n startImgPt: ImagePoint,\n currentImgPt: ImagePoint,\n imgWidth: number,\n imgHeight: number,\n aspectRatio?: number | null,\n transform?: ImageTransform\n): CropBox {\n // `aspectRatio` is the on-screen ratio; under a quarter turn it is inverted in image space.\n if (aspectRatio && transform && isQuarterTurnSwapped(transform)) {\n aspectRatio = 1 / aspectRatio;\n }\n const dx = currentImgPt.x - startImgPt.x;\n const dy = currentImgPt.y - startImgPt.y;\n\n // Whole crop box move\n if (handle === 'inside') {\n const maxX = Math.max(0, imgWidth - startCrop.width);\n const maxY = Math.max(0, imgHeight - startCrop.height);\n const newX = Math.max(0, Math.min(maxX, startCrop.x + dx));\n const newY = Math.max(0, Math.min(maxY, startCrop.y + dy));\n return {\n x: Math.round(newX),\n y: Math.round(newY),\n width: startCrop.width,\n height: startCrop.height,\n };\n }\n\n // Handle resizing\n let left = startCrop.x;\n let top = startCrop.y;\n let right = startCrop.x + startCrop.width;\n let bottom = startCrop.y + startCrop.height;\n\n const minSize = 20;\n\n if (handle === 'e' || handle === 'ne' || handle === 'se') {\n right = Math.min(imgWidth, Math.max(left + minSize, startCrop.x + startCrop.width + dx));\n }\n if (handle === 'w' || handle === 'nw' || handle === 'sw') {\n left = Math.max(0, Math.min(right - minSize, startCrop.x + dx));\n }\n if (handle === 's' || handle === 'se' || handle === 'sw') {\n bottom = Math.min(imgHeight, Math.max(top + minSize, startCrop.y + startCrop.height + dy));\n }\n if (handle === 'n' || handle === 'nw' || handle === 'ne') {\n top = Math.max(0, Math.min(bottom - minSize, startCrop.y + dy));\n }\n\n // Maintain aspect ratio if requested\n if (aspectRatio && aspectRatio > 0) {\n let currentW = right - left;\n let currentH = bottom - top;\n\n if (handle === 'e' || handle === 'w') {\n currentH = Math.min(imgHeight, currentW / aspectRatio);\n bottom = Math.min(imgHeight, top + currentH);\n } else if (handle === 'n' || handle === 's') {\n currentW = Math.min(imgWidth, currentH * aspectRatio);\n right = Math.min(imgWidth, left + currentW);\n } else {\n // Corner resizing\n const targetH = currentW / aspectRatio;\n if (top + targetH <= imgHeight) {\n bottom = top + targetH;\n } else {\n const targetW = currentH * aspectRatio;\n right = Math.min(imgWidth, left + targetW);\n }\n }\n }\n\n return {\n x: Math.round(left),\n y: Math.round(top),\n width: Math.round(Math.max(minSize, right - left)),\n height: Math.round(Math.max(minSize, bottom - top)),\n };\n}\n\n/**\n * Calculates bounding box of an annotation.\n */\nexport function getAnnotationBounds(ann: Annotation): { x: number; y: number; width: number; height: number } {\n switch (ann.type) {\n case 'rect':\n case 'image':\n return {\n x: Math.min(ann.x, ann.x + ann.width),\n y: Math.min(ann.y, ann.y + ann.height),\n width: Math.abs(ann.width),\n height: Math.abs(ann.height),\n };\n case 'circle':\n return {\n x: ann.x - Math.abs(ann.radiusX),\n y: ann.y - Math.abs(ann.radiusY),\n width: Math.abs(ann.radiusX) * 2,\n height: Math.abs(ann.radiusY) * 2,\n };\n case 'arrow':\n case 'line': {\n const minX = Math.min(ann.x, ann.endX);\n const minY = Math.min(ann.y, ann.endY);\n return {\n x: minX,\n y: minY,\n width: Math.max(Math.abs(ann.endX - ann.x), 10),\n height: Math.max(Math.abs(ann.endY - ann.y), 10),\n };\n }\n case 'pen': {\n if (!ann.points.length) return { x: ann.x, y: ann.y, width: 0, height: 0 };\n let minX = ann.points[0].x;\n let maxX = ann.points[0].x;\n let minY = ann.points[0].y;\n let maxY = ann.points[0].y;\n for (const pt of ann.points) {\n if (pt.x < minX) minX = pt.x;\n if (pt.x > maxX) maxX = pt.x;\n if (pt.y < minY) minY = pt.y;\n if (pt.y > maxY) maxY = pt.y;\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n }\n case 'text':\n return {\n x: ann.x,\n y: ann.y,\n width: ann.text.length * ann.fontSize * 0.6,\n height: ann.fontSize * 1.2,\n };\n }\n}\n\n/**\n * Hit tests if a point in image space is within an annotation's bounds.\n */\nexport function hitTestAnnotation(imgPt: ImagePoint, ann: Annotation, padding = 10): boolean {\n const b = getAnnotationBounds(ann);\n return (\n imgPt.x >= b.x - padding &&\n imgPt.x <= b.x + b.width + padding &&\n imgPt.y >= b.y - padding &&\n imgPt.y <= b.y + b.height + padding\n );\n}\n\n","// Portions ported from photocraft/crates/algo/src/selection.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\nimport type { CropBox } from '../types';\n\n/**\n * A selection: one 8-bit coverage value per image pixel (0 = not selected, 255 = fully\n * selected), row-major over the whole source image in natural pixels — the same space as the\n * crop box and annotations. Soft values are partial selection (feathered or anti-aliased edges).\n *\n * Treat a mask as immutable: every operation returns a new one, so history entries can share\n * them without copying.\n */\nexport interface SelectionMask {\n readonly width: number;\n readonly height: number;\n readonly data: Uint8Array;\n /** Bounding box of the non-zero coverage, or `null` when nothing is selected. */\n readonly bounds: CropBox | null;\n}\n\n/** How a new selection combines with the current one. */\nexport type SelectionMode = 'replace' | 'add' | 'subtract' | 'intersect';\n\nexport const SELECTION_MODES: readonly SelectionMode[] = ['replace', 'add', 'subtract', 'intersect'];\n\nexport function isSelectionMode(value: unknown): value is SelectionMode {\n return typeof value === 'string' && (SELECTION_MODES as readonly string[]).includes(value);\n}\n\n/** Parses `replace|add|subtract|intersect`; anything else is `replace`. */\nexport function parseSelectionMode(value: unknown): SelectionMode {\n return isSelectionMode(value) ? value : 'replace';\n}\n\n/** RGBA pixels, 8 bits per channel, straight alpha (an `ImageData` qualifies). */\nexport interface PixelBuffer {\n width: number;\n height: number;\n data: ArrayLike<number>;\n}\n\n/** Serialized selection: a run-length encoding of the 8-bit coverage. */\nexport interface SerializedSelection {\n width: number;\n height: number;\n /** `r1:` + base64 of (value byte, LEB128 run length) pairs. */\n rle: string;\n}\n\nconst MAX_SIDE = 1 << 15;\n\nfunction checkSize(width: number, height: number): void {\n if (!Number.isInteger(width) || !Number.isInteger(height) || width < 1 || height < 1 || width > MAX_SIDE || height > MAX_SIDE) {\n throw new Error(`Invalid selection size ${width}×${height}`);\n }\n}\n\n/** Bounding box of non-zero bytes. */\nexport function computeSelectionBounds(width: number, height: number, data: ArrayLike<number>): CropBox | null {\n let x0 = width;\n let x1 = -1;\n let y0 = -1;\n let y1 = -1;\n for (let y = 0; y < height; y++) {\n const row = y * width;\n let first = -1;\n for (let x = 0; x < width; x++) {\n if (data[row + x] !== 0) {\n first = x;\n break;\n }\n }\n if (first < 0) continue;\n let last = first;\n for (let x = width - 1; x > first; x--) {\n if (data[row + x] !== 0) {\n last = x;\n break;\n }\n }\n if (y0 < 0) y0 = y;\n y1 = y;\n if (first < x0) x0 = first;\n if (last > x1) x1 = last;\n }\n if (y0 < 0) return null;\n return { x: x0, y: y0, width: x1 - x0 + 1, height: y1 - y0 + 1 };\n}\n\n/** Wraps coverage bytes (taken over, not copied) as a selection, computing its bounds. */\nexport function createSelectionMask(width: number, height: number, data?: Uint8Array): SelectionMask {\n checkSize(width, height);\n const bytes = data ?? new Uint8Array(width * height);\n if (bytes.length !== width * height) throw new Error('Selection data does not match its size');\n return { width, height, data: bytes, bounds: data ? computeSelectionBounds(width, height, bytes) : null };\n}\n\n/** Select › All. */\nexport function fullSelection(width: number, height: number): SelectionMask {\n checkSize(width, height);\n return { width, height, data: new Uint8Array(width * height).fill(255), bounds: { x: 0, y: 0, width, height } };\n}\n\nexport function isSelectionEmpty(mask: SelectionMask | null | undefined): boolean {\n return !mask || mask.bounds === null;\n}\n\n/** Coverage at a pixel, 0..1 (0 outside the image). */\nexport function selectionValueAt(mask: SelectionMask, x: number, y: number): number {\n const xi = Math.floor(x);\n const yi = Math.floor(y);\n if (xi < 0 || yi < 0 || xi >= mask.width || yi >= mask.height) return 0;\n return mask.data[yi * mask.width + xi] / 255;\n}\n\n/** 8-bit value of a coverage (clamped and rounded; NaN → 0). */\nexport function coverageToByte(v: number): number {\n if (!(v > 0)) return 0;\n if (v >= 1) return 255;\n return Math.floor(v * 255 + 0.5);\n}\n\n/** A selection from 0..1 coverage. */\nexport function selectionFromCoverage(width: number, height: number, coverage: ArrayLike<number>): SelectionMask {\n const n = width * height;\n const out = new Uint8Array(n);\n for (let i = 0; i < n; i++) out[i] = coverageToByte(coverage[i]);\n return createSelectionMask(width, height, out);\n}\n\n/** The selection's coverage as 0..1 floats. */\nexport function selectionToCoverage(mask: SelectionMask): Float32Array {\n const out = new Float32Array(mask.data.length);\n for (let i = 0; i < out.length; i++) out[i] = mask.data[i] / 255;\n return out;\n}\n\n/** Number of fully-or-partly selected pixels, weighted by coverage (Σ coverage). */\nexport function selectionArea(mask: SelectionMask | null | undefined): number {\n if (!mask || !mask.bounds) return 0;\n let sum = 0;\n const { x, y, width, height } = mask.bounds;\n for (let yy = y; yy < y + height; yy++) {\n const row = yy * mask.width;\n for (let xx = x; xx < x + width; xx++) sum += mask.data[row + xx];\n }\n return sum / 255;\n}\n\n/**\n * Combines `next` with `prev` by `mode` (8-bit, exact: combining a mask with itself is a no-op).\n * Add is the maximum, Subtract `max(prev − next, 0)`, Intersect the minimum. A missing `prev`\n * reads as nothing selected. Returns `null` when nothing remains selected.\n */\nexport function combineSelections(\n prev: SelectionMask | null | undefined,\n next: SelectionMask,\n mode: SelectionMode\n): SelectionMask | null {\n let result: SelectionMask;\n if (mode === 'replace' || (!prev && mode === 'add')) {\n result = next;\n } else if (!prev) {\n return null;\n } else {\n if (prev.width !== next.width || prev.height !== next.height) throw new Error('Selections differ in size');\n const a = prev.data;\n const b = next.data;\n const out = new Uint8Array(a.length);\n if (mode === 'add') for (let i = 0; i < a.length; i++) out[i] = a[i] > b[i] ? a[i] : b[i];\n else if (mode === 'subtract') for (let i = 0; i < a.length; i++) out[i] = a[i] > b[i] ? a[i] - b[i] : 0;\n else for (let i = 0; i < a.length; i++) out[i] = a[i] < b[i] ? a[i] : b[i];\n result = createSelectionMask(prev.width, prev.height, out);\n }\n return result.bounds ? result : null;\n}\n\n/** Select › Inverse. */\nexport function invertSelection(mask: SelectionMask): SelectionMask {\n const out = new Uint8Array(mask.data.length);\n for (let i = 0; i < out.length; i++) out[i] = 255 - mask.data[i];\n return createSelectionMask(mask.width, mask.height, out);\n}\n\n/** Bilinear resample to another size (e.g. an AI mask returned at a different resolution). */\nexport function resizeSelection(mask: SelectionMask, width: number, height: number): SelectionMask {\n if (mask.width === width && mask.height === height) return mask;\n checkSize(width, height);\n const out = new Uint8Array(width * height);\n const sx = mask.width / width;\n const sy = mask.height / height;\n const src = mask.data;\n const mw = mask.width;\n for (let y = 0; y < height; y++) {\n const fy = Math.min(mask.height - 1, Math.max(0, (y + 0.5) * sy - 0.5));\n const y0 = Math.floor(fy);\n const y1 = Math.min(mask.height - 1, y0 + 1);\n const ty = fy - y0;\n for (let x = 0; x < width; x++) {\n const fx = Math.min(mw - 1, Math.max(0, (x + 0.5) * sx - 0.5));\n const x0 = Math.floor(fx);\n const x1 = Math.min(mw - 1, x0 + 1);\n const tx = fx - x0;\n const top = src[y0 * mw + x0] * (1 - tx) + src[y0 * mw + x1] * tx;\n const bot = src[y1 * mw + x0] * (1 - tx) + src[y1 * mw + x1] * tx;\n out[y * width + x] = Math.round(top * (1 - ty) + bot * ty);\n }\n }\n return createSelectionMask(width, height, out);\n}\n\nexport type SelectionChannel = 'alpha' | 'luminance' | 'red' | 'green' | 'blue';\n\n/**\n * A selection from an image: by default its luminance (white = selected, the usual convention\n * of segmentation masks), or one channel. Partly transparent pixels count as black for\n * luminance, so a mask PNG with transparency works either way.\n */\nexport function selectionFromPixels(\n pixels: PixelBuffer,\n options: { channel?: SelectionChannel; invert?: boolean; threshold?: number } = {}\n): SelectionMask {\n const { width, height, data } = pixels;\n checkSize(width, height);\n if (data.length < width * height * 4) throw new Error('Pixel data is shorter than width × height × 4');\n const channel = options.channel ?? 'luminance';\n const out = new Uint8Array(width * height);\n const threshold = options.threshold;\n for (let i = 0, p = 0; i < out.length; i++, p += 4) {\n let v: number;\n switch (channel) {\n case 'alpha':\n v = data[p + 3];\n break;\n case 'red':\n v = data[p];\n break;\n case 'green':\n v = data[p + 1];\n break;\n case 'blue':\n v = data[p + 2];\n break;\n default:\n v = Math.round(((0.2126 * data[p] + 0.7152 * data[p + 1] + 0.0722 * data[p + 2]) * data[p + 3]) / 255);\n }\n if (options.invert) v = 255 - v;\n if (threshold !== undefined) v = v >= threshold ? 255 : 0;\n out[i] = v;\n }\n return createSelectionMask(width, height, out);\n}\n\n/** The selection as RGBA pixels: grey (white = selected, opaque) or white with coverage as alpha. */\nexport function selectionToPixels(mask: SelectionMask, as: 'gray' | 'alpha' = 'gray'): { width: number; height: number; data: Uint8ClampedArray } {\n const out = new Uint8ClampedArray(mask.data.length * 4);\n for (let i = 0, p = 0; i < mask.data.length; i++, p += 4) {\n const v = mask.data[i];\n if (as === 'gray') {\n out[p] = out[p + 1] = out[p + 2] = v;\n out[p + 3] = 255;\n } else {\n out[p] = out[p + 1] = out[p + 2] = 255;\n out[p + 3] = v;\n }\n }\n return { width: mask.width, height: mask.height, data: out };\n}\n\n// ---------------------------------------------------------------------------\n// Run-length encoding\n// ---------------------------------------------------------------------------\n\nconst B64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nconst B64_INDEX = (() => {\n const t = new Int16Array(128).fill(-1);\n for (let i = 0; i < B64.length; i++) t[B64.charCodeAt(i)] = i;\n return t;\n})();\n\nfunction toBase64(bytes: Uint8Array, length: number): string {\n const parts: string[] = [];\n let chunk = '';\n for (let i = 0; i < length; i += 3) {\n const a = bytes[i];\n const b = i + 1 < length ? bytes[i + 1] : 0;\n const c = i + 2 < length ? bytes[i + 2] : 0;\n chunk += B64[a >> 2] + B64[((a & 3) << 4) | (b >> 4)];\n chunk += i + 1 < length ? B64[((b & 15) << 2) | (c >> 6)] : '=';\n chunk += i + 2 < length ? B64[c & 63] : '=';\n if (chunk.length >= 8192) {\n parts.push(chunk);\n chunk = '';\n }\n }\n parts.push(chunk);\n return parts.join('');\n}\n\nfunction fromBase64(text: string): Uint8Array {\n if (text.length % 4 !== 0) throw new Error('Invalid base64 length');\n let pad = 0;\n if (text.endsWith('==')) pad = 2;\n else if (text.endsWith('=')) pad = 1;\n const out = new Uint8Array((text.length / 4) * 3 - pad);\n let o = 0;\n const digit = (i: number, k: number): number => {\n const ch = text.charCodeAt(i + k);\n if (ch === 61 /* = */ && i + 4 === text.length && k >= 4 - pad) return 0;\n const idx = ch < 128 ? B64_INDEX[ch] : -1;\n if (idx < 0) throw new Error('Invalid base64 character');\n return idx;\n };\n for (let i = 0; i < text.length; i += 4) {\n const n = (digit(i, 0) << 18) | (digit(i, 1) << 12) | (digit(i, 2) << 6) | digit(i, 3);\n if (o < out.length) out[o++] = (n >> 16) & 255;\n if (o < out.length) out[o++] = (n >> 8) & 255;\n if (o < out.length) out[o++] = n & 255;\n }\n return out;\n}\n\n/** Run-length encodes coverage bytes: `r1:` + base64 of (value, LEB128 run length) pairs. */\nexport function encodeSelectionRle(data: Uint8Array): string {\n let buf = new Uint8Array(64);\n let len = 0;\n const push = (b: number) => {\n if (len === buf.length) {\n const next = new Uint8Array(buf.length * 2);\n next.set(buf);\n buf = next;\n }\n buf[len++] = b;\n };\n let i = 0;\n while (i < data.length) {\n const v = data[i];\n let j = i + 1;\n while (j < data.length && data[j] === v) j++;\n push(v);\n let run = j - i;\n while (run >= 128) {\n push((run & 127) | 128);\n run = Math.floor(run / 128);\n }\n push(run);\n i = j;\n }\n return 'r1:' + toBase64(buf, len);\n}\n\n/** Decodes {@link encodeSelectionRle}; throws unless the runs cover exactly `length` bytes. */\nexport function decodeSelectionRle(rle: string, length: number): Uint8Array {\n if (typeof rle !== 'string' || !rle.startsWith('r1:')) throw new Error('Unknown selection encoding');\n const bytes = fromBase64(rle.slice(3));\n const out = new Uint8Array(length);\n let o = 0;\n let i = 0;\n while (i < bytes.length) {\n const v = bytes[i++];\n let run = 0;\n let scale = 1;\n for (;;) {\n if (i >= bytes.length) throw new Error('Truncated selection run');\n const b = bytes[i++];\n run += (b & 127) * scale;\n if (b < 128) break;\n scale *= 128;\n if (scale > 2 ** 35) throw new Error('Selection run too long');\n }\n if (run === 0 || o + run > length) throw new Error('Selection runs do not match its size');\n if (v !== 0) out.fill(v, o, o + run);\n o += run;\n }\n if (o !== length) throw new Error('Selection runs do not match its size');\n return out;\n}\n\nexport function serializeSelection(mask: SelectionMask): SerializedSelection {\n return { width: mask.width, height: mask.height, rle: encodeSelectionRle(mask.data) };\n}\n\n/** Restores a {@link SerializedSelection}; throws on damaged data. */\nexport function deserializeSelection(value: unknown): SelectionMask {\n if (!value || typeof value !== 'object') throw new Error('selection must be an object');\n const v = value as Record<string, unknown>;\n const width = v.width as number;\n const height = v.height as number;\n checkSize(width, height);\n return createSelectionMask(width, height, decodeSelectionRle(v.rle as string, width * height));\n}\n\n/** A short, stable hash of a string or bytes (FNV-1a, 32-bit, hex) for cache keys. */\nexport function hashMaskContent(content: string | Uint8Array): string {\n let h = 0x811c9dc5;\n if (typeof content === 'string') {\n for (let i = 0; i < content.length; i++) {\n h ^= content.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n } else {\n for (let i = 0; i < content.length; i++) {\n h ^= content[i];\n h = Math.imul(h, 0x01000193);\n }\n }\n return `${(h >>> 0).toString(16)}:${content.length}`;\n}\n","// Portions ported from photocraft/crates/algo/src/selection.rs, photocraft/crates/algo/src/selection/distance.rs, photocraft/crates/algo/src/selection_blur.rs and photocraft/crates/algo/src/matting.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\nimport { createSelectionMask, coverageToByte, selectionToCoverage, type SelectionMask } from './mask';\n\n/** Distance reported for every pixel when there is no seed at all. */\nexport const EMPTY_DISTANCE = 1e10;\n\n/**\n * Exact Euclidean distance from every pixel centre to the nearest seed pixel centre (row-major\n * `inside`, non-zero = seed): nearest seeds along columns, then the lower envelope of parabolas\n * along rows (Felzenszwalb & Huttenlocher). Linear in the pixel count.\n */\nexport function distanceTransform(inside: ArrayLike<number | boolean>, width: number, height: number): Float32Array {\n const n = width * height;\n const out = new Float32Array(n);\n let any = false;\n let all = true;\n for (let i = 0; i < n; i++) {\n if (inside[i]) any = true;\n else all = false;\n }\n if (!any) return out.fill(EMPTY_DISTANCE);\n if (all) return out;\n const NONE = 0xffffffff;\n // Vertical distance to the nearest seed in the same column.\n const vertical = new Uint32Array(n).fill(NONE);\n for (let x = 0; x < width; x++) {\n let nearest = -1;\n for (let y = 0; y < height; y++) {\n const i = y * width + x;\n if (inside[i]) nearest = y;\n if (nearest >= 0) vertical[i] = y - nearest;\n }\n nearest = -1;\n for (let y = height - 1; y >= 0; y--) {\n const i = y * width + x;\n if (vertical[i] === 0) nearest = y;\n if (nearest >= 0) vertical[i] = Math.min(vertical[i], nearest - y);\n }\n }\n const sites = new Int32Array(width);\n const starts = new Float64Array(width);\n for (let y = 0; y < height; y++) {\n const row = y * width;\n let count = 0;\n for (let q = 0; q < width; q++) {\n const dq = vertical[row + q];\n if (dq === NONE) continue;\n const fq = dq * dq;\n let start = -Infinity;\n while (count > 0) {\n const p = sites[count - 1];\n const dp = vertical[row + p];\n start = (fq - dp * dp) / (2 * (q - p)) + (q + p) * 0.5;\n if (start > starts[count - 1]) break;\n count--;\n }\n if (count === 0) start = -Infinity;\n sites[count] = q;\n starts[count] = start;\n count++;\n }\n if (count === 0) {\n out.fill(EMPTY_DISTANCE, row, row + width);\n continue;\n }\n let k = 0;\n for (let x = 0; x < width; x++) {\n while (k + 1 < count && starts[k + 1] < x) k++;\n const site = sites[k];\n const dx = x - site;\n const dv = vertical[row + site];\n out[row + x] = Math.sqrt(dx * dx + dv * dv);\n }\n }\n return out;\n}\n\nfunction thresholdInside(m: ArrayLike<number>, threshold = 0.5): Uint8Array {\n const out = new Uint8Array(m.length);\n for (let i = 0; i < m.length; i++) out[i] = m[i] >= threshold ? 1 : 0;\n return out;\n}\n\n/** Grows coverage (0..1) by `r` pixels: covered when the nearest selected centre is ≤ r away (fractional r → partial). */\nexport function expandCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array {\n const d = distanceTransform(thresholdInside(m), w, h);\n const out = new Float32Array(m.length);\n for (let i = 0; i < out.length; i++) out[i] = Math.max(m[i], Math.min(1, Math.max(0, r + 1 - d[i])));\n return out;\n}\n\n/** Shrinks coverage by `r` pixels (expands the inverse). */\nexport function contractCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array {\n const inv = new Float32Array(m.length);\n for (let i = 0; i < inv.length; i++) inv[i] = 1 - m[i];\n const e = expandCoverage(inv, w, h, r);\n for (let i = 0; i < e.length; i++) e[i] = 1 - e[i];\n return e;\n}\n\n/**\n * Select › Modify › Border: a soft band `2r` wide centred on the edge. A pixel `D` away (centre\n * to centre) from the nearest pixel on the other side of the edge is selected `1 − (D − 1) / r`.\n */\nexport function borderCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array {\n const inside = thresholdInside(m);\n const outside = new Uint8Array(inside.length);\n for (let i = 0; i < inside.length; i++) outside[i] = inside[i] ? 0 : 1;\n const out = new Float32Array(m.length);\n if (!(r > 0)) return out;\n const toInside = distanceTransform(inside, w, h);\n const toOutside = distanceTransform(outside, w, h);\n for (let i = 0; i < out.length; i++) {\n const d = inside[i] ? toOutside[i] : toInside[i];\n out[i] = Math.min(1, Math.max(0, 1 - (d - 1) / r));\n }\n return out;\n}\n\n/** Box average of radius `r` along one line, edges replicated, via a running sum (O(1) per sample). */\nfunction boxLineReplicate(src: Float32Array, srcOff: number, stride: number, len: number, r: number, dst: Float32Array) {\n const at = (i: number) => src[srcOff + Math.min(len - 1, Math.max(0, i)) * stride];\n let sum = 0;\n for (let i = -r; i <= r; i++) sum += at(i);\n const k = 2 * r + 1;\n for (let i = 0; i < len; i++) {\n dst[i] = sum / k;\n sum += at(i + r + 1) - at(i - r);\n }\n}\n\n/**\n * Select › Modify › Smooth: box average of radius `round(r)` with replicated edges, then\n * re-thresholded at ½ — specks drop, corners round, straight edges stay hard.\n */\nexport function smoothCoverage(m: ArrayLike<number>, w: number, h: number, r: number): Float32Array {\n const rr = Number.isFinite(r) ? Math.max(0, Math.round(r)) : 0;\n const src = Float32Array.from(m);\n const tmp = new Float32Array(src.length);\n const line = new Float32Array(Math.max(w, h));\n if (rr > 0) {\n for (let y = 0; y < h; y++) {\n boxLineReplicate(src, y * w, 1, w, rr, line);\n tmp.set(line.subarray(0, w), y * w);\n }\n for (let x = 0; x < w; x++) {\n boxLineReplicate(tmp, x, w, h, rr, line);\n for (let y = 0; y < h; y++) src[y * w + x] = line[y];\n }\n }\n for (let i = 0; i < src.length; i++) src[i] = src[i] >= 0.5 ? 1 : 0;\n return src;\n}\n\n/** Normalised Gaussian kernel of σ, truncated at ⌈3σ⌉. */\nfunction gaussianKernel(sigma: number): Float32Array {\n const r = Math.ceil(sigma * 3);\n const k = new Float32Array(2 * r + 1);\n let s = 0;\n for (let i = -r; i <= r; i++) {\n const v = Math.exp(-(i * i) / (2 * sigma * sigma));\n k[i + r] = v;\n s += v;\n }\n for (let i = 0; i < k.length; i++) k[i] /= s;\n return k;\n}\n\n/** Above this σ a Gaussian is approximated by three box passes (cost independent of σ). */\nexport const DIRECT_GAUSSIAN_MAX_SIGMA = 8;\n\n/** Box sizes of three passes whose combined variance matches σ² (Kovesi). */\nfunction boxRadii(sigma: number): [number, number, number] {\n const n = 3;\n const wIdeal = Math.sqrt((12 * sigma * sigma) / n + 1);\n let wl = Math.floor(wIdeal);\n if (wl % 2 === 0) wl--;\n const wu = wl + 2;\n const mIdeal = (12 * sigma * sigma - n * wl * wl - 4 * n * wl - 3 * n) / (-4 * wl - 4);\n const m = Math.round(mIdeal);\n const sizes = [0, 1, 2].map((i) => (i < m ? wl : wu));\n return sizes.map((s) => (s - 1) / 2) as [number, number, number];\n}\n\ntype Edge = 'zero' | 'clamp';\n\nfunction convolveLine(src: Float32Array, off: number, stride: number, len: number, k: Float32Array, edge: Edge, dst: Float32Array) {\n const r = (k.length - 1) / 2;\n for (let i = 0; i < len; i++) {\n let a = 0;\n const lo = i - r;\n for (let j = 0; j < k.length; j++) {\n let x = lo + j;\n if (x < 0 || x >= len) {\n if (edge === 'zero') continue;\n x = x < 0 ? 0 : len - 1;\n }\n a += src[off + x * stride] * k[j];\n }\n dst[i] = a;\n }\n}\n\n/**\n * Three box passes along one line, run on the line padded by the passes' total reach (zeros or\n * replicated ends), so the result equals one convolution with the combined kernel over the\n * same outside values — clipping between passes would lose the mass that spilled out.\n */\nfunction boxesLine(\n src: Float32Array,\n off: number,\n stride: number,\n len: number,\n radii: readonly number[],\n edge: Edge,\n a: Float32Array,\n b: Float32Array,\n dst: Float32Array\n) {\n const pad = radii.reduce((s, r) => s + r, 0);\n const plen = len + 2 * pad;\n for (let i = 0; i < plen; i++) {\n const j = i - pad;\n a[i] = j < 0 ? (edge === 'zero' ? 0 : src[off]) : j >= len ? (edge === 'zero' ? 0 : src[off + (len - 1) * stride]) : src[off + j * stride];\n }\n let from = a;\n let to = b;\n for (const r of radii) {\n // Window clipped to the padded line; the padding is wide enough that the clip never\n // reaches the part that is kept.\n let sum = 0;\n for (let i = 0; i <= Math.min(r, plen - 1); i++) sum += from[i];\n const k = 2 * r + 1;\n for (let i = 0; i < plen; i++) {\n to[i] = sum / k;\n const add = i + r + 1;\n const drop = i - r;\n if (add < plen) sum += from[add];\n if (drop >= 0) sum -= from[drop];\n }\n const t = from;\n from = to;\n to = t;\n }\n for (let i = 0; i < len; i++) dst[i] = from[i + pad];\n}\n\n/**\n * Separable Gaussian blur of a single-channel float image. `edge` `zero` treats pixels beyond\n * the image as 0 (selection feather), `clamp` replicates the border (mask refinement). σ up to\n * {@link DIRECT_GAUSSIAN_MAX_SIGMA} is convolved directly; wider blurs use three box passes, so\n * the cost per pixel never grows with σ.\n */\nexport function gaussianBlur(src: ArrayLike<number>, w: number, h: number, sigma: number, edge: Edge = 'zero'): Float32Array {\n const out = Float32Array.from(src);\n if (!(sigma >= 0.1) || w <= 0 || h <= 0) return out;\n // Far beyond the image a wider blur changes nothing but cost.\n const s = Math.min(sigma, 4 * Math.max(w, h));\n const line = new Float32Array(Math.max(w, h));\n const passes: Array<(buf: Float32Array, off: number, stride: number, len: number) => void> = [];\n if (s <= DIRECT_GAUSSIAN_MAX_SIGMA) {\n const k = gaussianKernel(s);\n passes.push((buf, off, stride, len) => convolveLine(buf, off, stride, len, k, edge, line));\n } else {\n const radii = boxRadii(s);\n const plen = Math.max(w, h) + 2 * radii.reduce((a, r) => a + r, 0);\n const a = new Float32Array(plen);\n const b = new Float32Array(plen);\n passes.push((buf, off, stride, len) => boxesLine(buf, off, stride, len, radii, edge, a, b, line));\n }\n for (const pass of passes) {\n for (let y = 0; y < h; y++) {\n pass(out, y * w, 1, w);\n out.set(line.subarray(0, w), y * w);\n }\n }\n for (const pass of passes) {\n for (let x = 0; x < w; x++) {\n pass(out, x, w, h);\n for (let y = 0; y < h; y++) out[y * w + x] = line[y];\n }\n }\n return out;\n}\n\n/** Select › Modify › Feather: Gaussian blur with σ = radius (as Photoshop), zero beyond the image. */\nexport function featherCoverage(m: ArrayLike<number>, w: number, h: number, radius: number): Float32Array {\n const out = gaussianBlur(m, w, h, Number.isFinite(radius) ? Math.max(0, radius) : 0, 'zero');\n for (let i = 0; i < out.length; i++) if (Math.abs(out[i]) < 1e-7) out[i] = 0;\n return out;\n}\n\n/**\n * Running max (or min) over a window of radius `r` along one line (edge-clipped), van Herk /\n * Gil–Werman: about three comparisons per sample whatever the radius.\n */\nfunction runningExtreme(src: Float32Array, off: number, stride: number, len: number, r: number, max: boolean, g: Float32Array, hb: Float32Array, dst: Float32Array) {\n const k = 2 * r + 1;\n const pick = max ? (a: number, b: number) => (a > b ? a : b) : (a: number, b: number) => (a < b ? a : b);\n const fill = max ? -Infinity : Infinity;\n // Padded line: r fills on each side.\n const plen = len + 2 * r;\n const at = (i: number) => (i < r || i >= r + len ? fill : src[off + (i - r) * stride]);\n for (let start = 0; start < plen; start += k) {\n const end = Math.min(plen, start + k);\n g[start] = at(start);\n for (let i = start + 1; i < end; i++) g[i] = pick(g[i - 1], at(i));\n hb[end - 1] = at(end - 1);\n for (let i = end - 2; i >= start; i--) hb[i] = pick(hb[i + 1], at(i));\n }\n for (let i = 0; i < len; i++) {\n // Window over padded indices i .. i + 2r.\n const a = hb[i];\n const b = g[i + 2 * r];\n dst[i] = pick(a, b);\n }\n}\n\n/** Grey dilation (`grow`) or erosion with a square of radius `r`, separable, O(1) per pixel. */\nexport function greyMorphology(src: ArrayLike<number>, w: number, h: number, r: number, grow: boolean): Float32Array {\n const out = Float32Array.from(src);\n if (r <= 0) return out;\n const n = Math.max(w, h);\n const g = new Float32Array(n + 2 * r);\n const hb = new Float32Array(n + 2 * r);\n const line = new Float32Array(n);\n for (let y = 0; y < h; y++) {\n runningExtreme(out, y * w, 1, w, r, grow, g, hb, line);\n out.set(line.subarray(0, w), y * w);\n }\n for (let x = 0; x < w; x++) {\n runningExtreme(out, x, w, h, r, grow, g, hb, line);\n for (let y = 0; y < h; y++) out[y * w + x] = line[y];\n }\n return out;\n}\n\n/**\n * Grows (positive) or shrinks (negative) soft coverage by a fractional distance: whole pixels\n * use one morphology, the remainder blends with the next pixel, so 0.3 px differs from 1 px.\n */\nexport function shiftCoverage(src: ArrayLike<number>, w: number, h: number, amount: number): Float32Array {\n const mag = Math.abs(amount);\n if (!Number.isFinite(mag) || mag < 1e-4) return Float32Array.from(src);\n const grow = amount > 0;\n const whole = Math.floor(mag);\n const frac = mag - whole;\n if (frac < 1e-4) return greyMorphology(src, w, h, whole, grow);\n const lo = whole === 0 ? Float32Array.from(src) : greyMorphology(src, w, h, whole, grow);\n const hi = greyMorphology(src, w, h, whole + 1, grow);\n for (let i = 0; i < lo.length; i++) lo[i] += (hi[i] - lo[i]) * frac;\n return lo;\n}\n\n// ---------------------------------------------------------------------------\n// Selection-level wrappers\n// ---------------------------------------------------------------------------\n\nexport type SelectionModifyOp = 'grow' | 'shrink' | 'feather' | 'border' | 'smooth';\n\nexport const SELECTION_MODIFY_OPS: readonly SelectionModifyOp[] = ['grow', 'shrink', 'feather', 'border', 'smooth'];\n\nfunction wrap(mask: SelectionMask, coverage: Float32Array): SelectionMask {\n const out = new Uint8Array(coverage.length);\n for (let i = 0; i < out.length; i++) out[i] = coverageToByte(coverage[i]);\n return createSelectionMask(mask.width, mask.height, out);\n}\n\n/** Select › Modify (grow = Expand, shrink = Contract, feather, border, smooth) by `radius` pixels. */\nexport function modifySelection(mask: SelectionMask, op: SelectionModifyOp, radius: number): SelectionMask {\n const r = Number.isFinite(radius) ? Math.max(0, radius) : 0;\n if (r === 0 && op !== 'border') return mask;\n const m = selectionToCoverage(mask);\n const { width: w, height: h } = mask;\n switch (op) {\n case 'grow':\n return wrap(mask, expandCoverage(m, w, h, r));\n case 'shrink':\n return wrap(mask, contractCoverage(m, w, h, r));\n case 'feather':\n return wrap(mask, featherCoverage(m, w, h, r));\n case 'border':\n return wrap(mask, borderCoverage(m, w, h, r));\n case 'smooth':\n return wrap(mask, smoothCoverage(m, w, h, r));\n default:\n throw new Error(`Unknown selection modification \"${op as string}\"`);\n }\n}\n","// Portions ported from photocraft/crates/engine/src/layer_mask_props_cmds.rs and photocraft/crates/compose/src/masks.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\nimport type { AdjustmentLayer, AdjustmentLayerMask } from '../types';\nimport { unprojectCanvasPoint, type ImageProjection } from '../geometry';\nimport {\n createSelectionMask,\n decodeSelectionRle,\n encodeSelectionRle,\n hashMaskContent,\n type SelectionMask,\n} from './mask';\nimport { gaussianBlur } from './modify';\n\n/** Properties of a layer mask that leave its pixels intact (Photoshop's Properties › Masks). */\nexport interface LayerMaskProps {\n /** 0..1 (default 1): at 0.5 the masked-out areas still get half of the adjustment. */\n density?: number;\n /** Gaussian feather σ in pixels, 0..1000 (default 0). */\n feather?: number;\n /** Disabled masks are kept but ignored (the layer applies everywhere). Default true. */\n enabled?: boolean;\n}\n\nconst MAX_SIDE = 1 << 15;\n\n/**\n * A clean layer mask from stored data, or `null` when it is unusable. Defaults are left out\n * (density 1, feather 0, enabled), so a plain mask serializes as `{width, height, rle}`. The\n * RLE is only decoded when rendering.\n */\nexport function normalizeLayerMask(raw: unknown): AdjustmentLayerMask | null {\n if (!raw || typeof raw !== 'object') return null;\n const r = raw as Record<string, unknown>;\n const { width, height, rle } = r;\n if (\n typeof width !== 'number' ||\n typeof height !== 'number' ||\n !Number.isInteger(width) ||\n !Number.isInteger(height) ||\n width < 1 ||\n height < 1 ||\n width > MAX_SIDE ||\n height > MAX_SIDE ||\n typeof rle !== 'string' ||\n !rle.startsWith('r1:')\n ) {\n return null;\n }\n const out: AdjustmentLayerMask = { width, height, rle };\n if (typeof r.density === 'number' && Number.isFinite(r.density)) {\n const d = Math.min(1, Math.max(0, r.density));\n if (d !== 1) out.density = d;\n }\n if (typeof r.feather === 'number' && Number.isFinite(r.feather)) {\n const f = Math.min(1000, Math.max(0, r.feather));\n if (f !== 0) out.feather = f;\n }\n if (r.enabled === false) out.enabled = false;\n return out;\n}\n\n/** A layer mask holding the selection's pixels (Add Layer Mask › Reveal Selection). */\nexport function layerMaskFromSelection(selection: SelectionMask, props: LayerMaskProps = {}): AdjustmentLayerMask {\n return normalizeLayerMask({ width: selection.width, height: selection.height, rle: encodeSelectionRle(selection.data), ...props })!;\n}\n\n/** Applies property changes; `undefined` fields keep their value. */\nexport function updateLayerMaskProps(mask: AdjustmentLayerMask, props: LayerMaskProps): AdjustmentLayerMask {\n return normalizeLayerMask({\n ...mask,\n ...(props.density !== undefined ? { density: props.density } : {}),\n ...(props.feather !== undefined ? { feather: props.feather } : {}),\n ...(props.enabled !== undefined ? { enabled: props.enabled } : {}),\n })!;\n}\n\n// Small LRU caches: masks are stored as RLE strings and layers are deep-copied often.\nconst DECODE_LIMIT = 8;\nconst decoded = new Map<string, SelectionMask | null>();\nconst coverageCache = new Map<string, Float32Array | null>();\n\nfunction lru<T>(cache: Map<string, T>, key: string, make: () => T): T {\n if (cache.has(key)) {\n const v = cache.get(key)!;\n cache.delete(key);\n cache.set(key, v);\n return v;\n }\n const v = make();\n cache.set(key, v);\n if (cache.size > DECODE_LIMIT) cache.delete(cache.keys().next().value as string);\n return v;\n}\n\n/** The mask's pixels as a selection (Load Selection from mask), or `null` when the data is damaged. */\nexport function decodeLayerMask(mask: AdjustmentLayerMask): SelectionMask | null {\n const key = `${mask.width}x${mask.height}:${mask.rle}`;\n return lru(decoded, key, () => {\n try {\n return createSelectionMask(mask.width, mask.height, decodeSelectionRle(mask.rle, mask.width * mask.height));\n } catch {\n return null;\n }\n });\n}\n\n/** Cache key of everything about a mask that changes pixels. */\nexport function layerMaskKey(mask: AdjustmentLayerMask | undefined): string {\n if (!mask) return '';\n return `${mask.width}x${mask.height}:${hashMaskContent(mask.rle)}:${mask.density ?? 1}:${mask.feather ?? 0}:${mask.enabled !== false}`;\n}\n\n/**\n * The mask's effective coverage (0..1, mask resolution): feathered (σ = feather, borders\n * replicated), then density applied as `1 − density·(1 − v)`. `null` for a disabled or damaged\n * mask, meaning \"no mask\".\n */\nexport function layerMaskCoverage(mask: AdjustmentLayerMask): Float32Array | null {\n if (mask.enabled === false) return null;\n return lru(coverageCache, layerMaskKey(mask), () => {\n const sel = decodeLayerMask(mask);\n if (!sel) return null;\n let v: Float32Array = new Float32Array(sel.data.length);\n for (let i = 0; i < v.length; i++) v[i] = sel.data[i] / 255;\n const feather = mask.feather ?? 0;\n if (feather > 0) v = gaussianBlur(v, mask.width, mask.height, feather, 'clamp');\n const density = mask.density ?? 1;\n if (density !== 1) for (let i = 0; i < v.length; i++) v[i] = 1 - density * (1 - v[i]);\n return v;\n });\n}\n\n/**\n * Resamples mask coverage (natural-image aligned, any resolution) into a target raster drawn\n * through `projection` (the base canvas of the renderer: crop, rotation, flips): each target\n * pixel centre is unprojected to natural pixels and sampled bilinearly.\n */\nexport function projectMaskCoverage(\n coverage: Float32Array,\n maskWidth: number,\n maskHeight: number,\n naturalWidth: number,\n naturalHeight: number,\n projection: ImageProjection,\n targetWidth: number,\n targetHeight: number\n): Float32Array {\n const out = new Float32Array(targetWidth * targetHeight);\n const o = unprojectCanvasPoint({ x: 0.5, y: 0.5 }, projection);\n const ox = unprojectCanvasPoint({ x: 1.5, y: 0.5 }, projection);\n const oy = unprojectCanvasPoint({ x: 0.5, y: 1.5 }, projection);\n const kx = maskWidth / naturalWidth;\n const ky = maskHeight / naturalHeight;\n // Affine map target → mask coordinates (pixel centres at +0.5).\n const ux = (ox.x - o.x) * kx;\n const vx = (ox.y - o.y) * ky;\n const uy = (oy.x - o.x) * kx;\n const vy = (oy.y - o.y) * ky;\n const u0 = o.x * kx - 0.5;\n const v0 = o.y * ky - 0.5;\n const mw1 = maskWidth - 1;\n const mh1 = maskHeight - 1;\n for (let y = 0; y < targetHeight; y++) {\n let u = u0 + y * uy;\n let v = v0 + y * vy;\n const row = y * targetWidth;\n for (let x = 0; x < targetWidth; x++, u += ux, v += vx) {\n const fu = u < 0 ? 0 : u > mw1 ? mw1 : u;\n const fv = v < 0 ? 0 : v > mh1 ? mh1 : v;\n const x0 = fu | 0;\n const y0 = fv | 0;\n const x1 = x0 < mw1 ? x0 + 1 : x0;\n const y1 = y0 < mh1 ? y0 + 1 : y0;\n const tx = fu - x0;\n const ty = fv - y0;\n const a = coverage[y0 * maskWidth + x0] * (1 - tx) + coverage[y0 * maskWidth + x1] * tx;\n const b = coverage[y1 * maskWidth + x0] * (1 - tx) + coverage[y1 * maskWidth + x1] * tx;\n out[row + x] = a * (1 - ty) + b * ty;\n }\n }\n return out;\n}\n\n/**\n * Per-layer mask coverage for a render target, keyed by layer id; `undefined` when no layer has\n * an enabled, valid mask (so mask-free stacks take the exact same path as before).\n */\nexport function buildLayerMaskPlanes(\n layers: readonly AdjustmentLayer[] | undefined,\n naturalWidth: number,\n naturalHeight: number,\n projection: ImageProjection,\n targetWidth: number,\n targetHeight: number\n): Map<string, Float32Array> | undefined {\n if (!layers?.some((l) => l.mask && l.mask.enabled !== false)) return undefined;\n const planes = new Map<string, Float32Array>();\n for (const layer of layers) {\n if (!layer.mask) continue;\n const coverage = layerMaskCoverage(layer.mask);\n if (!coverage) continue;\n planes.set(\n layer.id,\n projectMaskCoverage(coverage, layer.mask.width, layer.mask.height, naturalWidth, naturalHeight, projection, targetWidth, targetHeight)\n );\n }\n return planes.size ? planes : undefined;\n}\n","// Portions ported from photocraft-main/crates/compose/src/adjust.rs, photocraft-main/crates/doc/src/adjust.rs and photocraft-main/crates/color/src/convert.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\nimport type {\n AdjustmentKind,\n AdjustmentLayer,\n AdjustmentLayerMask,\n AdjustmentLayerOf,\n AdjustmentParamsMap,\n BlackWhiteParams,\n ColorBalanceParams,\n ColorBalanceTone,\n CurvePoint,\n HueRange,\n HueSaturationParams,\n LevelsChannel,\n PhotoFilterParams,\n VibranceParams,\n} from './types';\nimport { type BlendMode, blendRgb, normalizeBlendMode, setLum } from './blend';\nimport { linearToSrgb, srgbToLinear } from './color';\nimport { layerMaskKey, normalizeLayerMask } from './selection/layer-mask';\n\n/**\n * Adjustment layers: Photoshop-matching evaluation on encoded sRGB colours in 0..1.\n *\n * Every layer is compiled once per parameter change into a per-pixel function (per-channel kinds\n * into three 4096-entry LUTs); {@link applyAdjustmentLayers} runs the stack on an ImageData.\n */\n\ntype Rgb = [number, number, number];\n\n/** Entries in a tone LUT (curves, levels, colour balance). */\nexport const ADJUSTMENT_LUT_SIZE = 4096;\n\nconst clamp01 = (v: number) => (v <= 0 ? 0 : v >= 1 ? 1 : v);\nconst finite = (v: unknown, fallback: number) => (typeof v === 'number' && Number.isFinite(v) ? v : fallback);\nconst clampTo = (v: unknown, lo: number, hi: number, fallback: number) => Math.min(hi, Math.max(lo, finite(v, fallback)));\nconst remEuclid = (a: number, b: number) => ((a % b) + b) % b;\n\n/** Linear interpolation into a 0..1-domain LUT. */\nexport function sampleLut(table: ArrayLike<number>, v: number): number {\n const n = table.length - 1;\n const x = clamp01(v) * n;\n const i = Math.floor(x);\n const j = Math.min(i + 1, n);\n const f = x - i;\n return table[i] * (1 - f) + table[j] * f;\n}\n\n// ---------------------------------------------------------------------------\n// Kinds, labels, defaults\n// ---------------------------------------------------------------------------\n\nexport interface AdjustmentKindInfo {\n kind: AdjustmentKind;\n label: string;\n}\n\nexport const ADJUSTMENT_KINDS: readonly AdjustmentKindInfo[] = [\n { kind: 'curves', label: 'Curves' },\n { kind: 'levels', label: 'Levels' },\n { kind: 'hueSaturation', label: 'Hue/Saturation' },\n { kind: 'vibrance', label: 'Vibrance' },\n { kind: 'colorBalance', label: 'Color Balance' },\n { kind: 'blackWhite', label: 'Black & White' },\n { kind: 'photoFilter', label: 'Photo Filter' },\n { kind: 'invert', label: 'Invert' },\n { kind: 'posterize', label: 'Posterize' },\n { kind: 'threshold', label: 'Threshold' },\n];\n\nconst KIND_LABELS = new Map(ADJUSTMENT_KINDS.map((k) => [k.kind, k.label]));\n\nexport function isAdjustmentKind(value: unknown): value is AdjustmentKind {\n return typeof value === 'string' && KIND_LABELS.has(value as AdjustmentKind);\n}\n\nexport function adjustmentKindLabel(kind: AdjustmentKind): string {\n return KIND_LABELS.get(kind) ?? kind;\n}\n\nexport const HUE_RANGE_LABELS = ['Reds', 'Yellows', 'Greens', 'Cyans', 'Blues', 'Magentas'] as const;\n\n/** The neutral range `i` (0 reds … 5 magentas): fully on for 30° around its centre, fading over 30° each side. */\nexport function neutralHueRange(i: number): HueRange {\n const c = 60 * i;\n return { hue: 0, saturation: 0, lightness: 0, bounds: [c - 45, c - 15, c + 15, c + 45] };\n}\n\nexport const identityCurve = (): CurvePoint[] => [\n { input: 0, output: 0 },\n { input: 255, output: 255 },\n];\n\nexport const identityLevels = (): LevelsChannel => ({ inBlack: 0, inWhite: 255, gamma: 1, outBlack: 0, outWhite: 255 });\n\n/** Neutral parameters of every kind (fresh objects on every call). */\nexport function defaultAdjustmentParams<K extends AdjustmentKind>(kind: K): AdjustmentParamsMap[K] {\n const defaults: { [P in AdjustmentKind]: () => AdjustmentParamsMap[P] } = {\n curves: () => ({ master: identityCurve(), red: identityCurve(), green: identityCurve(), blue: identityCurve() }),\n levels: () => ({ master: identityLevels(), red: identityLevels(), green: identityLevels(), blue: identityLevels() }),\n hueSaturation: () => ({\n hue: 0,\n saturation: 0,\n lightness: 0,\n colorize: false,\n ranges: [0, 1, 2, 3, 4, 5].map(neutralHueRange),\n }),\n vibrance: () => ({ vibrance: 0, saturation: 0 }),\n colorBalance: () => ({ shadows: [0, 0, 0], midtones: [0, 0, 0], highlights: [0, 0, 0], preserveLuminosity: true }),\n blackWhite: () => ({ reds: 40, yellows: 60, greens: 40, cyans: 60, blues: 20, magentas: 80, tint: null }),\n invert: () => ({}) as Record<string, never>,\n posterize: () => ({ levels: 4 }),\n threshold: () => ({ level: 128 }),\n photoFilter: () => ({ color: '#ec8a00', density: 25, preserveLuminosity: true }),\n };\n return defaults[kind]() as AdjustmentParamsMap[K];\n}\n\nlet layerCounter = 0;\n\n/** A new layer of `kind` with neutral (or the given) parameters, enabled, opacity 1, normal blend. */\nexport function createAdjustmentLayer<K extends AdjustmentKind>(\n kind: K,\n options: {\n id?: string;\n name?: string;\n params?: Partial<AdjustmentParamsMap[K]>;\n enabled?: boolean;\n opacity?: number;\n blend?: BlendMode;\n mask?: AdjustmentLayerMask;\n } = {}\n): AdjustmentLayerOf<K> {\n const raw = {\n id: options.id ?? `adj_${Date.now().toString(36)}_${(++layerCounter).toString(36)}`,\n kind,\n name: options.name,\n params: { ...defaultAdjustmentParams(kind), ...(options.params ?? {}) },\n enabled: options.enabled ?? true,\n opacity: options.opacity ?? 1,\n blend: options.blend ?? 'normal',\n mask: options.mask,\n };\n return normalizeAdjustmentLayer(raw) as AdjustmentLayerOf<K>;\n}\n\n// ---------------------------------------------------------------------------\n// Normalisation of stored layers\n// ---------------------------------------------------------------------------\n\nconst HEX = /^#[0-9a-f]{6}$/i;\n\nfunction normCurve(points: unknown): CurvePoint[] {\n if (!Array.isArray(points)) return identityCurve();\n const out = points\n .filter((p) => p && typeof p === 'object')\n .map((p) => ({ input: clampTo(p.input, 0, 255, 0), output: clampTo(p.output, 0, 255, 0) }))\n .sort((a, b) => a.input - b.input);\n return out.length >= 2 ? out : identityCurve();\n}\n\nfunction normLevels(ch: unknown): LevelsChannel {\n const c = (ch && typeof ch === 'object' ? ch : {}) as Partial<LevelsChannel>;\n return {\n inBlack: clampTo(c.inBlack, 0, 254, 0),\n inWhite: clampTo(c.inWhite, 1, 255, 255),\n gamma: clampTo(c.gamma, 0.1, 9.99, 1),\n outBlack: clampTo(c.outBlack, 0, 255, 0),\n outWhite: clampTo(c.outWhite, 0, 255, 255),\n };\n}\n\nfunction normTone(t: unknown): ColorBalanceTone {\n const a = Array.isArray(t) ? t : [];\n return [clampTo(a[0], -100, 100, 0), clampTo(a[1], -100, 100, 0), clampTo(a[2], -100, 100, 0)];\n}\n\nfunction normParams(kind: AdjustmentKind, raw: unknown): AdjustmentParamsMap[AdjustmentKind] {\n const p = (raw && typeof raw === 'object' ? raw : {}) as Record<string, any>;\n const d = defaultAdjustmentParams(kind) as Record<string, any>;\n switch (kind) {\n case 'curves':\n return { master: normCurve(p.master), red: normCurve(p.red), green: normCurve(p.green), blue: normCurve(p.blue) };\n case 'levels':\n return { master: normLevels(p.master), red: normLevels(p.red), green: normLevels(p.green), blue: normLevels(p.blue) };\n case 'hueSaturation': {\n const ranges: HueRange[] = [0, 1, 2, 3, 4, 5].map((i) => {\n const r = Array.isArray(p.ranges) && p.ranges[i] && typeof p.ranges[i] === 'object' ? p.ranges[i] : {};\n const n = neutralHueRange(i);\n const b = Array.isArray(r.bounds) && r.bounds.length === 4 && r.bounds.every((v: unknown) => Number.isFinite(v)) ? r.bounds : n.bounds;\n return {\n hue: clampTo(r.hue, -180, 180, 0),\n saturation: clampTo(r.saturation, -100, 100, 0),\n lightness: clampTo(r.lightness, -100, 100, 0),\n bounds: [b[0], b[1], b[2], b[3]] as [number, number, number, number],\n };\n });\n const colorize = p.colorize === true;\n return {\n hue: colorize ? clampTo(p.hue, 0, 360, 0) : clampTo(p.hue, -180, 180, 0),\n saturation: clampTo(p.saturation, -100, 100, 0),\n lightness: clampTo(p.lightness, -100, 100, 0),\n colorize,\n ranges,\n } satisfies HueSaturationParams;\n }\n case 'vibrance':\n return { vibrance: clampTo(p.vibrance, -100, 100, 0), saturation: clampTo(p.saturation, -100, 100, 0) } satisfies VibranceParams;\n case 'colorBalance':\n return {\n shadows: normTone(p.shadows),\n midtones: normTone(p.midtones),\n highlights: normTone(p.highlights),\n preserveLuminosity: p.preserveLuminosity !== false,\n } satisfies ColorBalanceParams;\n case 'blackWhite': {\n const out = {} as BlackWhiteParams;\n for (const k of ['reds', 'yellows', 'greens', 'cyans', 'blues', 'magentas'] as const) out[k] = clampTo(p[k], -200, 300, d[k]);\n out.tint = typeof p.tint === 'string' && HEX.test(p.tint) ? p.tint.toLowerCase() : null;\n return out;\n }\n case 'photoFilter':\n return {\n color: typeof p.color === 'string' && HEX.test(p.color) ? p.color.toLowerCase() : d.color,\n density: clampTo(p.density, 0, 100, d.density),\n preserveLuminosity: p.preserveLuminosity !== false,\n } satisfies PhotoFilterParams;\n case 'posterize':\n return { levels: Math.round(clampTo(p.levels, 2, 255, 4)) };\n case 'threshold':\n return { level: Math.round(clampTo(p.level, 1, 255, 128)) };\n case 'invert':\n return {} as Record<string, never>;\n }\n}\n\n/**\n * A clean, deep-copied layer from stored or hand-written data: missing fields get neutral\n * defaults, numbers are clamped to their ranges. `null` for an unknown kind.\n */\nexport function normalizeAdjustmentLayer(raw: unknown): AdjustmentLayer | null {\n if (!raw || typeof raw !== 'object') return null;\n const r = raw as Record<string, any>;\n if (!isAdjustmentKind(r.kind)) return null;\n const layer: Record<string, unknown> = {\n id: typeof r.id === 'string' && r.id ? r.id : `adj_${Date.now().toString(36)}_${(++layerCounter).toString(36)}`,\n kind: r.kind,\n enabled: r.enabled !== false,\n opacity: clampTo(r.opacity, 0, 1, 1),\n blend: normalizeBlendMode(r.blend),\n params: normParams(r.kind, r.params),\n };\n if (typeof r.name === 'string' && r.name) layer.name = r.name;\n // Only present when the layer has a usable mask, so mask-free layers serialize as before.\n const mask = normalizeLayerMask(r.mask);\n if (mask) layer.mask = mask;\n return layer as unknown as AdjustmentLayer;\n}\n\n/** Normalises a stored layer list (drops unknown kinds, de-duplicates ids). */\nexport function normalizeAdjustmentLayers(raw: unknown): AdjustmentLayer[] {\n if (!Array.isArray(raw)) return [];\n const seen = new Set<string>();\n const out: AdjustmentLayer[] = [];\n for (const item of raw) {\n const layer = normalizeAdjustmentLayer(item);\n if (!layer) continue;\n while (seen.has(layer.id)) layer.id = `${layer.id}_${(++layerCounter).toString(36)}`;\n seen.add(layer.id);\n out.push(layer);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Curves\n// ---------------------------------------------------------------------------\n\n/**\n * Photoshop curve: a natural cubic spline through the points (0..1 in and out; it may overshoot\n * between points, as Photoshop's does), constant outside the first / last point, clamped to\n * 0..1, sampled into a LUT. Fewer than two distinct points: the identity.\n */\nexport function curveLut(points: ReadonlyArray<{ input: number; output: number }>, size = ADJUSTMENT_LUT_SIZE): Float32Array {\n const pts = points\n .filter((p) => Number.isFinite(p.input) && Number.isFinite(p.output))\n .map((p) => [p.input, p.output] as [number, number])\n .sort((a, b) => a[0] - b[0]);\n const dedup: [number, number][] = [];\n for (const p of pts) {\n if (dedup.length && Math.abs(dedup[dedup.length - 1][0] - p[0]) < 1e-6) continue;\n dedup.push(p);\n }\n const out = new Float32Array(size);\n const n = dedup.length;\n if (n < 2) {\n for (let k = 0; k < size; k++) out[k] = k / (size - 1);\n return out;\n }\n const x = dedup.map((p) => p[0]);\n const y = dedup.map((p) => p[1]);\n // Second derivatives of the natural spline (tridiagonal solve).\n const m2 = new Float64Array(n);\n if (n > 2) {\n const c = new Float64Array(n);\n const d = new Float64Array(n);\n for (let i = 1; i < n - 1; i++) {\n const h0 = x[i] - x[i - 1];\n const h1 = x[i + 1] - x[i];\n const a = h0 / 6;\n const b = (h0 + h1) / 3;\n const cc = h1 / 6;\n const r = (y[i + 1] - y[i]) / h1 - (y[i] - y[i - 1]) / h0;\n const denom = b - a * c[i - 1];\n c[i] = cc / denom;\n d[i] = (r - a * d[i - 1]) / denom;\n }\n for (let i = n - 2; i >= 1; i--) m2[i] = d[i] - c[i] * m2[i + 1];\n }\n let seg = 0;\n for (let k = 0; k < size; k++) {\n const xv = k / (size - 1);\n if (xv <= x[0]) {\n out[k] = clamp01(y[0]);\n continue;\n }\n if (xv >= x[n - 1]) {\n out[k] = clamp01(y[n - 1]);\n continue;\n }\n while (seg < n - 2 && xv > x[seg + 1]) seg++;\n const x0 = x[seg], x1 = x[seg + 1];\n const h = x1 - x0;\n const a = (x1 - xv) / h;\n const b = (xv - x0) / h;\n const v = a * y[seg] + b * y[seg + 1] + ((a * a * a - a) * m2[seg] + (b * b * b - b) * m2[seg + 1]) * (h * h) / 6;\n out[k] = clamp01(v);\n }\n return out;\n}\n\n/** {@link curveLut} for Curves points in levels (0..255). */\nexport function curveLutFromLevels(points: readonly CurvePoint[]): Float32Array {\n return curveLut(points.map((p) => ({ input: p.input / 255, output: p.output / 255 })));\n}\n\n// ---------------------------------------------------------------------------\n// Levels\n// ---------------------------------------------------------------------------\n\n/** A Levels record with values in 0..1 (as `levelsValue` takes them). */\nexport interface UnitLevels {\n inBlack: number;\n inWhite: number;\n gamma: number;\n outBlack: number;\n outWhite: number;\n}\n\nconst toUnitLevels = (c: LevelsChannel): UnitLevels => ({\n inBlack: c.inBlack / 255,\n inWhite: c.inWhite / 255,\n gamma: c.gamma,\n outBlack: c.outBlack / 255,\n outWhite: c.outWhite / 255,\n});\n\n/**\n * One Levels record on `v` (0..1). With `quantum` (8-bit: 255) Photoshop works on whole levels:\n * the input is a level and the stretch is rounded (half up) before the gamma. A gamma above 1 has\n * Photoshop's soft shadow toe: a p-norm soft-min of the power curve and a line of slope ≈ 2^gamma.\n */\nexport function levelsValue(ch: UnitLevels, v: number, quantum?: number): number {\n const range = Math.max(1e-6, ch.inWhite - ch.inBlack);\n let u: number;\n if (quantum !== undefined && Number.isFinite(quantum) && quantum >= 1) {\n const q = quantum;\n const vq = Math.round(v * q) / q;\n u = Math.floor(clamp01((vq - ch.inBlack) / range) * q + 0.5 + 1e-3) / q;\n } else {\n u = clamp01((v - ch.inBlack) / range);\n }\n const g = Math.max(0.01, ch.gamma);\n let t: number;\n if (g > 1) {\n const power = Math.pow(u, 1 / g);\n const line = 0.93 * Math.pow(2, g) * u;\n if (power <= 1e-6 || line <= 1e-6) t = Math.min(power, line);\n else {\n const p = 10;\n t = Math.pow(Math.pow(power, -p) + Math.pow(line, -p), -1 / p);\n }\n } else {\n t = Math.pow(u, 1 / g);\n }\n return ch.outBlack + t * (ch.outWhite - ch.outBlack);\n}\n\n// ---------------------------------------------------------------------------\n// HSL and Hue/Saturation\n// ---------------------------------------------------------------------------\n\n/** RGB (0..1) → HSL with hue in turns (0..1). */\nexport function rgbToHsl(c: readonly number[]): [number, number, number] {\n const max = Math.max(c[0], c[1], c[2]);\n const min = Math.min(c[0], c[1], c[2]);\n const l = (max + min) / 2;\n if (Math.abs(max - min) < 1e-7) return [0, 0, l];\n const d = max - min;\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n let h: number;\n if (max === c[0]) h = remEuclid((c[1] - c[2]) / d, 6);\n else if (max === c[1]) h = (c[2] - c[0]) / d + 2;\n else h = (c[0] - c[1]) / d + 4;\n return [h / 6, s, l];\n}\n\nexport function hslToRgb(h: number, s: number, l: number): Rgb {\n if (s <= 0) return [l, l, l];\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n const f = (t: number) => {\n t = remEuclid(t, 1);\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 0.5) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n return [f(h + 1 / 3), f(h), f(h - 1 / 3)];\n}\n\n/** How much a pixel of hue `deg` belongs to `range` (0..1): a trapezoid that may wrap past 0/360. */\nexport function hueRangeWeight(range: Pick<HueRange, 'bounds'>, deg: number): number {\n const [a, b0, c0, d0] = range.bounds;\n const rel = (x: number) => (Number.isFinite(x) && Number.isFinite(a) ? remEuclid(x - a, 360) : 0);\n const b = rel(b0);\n const c = Math.max(rel(c0), b);\n const d = Math.max(rel(d0), c);\n const h = rel(deg);\n if (h <= b) return b <= 0 ? 1 : h / b;\n if (h <= c) return 1;\n if (h <= d) return d <= c ? 1 : (d - h) / (d - c);\n return 0;\n}\n\nconst isNeutralRange = (r: HueRange) => r.hue === 0 && r.saturation === 0 && r.lightness === 0;\n\n/** Range edits as three hue-indexed tables (hue shift in degrees, saturation and lightness as fractions). */\nexport function hueRangeTables(ranges: readonly HueRange[]): [Float32Array, Float32Array, Float32Array] {\n const n = ADJUSTMENT_LUT_SIZE;\n const t: [Float32Array, Float32Array, Float32Array] = [new Float32Array(n), new Float32Array(n), new Float32Array(n)];\n const active = ranges.filter((r) => !isNeutralRange(r));\n for (let k = 0; k < n; k++) {\n const deg = (k / (n - 1)) * 360;\n for (const r of active) {\n const w = hueRangeWeight(r, deg);\n t[0][k] += w * r.hue;\n t[1][k] += (w * r.saturation) / 100;\n t[2][k] += (w * r.lightness) / 100;\n }\n }\n return t;\n}\n\n/**\n * One Hue/Saturation evaluation: hue shift in degrees, saturation and lightness in -1..1.\n * Lightness first, then hue and saturation (raising divides by 1 − s, lowering multiplies by\n * 1 + s). Colorize sets hue and saturation at the lightened lightness.\n */\nexport function hueSaturation(c: readonly number[], hue: number, s: number, l: number, colorize: boolean): Rgb {\n const lighten = (v: number) => (l > 0 ? v + (1 - v) * l : v * (1 + l));\n if (colorize) {\n const ll = rgbToHsl(c)[2];\n return hslToRgb(remEuclid(hue, 360) / 360, Math.min(1, Math.abs(s)), lighten(ll));\n }\n const [hh0, ss0, ll] = rgbToHsl([lighten(c[0]), lighten(c[1]), lighten(c[2])]);\n const hh = remEuclid(hh0 + hue / 360, 1);\n const ss = Math.min(1, Math.max(0, s > 0 ? ss0 / Math.max(1 / 512, 1 - s) : ss0 * (1 + s)));\n return hslToRgb(hh, ss, ll);\n}\n\n/** A colour range's Lightness: towards the brightest channel when raised, the darkest when lowered. */\nexport function rangeLightness(c: readonly number[], l: number): Rgb {\n const k = Math.min(1, Math.max(-1, l));\n const target = k > 0 ? Math.max(c[0], c[1], c[2]) : Math.min(c[0], c[1], c[2]);\n const a = Math.abs(k);\n return [c[0] + (target - c[0]) * a, c[1] + (target - c[1]) * a, c[2] + (target - c[2]) * a];\n}\n\n// ---------------------------------------------------------------------------\n// Vibrance\n// ---------------------------------------------------------------------------\n\n/** Grey Vibrance › Saturation desaturates to (linear light; blue has no weight). */\nexport const VIBRANCE_GREY: readonly [number, number] = [0.288, 0.712];\nconst VIBRANCE_BOOST = [0.5001, 0.0887, 0.4374, 0.7573, -0.8113, 0.5154, 2.8026] as const;\n\nfunction vibranceSkin(h: number): number {\n if (h <= 30) return 1;\n if (h < 45) return (45 - h) / 15;\n if (h < 300) return 0;\n return (h - 300) / 60;\n}\n\nfunction hsvHue(c: readonly number[], mx: number, mn: number): number {\n const d = mx - mn;\n let h: number;\n if (mx === c[0]) h = remEuclid((c[1] - c[2]) / d, 6);\n else if (mx === c[1]) h = (c[2] - c[0]) / d + 2;\n else h = (c[0] - c[1]) / d + 4;\n return h * 60;\n}\n\n/** The Vibrance slider (`v` in -1..1) on a linear-light pixel: an HSV change that keeps the hue. */\nexport function vibranceLinear(c: Rgb, v: number): Rgb {\n const mx = Math.max(c[0], c[1], c[2]);\n const mn = Math.min(c[0], c[1], c[2]);\n if (mx <= 0 || mx - mn <= 1e-9) return c;\n const t = 1 - mn / mx;\n const shape = t * (1 - t) * (2 - t + t * t) * mx * Math.max(0, 1 - mx);\n let t2: number, v2: number;\n if (v < 0) {\n const a = -v;\n t2 = t * (1 - a / 4) * (1 - a + (a * t * (1 + t)) / 2);\n v2 = mx - a * shape;\n } else {\n const [c0, c1, p, q, r0, ra, rt] = VIBRANCE_BOOST;\n const w = vibranceSkin(hsvHue(c, mx, mn));\n const a = v * (1 - w) + 0.64 * Math.pow(v, 1.6) * w;\n const boost =\n (c0 * a + c1 * a * a) * Math.pow(t, p) * Math.pow(1 - t, q) * Math.exp((r0 + ra * a + rt * (1 - t)) * Math.max(0, 1 - mx));\n t2 = Math.min(1, t * (1 + boost));\n v2 = mx + (v / 4) * shape;\n }\n const m2 = v2 * (1 - t2);\n const k = (v2 - m2) / (mx - mn);\n return [m2 + (c[0] - mn) * k, m2 + (c[1] - mn) * k, m2 + (c[2] - mn) * k];\n}\n\n/** Photoshop's Vibrance on one encoded sRGB pixel (`v`, `s`: the sliders / 100). */\nexport function vibrancePixel(c: readonly number[], v: number, s: number): Rgb {\n let l: Rgb = [srgbToLinear(Math.max(0, c[0])), srgbToLinear(Math.max(0, c[1])), srgbToLinear(Math.max(0, c[2]))];\n if (v !== 0) l = vibranceLinear(l, v);\n if (s !== 0) {\n const g = VIBRANCE_GREY[0] * l[0] + VIBRANCE_GREY[1] * l[1];\n l = l.map((x) => Math.min(1, Math.max(0, g + (1 + s) * (x - g)))) as Rgb;\n }\n return l.map((x) => linearToSrgb(clamp01(x))) as Rgb;\n}\n\n// ---------------------------------------------------------------------------\n// Color Balance\n// ---------------------------------------------------------------------------\n\n/** How far one Color Balance slider at ±100 moves the black or white point. */\nconst BALANCE_LEVELS = 0.39;\n\n/**\n * Color Balance on channel `ch` (0 red, 1 green, 2 blue) of `v` (0..1); `tones` are the\n * shadows, midtones and highlights slider triples (-100..100). Highlights, shadows, then midtones.\n */\nexport function colorBalanceChannel(\n tones: readonly [readonly number[], readonly number[], readonly number[]],\n preserveLuminosity: boolean,\n ch: number,\n v: number\n): number {\n const [shadows, midtones, highlights] = tones;\n const black = (x: number, b: number) => Math.max(0, (x - b) / (1 - b));\n const white = (x: number, w: number) => Math.min(1, x / w);\n let out = clamp01(v);\n for (const [tone, sliders] of [\n [2, highlights],\n [0, shadows],\n [1, midtones],\n ] as const) {\n const a = [0, 1, 2].map((i) => Math.min(1, Math.max(-1, sliders[i] / 100)));\n if (preserveLuminosity) {\n const own = a[ch] ?? 0;\n const lo = Math.min(a[0], a[1], a[2]);\n const hi = Math.max(a[0], a[1], a[2]);\n if (tone === 0) out = black(out, BALANCE_LEVELS * (hi - own));\n else if (tone === 1) out = Math.pow(out, Math.pow(2, (hi + lo) / 2 - own));\n else out = white(out, 1 - BALANCE_LEVELS * (own - lo));\n continue;\n }\n const s = a[ch];\n if (s === 0) continue;\n if (tone === 1) out = Math.pow(out, Math.pow(2, -s));\n else if (tone === 0 && s < 0) out = Math.pow(black(out, BALANCE_LEVELS * -s), Math.pow(2, -s / 2));\n else if (tone === 2 && s > 0) out = Math.pow(white(out, 1 - BALANCE_LEVELS * s), Math.pow(2, -s / 2));\n else out = Math.pow(out, Math.pow(2, -s / 2));\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Black & White, Photo Filter, Posterize, Threshold\n// ---------------------------------------------------------------------------\n\n/**\n * Black & White grey: the smallest channel, plus the secondary part (middle − smallest) and the\n * primary part (largest − middle) weighted by the sliders (percent: reds, yellows, greens, cyans,\n * blues, magentas).\n */\nexport function blackWhiteGray(c: readonly number[], weights: readonly number[]): number {\n const [r, g, b] = c;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const mid = r + g + b - max - min;\n const primary = r >= g && r >= b ? 0 : g >= b ? 2 : 4;\n const secondary = b <= r && b <= g ? 1 : r <= g ? 3 : 5;\n return clamp01(min + ((mid - min) * weights[secondary]) / 100 + ((max - mid) * weights[primary]) / 100);\n}\n\n/** D50 white (ICC PCS). */\nconst D50 = [0.96422, 1.0, 0.82521] as const;\n/** Linear sRGB → D50 XYZ (Bradford-adapted, as in the ICC sRGB profile). */\nconst SRGB_TO_XYZ_D50 = [\n [0.436074, 0.385064, 0.14308],\n [0.222504, 0.716878, 0.060618],\n [0.013932, 0.097104, 0.714173],\n] as const;\n/** D50 XYZ → linear sRGB. */\nconst XYZ_D50_TO_SRGB = [\n [3.133856, -1.616867, -0.490615],\n [-0.978768, 1.916142, 0.033454],\n [0.071945, -0.228991, 1.405243],\n] as const;\n\n/**\n * Photo Filter's linear-light RGB matrix (row-major 3×3): the pixel's D50 XYZ, relative to white,\n * multiplied by the filter colour's mixed in by `density` (0..1). `normalizeY` keeps luminance Y.\n */\nexport function photoFilterMatrix(color: readonly number[], density: number, normalizeY = false): number[][] {\n const d = Number.isFinite(density) ? clamp01(density) : 0;\n const lin = [0, 1, 2].map((i) => srgbToLinear(clamp01(color[i])));\n const xyz = SRGB_TO_XYZ_D50.map((r) => r[0] * lin[0] + r[1] * lin[1] + r[2] * lin[2]);\n let s = [0, 1, 2].map((i) => 1 - d + (d * xyz[i]) / D50[i]);\n if (normalizeY && s[1] > 1e-6) {\n const y = s[1];\n s = s.map((v) => v / y);\n }\n return [0, 1, 2].map((r) =>\n [0, 1, 2].map((c) => XYZ_D50_TO_SRGB[r][0] * s[0] * SRGB_TO_XYZ_D50[0][c] + XYZ_D50_TO_SRGB[r][1] * s[1] * SRGB_TO_XYZ_D50[1][c] + XYZ_D50_TO_SRGB[r][2] * s[2] * SRGB_TO_XYZ_D50[2][c])\n );\n}\n\n/** Photoshop posterize: `levels` equal input bins over 0..255, outputs `floor(k·255 / (levels − 1))`. */\nexport function posterizeValue(v: number, levels: number): number {\n const n = Math.min(255, Math.max(2, Math.round(levels)));\n const x = Math.round(clamp01(v) * 255);\n const bin = Math.min(n - 1, Math.floor((x * n) / 256));\n return Math.floor((bin * 255) / (n - 1)) / 255;\n}\n\n/** Rec.601 luma (Photoshop's grey for Threshold). */\nexport const rgbToGray = (c: readonly number[]) => 0.299 * c[0] + 0.587 * c[1] + 0.114 * c[2];\n\n/** `#rrggbb` → 0..1 RGB (black for anything else). */\nexport function hexToRgb(hex: string): Rgb {\n if (!HEX.test(hex)) return [0, 0, 0];\n const n = parseInt(hex.slice(1), 16);\n return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255];\n}\n\n// ---------------------------------------------------------------------------\n// Compilation and evaluation\n// ---------------------------------------------------------------------------\n\n/** Mutates an encoded sRGB colour (0..1) in place. */\nexport type PixelOp = (c: Rgb) => void;\n\nfunction lutOp(luts: [Float32Array, Float32Array, Float32Array]): PixelOp {\n const [lr, lg, lb] = luts;\n return (c) => {\n c[0] = sampleLut(lr, c[0]);\n c[1] = sampleLut(lg, c[1]);\n c[2] = sampleLut(lb, c[2]);\n };\n}\n\nconst isIdentityCurve = (pts: readonly CurvePoint[]) =>\n pts.length === 2 && pts[0].input === 0 && pts[0].output === 0 && pts[1].input === 255 && pts[1].output === 255;\n\nconst isIdentityLevels = (c: LevelsChannel) =>\n c.inBlack === 0 && c.inWhite === 255 && c.gamma === 1 && c.outBlack === 0 && c.outWhite === 255;\n\n/** Quantum Levels works in (8-bit documents: whole levels). */\nconst LEVELS_QUANTUM = 255;\n\n/**\n * Per-channel LUTs of a Curves or Levels layer: each channel's record first, then the master.\n * `null` for any other kind.\n */\nexport function toneLuts(layer: AdjustmentLayer): [Float32Array, Float32Array, Float32Array] | null {\n const n = ADJUSTMENT_LUT_SIZE;\n if (layer.kind === 'curves') {\n const m = curveLutFromLevels(layer.params.master);\n return [layer.params.red, layer.params.green, layer.params.blue].map((pts) => {\n const ch = curveLutFromLevels(pts);\n for (let k = 0; k < n; k++) ch[k] = sampleLut(m, ch[k]);\n return ch;\n }) as [Float32Array, Float32Array, Float32Array];\n }\n if (layer.kind === 'levels') {\n const m = toUnitLevels(layer.params.master);\n return [layer.params.red, layer.params.green, layer.params.blue].map((rec) => {\n const c = toUnitLevels(rec);\n const out = new Float32Array(n);\n for (let k = 0; k < n; k++) out[k] = levelsValue(m, levelsValue(c, k / (n - 1), LEVELS_QUANTUM), LEVELS_QUANTUM);\n return out;\n }) as [Float32Array, Float32Array, Float32Array];\n }\n return null;\n}\n\n/**\n * Compiles a layer into a pixel function, or `null` when it is the identity (neutral parameters).\n * Pure: depends on `kind` and `params` only.\n */\nexport function compileAdjustmentLayer(layer: AdjustmentLayer): PixelOp | null {\n switch (layer.kind) {\n case 'curves': {\n const p = layer.params;\n if ([p.master, p.red, p.green, p.blue].every(isIdentityCurve)) return null;\n return lutOp(toneLuts(layer)!);\n }\n case 'levels': {\n const p = layer.params;\n if ([p.master, p.red, p.green, p.blue].every(isIdentityLevels)) return null;\n return lutOp(toneLuts(layer)!);\n }\n case 'hueSaturation': {\n const p = layer.params;\n const rangesActive = !p.colorize && p.ranges.some((r) => !isNeutralRange(r));\n if (!p.colorize && !rangesActive && p.hue === 0 && p.saturation === 0 && p.lightness === 0) return null;\n const tables = rangesActive ? hueRangeTables(p.ranges) : null;\n const sat = p.saturation / 100;\n const light = Math.min(1, Math.max(-1, p.lightness / 100));\n return (c) => {\n let dh = 0, ds = 0, dl = 0;\n if (tables) {\n const h0 = rgbToHsl(c)[0];\n dh = sampleLut(tables[0], h0);\n ds = sampleLut(tables[1], h0);\n dl = sampleLut(tables[2], h0);\n }\n const out = rangeLightness(hueSaturation(c, p.hue + dh, Math.min(1, Math.max(-1, sat + ds)), light, p.colorize), dl);\n c[0] = out[0];\n c[1] = out[1];\n c[2] = out[2];\n };\n }\n case 'vibrance': {\n const v = layer.params.vibrance / 100;\n const s = layer.params.saturation / 100;\n if (v === 0 && s === 0) return null;\n return (c) => {\n const out = vibrancePixel(c, v, s);\n c[0] = out[0];\n c[1] = out[1];\n c[2] = out[2];\n };\n }\n case 'colorBalance': {\n const p = layer.params;\n const tones = [p.shadows, p.midtones, p.highlights] as const;\n if (tones.every((t) => t[0] === 0 && t[1] === 0 && t[2] === 0)) return null;\n const n = ADJUSTMENT_LUT_SIZE;\n const luts = [0, 1, 2].map((ch) => {\n const out = new Float32Array(n);\n for (let k = 0; k < n; k++) out[k] = colorBalanceChannel(tones, p.preserveLuminosity, ch, k / (n - 1));\n return out;\n }) as [Float32Array, Float32Array, Float32Array];\n return lutOp(luts);\n }\n case 'blackWhite': {\n const p = layer.params;\n const weights = [p.reds, p.yellows, p.greens, p.cyans, p.blues, p.magentas];\n const tint = p.tint ? hexToRgb(p.tint) : null;\n return (c) => {\n const g = blackWhiteGray(c, weights);\n if (tint) {\n const t = setLum(tint, g);\n c[0] = clamp01(t[0]);\n c[1] = clamp01(t[1]);\n c[2] = clamp01(t[2]);\n } else {\n c[0] = c[1] = c[2] = g;\n }\n };\n }\n case 'photoFilter': {\n const p = layer.params;\n if (p.density <= 0) return null;\n const m = photoFilterMatrix(hexToRgb(p.color), p.density / 100, false);\n const preserve = p.preserveLuminosity;\n return (c) => {\n const l = [srgbToLinear(Math.max(0, c[0])), srgbToLinear(Math.max(0, c[1])), srgbToLinear(Math.max(0, c[2]))];\n let f: Rgb = [0, 1, 2].map((r) => linearToSrgb(Math.max(0, m[r][0] * l[0] + m[r][1] * l[1] + m[r][2] * l[2]))) as Rgb;\n if (preserve) {\n const target = 0.3 * c[0] + 0.59 * c[1] + 0.11 * c[2];\n f = setLum(f, target);\n }\n c[0] = clamp01(f[0]);\n c[1] = clamp01(f[1]);\n c[2] = clamp01(f[2]);\n };\n }\n case 'invert':\n return (c) => {\n c[0] = 1 - c[0];\n c[1] = 1 - c[1];\n c[2] = 1 - c[2];\n };\n case 'posterize': {\n const levels = layer.params.levels;\n return (c) => {\n c[0] = posterizeValue(c[0], levels);\n c[1] = posterizeValue(c[1], levels);\n c[2] = posterizeValue(c[2], levels);\n };\n }\n case 'threshold': {\n const t = Math.round(layer.params.level);\n return (c) => {\n const v = Math.round(rgbToGray(c) * 255) >= t ? 1 : 0;\n c[0] = c[1] = c[2] = v;\n };\n }\n }\n return null;\n}\n\n// Compiled layers keyed by kind + params, so a stack is compiled once per parameter change.\nconst COMPILE_CACHE_LIMIT = 64;\nconst compileCache = new Map<string, PixelOp | null>();\n\nfunction compiledFor(layer: AdjustmentLayer): PixelOp | null {\n const key = `${layer.kind}:${JSON.stringify(layer.params)}`;\n if (compileCache.has(key)) {\n const op = compileCache.get(key)!;\n // Refresh recency.\n compileCache.delete(key);\n compileCache.set(key, op);\n return op;\n }\n const op = compileAdjustmentLayer(layer);\n compileCache.set(key, op);\n if (compileCache.size > COMPILE_CACHE_LIMIT) compileCache.delete(compileCache.keys().next().value as string);\n return op;\n}\n\n/** Layers that change pixels: enabled, visible, not the identity. */\nexport function activeAdjustmentLayers(layers: readonly AdjustmentLayer[] | undefined): AdjustmentLayer[] {\n if (!layers?.length) return [];\n return layers.filter((l) => l.enabled !== false && (l.opacity ?? 1) > 0 && compiledFor(l) !== null);\n}\n\n/**\n * Evaluates one colour (encoded sRGB, 0..1) through a layer stack: each layer adjusts the result\n * of the layers below and is blended over it with its blend mode and opacity (an opaque\n * backdrop, so `(1 − α)·Cb + α·B(Cb, Cs)`).\n */\nexport function evaluateAdjustmentLayers(color: readonly number[], layers: readonly AdjustmentLayer[]): Rgb {\n const c: Rgb = [color[0], color[1], color[2]];\n for (const layer of layers) applyLayer(c, layer, compiledFor(layer));\n return c;\n}\n\nfunction applyLayer(c: Rgb, layer: AdjustmentLayer, op: PixelOp | null, coverage = 1): void {\n if (!op || layer.enabled === false) return;\n const alpha = Math.min(1, Math.max(0, layer.opacity ?? 1)) * coverage;\n if (alpha <= 0) return;\n const blend = layer.blend ?? 'normal';\n if (blend === 'normal' && alpha >= 1) {\n op(c);\n return;\n }\n const cb0 = c[0], cb1 = c[1], cb2 = c[2];\n op(c);\n const b = blend === 'normal' ? c : blendRgb(blend, [cb0, cb1, cb2], c);\n c[0] = (1 - alpha) * cb0 + alpha * b[0];\n c[1] = (1 - alpha) * cb1 + alpha * b[1];\n c[2] = (1 - alpha) * cb2 + alpha * b[2];\n}\n\n/**\n * Applies an adjustment-layer stack to 8-bit straight RGBA pixels in place. Each pixel is\n * decoded once, run through every layer in float, and encoded once. Transparent pixels are\n * left alone; alpha is never changed.\n *\n * `masks` (layer id → 0..1 coverage per pixel of `imageData`, see `buildLayerMaskPlanes`)\n * scales each masked layer's opacity per pixel: coverage 0 leaves the pixel as the layers below\n * made it, 1 applies the layer fully.\n */\nexport function applyAdjustmentLayers(\n imageData: Pick<ImageData, 'data'>,\n layers: readonly AdjustmentLayer[] | undefined,\n masks?: ReadonlyMap<string, ArrayLike<number>>\n): void {\n const active = activeAdjustmentLayers(layers);\n if (!active.length) return;\n const ops = active.map((l) => compiledFor(l));\n const planes = active.map((l) => masks?.get(l.id));\n const data = imageData.data;\n const len = data.length;\n const c: Rgb = [0, 0, 0];\n for (let i = 0; i < len; i += 4) {\n if (data[i + 3] === 0) continue;\n c[0] = data[i] / 255;\n c[1] = data[i + 1] / 255;\n c[2] = data[i + 2] / 255;\n for (let k = 0; k < active.length; k++) {\n const plane = planes[k];\n if (plane) {\n const cov = plane[i >> 2];\n if (cov > 0) applyLayer(c, active[k], ops[k], cov >= 1 ? 1 : cov);\n } else {\n applyLayer(c, active[k], ops[k]);\n }\n }\n data[i] = Math.round(clamp01(c[0]) * 255);\n data[i + 1] = Math.round(clamp01(c[1]) * 255);\n data[i + 2] = Math.round(clamp01(c[2]) * 255);\n }\n}\n\n/** Stable cache key of a layer stack's pixel effect (for renderer caches). */\nexport function adjustmentLayersKey(layers: readonly AdjustmentLayer[] | undefined): string {\n if (!layers?.length) return '';\n return JSON.stringify(\n layers.map((l) => {\n const key: unknown[] = [l.kind, l.enabled !== false, l.opacity ?? 1, l.blend ?? 'normal', l.params];\n if (l.mask) key.push(layerMaskKey(l.mask));\n return key;\n })\n );\n}\n","import type { DepthMaskOptions, ImageAdjustments } from './types';\nimport {\n LUMA_709,\n LATEST_PROCESS_VERSION,\n TONE_LUT_SIZE,\n buildToneLut,\n linearToSrgb,\n normalizeProcessVersion,\n srgbToLinear,\n whiteBalanceMatrix,\n} from './color';\nimport { applyAdjustmentLayers } from './adjustment-layers';\n\nfunction clamp(value: number, min = 0, max = 255): number {\n return Math.max(min, Math.min(max, value));\n}\n\n/**\n * Applies color and tone adjustments (brightness, contrast, saturation, exposure, temperature, tint,\n * opacity, then any adjustment `layers`, then blur) directly to the pixel data of an ImageData buffer.\n *\n * `adjustments.process` selects the rendering: `2` is the linear-light pipeline\n * ({@link applyProcess2Adjustments}); anything else (including a missing value, as in edits saved\n * before process versions existed) is the frozen legacy rendering ({@link applyLegacyAdjustments}).\n */\nexport function applyAdjustments(\n imageData: ImageData,\n adjustments: ImageAdjustments,\n options: { layerMasks?: ReadonlyMap<string, ArrayLike<number>> } = {}\n): void {\n if (normalizeProcessVersion(adjustments.process) === LATEST_PROCESS_VERSION) {\n applyProcess2Adjustments(imageData, adjustments);\n } else {\n applyLegacyAdjustments(imageData, adjustments);\n }\n\n // Adjustment layers, bottom to top, on the encoded result (no-op without layers).\n // Layer masks (see `buildLayerMaskPlanes`) are aligned with `imageData`.\n applyAdjustmentLayers(imageData, adjustments.layers, options.layerMasks);\n\n // Apply blur if requested\n if (adjustments.blur > 0) {\n applyFastBoxBlur(imageData, Math.min(Math.round(adjustments.blur), 40));\n }\n}\n\n/**\n * Process 1: the original 8-bit gamma-space rendering, clamping after every step. Frozen so\n * that edits saved without a `process` look exactly as they always have. `tint` is ignored.\n */\nexport function applyLegacyAdjustments(imageData: ImageData, adjustments: ImageAdjustments): void {\n const { brightness, contrast, saturation, exposure, temperature, opacity } = adjustments;\n const data = imageData.data;\n const len = data.length;\n\n const hasBrightness = brightness !== 0;\n const hasContrast = contrast !== 0;\n const hasSaturation = saturation !== 0;\n const hasExposure = exposure !== 0;\n const hasTemperature = temperature !== 0;\n const hasOpacity = opacity < 1;\n\n // Pre-calculate contrast factor\n const contrastFactor = hasContrast\n ? (259 * (contrast + 255)) / (255 * (259 - contrast))\n : 1;\n\n // Pre-calculate exposure multiplier\n const exposureMultiplier = hasExposure ? Math.pow(2, exposure / 50) : 1;\n\n // Pre-calculate saturation multiplier\n const satMultiplier = hasSaturation ? 1 + saturation / 100 : 1;\n\n // Pre-calculate temperature offsets\n const tempOffset = hasTemperature ? temperature * 0.8 : 0;\n\n if (hasBrightness || hasContrast || hasSaturation || hasExposure || hasTemperature || hasOpacity) {\n for (let i = 0; i < len; i += 4) {\n let r = data[i];\n let g = data[i + 1];\n let b = data[i + 2];\n let a = data[i + 3];\n\n // Exposure\n if (hasExposure) {\n r = clamp(r * exposureMultiplier);\n g = clamp(g * exposureMultiplier);\n b = clamp(b * exposureMultiplier);\n }\n\n // Brightness\n if (hasBrightness) {\n const bOffset = brightness * 2.55;\n r = clamp(r + bOffset);\n g = clamp(g + bOffset);\n b = clamp(b + bOffset);\n }\n\n // Contrast\n if (hasContrast) {\n r = clamp(contrastFactor * (r - 128) + 128);\n g = clamp(contrastFactor * (g - 128) + 128);\n b = clamp(contrastFactor * (b - 128) + 128);\n }\n\n // Saturation\n if (hasSaturation) {\n const luminance = 0.2989 * r + 0.587 * g + 0.114 * b;\n r = clamp(luminance + (r - luminance) * satMultiplier);\n g = clamp(luminance + (g - luminance) * satMultiplier);\n b = clamp(luminance + (b - luminance) * satMultiplier);\n }\n\n // Temperature / Warmth\n if (hasTemperature) {\n r = clamp(r + tempOffset);\n b = clamp(b - tempOffset);\n }\n\n // Opacity\n if (hasOpacity) {\n a = clamp(a * opacity);\n }\n\n data[i] = r;\n data[i + 1] = g;\n data[i + 2] = b;\n data[i + 3] = a;\n }\n }\n}\n\n/** sRGB byte → linear light (exact; shared by every process 2 render). */\nconst DECODE_LUT: Float32Array = (() => {\n const lut = new Float32Array(256);\n for (let i = 0; i < 256; i++) lut[i] = srgbToLinear(i / 255);\n return lut;\n})();\n\n/** Intervals of the linear → sRGB byte encode table over [0, 1]. */\nconst ENCODE_LUT_SIZE = 65535;\nlet encodeLut: Uint8Array | null = null;\nfunction getEncodeLut(): Uint8Array {\n if (!encodeLut) {\n encodeLut = new Uint8Array(ENCODE_LUT_SIZE + 1);\n for (let i = 0; i <= ENCODE_LUT_SIZE; i++) {\n encodeLut[i] = Math.round(linearToSrgb(i / ENCODE_LUT_SIZE) * 255);\n }\n }\n return encodeLut;\n}\n\ninterface Process2Plan {\n key: string;\n /** Exposure gain folded into the white-balance matrix (row-major). */\n m: Float64Array;\n /** Per-channel tone LUTs over [0, headroom[c]]. */\n luts: [Float32Array, Float32Array, Float32Array];\n /** LUT index scale per channel: TONE_LUT_SIZE / headroom[c]. */\n scale: [number, number, number];\n saturation: number;\n}\n\nlet cachedPlan: Process2Plan | null = null;\n\n/**\n * Precomputes everything per parameter change: the 3×3 colour matrix (exposure gain × white\n * balance) and one tone LUT per channel whose domain is that channel's largest possible value,\n * so the highlight shoulder absorbs it instead of clipping.\n */\nfunction getProcess2Plan(adjustments: ImageAdjustments): Process2Plan {\n const exposure = adjustments.exposure || 0;\n const temperature = adjustments.temperature || 0;\n const tint = adjustments.tint || 0;\n const contrast = adjustments.contrast || 0;\n const brightness = adjustments.brightness || 0;\n const saturation = 1 + (adjustments.saturation || 0) / 100;\n const key = `${exposure},${temperature},${tint},${contrast},${brightness},${saturation}`;\n if (cachedPlan && cachedPlan.key === key) return cachedPlan;\n\n const gain = Math.pow(2, exposure / 50);\n const wb = whiteBalanceMatrix(temperature, tint);\n const m = new Float64Array(9);\n for (let i = 0; i < 9; i++) m[i] = wb[i] * gain;\n const luts = [] as unknown as [Float32Array, Float32Array, Float32Array];\n const scale = [0, 0, 0] as [number, number, number];\n for (let c = 0; c < 3; c++) {\n // Largest value this channel can reach from inputs in [0, 1].\n let reach = 0;\n for (let k = 0; k < 3; k++) reach += Math.max(0, m[c * 3 + k]);\n const headroom = Math.max(1, reach);\n luts[c] = buildToneLut(contrast, brightness, headroom);\n scale[c] = TONE_LUT_SIZE / headroom;\n }\n cachedPlan = { key, m, luts, scale, saturation };\n return cachedPlan;\n}\n\n/**\n * Process 2: decode sRGB to linear float once; apply exposure (gain) and white balance (a\n * Bradford matrix relative to as-shot) in linear light; a per-channel tone LUT for the\n * highlight shoulder, contrast and brightness; luminance-preserving saturation in linear light;\n * then encode back to sRGB through a LUT. Nothing is clamped between stages, only at the final\n * encode. Neutral settings are the identity.\n */\nexport function applyProcess2Adjustments(imageData: ImageData, adjustments: ImageAdjustments): void {\n const data = imageData.data;\n const len = data.length;\n const opacity = adjustments.opacity ?? 1;\n const hasOpacity = opacity < 1;\n const hasColor =\n !!adjustments.brightness ||\n !!adjustments.contrast ||\n !!adjustments.saturation ||\n !!adjustments.exposure ||\n !!adjustments.temperature ||\n !!adjustments.tint;\n\n if (!hasColor) {\n if (hasOpacity) {\n for (let i = 3; i < len; i += 4) data[i] = clamp(data[i] * opacity);\n }\n return;\n }\n\n const plan = getProcess2Plan(adjustments);\n const dec = DECODE_LUT;\n const enc = getEncodeLut();\n const { m, luts, scale, saturation } = plan;\n const m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3], m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7], m8 = m[8];\n const lutR = luts[0], lutG = luts[1], lutB = luts[2];\n const sR = scale[0], sG = scale[1], sB = scale[2];\n const N = TONE_LUT_SIZE;\n const hasSaturation = saturation !== 1;\n const wr = LUMA_709[0], wg = LUMA_709[1], wb = LUMA_709[2];\n\n for (let i = 0; i < len; i += 4) {\n const r0 = dec[data[i]];\n const g0 = dec[data[i + 1]];\n const b0 = dec[data[i + 2]];\n\n // Exposure × white balance (linear light, unclamped).\n let r = m0 * r0 + m1 * g0 + m2 * b0;\n let g = m3 * r0 + m4 * g0 + m5 * b0;\n let b = m6 * r0 + m7 * g0 + m8 * b0;\n\n // Tone LUTs (linear interpolation).\n let f: number;\n let k: number;\n if (r <= 0) r = lutR[0];\n else if ((f = r * sR) >= N) r = lutR[N];\n else { k = f | 0; r = lutR[k] + (lutR[k + 1] - lutR[k]) * (f - k); }\n if (g <= 0) g = lutG[0];\n else if ((f = g * sG) >= N) g = lutG[N];\n else { k = f | 0; g = lutG[k] + (lutG[k + 1] - lutG[k]) * (f - k); }\n if (b <= 0) b = lutB[0];\n else if ((f = b * sB) >= N) b = lutB[N];\n else { k = f | 0; b = lutB[k] + (lutB[k + 1] - lutB[k]) * (f - k); }\n\n // Luminance-preserving saturation in linear light.\n if (hasSaturation) {\n const y = wr * r + wg * g + wb * b;\n r = y + (r - y) * saturation;\n g = y + (g - y) * saturation;\n b = y + (b - y) * saturation;\n }\n\n // Encode (the only clamp).\n data[i] = enc[r <= 0 ? 0 : r >= 1 ? ENCODE_LUT_SIZE : (r * ENCODE_LUT_SIZE + 0.5) | 0];\n data[i + 1] = enc[g <= 0 ? 0 : g >= 1 ? ENCODE_LUT_SIZE : (g * ENCODE_LUT_SIZE + 0.5) | 0];\n data[i + 2] = enc[b <= 0 ? 0 : b >= 1 ? ENCODE_LUT_SIZE : (b * ENCODE_LUT_SIZE + 0.5) | 0];\n if (hasOpacity) data[i + 3] = clamp(data[i + 3] * opacity);\n }\n}\n\n/**\n * Fast separable box blur running horizontally and vertically.\n */\nfunction applyFastBoxBlur(imageData: ImageData, radius: number): void {\n if (radius < 1) return;\n const w = imageData.width;\n const h = imageData.height;\n const src = imageData.data;\n const temp = new Uint8ClampedArray(src.length);\n\n // Horizontal blur pass\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n let r = 0, g = 0, b = 0, a = 0;\n let count = 0;\n for (let k = -radius; k <= radius; k++) {\n const px = Math.min(w - 1, Math.max(0, x + k));\n const idx = (y * w + px) * 4;\n r += src[idx];\n g += src[idx + 1];\n b += src[idx + 2];\n a += src[idx + 3];\n count++;\n }\n const dstIdx = (y * w + x) * 4;\n temp[dstIdx] = Math.round(r / count);\n temp[dstIdx + 1] = Math.round(g / count);\n temp[dstIdx + 2] = Math.round(b / count);\n temp[dstIdx + 3] = Math.round(a / count);\n }\n }\n\n // Vertical blur pass back into src\n for (let x = 0; x < w; x++) {\n for (let y = 0; y < h; y++) {\n let r = 0, g = 0, b = 0, a = 0;\n let count = 0;\n for (let k = -radius; k <= radius; k++) {\n const py = Math.min(h - 1, Math.max(0, y + k));\n const idx = (py * w + x) * 4;\n r += temp[idx];\n g += temp[idx + 1];\n b += temp[idx + 2];\n a += temp[idx + 3];\n count++;\n }\n const dstIdx = (y * w + x) * 4;\n src[dstIdx] = Math.round(r / count);\n src[dstIdx + 1] = Math.round(g / count);\n src[dstIdx + 2] = Math.round(b / count);\n src[dstIdx + 3] = Math.round(a / count);\n }\n }\n}\n\n/**\n * Blends a depth/alpha mask into the main image data based on Gleamforge depth masking.\n * Supports threshold range with softness gradation, brightness mode, and optional inversion.\n */\nexport function applyDepthMask(\n mainImageData: ImageData,\n maskImageData: ImageData,\n options: DepthMaskOptions\n): void {\n const { mode, depthRange, softness, invert } = options;\n const mainData = mainImageData.data;\n const maskData = maskImageData.data;\n const len = Math.min(mainData.length, maskData.length);\n const effectiveSoftness = Math.max(1, softness || 10);\n const minDepth = depthRange[0];\n const maxDepth = depthRange[1];\n\n for (let i = 0; i < len; i += 4) {\n let maskValue = maskData[i]; // Use red channel of mask (or grayscale)\n if (invert) {\n maskValue = 255 - maskValue;\n }\n\n let alphaValue: number;\n\n if (mode === 'threshold') {\n if (maskValue >= maxDepth + effectiveSoftness) {\n alphaValue = 0;\n } else if (maskValue > maxDepth) {\n alphaValue = Math.round(((maxDepth + effectiveSoftness - maskValue) / effectiveSoftness) * 255);\n } else if (maskValue >= minDepth) {\n alphaValue = 255;\n } else if (maskValue < minDepth - effectiveSoftness) {\n alphaValue = 0;\n } else {\n alphaValue = Math.round(((maskValue - (minDepth - effectiveSoftness)) / effectiveSoftness) * 255);\n }\n } else {\n // Brightness mode\n alphaValue = clamp(maskValue + minDepth);\n }\n\n // Multiply existing alpha with mask alpha\n mainData[i + 3] = clamp((mainData[i + 3] * alphaValue) / 255);\n }\n}\n\n/**\n * Removes alpha channel by setting all alpha bytes to 255 (completely opaque).\n * From Gleamforge image-filters.ts.\n */\nexport function removeAlpha(imageData: ImageData): void {\n const data = imageData.data;\n const len = data.length;\n for (let i = 3; i < len; i += 4) {\n data[i] = 255;\n }\n}\n","// Portions ported from photocraft-main/crates/algo/src/histogram.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\n/** Display bins of a histogram. */\nexport const HISTOGRAM_BINS = 256;\n\nexport interface ImageHistogram {\n /** 256-bin counts per channel. */\n red: Uint32Array;\n green: Uint32Array;\n blue: Uint32Array;\n /** 256-bin counts of Rec.709 luma `round(0.2126 R + 0.7152 G + 0.0722 B)` of the encoded values. */\n luminance: Uint32Array;\n /** Visible pixels counted (alpha > 0). Each counts once, partially transparent ones included. */\n samples: number;\n /** Fully transparent pixels, excluded from every bin. */\n transparent: number;\n /** Per channel (R, G, B): visible pixels at exactly 0. */\n shadows: [number, number, number];\n /** Per channel (R, G, B): visible pixels at exactly 255. */\n highlights: [number, number, number];\n /** Largest bin count over R, G, B and luminance (for scaling a plot). */\n max: number;\n}\n\ninterface PixelSource {\n data: ArrayLike<number>;\n width?: number;\n height?: number;\n}\n\n/**\n * Per-channel and luminance histograms of straight 8-bit RGBA pixels (an `ImageData` or anything\n * with `data`), with clipping counts at the exact endpoints. Transparent pixels cannot add\n * phantom peaks: they are counted separately and excluded.\n */\nexport function computeHistogram(imageData: PixelSource): ImageHistogram {\n const red = new Uint32Array(HISTOGRAM_BINS);\n const green = new Uint32Array(HISTOGRAM_BINS);\n const blue = new Uint32Array(HISTOGRAM_BINS);\n const luminance = new Uint32Array(HISTOGRAM_BINS);\n const shadows: [number, number, number] = [0, 0, 0];\n const highlights: [number, number, number] = [0, 0, 0];\n let samples = 0;\n let transparent = 0;\n const data = imageData.data;\n const len = data.length - (data.length % 4);\n for (let i = 0; i < len; i += 4) {\n if (!(data[i + 3] > 0)) {\n transparent++;\n continue;\n }\n samples++;\n const r = clampByte(data[i]);\n const g = clampByte(data[i + 1]);\n const b = clampByte(data[i + 2]);\n red[r]++;\n green[g]++;\n blue[b]++;\n luminance[Math.round(0.2126 * r + 0.7152 * g + 0.0722 * b)]++;\n if (r === 0) shadows[0]++;\n if (g === 0) shadows[1]++;\n if (b === 0) shadows[2]++;\n if (r === 255) highlights[0]++;\n if (g === 255) highlights[1]++;\n if (b === 255) highlights[2]++;\n }\n let max = 0;\n for (const bins of [red, green, blue, luminance]) {\n for (let k = 0; k < HISTOGRAM_BINS; k++) if (bins[k] > max) max = bins[k];\n }\n return { red, green, blue, luminance, samples, transparent, shadows, highlights, max };\n}\n\nfunction clampByte(v: number): number {\n return v <= 0 ? 0 : v >= 255 ? 255 : Math.round(v);\n}\n\nexport type HistogramChannel = 'red' | 'green' | 'blue' | 'luminance';\n\n/**\n * An SVG path (`M … Z`) of one channel scaled into a `width` × `height` box, bins left to right,\n * counts up from the bottom. `scale: 'sqrt'` (default) keeps small populations visible.\n */\nexport function histogramPath(\n histogram: ImageHistogram,\n channel: HistogramChannel,\n width: number,\n height: number,\n options: { scale?: 'linear' | 'sqrt'; max?: number } = {}\n): string {\n const bins = histogram[channel];\n const sqrt = (options.scale ?? 'sqrt') === 'sqrt';\n const f = (v: number) => (sqrt ? Math.sqrt(v) : v);\n const top = f(options.max ?? histogram.max) || 1;\n const dx = width / (HISTOGRAM_BINS - 1);\n let d = `M0 ${height}`;\n for (let k = 0; k < HISTOGRAM_BINS; k++) {\n const y = height - (f(bins[k]) / top) * height;\n d += ` L${round2(k * dx)} ${round2(y)}`;\n }\n return `${d} L${round2(width)} ${height} Z`;\n}\n\nconst round2 = (v: number) => Math.round(v * 100) / 100;\n","import type { SelectionMask } from './mask';\n\n/**\n * The selection's outline at `threshold` (0..255, default 128) as axis-aligned segments on pixel\n * boundaries, `[x0, y0, x1, y1, …]` in natural image pixels, with collinear neighbours merged.\n * This is what marching ants are drawn from. Linear in the pixel count.\n */\nexport function selectionOutline(mask: SelectionMask, threshold = 128): Float32Array {\n const { width: w, height: h, data } = mask;\n const segs: number[] = [];\n if (!mask.bounds) return new Float32Array(0);\n const b = mask.bounds;\n const inside = (x: number, y: number) => x >= 0 && y >= 0 && x < w && y < h && data[y * w + x] >= threshold;\n // Horizontal boundaries: the line y separates rows y − 1 and y.\n for (let y = b.y; y <= b.y + b.height; y++) {\n let start = -1;\n for (let x = b.x; x <= b.x + b.width; x++) {\n const edge = x < b.x + b.width && inside(x, y - 1) !== inside(x, y);\n if (edge && start < 0) start = x;\n else if (!edge && start >= 0) {\n segs.push(start, y, x, y);\n start = -1;\n }\n }\n }\n // Vertical boundaries: the line x separates columns x − 1 and x.\n for (let x = b.x; x <= b.x + b.width; x++) {\n let start = -1;\n for (let y = b.y; y <= b.y + b.height; y++) {\n const edge = y < b.y + b.height && inside(x - 1, y) !== inside(x, y);\n if (edge && start < 0) start = y;\n else if (!edge && start >= 0) {\n segs.push(x, start, x, y);\n start = -1;\n }\n }\n }\n return Float32Array.from(segs);\n}\n\nexport interface QuickMaskStyle {\n /** Overlay colour, `[r, g, b]` 0..255 (default Photoshop's rubylith red). */\n color?: readonly [number, number, number];\n /** 0..1 (default 0.5): opacity over fully unselected pixels. */\n opacity?: number;\n}\n\n/**\n * Quick Mask view: RGBA pixels (natural image size) tinting the *unselected* area, so the\n * selection shows through clear, as Photoshop's rubylith overlay.\n */\nexport function quickMaskPixels(mask: SelectionMask, style: QuickMaskStyle = {}): Uint8ClampedArray {\n const [r, g, b] = style.color ?? [255, 0, 0];\n const k = Math.min(1, Math.max(0, style.opacity ?? 0.5));\n const out = new Uint8ClampedArray(mask.data.length * 4);\n for (let i = 0, p = 0; i < mask.data.length; i++, p += 4) {\n out[p] = r;\n out[p + 1] = g;\n out[p + 2] = b;\n out[p + 3] = Math.round((255 - mask.data[i]) * k);\n }\n return out;\n}\n","import type {\n Annotation,\n CropBox,\n ImagePoint,\n ExportOptions,\n ImageEditorState,\n ImageTransform,\n PenAnnotation,\n RectAnnotation,\n CircleAnnotation,\n ArrowAnnotation,\n LineAnnotation,\n TextAnnotation,\n ImageAnnotation,\n} from './types';\nimport { applyAdjustments, applyDepthMask } from './filters';\nimport { adjustmentLayersKey } from './adjustment-layers';\nimport { canvasCompositeOperation, blendImageData, normalizeBlendMode } from './blend';\nimport { computeHistogram, type ImageHistogram } from './histogram';\nimport { normalizeProcessVersion } from './color';\nimport { buildLayerMaskPlanes } from './selection/layer-mask';\nimport { selectionOutline, quickMaskPixels } from './selection/overlay';\nimport type { SelectionMask } from './selection/mask';\nimport {\n applyImageProjectionToContext,\n clampCropToImage,\n getAnnotationBounds,\n getRotatedSize,\n getViewportMetrics,\n getViewportProjection,\n normalizeAngle,\n type ImageProjection,\n type ViewportMetrics,\n} from './geometry';\n\nexport interface RenderOptions {\n viewportWidth?: number;\n viewportHeight?: number;\n showCropOverlay?: boolean;\n showSelectionOverlay?: boolean;\n interactive?: boolean;\n draftAnnotation?: Annotation | null;\n draftCrop?: CropBox | null;\n /**\n * How the active selection is shown: marching ants (default when there is a selection),\n * a Quick Mask tint over the unselected area (default when `state.quickMask`), or not at all.\n */\n selectionDisplay?: 'ants' | 'quickMask' | 'none';\n /** Dash offset of the marching ants in screen pixels (animate it to make them march). */\n antsOffset?: number;\n /** A selection being drawn (e.g. a lasso), shown as a dashed outline in natural pixels. */\n draftSelectionPath?: ImagePoint[] | null;\n}\n\n/**\n * Image Cache to avoid refetching HTMLImageElement objects repeatedly during re-renders.\n */\nclass ImageCache {\n private cache = new Map<string, HTMLImageElement>();\n\n public async get(src: string): Promise<HTMLImageElement> {\n const existing = this.cache.get(src);\n if (existing && existing.complete) {\n return existing;\n }\n\n return new Promise((resolve, reject) => {\n if (typeof window === 'undefined' || typeof Image === 'undefined') {\n reject(new Error('Image loading is only supported in browser/DOM environments'));\n return;\n }\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = () => {\n this.cache.set(src, img);\n resolve(img);\n };\n img.onerror = (e) => reject(new Error(`Failed to load image from: ${src}`));\n img.src = src;\n\n // In JSDOM or test environments where Image resource loading is inactive, resolve promptly\n if (typeof navigator !== 'undefined' && /jsdom/i.test(navigator.userAgent)) {\n setTimeout(() => {\n try {\n Object.defineProperty(img, 'naturalWidth', { value: 800, configurable: true });\n Object.defineProperty(img, 'naturalHeight', { value: 600, configurable: true });\n Object.defineProperty(img, 'complete', { value: true, configurable: true });\n } catch {\n // Ignore definition errors in restrictive environments\n }\n this.cache.set(src, img);\n resolve(img);\n }, 10);\n }\n });\n }\n\n public set(src: string, img: HTMLImageElement): void {\n this.cache.set(src, img);\n }\n\n public clear(): void {\n this.cache.clear();\n }\n}\n\nexport const globalImageCache = new ImageCache();\n\n/**\n * Renders an image with all its transformations, filters, depth masks, and annotations\n * to a target HTMLCanvasElement.\n */\nexport class ImageEditorRenderer {\n public imageCache = globalImageCache;\n private cachedBaseCanvas: HTMLCanvasElement | null = null;\n private cachedBaseKey = '';\n /**\n * Histogram of the last viewport base render (after adjustments and layers, before\n * annotations); `null` until a render with pixel access has happened.\n */\n public previewHistogram: ImageHistogram | null = null;\n /** Called whenever the viewport base image is re-rendered with the new histogram. */\n public onPreviewHistogram?: (histogram: ImageHistogram | null) => void;\n private sourceIds = new WeakMap<object, number>();\n private nextSourceId = 0;\n\n /**\n * Helper to create a canvas element safely in browser/JSDOM.\n */\n public createCanvas(width: number, height: number): HTMLCanvasElement {\n if (typeof document !== 'undefined' && document.createElement) {\n const c = document.createElement('canvas');\n c.width = Math.max(1, Math.round(width));\n c.height = Math.max(1, Math.round(height));\n return c;\n }\n // Fallback for non-DOM / headless\n return {\n width: Math.max(1, Math.round(width)),\n height: Math.max(1, Math.round(height)),\n getContext: () => null,\n toDataURL: () => '',\n toBlob: () => {},\n } as unknown as HTMLCanvasElement;\n }\n\n /**\n * Renders the editor state onto a canvas (viewport or preview).\n */\n public async renderToCanvas(\n targetCanvas: HTMLCanvasElement,\n imageSource: CanvasImageSource | string,\n state: ImageEditorState,\n options: RenderOptions = {}\n ): Promise<void> {\n const ctx = targetCanvas.getContext('2d');\n if (!ctx) return;\n\n let img: CanvasImageSource;\n if (typeof imageSource === 'string') {\n img = await this.imageCache.get(imageSource);\n } else {\n img = imageSource;\n }\n\n const { width: naturalWidth, height: naturalHeight } = getSourceSize(img);\n // Geometry helpers read `imageDimensions`; make sure they see the real source size so the\n // viewport drawn here and the hit-testing done by the UI share one projection.\n const geoState: ImageEditorState =\n state.imageDimensions.width === naturalWidth && state.imageDimensions.height === naturalHeight\n ? state\n : { ...state, imageDimensions: { width: naturalWidth, height: naturalHeight } };\n\n const { crop, transform, adjustments, depthMask, annotations, selectedAnnotationId, zoom, pan, isOriginalCompared } = state;\n\n // Viewport dimensions\n const vpWidth = options.viewportWidth || targetCanvas.width;\n const vpHeight = options.viewportHeight || targetCanvas.height;\n\n targetCanvas.width = vpWidth;\n targetCanvas.height = vpHeight;\n\n ctx.clearRect(0, 0, vpWidth, vpHeight);\n\n // If in compare mode, render original image directly and exit\n if (isOriginalCompared) {\n this.drawFittedImage(ctx, img, naturalWidth, naturalHeight, vpWidth, vpHeight, zoom, pan);\n return;\n }\n\n // When actively in crop tool or overlay requested, show full image so user can adjust the crop box\n const isActivelyCropping = Boolean(options.showCropOverlay || state.activeTool === 'crop');\n const projection = getViewportProjection(geoState, vpWidth, vpHeight, isActivelyCropping);\n const { region } = projection;\n const rotated = getRotatedSize(region.width, region.height, transform);\n\n // 1. Offscreen canvas for Base Image + Transform (Flip/Rotate) + Crop + Adjustments + Depth mask\n const baseKey = [\n this.getSourceId(img),\n state.sourceUrl,\n `${naturalWidth}x${naturalHeight}`,\n `${region.x},${region.y},${region.width},${region.height}`,\n `${projection.angle},${transform.flipH},${transform.flipV}`,\n `${adjustments.brightness},${adjustments.contrast},${adjustments.saturation},${adjustments.exposure},${adjustments.temperature},${adjustments.tint ?? 0},${adjustments.blur},${adjustments.opacity},p${normalizeProcessVersion(adjustments.process)}`,\n adjustmentLayersKey(adjustments.layers),\n `${depthMask.enabled},${depthMask.maskSource},${depthMask.depthRange?.[0]}-${depthMask.depthRange?.[1]},${depthMask.softness},${depthMask.invert},${depthMask.mode}`,\n ].join('|');\n\n let baseCanvas = this.cachedBaseCanvas;\n if (!baseCanvas || this.cachedBaseKey !== baseKey) {\n let histogram: ImageHistogram | null = null;\n baseCanvas = await this.renderBaseImage(img, naturalWidth, naturalHeight, region, transform, state, (pixels) => {\n histogram = computeHistogram(pixels);\n });\n this.cachedBaseCanvas = baseCanvas;\n this.cachedBaseKey = baseKey;\n this.previewHistogram = histogram;\n this.onPreviewHistogram?.(histogram);\n }\n\n // 2. Draw the base canvas into the viewport (centred, fitted, zoomed, panned)\n const drawW = rotated.width * projection.scale;\n const drawH = rotated.height * projection.scale;\n ctx.drawImage(baseCanvas, projection.originX - drawW / 2, projection.originY - drawH / 2, drawW, drawH);\n\n // 3. Annotations live in natural image space: draw them through the same projection,\n // clipped to the visible (cropped) region.\n if (annotations.length > 0 || options.draftAnnotation) {\n ctx.save();\n applyImageProjectionToContext(ctx, projection);\n ctx.beginPath();\n ctx.rect(region.x, region.y, region.width, region.height);\n ctx.clip();\n\n for (const ann of annotations) {\n await this.drawAnnotation(ctx, ann);\n if (options.showSelectionOverlay && ann.id === selectedAnnotationId) {\n this.drawAnnotationSelection(ctx, ann);\n }\n }\n\n // Render active live draft annotation\n if (options.draftAnnotation) {\n await this.drawAnnotation(ctx, options.draftAnnotation);\n }\n\n ctx.restore();\n }\n\n // 4. Selection: marching ants or Quick Mask, through the same projection.\n const display = options.selectionDisplay ?? (state.quickMask ? 'quickMask' : 'ants');\n if ((state.selection?.bounds && display !== 'none') || options.draftSelectionPath?.length) {\n ctx.save();\n try {\n applyImageProjectionToContext(ctx, projection);\n ctx.beginPath();\n ctx.rect(region.x, region.y, region.width, region.height);\n ctx.clip();\n if (state.selection?.bounds && display === 'quickMask') this.drawQuickMask(ctx, state.selection);\n else if (state.selection?.bounds && display === 'ants') this.drawAnts(ctx, state.selection, projection.scale, options.antsOffset ?? 0);\n if (options.draftSelectionPath?.length) this.drawDraftPath(ctx, options.draftSelectionPath, projection.scale);\n } catch {\n // Overlays are best effort (headless / mocked contexts).\n }\n ctx.restore();\n }\n\n // 5. Draw Crop Grid Overlay if crop overlay is requested\n if (isActivelyCropping) {\n const activeCrop =\n options.draftCrop !== undefined && options.draftCrop !== null\n ? options.draftCrop\n : (crop ?? { x: 0, y: 0, width: naturalWidth, height: naturalHeight });\n this.drawCropOverlay(ctx, getViewportMetrics(geoState, vpWidth, vpHeight, true, activeCrop));\n }\n }\n\n /**\n * Draws `region` of the source image with rotation/flip applied, then pixel adjustments\n * and the depth mask (which receives the identical transform so it stays aligned).\n */\n private async renderBaseImage(\n img: CanvasImageSource,\n naturalWidth: number,\n naturalHeight: number,\n region: CropBox,\n transform: ImageTransform,\n state: Pick<ImageEditorState, 'adjustments' | 'depthMask'>,\n onPixels?: (pixels: ImageData) => void\n ): Promise<HTMLCanvasElement> {\n const { adjustments, depthMask } = state;\n const rotated = getRotatedSize(region.width, region.height, transform);\n const baseW = Math.max(1, Math.round(rotated.width));\n const baseH = Math.max(1, Math.round(rotated.height));\n const baseCanvas = this.createCanvas(baseW, baseH);\n const baseCtx = baseCanvas.getContext('2d');\n if (!baseCtx) return baseCanvas;\n\n const projection = getBaseProjection(region, transform, baseW, baseH);\n\n baseCtx.save();\n applyImageProjectionToContext(baseCtx, projection);\n baseCtx.drawImage(\n img,\n region.x, region.y, region.width, region.height,\n region.x, region.y, region.width, region.height\n );\n baseCtx.restore();\n\n const imageData = baseCtx.getImageData(0, 0, baseW, baseH);\n if (imageData) {\n // Layer masks live in natural pixels: resample them through the same projection.\n const layerMasks = buildLayerMaskPlanes(adjustments.layers, naturalWidth, naturalHeight, projection, baseW, baseH);\n applyAdjustments(imageData, adjustments, layerMasks ? { layerMasks } : {});\n\n if (depthMask.enabled && depthMask.maskSource) {\n try {\n const maskImg = await this.imageCache.get(depthMask.maskSource);\n const maskSize = getSourceSize(maskImg, naturalWidth, naturalHeight);\n const sx = maskSize.width / naturalWidth;\n const sy = maskSize.height / naturalHeight;\n const maskCanvas = this.createCanvas(baseW, baseH);\n const maskCtx = maskCanvas.getContext('2d');\n if (maskCtx) {\n // The depth map covers the whole source image; scale it to natural pixels and\n // apply the exact same rotate/flip/crop projection as the image itself.\n maskCtx.save();\n applyImageProjectionToContext(maskCtx, projection);\n maskCtx.drawImage(\n maskImg,\n region.x * sx, region.y * sy, region.width * sx, region.height * sy,\n region.x, region.y, region.width, region.height\n );\n maskCtx.restore();\n const maskData = maskCtx.getImageData(0, 0, baseW, baseH);\n if (maskData) {\n applyDepthMask(imageData, maskData, depthMask);\n }\n }\n } catch {\n // Mask failed to load; continue without crashing\n }\n }\n\n onPixels?.(imageData);\n baseCtx.putImageData(imageData, 0, 0);\n }\n\n return baseCanvas;\n }\n\n private quickMaskCache = new WeakMap<SelectionMask, HTMLCanvasElement>();\n private outlineCache = new WeakMap<SelectionMask, Float32Array>();\n\n /** Rubylith over the unselected area, drawn in natural image space. */\n private drawQuickMask(ctx: CanvasRenderingContext2D, selection: SelectionMask): void {\n let canvas = this.quickMaskCache.get(selection);\n if (!canvas) {\n canvas = this.createCanvas(selection.width, selection.height);\n const mctx = canvas.getContext('2d');\n if (!mctx || typeof mctx.createImageData !== 'function') return;\n const img = mctx.createImageData(selection.width, selection.height);\n img.data.set(quickMaskPixels(selection));\n mctx.putImageData(img, 0, 0);\n this.quickMaskCache.set(selection, canvas);\n }\n ctx.drawImage(canvas, 0, 0, selection.width, selection.height);\n }\n\n /** Marching ants: a white line under a black dashed one, one screen pixel wide. */\n private drawAnts(ctx: CanvasRenderingContext2D, selection: SelectionMask, scale: number, offset: number): void {\n let segs = this.outlineCache.get(selection);\n if (!segs) {\n segs = selectionOutline(selection);\n this.outlineCache.set(selection, segs);\n }\n if (!segs.length) return;\n const px = 1 / (scale || 1);\n ctx.beginPath();\n for (let i = 0; i < segs.length; i += 4) {\n ctx.moveTo(segs[i], segs[i + 1]);\n ctx.lineTo(segs[i + 2], segs[i + 3]);\n }\n ctx.lineWidth = px;\n ctx.strokeStyle = '#ffffff';\n ctx.stroke();\n if (typeof ctx.setLineDash === 'function') {\n ctx.setLineDash([4 * px, 4 * px]);\n ctx.lineDashOffset = -offset * px;\n }\n ctx.strokeStyle = '#000000';\n ctx.stroke();\n if (typeof ctx.setLineDash === 'function') ctx.setLineDash([]);\n }\n\n private drawDraftPath(ctx: CanvasRenderingContext2D, points: ImagePoint[], scale: number): void {\n const px = 1 / (scale || 1);\n ctx.beginPath();\n points.forEach((p, i) => (i === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y)));\n ctx.closePath();\n ctx.lineWidth = px;\n ctx.strokeStyle = '#ffffff';\n ctx.stroke();\n if (typeof ctx.setLineDash === 'function') ctx.setLineDash([4 * px, 4 * px]);\n ctx.strokeStyle = '#000000';\n ctx.stroke();\n if (typeof ctx.setLineDash === 'function') ctx.setLineDash([]);\n }\n\n private getSourceId(img: CanvasImageSource): number {\n const key = img as unknown as object;\n let id = this.sourceIds.get(key);\n if (id === undefined) {\n id = ++this.nextSourceId;\n this.sourceIds.set(key, id);\n }\n return id;\n }\n\n /**\n * Draws an individual annotation onto the canvas.\n */\n public async drawAnnotation(ctx: CanvasRenderingContext2D, ann: Annotation): Promise<void> {\n const blend = normalizeBlendMode(ann.blend);\n if (blend === 'normal') {\n await this.drawAnnotationContent(ctx, ann);\n return;\n }\n const op = canvasCompositeOperation(blend);\n if (op) {\n ctx.save();\n ctx.globalCompositeOperation = op;\n await this.drawAnnotationContent(ctx, ann);\n ctx.restore();\n return;\n }\n if (!(await this.drawAnnotationBlended(ctx, ann))) {\n // No pixel access (e.g. a tainted or headless canvas): draw it normally.\n await this.drawAnnotationContent(ctx, ann);\n }\n }\n\n /**\n * Scalar fallback for blend modes the canvas cannot composite (Photoshop soft light, linear /\n * vivid / pin light, hard mix, subtract, divide, darker / lighter colour, linear burn / dodge):\n * draws the annotation on a same-size layer with the same transform, blends it into a copy of\n * the target's pixels with `blendImageData`, and copies the result back inside the current clip.\n */\n private async drawAnnotationBlended(ctx: CanvasRenderingContext2D, ann: Annotation): Promise<boolean> {\n const canvas = ctx.canvas as HTMLCanvasElement | undefined;\n if (!canvas || typeof ctx.getTransform !== 'function' || typeof ctx.getImageData !== 'function') return false;\n const w = canvas.width;\n const h = canvas.height;\n const layer = this.createCanvas(w, h);\n const lctx = layer.getContext('2d');\n if (!lctx) return false;\n try {\n lctx.setTransform(ctx.getTransform());\n lctx.globalAlpha = ctx.globalAlpha;\n await this.drawAnnotationContent(lctx, ann);\n const backdrop = ctx.getImageData(0, 0, w, h);\n const source = lctx.getImageData(0, 0, w, h);\n if (!backdrop || !source) return false;\n blendImageData(backdrop, source, normalizeBlendMode(ann.blend));\n lctx.setTransform(1, 0, 0, 1, 0, 0);\n lctx.putImageData(backdrop, 0, 0);\n } catch {\n return false;\n }\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.globalAlpha = 1;\n ctx.globalCompositeOperation = 'copy';\n ctx.drawImage(layer, 0, 0);\n ctx.restore();\n return true;\n }\n\n private async drawAnnotationContent(ctx: CanvasRenderingContext2D, ann: Annotation): Promise<void> {\n ctx.save();\n if (ann.opacity !== undefined) {\n ctx.globalAlpha = ann.opacity;\n }\n\n if (ann.rotation) {\n ctx.translate(ann.x, ann.y);\n ctx.rotate((ann.rotation * Math.PI) / 180);\n ctx.translate(-ann.x, -ann.y);\n }\n\n switch (ann.type) {\n case 'pen': {\n const pen = ann as PenAnnotation;\n if (pen.points.length > 0) {\n ctx.beginPath();\n ctx.strokeStyle = pen.strokeColor;\n ctx.lineWidth = pen.strokeWidth;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n ctx.moveTo(pen.points[0].x, pen.points[0].y);\n for (let i = 1; i < pen.points.length; i++) {\n ctx.lineTo(pen.points[i].x, pen.points[i].y);\n }\n ctx.stroke();\n }\n break;\n }\n\n case 'rect': {\n const rect = ann as RectAnnotation;\n ctx.strokeStyle = rect.strokeColor;\n ctx.lineWidth = rect.strokeWidth;\n if (rect.fillColor) {\n ctx.fillStyle = rect.fillColor;\n ctx.fillRect(rect.x, rect.y, rect.width, rect.height);\n }\n if (rect.strokeWidth > 0) {\n ctx.strokeRect(rect.x, rect.y, rect.width, rect.height);\n }\n break;\n }\n\n case 'circle': {\n const circle = ann as CircleAnnotation;\n ctx.beginPath();\n ctx.strokeStyle = circle.strokeColor;\n ctx.lineWidth = circle.strokeWidth;\n ctx.ellipse(circle.x, circle.y, Math.abs(circle.radiusX), Math.abs(circle.radiusY), 0, 0, 2 * Math.PI);\n if (circle.fillColor) {\n ctx.fillStyle = circle.fillColor;\n ctx.fill();\n }\n if (circle.strokeWidth > 0) {\n ctx.stroke();\n }\n break;\n }\n\n case 'arrow': {\n const arrow = ann as ArrowAnnotation;\n ctx.strokeStyle = arrow.strokeColor;\n ctx.fillStyle = arrow.strokeColor;\n ctx.lineWidth = arrow.strokeWidth;\n\n // Line body\n ctx.beginPath();\n ctx.moveTo(arrow.x, arrow.y);\n ctx.lineTo(arrow.endX, arrow.endY);\n ctx.stroke();\n\n // Arrow head\n const angle = Math.atan2(arrow.endY - arrow.y, arrow.endX - arrow.x);\n const headLen = Math.max(12, arrow.strokeWidth * 3);\n ctx.beginPath();\n ctx.moveTo(arrow.endX, arrow.endY);\n ctx.lineTo(\n arrow.endX - headLen * Math.cos(angle - Math.PI / 6),\n arrow.endY - headLen * Math.sin(angle - Math.PI / 6)\n );\n ctx.lineTo(\n arrow.endX - headLen * Math.cos(angle + Math.PI / 6),\n arrow.endY - headLen * Math.sin(angle + Math.PI / 6)\n );\n ctx.closePath();\n ctx.fill();\n break;\n }\n\n case 'line': {\n const line = ann as LineAnnotation;\n ctx.beginPath();\n ctx.strokeStyle = line.strokeColor;\n ctx.lineWidth = line.strokeWidth;\n ctx.moveTo(line.x, line.y);\n ctx.lineTo(line.endX, line.endY);\n ctx.stroke();\n break;\n }\n\n case 'text': {\n const textAnn = ann as TextAnnotation;\n ctx.font = `${textAnn.fontWeight || 'normal'} ${textAnn.fontSize}px ${textAnn.fontFamily || 'sans-serif'}`;\n ctx.fillStyle = textAnn.color;\n ctx.textBaseline = 'top';\n ctx.fillText(textAnn.text, textAnn.x, textAnn.y);\n break;\n }\n\n case 'image': {\n const imgAnn = ann as ImageAnnotation;\n try {\n const loadedImg = await this.imageCache.get(imgAnn.src);\n ctx.drawImage(loadedImg, imgAnn.x, imgAnn.y, imgAnn.width, imgAnn.height);\n } catch {\n // Skip if watermark image failed to load\n }\n break;\n }\n }\n\n ctx.restore();\n }\n\n /**\n * Draws selection box around active annotation.\n */\n private drawAnnotationSelection(ctx: CanvasRenderingContext2D, ann: Annotation): void {\n ctx.save();\n ctx.strokeStyle = '#3b82f6'; // Tailwind blue-500\n ctx.lineWidth = 1.5;\n ctx.setLineDash([4, 4]);\n\n const bounds = getAnnotationBounds(ann);\n const pad = 4;\n ctx.strokeRect(bounds.x - pad, bounds.y - pad, bounds.width + pad * 2, bounds.height + pad * 2);\n\n // Draw handles\n ctx.fillStyle = '#ffffff';\n ctx.strokeStyle = '#3b82f6';\n ctx.setLineDash([]);\n const handleSize = 6;\n const corners = [\n { x: bounds.x - pad, y: bounds.y - pad },\n { x: bounds.x + bounds.width + pad, y: bounds.y - pad },\n { x: bounds.x - pad, y: bounds.y + bounds.height + pad },\n { x: bounds.x + bounds.width + pad, y: bounds.y + bounds.height + pad },\n ];\n for (const c of corners) {\n ctx.fillRect(c.x - handleSize / 2, c.y - handleSize / 2, handleSize, handleSize);\n ctx.strokeRect(c.x - handleSize / 2, c.y - handleSize / 2, handleSize, handleSize);\n }\n\n ctx.restore();\n }\n\n /** @deprecated Use the standalone `getAnnotationBounds` from the geometry module. */\n public getAnnotationBounds(ann: Annotation): { x: number; y: number; width: number; height: number } {\n return getAnnotationBounds(ann);\n }\n\n /**\n * Draws a rule-of-thirds crop grid overlay. All rectangles come from\n * `getViewportMetrics`, i.e. the crop box projected through rotation/flip.\n */\n private drawCropOverlay(ctx: CanvasRenderingContext2D, metrics: ViewportMetrics): void {\n const { imageRect, cropRect } = metrics;\n if (!cropRect) return;\n\n const imgL = imageRect.x;\n const imgT = imageRect.y;\n const imgR = imageRect.x + imageRect.width;\n const imgB = imageRect.y + imageRect.height;\n const startX = cropRect.x;\n const startY = cropRect.y;\n const cropBoxW = cropRect.width;\n const cropBoxH = cropRect.height;\n\n ctx.save();\n\n // Dark semi-transparent scrim outside crop box (within the image)\n ctx.fillStyle = 'rgba(0, 0, 0, 0.45)';\n // Top\n ctx.fillRect(imgL, imgT, imageRect.width, Math.max(0, startY - imgT));\n // Bottom\n ctx.fillRect(imgL, startY + cropBoxH, imageRect.width, Math.max(0, imgB - (startY + cropBoxH)));\n // Left\n ctx.fillRect(imgL, startY, Math.max(0, startX - imgL), cropBoxH);\n // Right\n ctx.fillRect(startX + cropBoxW, startY, Math.max(0, imgR - (startX + cropBoxW)), cropBoxH);\n\n // Crop border\n ctx.strokeStyle = '#ffffff';\n ctx.lineWidth = 2;\n ctx.strokeRect(startX, startY, cropBoxW, cropBoxH);\n\n // Rule of thirds lines\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.4)';\n ctx.lineWidth = 1;\n ctx.beginPath();\n // Vertical lines\n ctx.moveTo(startX + cropBoxW / 3, startY);\n ctx.lineTo(startX + cropBoxW / 3, startY + cropBoxH);\n ctx.moveTo(startX + (cropBoxW * 2) / 3, startY);\n ctx.lineTo(startX + (cropBoxW * 2) / 3, startY + cropBoxH);\n // Horizontal lines\n ctx.moveTo(startX, startY + cropBoxH / 3);\n ctx.lineTo(startX + cropBoxW, startY + cropBoxH / 3);\n ctx.moveTo(startX, startY + (cropBoxH * 2) / 3);\n ctx.lineTo(startX + cropBoxW, startY + (cropBoxH * 2) / 3);\n ctx.stroke();\n\n // Corner and edge handles\n ctx.fillStyle = '#ffffff';\n ctx.strokeStyle = '#0284c7';\n ctx.lineWidth = 1.5;\n const handleSize = 10;\n const handles = [\n // Corners\n { x: startX, y: startY },\n { x: startX + cropBoxW, y: startY },\n { x: startX, y: startY + cropBoxH },\n { x: startX + cropBoxW, y: startY + cropBoxH },\n // Edges\n { x: startX + cropBoxW / 2, y: startY },\n { x: startX + cropBoxW / 2, y: startY + cropBoxH },\n { x: startX, y: startY + cropBoxH / 2 },\n { x: startX + cropBoxW, y: startY + cropBoxH / 2 },\n ];\n for (const h of handles) {\n ctx.fillRect(h.x - handleSize / 2, h.y - handleSize / 2, handleSize, handleSize);\n ctx.strokeRect(h.x - handleSize / 2, h.y - handleSize / 2, handleSize, handleSize);\n }\n\n ctx.restore();\n }\n\n private drawFittedImage(\n ctx: CanvasRenderingContext2D,\n img: CanvasImageSource,\n imgW: number,\n imgH: number,\n vpW: number,\n vpH: number,\n zoom: number,\n pan: { x: number; y: number }\n ): void {\n ctx.save();\n ctx.translate(vpW / 2 + pan.x, vpH / 2 + pan.y);\n ctx.scale(zoom, zoom);\n const fitScale = Math.min((vpW * 0.85) / imgW, (vpH * 0.85) / imgH, 1);\n const renderW = imgW * fitScale;\n const renderH = imgH * fitScale;\n ctx.drawImage(img, -renderW / 2, -renderH / 2, renderW, renderH);\n ctx.restore();\n }\n\n /**\n * Performs an export render at exact pixel dimensions without zoom/pan viewport offsets.\n */\n public async renderExport(\n imageSource: CanvasImageSource | string,\n state: ImageEditorState,\n options: ExportOptions = {}\n ): Promise<HTMLCanvasElement> {\n let img: CanvasImageSource;\n if (typeof imageSource === 'string') {\n img = await this.imageCache.get(imageSource);\n } else {\n img = imageSource;\n }\n\n const { width: naturalWidth, height: naturalHeight } = getSourceSize(img);\n const { crop, transform, annotations } = state;\n\n const region = crop\n ? clampCropToImage(crop, naturalWidth, naturalHeight)\n : { x: 0, y: 0, width: naturalWidth, height: naturalHeight };\n const rotated = getRotatedSize(region.width, region.height, transform);\n const baseW = Math.max(1, Math.round(rotated.width));\n const baseH = Math.max(1, Math.round(rotated.height));\n\n const exportW = options.width || baseW;\n const exportH = options.height || baseH;\n\n const exportCanvas = this.createCanvas(exportW, exportH);\n const ctx = exportCanvas.getContext('2d');\n if (!ctx) return exportCanvas;\n\n const baseCanvas = await this.renderBaseImage(img, naturalWidth, naturalHeight, region, transform, state);\n\n // Scale to target export dimensions\n ctx.drawImage(baseCanvas, 0, 0, baseW, baseH, 0, 0, exportW, exportH);\n\n // Draw annotations (natural image space) through the same rotate/flip/crop projection\n if (options.includeAnnotations !== false && annotations.length > 0) {\n ctx.save();\n ctx.scale(exportW / baseW, exportH / baseH);\n applyImageProjectionToContext(ctx, getBaseProjection(region, transform, baseW, baseH));\n for (const ann of annotations) {\n await this.drawAnnotation(ctx, ann);\n }\n ctx.restore();\n }\n\n return exportCanvas;\n }\n\n /**\n * Generates a strictly binary mask canvas (white = area to regenerate, black = keep) in\n * natural image pixel space of the current source image — the same space the crop box\n * and annotations are stored in. Pair it with `toSourceDataURL()` for AI inpainting.\n */\n public async renderMask(\n state: ImageEditorState,\n options?: { useAnnotations?: boolean; useCrop?: boolean; useSelection?: boolean }\n ): Promise<HTMLCanvasElement> {\n const naturalWidth = Math.max(1, Math.round(state.imageDimensions.width));\n const naturalHeight = Math.max(1, Math.round(state.imageDimensions.height));\n const maskCanvas = this.createCanvas(naturalWidth, naturalHeight);\n const ctx = maskCanvas.getContext('2d');\n if (!ctx) return maskCanvas;\n\n // Background: unmasked (black)\n ctx.fillStyle = MASK_BLACK;\n ctx.fillRect(0, 0, naturalWidth, naturalHeight);\n\n const useCrop = options?.useCrop ?? true;\n const useAnnotations = options?.useAnnotations ?? true;\n\n // Crop box mask (if active)\n if (useCrop && state.crop) {\n ctx.fillStyle = MASK_WHITE;\n ctx.fillRect(state.crop.x, state.crop.y, state.crop.width, state.crop.height);\n }\n\n // Annotation masks (drawn in solid white, never in annotation colours)\n if (useAnnotations && state.annotations.length > 0) {\n for (const ann of state.annotations) {\n this.drawAnnotationMask(ctx, ann);\n }\n }\n\n // Anti-aliased edges produce grey pixels: threshold to pure black/white.\n const imageData = ctx.getImageData?.(0, 0, naturalWidth, naturalHeight);\n // The active selection (same natural space) is added to the mask.\n const selection =\n (options?.useSelection ?? true) &&\n state.selection?.bounds &&\n state.selection.width === naturalWidth &&\n state.selection.height === naturalHeight\n ? state.selection\n : null;\n if (imageData) {\n const d = imageData.data;\n for (let i = 0; i < d.length; i += 4) {\n const v = d[i] >= 128 || (selection !== null && selection.data[i >> 2] >= 128) ? 255 : 0;\n d[i] = v;\n d[i + 1] = v;\n d[i + 2] = v;\n d[i + 3] = 255;\n }\n ctx.putImageData(imageData, 0, 0);\n }\n\n return maskCanvas;\n }\n\n private drawAnnotationMask(ctx: CanvasRenderingContext2D, ann: Annotation): void {\n ctx.save();\n ctx.globalAlpha = 1;\n ctx.fillStyle = MASK_WHITE;\n ctx.strokeStyle = MASK_WHITE;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n if (ann.rotation) {\n ctx.translate(ann.x, ann.y);\n ctx.rotate((ann.rotation * Math.PI) / 180);\n ctx.translate(-ann.x, -ann.y);\n }\n\n switch (ann.type) {\n case 'pen': {\n if (ann.points.length > 0) {\n ctx.beginPath();\n ctx.lineWidth = Math.max(ann.strokeWidth || 0, 8);\n ctx.moveTo(ann.points[0].x, ann.points[0].y);\n for (let i = 1; i < ann.points.length; i++) {\n ctx.lineTo(ann.points[i].x, ann.points[i].y);\n }\n ctx.stroke();\n }\n break;\n }\n case 'circle': {\n ctx.beginPath();\n ctx.ellipse(ann.x, ann.y, Math.abs(ann.radiusX), Math.abs(ann.radiusY), 0, 0, Math.PI * 2);\n ctx.fill();\n break;\n }\n case 'arrow':\n case 'line': {\n ctx.beginPath();\n ctx.lineWidth = Math.max(ann.strokeWidth || 0, 8);\n ctx.moveTo(ann.x, ann.y);\n ctx.lineTo(ann.endX, ann.endY);\n ctx.stroke();\n break;\n }\n case 'rect':\n case 'image':\n case 'text': {\n const b = getAnnotationBounds(ann);\n ctx.fillRect(b.x, b.y, b.width, b.height);\n break;\n }\n }\n ctx.restore();\n }\n}\n\nconst MASK_WHITE = '#ffffff';\nconst MASK_BLACK = '#000000';\n\nfunction getSourceSize(img: CanvasImageSource, fallbackW = 800, fallbackH = 600): { width: number; height: number } {\n const anyImg = img as any;\n return {\n width: anyImg.naturalWidth || anyImg.videoWidth || anyImg.width || fallbackW,\n height: anyImg.naturalHeight || anyImg.videoHeight || anyImg.height || fallbackH,\n };\n}\n\nfunction getBaseProjection(region: CropBox, transform: ImageTransform, baseW: number, baseH: number): ImageProjection {\n return {\n region,\n angle: normalizeAngle(transform.rotate),\n flipH: transform.flipH,\n flipV: transform.flipV,\n scale: 1,\n originX: baseW / 2,\n originY: baseH / 2,\n };\n}\n","// Portions ported from photocraft/crates/algo/src/selection.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\nimport type { CropBox, ImagePoint } from '../types';\nimport { createSelectionMask, coverageToByte, type SelectionMask } from './mask';\n\nexport interface ShapeSelectionOptions {\n /** Partial coverage along the edge (default true). */\n antiAlias?: boolean;\n}\n\ninterface Edge {\n top: number;\n bottom: number;\n ax: number;\n ay: number;\n bx: number;\n by: number;\n}\n\n/**\n * Even-odd polygon coverage over a `width × height` image: exact horizontal coverage on 4\n * sub-rows per pixel row (1 without anti-aliasing, where a pixel is in when its centre is).\n * Each sub-row only tests the edges that cross it (an active edge list over edges sorted by\n * their top), so the cost is about pixels + edges × rows they span.\n */\nexport function polygonCoverage(\n points: readonly ImagePoint[],\n width: number,\n height: number,\n antiAlias = true\n): Float32Array {\n const m = new Float32Array(width * height);\n if (points.length < 3 || width <= 0 || height <= 0) return m;\n const sub = antiAlias ? 4 : 1;\n const edges: Edge[] = [];\n for (let i = 0; i < points.length; i++) {\n const a = points[i];\n const b = points[(i + 1) % points.length];\n if (![a.x, a.y, b.x, b.y].every(Number.isFinite)) continue;\n if (a.y < b.y) edges.push({ top: a.y, bottom: b.y, ax: a.x, ay: a.y, bx: b.x, by: b.y });\n else if (b.y < a.y) edges.push({ top: b.y, bottom: a.y, ax: a.x, ay: a.y, bx: b.x, by: b.y });\n }\n edges.sort((p, q) => p.top - q.top);\n let next = 0;\n let active: Edge[] = [];\n const xs: number[] = [];\n for (let py = 0; py < height; py++) {\n const row = py * width;\n for (let s = 0; s < sub; s++) {\n const y = py + (s + 0.5) / sub;\n while (next < edges.length && edges[next].top <= y) active.push(edges[next++]);\n if (active.length) active = active.filter((e) => e.bottom > y);\n if (!active.length) continue;\n xs.length = 0;\n for (const e of active) {\n if (e.top <= y) xs.push(e.ax + ((y - e.ay) / (e.by - e.ay)) * (e.bx - e.ax));\n }\n xs.sort((a, b) => a - b);\n for (let k = 0; k + 1 < xs.length; k += 2) {\n const x0 = Math.max(0, xs[k]);\n const x1 = Math.min(width, xs[k + 1]);\n if (x1 <= x0) continue;\n const c0 = Math.floor(x0);\n const c1 = Math.min(width, Math.ceil(x1));\n for (let cx = c0; cx < c1; cx++) {\n let cov: number;\n if (antiAlias) cov = Math.min(cx + 1, x1) - Math.max(cx, x0);\n else {\n const c = cx + 0.5;\n cov = c >= x0 && c < x1 ? 1 : 0;\n }\n if (cov > 0) m[row + cx] += cov / sub;\n }\n }\n }\n }\n for (let i = 0; i < m.length; i++) if (m[i] > 1) m[i] = 1;\n return m;\n}\n\nfunction toMask(width: number, height: number, coverage: Float32Array): SelectionMask {\n const out = new Uint8Array(coverage.length);\n for (let i = 0; i < out.length; i++) out[i] = coverageToByte(coverage[i]);\n return createSelectionMask(width, height, out);\n}\n\n/** Lasso / polygonal lasso: an even-odd polygon in natural image pixels. */\nexport function polygonSelection(\n width: number,\n height: number,\n points: readonly ImagePoint[],\n options: ShapeSelectionOptions = {}\n): SelectionMask {\n return toMask(width, height, polygonCoverage(points, width, height, options.antiAlias ?? true));\n}\n\n/** Normalises a rectangle with a negative width or height. */\nexport function normalizeRect(rect: CropBox): CropBox {\n const x = rect.width < 0 ? rect.x + rect.width : rect.x;\n const y = rect.height < 0 ? rect.y + rect.height : rect.y;\n return { x, y, width: Math.abs(rect.width), height: Math.abs(rect.height) };\n}\n\n/** Rectangular marquee. Fractional edges get partial coverage when anti-aliased. */\nexport function rectSelection(width: number, height: number, rect: CropBox, options: ShapeSelectionOptions = {}): SelectionMask {\n const r = normalizeRect(rect);\n const pts = [\n { x: r.x, y: r.y },\n { x: r.x + r.width, y: r.y },\n { x: r.x + r.width, y: r.y + r.height },\n { x: r.x, y: r.y + r.height },\n ];\n return polygonSelection(width, height, pts, options);\n}\n\n/** The ellipse inscribed in `rect` as a polygon fine enough that its chords stay within 0.05 px. */\nexport function ellipsePoints(rect: CropBox): ImagePoint[] {\n const r = normalizeRect(rect);\n const rx = r.width / 2;\n const ry = r.height / 2;\n const cx = r.x + rx;\n const cy = r.y + ry;\n const rmax = Math.max(rx, ry, 0.5);\n // Sagitta of a chord with angle step θ is r(1 − cos(θ/2)) ≈ rθ²/8 ≤ 0.05.\n const step = Math.sqrt(0.4 / rmax);\n const n = Math.min(4096, Math.max(16, Math.ceil((2 * Math.PI) / step)));\n const pts: ImagePoint[] = [];\n for (let i = 0; i < n; i++) {\n const t = (i / n) * 2 * Math.PI;\n pts.push({ x: cx + rx * Math.cos(t), y: cy + ry * Math.sin(t) });\n }\n return pts;\n}\n\n/** Elliptical marquee inscribed in `rect`. */\nexport function ellipseSelection(width: number, height: number, rect: CropBox, options: ShapeSelectionOptions = {}): SelectionMask {\n return polygonSelection(width, height, ellipsePoints(rect), options);\n}\n","// Portions ported from photocraft/crates/algo/src/selection.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\nimport type { ImagePoint } from '../types';\nimport { createSelectionMask, coverageToByte, type PixelBuffer, type SelectionMask } from './mask';\n\n/** How the magic wand measures colour difference. */\nexport type ColorDistance = 'rgb' | 'perceptual';\n\nexport interface MagicWandOptions {\n /**\n * 0..255. `rgb`: the largest per-channel difference in levels (alpha included), as\n * Photoshop's wand. `perceptual`: CIE76 ΔE*ab, with 255 ≙ ΔE 100. Default 32.\n */\n tolerance?: number;\n /** Only the 4-connected region around the seed (default true); otherwise every similar pixel. */\n contiguous?: boolean;\n /** Soft one-pixel fringe on the edge (default true). */\n antiAlias?: boolean;\n /** Default `rgb`. */\n distance?: ColorDistance;\n}\n\nfunction checkPixels(p: PixelBuffer): number {\n const n = p.width * p.height;\n if (!Number.isInteger(p.width) || !Number.isInteger(p.height) || p.width < 1 || p.height < 1) {\n throw new Error('Invalid pixel buffer size');\n }\n if (p.data.length < n * 4) throw new Error('Pixel data is shorter than width × height × 4');\n return n;\n}\n\nconst SRGB_TO_LINEAR = (() => {\n const t = new Float32Array(256);\n for (let i = 0; i < 256; i++) {\n const v = i / 255;\n t[i] = v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);\n }\n return t;\n})();\n\nconst labF = (t: number) => (t > 216 / 24389 ? Math.cbrt(t) : (24389 / 27 * t + 16) / 116);\n\n/** CIE Lab (D65) of an 8-bit sRGB colour. */\nexport function srgb8ToLab(r: number, g: number, b: number): [number, number, number] {\n const rl = SRGB_TO_LINEAR[r & 255];\n const gl = SRGB_TO_LINEAR[g & 255];\n const bl = SRGB_TO_LINEAR[b & 255];\n const x = (0.4124564 * rl + 0.3575761 * gl + 0.1804375 * bl) / 0.95047;\n const y = 0.2126729 * rl + 0.7151522 * gl + 0.072175 * bl;\n const z = (0.0193339 * rl + 0.119192 * gl + 0.9503041 * bl) / 1.08883;\n const fx = labF(x);\n const fy = labF(y);\n const fz = labF(z);\n return [116 * fy - 16, 500 * (fx - fy), 200 * (fy - fz)];\n}\n\n/** `similar(i)` for the wand: does pixel `i` match the seed colour within the tolerance? */\nfunction similarity(pixels: PixelBuffer, seed: number, tolerance: number, distance: ColorDistance): (i: number) => boolean {\n const d = pixels.data;\n const tr = d[seed * 4];\n const tg = d[seed * 4 + 1];\n const tb = d[seed * 4 + 2];\n const ta = d[seed * 4 + 3];\n const tol = Math.max(0, Math.floor(tolerance + 1e-3));\n if (distance === 'perceptual') {\n const [tl, taa, tbb] = srgb8ToLab(tr, tg, tb);\n const de = (Math.max(0, tolerance) * 100) / 255;\n const de2 = de * de + 1e-6;\n return (i) => {\n const p = i * 4;\n const a = d[p + 3];\n // Copying a selection can leave RGB under zero alpha; hidden colours must not split a\n // transparent region.\n if (ta === 0 && a === 0) return true;\n if (Math.abs(a - ta) > tol) return false;\n const [l, aa, bb] = srgb8ToLab(d[p], d[p + 1], d[p + 2]);\n return (l - tl) ** 2 + (aa - taa) ** 2 + (bb - tbb) ** 2 <= de2;\n };\n }\n return (i) => {\n const p = i * 4;\n const a = d[p + 3];\n if (ta === 0 && a === 0) return true;\n return (\n Math.abs(d[p] - tr) <= tol &&\n Math.abs(d[p + 1] - tg) <= tol &&\n Math.abs(d[p + 2] - tb) <= tol &&\n Math.abs(a - ta) <= tol\n );\n };\n}\n\n/**\n * Softens hard edges: an edge pixel (one whose 3×3 neighbourhood differs from it) becomes\n * `½ + ½·avg` if selected, `½·avg` if not (neighbours outside the image count as the pixel).\n * Only the box `x0..x1 × y0..y1` (exclusive ends) is visited.\n */\nfunction antialiasMarks(marks: Uint8Array, w: number, h: number, x0: number, y0: number, x1: number, y1: number): Uint8Array {\n const out = marks.slice();\n for (let y = y0; y < y1; y++) {\n for (let x = x0; x < x1; x++) {\n const i = y * w + x;\n const v = marks[i];\n let sum = 0;\n let edge = false;\n for (let dy = -1; dy <= 1; dy++) {\n const ny = y + dy;\n for (let dx = -1; dx <= 1; dx++) {\n const nx = x + dx;\n const n = nx < 0 || ny < 0 || nx >= w || ny >= h ? v : marks[ny * w + nx];\n if (n !== v) edge = true;\n sum += n;\n }\n }\n if (edge) {\n const avg = sum / (9 * 255);\n out[i] = Math.round((v > 127 ? 0.5 + 0.5 * avg : 0.5 * avg) * 255);\n }\n }\n }\n return out;\n}\n\n/**\n * Magic wand: pixels similar to the seed pixel. Contiguous mode is a scanline span fill with an\n * explicit stack (fill a run, then scan the rows above and below it for new runs), so it is\n * linear in the pixels visited and never recurses. An empty selection when the seed is outside.\n */\nexport function magicWand(pixels: PixelBuffer, seed: ImagePoint, options: MagicWandOptions = {}): SelectionMask {\n const n = checkPixels(pixels);\n const { width: w, height: h } = pixels;\n const sx = Math.floor(seed.x);\n const sy = Math.floor(seed.y);\n if (!(sx >= 0 && sy >= 0 && sx < w && sy < h)) return createSelectionMask(w, h);\n const similar = similarity(pixels, sy * w + sx, options.tolerance ?? 32, options.distance ?? 'rgb');\n const marks = new Uint8Array(n);\n let bx0 = w;\n let by0 = h;\n let bx1 = -1;\n let by1 = -1;\n if (options.contiguous ?? true) {\n // Span fill. Each stack entry is a seed pixel index.\n const stack: number[] = [sy * w + sx];\n while (stack.length) {\n const idx = stack.pop()!;\n if (marks[idx]) continue;\n const y = (idx / w) | 0;\n const row = y * w;\n let l = idx - row;\n let r = l;\n while (l > 0 && !marks[row + l - 1] && similar(row + l - 1)) l--;\n while (r + 1 < w && !marks[row + r + 1] && similar(row + r + 1)) r++;\n marks.fill(255, row + l, row + r + 1);\n if (l < bx0) bx0 = l;\n if (r > bx1) bx1 = r;\n if (y < by0) by0 = y;\n if (y > by1) by1 = y;\n for (const ny of [y - 1, y + 1]) {\n if (ny < 0 || ny >= h) continue;\n const nrow = ny * w;\n let inRun = false;\n for (let nx = l; nx <= r; nx++) {\n const ok = !marks[nrow + nx] && similar(nrow + nx);\n if (ok && !inRun) stack.push(nrow + nx);\n inRun = ok;\n }\n }\n }\n } else {\n for (let y = 0; y < h; y++) {\n const row = y * w;\n for (let x = 0; x < w; x++) {\n if (similar(row + x)) {\n marks[row + x] = 255;\n if (x < bx0) bx0 = x;\n if (x > bx1) bx1 = x;\n if (y < by0) by0 = y;\n if (y > by1) by1 = y;\n }\n }\n }\n }\n if (bx1 < 0) return createSelectionMask(w, h);\n if (!(options.antiAlias ?? true)) return createSelectionMask(w, h, marks);\n return createSelectionMask(\n w,\n h,\n antialiasMarks(marks, w, h, Math.max(0, bx0 - 1), Math.max(0, by0 - 1), Math.min(w, bx1 + 2), Math.min(h, by1 + 2))\n );\n}\n\n/** One Color Range sample: a colour (0..255 levels or `#rrggbb`) and, optionally, where it was picked. */\nexport interface ColorRangeSample {\n color: readonly [number, number, number] | string;\n at?: ImagePoint;\n}\n\nexport interface ColorRangeOptions {\n /** 0..200 levels (default 40): coverage falls off linearly to 0 at `fuzziness + 1` levels. */\n fuzziness?: number;\n /**\n * Localized Color Clusters: a sample with a position also fades with distance from it,\n * reaching 0 at this many pixels.\n */\n localized?: number;\n}\n\nfunction sampleColor(c: ColorRangeSample['color']): [number, number, number] {\n if (typeof c === 'string') {\n const m = /^#?([0-9a-f]{6})$/i.exec(c.trim());\n if (!m) throw new Error(`Invalid colour \"${c}\"`);\n const v = parseInt(m[1], 16);\n return [(v >> 16) & 255, (v >> 8) & 255, v & 255];\n }\n return [c[0], c[1], c[2]];\n}\n\n/**\n * Select › Color Range › Sampled Colors: each pixel takes its best match over the samples; a\n * match falls off linearly with the largest per-channel difference, `1 − d / (fuzziness + 1)`.\n * Transparent pixels are never selected.\n */\nexport function colorRange(pixels: PixelBuffer, samples: readonly ColorRangeSample[], options: ColorRangeOptions = {}): SelectionMask {\n const n = checkPixels(pixels);\n const { width: w, height: h, data } = pixels;\n const f = Math.max(0, options.fuzziness ?? 40) + 1;\n const parsed = samples.map((s) => ({ c: sampleColor(s.color), at: s.at }));\n const radius = options.localized !== undefined ? Math.max(1, options.localized) : undefined;\n const out = new Uint8Array(n);\n if (!parsed.length) return createSelectionMask(w, h, out);\n for (let i = 0; i < n; i++) {\n const p = i * 4;\n if (data[p + 3] <= 0) continue;\n const x = i % w;\n const y = (i - x) / w;\n let best = 0;\n for (const s of parsed) {\n const d = Math.max(Math.abs(data[p] - s.c[0]), Math.abs(data[p + 1] - s.c[1]), Math.abs(data[p + 2] - s.c[2]));\n let k = Math.min(1, Math.max(0, 1 - d / f));\n if (k > 0 && radius !== undefined && s.at) {\n const dist = Math.hypot(x - s.at.x, y - s.at.y);\n k *= Math.min(1, Math.max(0, 1 - dist / radius));\n }\n if (k > best) best = k;\n }\n out[i] = coverageToByte(best);\n }\n return createSelectionMask(w, h, out);\n}\n\nexport type ToneRangePreset = 'shadows' | 'midtones' | 'highlights';\n\n/** Luma bounds (0..255, Rec. 601) of the tonal presets. */\nexport const TONE_RANGE_PRESETS: Record<ToneRangePreset, [number, number]> = {\n shadows: [0, 65],\n midtones: [105, 150],\n highlights: [190, 255],\n};\n\n/**\n * Select › Color Range › Shadows / Midtones / Highlights: pixels whose luma lies in `lo..hi` are\n * selected; outside, selection falls off linearly to 0 over `falloff` levels.\n */\nexport function toneRange(\n pixels: PixelBuffer,\n range: ToneRangePreset | readonly [number, number],\n falloff = 20\n): SelectionMask {\n const n = checkPixels(pixels);\n const [lo, hi] = typeof range === 'string' ? TONE_RANGE_PRESETS[range] : range;\n const ramp = Math.max(1e-3, falloff);\n const out = new Uint8Array(n);\n const d = pixels.data;\n for (let i = 0; i < n; i++) {\n const p = i * 4;\n if (d[p + 3] <= 0) continue;\n const l = Math.min(255, Math.max(0, 0.299 * d[p] + 0.587 * d[p + 1] + 0.114 * d[p + 2]));\n const outside = l < lo ? lo - l : l > hi ? l - hi : 0;\n out[i] = coverageToByte(1 - outside / ramp);\n }\n return createSelectionMask(pixels.width, pixels.height, out);\n}\n\n/**\n * Select › Color Range › Reds … Magentas (`center` 0, 60, …, 300°): closeness of hue (full at\n * the centre, none 60° away) × chroma × (2 − max), so neutrals are never selected.\n */\nexport function hueRange(pixels: PixelBuffer, center: number): SelectionMask {\n const n = checkPixels(pixels);\n const out = new Uint8Array(n);\n const d = pixels.data;\n for (let i = 0; i < n; i++) {\n const p = i * 4;\n if (d[p + 3] <= 0) continue;\n const r = d[p] / 255;\n const g = d[p + 1] / 255;\n const b = d[p + 2] / 255;\n const mx = Math.max(r, g, b);\n const mn = Math.min(r, g, b);\n const chroma = mx - mn;\n if (chroma <= 0) continue;\n let hue: number;\n if (mx === r) hue = (((g - b) / chroma) % 6 + 6) % 6;\n else if (mx === g) hue = (b - r) / chroma + 2;\n else hue = (r - g) / chroma + 4;\n hue *= 60;\n let dh = (((hue - center) % 360) + 360) % 360;\n dh = Math.min(dh, 360 - dh);\n out[i] = coverageToByte(Math.min(1, Math.max(0, 1 - dh / 60)) * chroma * (2 - mx));\n }\n return createSelectionMask(pixels.width, pixels.height, out);\n}\n","// Portions ported from photocraft/crates/algo/src/matting.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\nimport type { CropBox } from '../types';\nimport { createSelectionMask, coverageToByte, type PixelBuffer, type SelectionMask } from './mask';\nimport { distanceTransform, gaussianBlur, greyMorphology, shiftCoverage } from './modify';\n\n/**\n * Refine Edge / Select and Mask parameters (Photoshop's units). Refinement is edge-aware: within\n * `radius` pixels of the mask's edge the coverage is re-estimated from the image with a colour\n * guided filter (He et al.), so a coarse or misaligned mask (e.g. an AI segmentation) follows\n * the real edges of the image.\n */\nexport interface RefineEdgeParams {\n /** Edge-detection band radius in pixels (0 = no edge detection). */\n radius?: number;\n /** Narrow the band where the image edge is sharp (hair stays soft, hard edges stay hard). */\n smartRadius?: boolean;\n /** 0..100: rounds jagged edges. */\n smooth?: number;\n /** Pixels of Gaussian softening. */\n feather?: number;\n /** 0..100: hardens soft edges. */\n contrast?: number;\n /** −100..100: moves the edge out (positive) or in; 100 % is `max(radius, 4)` pixels. */\n shiftEdge?: number;\n}\n\nexport const DEFAULT_REFINE_EDGE_PARAMS: Required<RefineEdgeParams> = {\n radius: 0,\n smartRadius: false,\n smooth: 0,\n feather: 0,\n contrast: 0,\n shiftEdge: 0,\n};\n\n/** Guided-filter regulariser (colour guide, samples in 0..1). */\nexport const GUIDED_FILTER_EPS = 1e-4;\n\nconst fin = (v: unknown, d: number) => (typeof v === 'number' && Number.isFinite(v) ? v : d);\n\n/** Clamped, complete parameters. */\nexport function normalizeRefineEdgeParams(p: RefineEdgeParams = {}): Required<RefineEdgeParams> {\n return {\n radius: Math.min(250, Math.max(0, fin(p.radius, 0))),\n smartRadius: p.smartRadius === true,\n smooth: Math.min(100, Math.max(0, fin(p.smooth, 0))),\n feather: Math.min(1000, Math.max(0, fin(p.feather, 0))),\n contrast: Math.min(100, Math.max(0, fin(p.contrast, 0))),\n shiftEdge: Math.min(100, Math.max(-100, fin(p.shiftEdge, 0))),\n };\n}\n\nconst gfRadius = (p: Required<RefineEdgeParams>) => Math.min(64, Math.max(1, Math.ceil(p.radius)));\nconst smoothSigma = (p: Required<RefineEdgeParams>) => (p.smooth / 100) * 4;\nconst featherSigma = (p: Required<RefineEdgeParams>) => p.feather / 2;\nfunction shiftAmount(p: Required<RefineEdgeParams>): number {\n const px = (p.shiftEdge / 100) * Math.max(p.radius, 4);\n return Number.isFinite(px) ? Math.min(64, Math.max(-64, px)) : 0;\n}\n\n/** Pixels around the mask's content that refinement can read or write. */\nexport function refineEdgeHalo(params: RefineEdgeParams = {}): number {\n const p = normalizeRefineEdgeParams(params);\n const g = gfRadius(p);\n const edge = p.radius > 0 ? Math.max(Math.ceil(p.radius), 2 * g + (p.smartRadius ? g + 1 : 0)) : 0;\n return (\n edge +\n Math.ceil(3 * smoothSigma(p)) +\n Math.ceil(3 * featherSigma(p)) +\n Math.ceil(Math.abs(shiftAmount(p))) +\n 2\n );\n}\n\n/** Box mean of radius `r` (window clipped to the image, divided by its pixel count). O(1) per pixel. */\nexport function boxMean(src: ArrayLike<number>, w: number, h: number, r: number): Float32Array {\n const tmp = new Float32Array(w * h);\n const pre = new Float64Array(Math.max(w, h) + 1);\n for (let y = 0; y < h; y++) {\n const row = y * w;\n for (let x = 0; x < w; x++) pre[x + 1] = pre[x] + src[row + x];\n for (let x = 0; x < w; x++) {\n const lo = Math.max(0, x - r);\n const hi = Math.min(w, x + r + 1);\n tmp[row + x] = (pre[hi] - pre[lo]) / (hi - lo);\n }\n }\n const out = new Float32Array(w * h);\n for (let x = 0; x < w; x++) {\n for (let y = 0; y < h; y++) pre[y + 1] = pre[y] + tmp[y * w + x];\n for (let y = 0; y < h; y++) {\n const lo = Math.max(0, y - r);\n const hi = Math.min(h, y + r + 1);\n out[y * w + x] = (pre[hi] - pre[lo]) / (hi - lo);\n }\n }\n return out;\n}\n\n/**\n * Guided filter with a colour guide (He et al., Eq. 19–21: `a_k = (Σ_k + εU)⁻¹ cov_k(I, p)`):\n * filters `p` so that it is locally a linear function of the guide's colour, which makes the\n * output's edges follow the guide's edges. `guide` is three planes of 0..1 values.\n */\nexport function guidedFilterColor(\n guide: readonly [Float32Array, Float32Array, Float32Array],\n p: Float32Array,\n w: number,\n h: number,\n r: number,\n eps = GUIDED_FILTER_EPS\n): Float32Array {\n const n = w * h;\n const [c0, c1, c2] = guide;\n const prod = (a: ArrayLike<number>, b: ArrayLike<number>) => {\n const o = new Float32Array(n);\n for (let i = 0; i < n; i++) o[i] = a[i] * b[i];\n return o;\n };\n const m0 = boxMean(c0, w, h, r);\n const m1 = boxMean(c1, w, h, r);\n const m2 = boxMean(c2, w, h, r);\n const mp = boxMean(p, w, h, r);\n const mip0 = boxMean(prod(c0, p), w, h, r);\n const mip1 = boxMean(prod(c1, p), w, h, r);\n const mip2 = boxMean(prod(c2, p), w, h, r);\n const s00 = boxMean(prod(c0, c0), w, h, r);\n const s01 = boxMean(prod(c0, c1), w, h, r);\n const s02 = boxMean(prod(c0, c2), w, h, r);\n const s11 = boxMean(prod(c1, c1), w, h, r);\n const s12 = boxMean(prod(c1, c2), w, h, r);\n const s22 = boxMean(prod(c2, c2), w, h, r);\n const a0 = new Float32Array(n);\n const a1 = new Float32Array(n);\n const a2 = new Float32Array(n);\n const b = new Float32Array(n);\n for (let i = 0; i < n; i++) {\n const u0 = m0[i], u1 = m1[i], u2 = m2[i], up = mp[i];\n const rr = s00[i] - u0 * u0 + eps;\n const rg = s01[i] - u0 * u1;\n const rb = s02[i] - u0 * u2;\n const gg = s11[i] - u1 * u1 + eps;\n const gb = s12[i] - u1 * u2;\n const bb = s22[i] - u2 * u2 + eps;\n const v0 = mip0[i] - u0 * up;\n const v1 = mip1[i] - u1 * up;\n const v2 = mip2[i] - u2 * up;\n // Inverse of the symmetric 3×3 matrix.\n const i00 = gg * bb - gb * gb;\n const i01 = gb * rb - rg * bb;\n const i02 = rg * gb - gg * rb;\n const i11 = rr * bb - rb * rb;\n const i12 = rb * rg - rr * gb;\n const i22 = rr * gg - rg * rg;\n const det = rr * i00 + rg * i01 + rb * i02;\n let x0 = 0, x1 = 0, x2 = 0;\n if (Math.abs(det) >= 1e-30) {\n x0 = (i00 * v0 + i01 * v1 + i02 * v2) / det;\n x1 = (i01 * v0 + i11 * v1 + i12 * v2) / det;\n x2 = (i02 * v0 + i12 * v1 + i22 * v2) / det;\n }\n a0[i] = x0;\n a1[i] = x1;\n a2[i] = x2;\n b[i] = up - x0 * u0 - x1 * u1 - x2 * u2;\n }\n const ma0 = boxMean(a0, w, h, r);\n const ma1 = boxMean(a1, w, h, r);\n const ma2 = boxMean(a2, w, h, r);\n const mb = boxMean(b, w, h, r);\n const out = new Float32Array(n);\n for (let i = 0; i < n; i++) out[i] = ma0[i] * c0[i] + ma1[i] * c1[i] + ma2[i] * c2[i] + mb[i];\n return out;\n}\n\n/**\n * Per-pixel transition width (pixels) of the guide's luminance: local range over local maximum\n * gradient in a window of radius `r` (a sharp step gives about 2, a ramp of width L about L).\n */\nexport function edgeWidth(guide: readonly [Float32Array, Float32Array, Float32Array], w: number, h: number, r: number): Float32Array {\n const n = w * h;\n const y = new Float32Array(n);\n for (let i = 0; i < n; i++) y[i] = 0.299 * guide[0][i] + 0.587 * guide[1][i] + 0.114 * guide[2][i];\n const g = new Float32Array(n);\n for (let yy = 0; yy < h; yy++) {\n for (let xx = 0; xx < w; xx++) {\n const gx = (y[yy * w + Math.min(w - 1, xx + 1)] - y[yy * w + Math.max(0, xx - 1)]) / 2;\n const gy = (y[Math.min(h - 1, yy + 1) * w + xx] - y[Math.max(0, yy - 1) * w + xx]) / 2;\n g[yy * w + xx] = Math.sqrt(gx * gx + gy * gy);\n }\n }\n const gm = greyMorphology(g, w, h, r, true);\n const hi = greyMorphology(y, w, h, r, true);\n const lo = greyMorphology(y, w, h, r, false);\n const out = new Float32Array(n);\n for (let i = 0; i < n; i++) out[i] = (hi[i] - lo[i]) / Math.max(gm[i], 1e-4);\n return out;\n}\n\n/**\n * Refines soft coverage `m` (`w × h`, 0..1) with `guide` (three 0..1 planes, required when\n * `radius > 0`): edge-aware re-estimation in a band around the edge, then smooth, feather,\n * contrast and shift edge, in that order.\n */\nexport function refineCoverage(\n guide: readonly [Float32Array, Float32Array, Float32Array] | null,\n m: Float32Array,\n w: number,\n h: number,\n params: RefineEdgeParams = {}\n): Float32Array {\n const p = normalizeRefineEdgeParams(params);\n let a: Float32Array = Float32Array.from(m);\n if (p.radius > 0 && guide) {\n const n = w * h;\n const boundary = new Uint8Array(n);\n let any = false;\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n const i = y * w + x;\n const v = m[i] >= 0.5;\n const diff =\n (x > 0 && m[i - 1] >= 0.5 !== v) ||\n (x + 1 < w && m[i + 1] >= 0.5 !== v) ||\n (y > 0 && m[i - w] >= 0.5 !== v) ||\n (y + 1 < h && m[i + w] >= 0.5 !== v);\n if (diff) {\n boundary[i] = 1;\n any = true;\n }\n }\n }\n if (any) {\n const dist = distanceTransform(boundary, w, h);\n const r = gfRadius(p);\n const q = guidedFilterColor(guide, m, w, h, r);\n const widths = p.smartRadius ? edgeWidth(guide, w, h, r) : null;\n for (let i = 0; i < n; i++) {\n const reff = widths ? Math.min(Math.max(p.radius, 1.5), Math.max(1.5, widths[i])) : p.radius;\n const wgt = Math.min(1, Math.max(0, reff + 1 - dist[i]));\n if (wgt > 0) {\n const qi = Math.min(1, Math.max(0, q[i]));\n a[i] = m[i] + (qi - m[i]) * wgt;\n }\n }\n }\n }\n const ss = smoothSigma(p);\n if (ss >= 0.3) {\n a = gaussianBlur(a, w, h, ss, 'clamp');\n const gain = 1 + ss;\n for (let i = 0; i < a.length; i++) a[i] = Math.min(1, Math.max(0, (a[i] - 0.5) * gain + 0.5));\n }\n a = gaussianBlur(a, w, h, featherSigma(p), 'clamp');\n if (p.contrast > 0) {\n const gain = 1 / (1 - (0.99 * p.contrast) / 100);\n for (let i = 0; i < a.length; i++) a[i] = Math.min(1, Math.max(0, (a[i] - 0.5) * gain + 0.5));\n }\n const amount = shiftAmount(p);\n if (Math.abs(amount) >= 1e-4) a = shiftCoverage(a, w, h, amount);\n return a;\n}\n\n/** Three 0..1 planes of a window of an RGBA buffer. */\nexport function guidePlanes(pixels: PixelBuffer, win?: CropBox): [Float32Array, Float32Array, Float32Array] {\n const box = win ?? { x: 0, y: 0, width: pixels.width, height: pixels.height };\n const n = box.width * box.height;\n const r = new Float32Array(n);\n const g = new Float32Array(n);\n const b = new Float32Array(n);\n const d = pixels.data;\n for (let y = 0; y < box.height; y++) {\n for (let x = 0; x < box.width; x++) {\n const i = y * box.width + x;\n const p = ((box.y + y) * pixels.width + box.x + x) * 4;\n r[i] = d[p] / 255;\n g[i] = d[p + 1] / 255;\n b[i] = d[p + 2] / 255;\n }\n }\n return [r, g, b];\n}\n\n/**\n * Refine Edge on a selection (or a coarse AI mask loaded as one) against `pixels` (the image,\n * same size). Work is confined to the mask's bounds grown by {@link refineEdgeHalo}, so a small\n * selection on a large image stays cheap.\n */\nexport function refineSelection(pixels: PixelBuffer | null, mask: SelectionMask, params: RefineEdgeParams = {}): SelectionMask {\n const p = normalizeRefineEdgeParams(params);\n if (pixels && (pixels.width !== mask.width || pixels.height !== mask.height)) {\n throw new Error('Refine Edge needs pixels the size of the selection');\n }\n if (!mask.bounds) return mask;\n const halo = refineEdgeHalo(p);\n // The guided filter reads 2r beyond the band; the window must hold that too.\n const x0 = Math.max(0, mask.bounds.x - halo);\n const y0 = Math.max(0, mask.bounds.y - halo);\n const x1 = Math.min(mask.width, mask.bounds.x + mask.bounds.width + halo);\n const y1 = Math.min(mask.height, mask.bounds.y + mask.bounds.height + halo);\n const ww = x1 - x0;\n const wh = y1 - y0;\n const m = new Float32Array(ww * wh);\n for (let y = 0; y < wh; y++) {\n const src = (y0 + y) * mask.width + x0;\n for (let x = 0; x < ww; x++) m[y * ww + x] = mask.data[src + x] / 255;\n }\n const guide = pixels && p.radius > 0 ? guidePlanes(pixels, { x: x0, y: y0, width: ww, height: wh }) : null;\n const refined = refineCoverage(guide, m, ww, wh, p);\n const out = new Uint8Array(mask.width * mask.height);\n for (let y = 0; y < wh; y++) {\n const dst = (y0 + y) * mask.width + x0;\n for (let x = 0; x < ww; x++) out[dst + x] = coverageToByte(refined[y * ww + x]);\n }\n return createSelectionMask(mask.width, mask.height, out);\n}\n","import {\n AdjustmentKind,\n AdjustmentLayer,\n AdjustmentParamsMap,\n Annotation,\n CreateAnnotationPayload,\n AspectRatio,\n CropBox,\n DepthMaskOptions,\n ExportOptions,\n ImageAdjustments,\n ImageDimensions,\n ImageEditorOptions,\n ImageEditorState,\n ImageEditorTool,\n ImageTransform,\n ImagePoint,\n SerializedImageEditorState,\n} from './types';\nimport { ImageEditorRenderer, RenderOptions } from './renderer';\nimport { clampCropToImage, isQuarterTurnSwapped } from './geometry';\nimport { LATEST_PROCESS_VERSION, LEGACY_PROCESS_VERSION, normalizeProcessVersion } from './color';\nimport { createAdjustmentLayer, normalizeAdjustmentLayer, normalizeAdjustmentLayers } from './adjustment-layers';\nimport type { BlendMode } from './blend';\nimport type { ImageHistogram } from './histogram';\nimport { applyAdjustments } from './filters';\nimport {\n combineSelections,\n createSelectionMask,\n deserializeSelection,\n fullSelection,\n invertSelection as invertSelectionMask,\n resizeSelection,\n selectionFromPixels,\n serializeSelection,\n type PixelBuffer,\n type SelectionChannel,\n type SelectionMask,\n type SelectionMode,\n} from './selection/mask';\nimport { ellipseSelection, polygonSelection, rectSelection, type ShapeSelectionOptions } from './selection/shapes';\nimport { colorRange, magicWand, type ColorRangeOptions, type ColorRangeSample, type MagicWandOptions } from './selection/wand';\nimport { modifySelection as modifySelectionMask, type SelectionModifyOp } from './selection/modify';\nimport { refineSelection as refineSelectionMask, type RefineEdgeParams } from './selection/refine';\nimport {\n decodeLayerMask,\n layerMaskFromSelection,\n updateLayerMaskProps,\n type LayerMaskProps,\n} from './selection/layer-mask';\nimport type { AdjustmentLayerMask } from './types';\n\n/** Latest serialized schema version (`2`: adjustment layers). */\nexport const IMAGE_EDITOR_SCHEMA_VERSION = 2 as const;\n\n/** Changes to an adjustment layer; `params` is merged into the current parameters. */\nexport interface AdjustmentLayerUpdate<K extends AdjustmentKind = AdjustmentKind> {\n params?: Partial<AdjustmentParamsMap[K]>;\n enabled?: boolean;\n opacity?: number;\n blend?: BlendMode;\n name?: string;\n /** A layer mask, or `null` to remove it. */\n mask?: AdjustmentLayerMask | null;\n}\n\n/** Options shared by the selection commands. */\nexport interface SelectionCommandOptions {\n /** How the result combines with the current selection (default `replace`). */\n mode?: SelectionMode;\n /** Feather the new shape by this many pixels before combining (default 0). */\n feather?: number;\n}\n\n/** Where the selection tools read colours from. */\nexport interface SampleOptions {\n /** Sample the adjusted image (base adjustments and layers) instead of the source pixels. */\n sampleMerged?: boolean;\n /** Pixels to use instead of reading the source image (natural size, RGBA). */\n pixels?: PixelBuffer;\n}\n\n/** A new adjustment layer: its kind plus optional initial values. */\nexport interface AdjustmentLayerInit<K extends AdjustmentKind = AdjustmentKind> extends AdjustmentLayerUpdate<K> {\n kind: K;\n id?: string;\n}\n\n/** The image a history entry was recorded against. */\ninterface SourceSnapshot {\n sourceUrl: string | null;\n element: CanvasImageSource | null;\n dimensions: ImageDimensions;\n}\n\n/**\n * Undo/redo entry: the serializable edit state plus the source image it applies to, so\n * AI edits that replace the image are restorable.\n */\ninterface HistoryEntry {\n state: SerializedImageEditorState;\n source: SourceSnapshot;\n /** Selections are immutable, so entries share them instead of encoding them. */\n selection: SelectionMask | null;\n}\n\nexport const DEFAULT_ADJUSTMENTS: ImageAdjustments = {\n brightness: 0,\n contrast: 0,\n saturation: 0,\n exposure: 0,\n temperature: 0,\n tint: 0,\n blur: 0,\n opacity: 1,\n process: LATEST_PROCESS_VERSION,\n};\n\n/**\n * Fills in defaults for stored adjustments. A stored object without `process` was saved before\n * process versions existed and keeps the legacy rendering.\n */\nexport function normalizeStoredAdjustments(stored: Partial<ImageAdjustments> | undefined | null): ImageAdjustments {\n if (!stored) return { ...DEFAULT_ADJUSTMENTS };\n const out: ImageAdjustments = {\n ...DEFAULT_ADJUSTMENTS,\n ...stored,\n process: normalizeProcessVersion(stored.process),\n };\n // Layers are deep-copied and cleaned; an empty or missing list is left out entirely.\n const layers = normalizeAdjustmentLayers(stored.layers);\n if (layers.length) out.layers = layers;\n else delete out.layers;\n return out;\n}\n\n/**\n * Brings a stored editor state of any schema version to the current shape. Version 1 (and a\n * missing version) has no adjustment layers; everything else is unchanged, so old states load\n * and render exactly as before.\n */\nexport function migrateSerializedImageEditorState(\n data: Partial<SerializedImageEditorState> & { version?: number }\n): SerializedImageEditorState {\n const adjustments = normalizeStoredAdjustments(data.adjustments);\n return {\n version: adjustments.layers?.length ? IMAGE_EDITOR_SCHEMA_VERSION : 1,\n crop: data.crop ? { ...data.crop } : null,\n transform: { ...DEFAULT_TRANSFORM, ...data.transform },\n adjustments: serializeAdjustments(adjustments),\n depthMask: {\n ...DEFAULT_DEPTH_MASK,\n ...data.depthMask,\n depthRange: [...(data.depthMask?.depthRange ?? DEFAULT_DEPTH_MASK.depthRange)] as [number, number],\n },\n annotations: JSON.parse(JSON.stringify(data.annotations ?? [])),\n ...(data.selection ? { selection: { ...data.selection } } : {}),\n };\n}\n\nexport const DEFAULT_TRANSFORM: ImageTransform = {\n rotate: 0,\n flipH: false,\n flipV: false,\n};\n\nexport const DEFAULT_DEPTH_MASK: DepthMaskOptions = {\n enabled: false,\n maskSource: null,\n mode: 'threshold',\n depthRange: [0, 255],\n softness: 10,\n invert: false,\n};\n\n/**\n * ImageEditorController manages the complete lifecycle, canvas rendering pipeline,\n * tool interaction states, undo/redo history, serialization, and image export.\n */\nexport class ImageEditorController {\n private state: ImageEditorState;\n private renderer: ImageEditorRenderer;\n private imageElement: CanvasImageSource | null = null;\n private listeners = new Set<(state: ImageEditorState) => void>();\n private histogramListeners = new Set<(histogram: ImageHistogram | null) => void>();\n private onStateChange?: (state: ImageEditorState) => void;\n\n // History stacks\n private undoStack: HistoryEntry[] = [];\n private redoStack: HistoryEntry[] = [];\n private maxHistoryDepth: number;\n private isApplyingHistory = false;\n private initialSnapshot: HistoryEntry;\n /** Pixels the selection tools sample (host-provided or read back from the source). */\n private samplePixels: PixelBuffer | null = null;\n private samplePixelsOverride = false;\n\n constructor(options: ImageEditorOptions = {}) {\n this.maxHistoryDepth = options.maxHistoryDepth ?? 50;\n this.onStateChange = options.onStateChange;\n this.renderer = new ImageEditorRenderer();\n this.renderer.onPreviewHistogram = (histogram) => {\n this.histogramListeners.forEach((l) => l(histogram));\n };\n\n const initialAdjustments = normalizeStoredAdjustments(options.initialState?.adjustments);\n\n const initialTransform: ImageTransform = {\n ...DEFAULT_TRANSFORM,\n ...options.initialState?.transform,\n };\n\n const initialDepthMask: DepthMaskOptions = {\n ...DEFAULT_DEPTH_MASK,\n ...options.initialState?.depthMask,\n };\n\n this.state = {\n sourceUrl: typeof options.image === 'string' ? options.image : null,\n imageDimensions: { width: 800, height: 600 },\n crop: options.initialState?.crop ?? null,\n transform: initialTransform,\n adjustments: initialAdjustments,\n depthMask: initialDepthMask,\n annotations: options.initialState?.annotations ?? [],\n selectedAnnotationId: null,\n activeTool: 'select',\n zoom: 1,\n pan: { x: 0, y: 0 },\n isOriginalCompared: false,\n selection: null,\n quickMask: false,\n };\n if (options.initialState?.selection) {\n try {\n this.state.selection = normalizeSelection(deserializeSelection(options.initialState.selection));\n } catch {\n // A damaged selection is dropped; the rest of the state still loads.\n }\n }\n\n if (options.image instanceof Object && 'width' in options.image) {\n this.imageElement = options.image as CanvasImageSource;\n this.state.sourceUrl = (options.image as any).src || null;\n this.state.imageDimensions = {\n width: (options.image as any).naturalWidth || (options.image as any).width || 800,\n height: (options.image as any).naturalHeight || (options.image as any).height || 600,\n };\n }\n\n this.initialSnapshot = this.captureHistoryEntry();\n\n if (typeof options.image === 'string') {\n this.loadImage(options.image);\n }\n }\n\n // --- Image Loading ---\n\n /**\n * Loads a new source image and makes it the baseline that `reset()` returns to.\n * Does not record history; use `applyInpaintedImage` / `applyBackgroundRemovedImage`\n * for undoable source replacement.\n */\n public async loadImage(src: string | HTMLImageElement): Promise<void> {\n // Keep the URL visible synchronously (UI bindings compare against it while loading).\n if (typeof src === 'string') this.state.sourceUrl = src;\n const source = await this.resolveSource(src);\n this.imageElement = source.element;\n this.state.sourceUrl = source.sourceUrl;\n this.state.imageDimensions = source.dimensions;\n this.samplePixels = null;\n this.dropMismatchedSelection();\n\n this.initialSnapshot = this.captureHistoryEntry();\n this.notify();\n }\n\n private async resolveSource(src: string | HTMLImageElement): Promise<SourceSnapshot> {\n if (typeof src === 'string') {\n try {\n const img = await this.renderer.imageCache.get(src);\n return {\n sourceUrl: src,\n element: img,\n dimensions: {\n width: img.naturalWidth || img.width || 800,\n height: img.naturalHeight || img.height || 600,\n },\n };\n } catch {\n // In SSR / non-DOM environments, retain current dimensions\n return { sourceUrl: src, element: null, dimensions: { ...this.state.imageDimensions } };\n }\n }\n return {\n sourceUrl: (src as any).src || null,\n element: src,\n dimensions: {\n width: src.naturalWidth || src.width || 800,\n height: src.naturalHeight || src.height || 600,\n },\n };\n }\n\n public getImageElement(): CanvasImageSource | null {\n return this.imageElement;\n }\n\n // --- State & Subscription ---\n\n public getState(): ImageEditorState {\n return this.state;\n }\n\n public subscribe(listener: (state: ImageEditorState) => void): () => void {\n this.listeners.add(listener);\n listener(this.state);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private notify(): void {\n const currentState = { ...this.state };\n this.onStateChange?.(currentState);\n this.listeners.forEach((l) => l(currentState));\n }\n\n // --- History (Undo / Redo / Reset) ---\n\n private captureHistoryEntry(): HistoryEntry {\n return {\n state: this.serializeState(),\n source: {\n sourceUrl: this.state.sourceUrl,\n element: this.imageElement,\n dimensions: { ...this.state.imageDimensions },\n },\n selection: this.state.selection ?? null,\n };\n }\n\n private restoreHistoryEntry(entry: HistoryEntry): void {\n this.applySerializedState(entry.state);\n this.state.selection = entry.selection;\n if (this.imageElement !== entry.source.element) this.samplePixels = null;\n this.imageElement = entry.source.element;\n this.state.sourceUrl = entry.source.sourceUrl;\n this.state.imageDimensions = { ...entry.source.dimensions };\n if (\n this.state.selectedAnnotationId &&\n !this.state.annotations.some((a) => a.id === this.state.selectedAnnotationId)\n ) {\n this.state.selectedAnnotationId = null;\n }\n }\n\n private recordHistory(): void {\n if (this.isApplyingHistory) return;\n this.undoStack.push(this.captureHistoryEntry());\n if (this.undoStack.length > this.maxHistoryDepth) {\n this.undoStack.shift();\n }\n this.redoStack = [];\n }\n\n public get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n public get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n public undo(): boolean {\n if (!this.canUndo) return false;\n this.isApplyingHistory = true;\n this.redoStack.push(this.captureHistoryEntry());\n\n const prev = this.undoStack.pop()!;\n this.restoreHistoryEntry(prev);\n this.isApplyingHistory = false;\n this.notify();\n return true;\n }\n\n public redo(): boolean {\n if (!this.canRedo) return false;\n this.isApplyingHistory = true;\n this.undoStack.push(this.captureHistoryEntry());\n\n const next = this.redoStack.pop()!;\n this.restoreHistoryEntry(next);\n this.isApplyingHistory = false;\n this.notify();\n return true;\n }\n\n public reset(): void {\n this.recordHistory();\n this.restoreHistoryEntry(this.initialSnapshot);\n this.state.zoom = 1;\n this.state.pan = { x: 0, y: 0 };\n this.state.activeTool = 'select';\n this.state.selectedAnnotationId = null;\n this.notify();\n }\n\n // --- Active Tool ---\n\n public setTool(tool: ImageEditorTool): void {\n if (this.state.activeTool === tool) return;\n this.state.activeTool = tool;\n if (tool !== 'select') {\n this.state.selectedAnnotationId = null;\n }\n // If switching to crop tool and no crop is defined, initialize crop to full image\n if (tool === 'crop' && !this.state.crop) {\n this.state.crop = {\n x: 0,\n y: 0,\n width: this.state.imageDimensions.width,\n height: this.state.imageDimensions.height,\n };\n }\n this.notify();\n }\n\n // --- Crop ---\n\n public setCrop(crop: CropBox | null, addToHistory = true): void {\n if (addToHistory) {\n this.recordHistory();\n }\n this.state.crop = crop;\n this.notify();\n }\n\n public applyCropPreset(ratio: AspectRatio): void {\n this.recordHistory();\n const { width, height } = this.state.imageDimensions;\n // `ratio` is the on-screen aspect; the crop box lives in natural image space.\n if (ratio && isQuarterTurnSwapped(this.state.transform)) {\n ratio = 1 / ratio;\n }\n if (!ratio) {\n // Freeform: full image\n this.state.crop = { x: 0, y: 0, width, height };\n } else {\n let targetW = width;\n let targetH = targetW / ratio;\n\n if (targetH > height) {\n targetH = height;\n targetW = targetH * ratio;\n }\n\n const x = Math.max(0, Math.round((width - targetW) / 2));\n const y = Math.max(0, Math.round((height - targetH) / 2));\n this.state.crop = {\n x,\n y,\n width: Math.round(targetW),\n height: Math.round(targetH),\n };\n }\n this.notify();\n }\n\n public resetCrop(): void {\n this.recordHistory();\n this.state.crop = null;\n this.notify();\n }\n\n // --- Transformations (Rotate / Flip) ---\n\n public rotate(degrees: number): void {\n this.recordHistory();\n const current = this.state.transform.rotate;\n this.state.transform = { ...this.state.transform, rotate: (current + degrees) % 360 };\n this.notify();\n }\n\n public setRotation(degrees: number): void {\n this.recordHistory();\n this.state.transform = { ...this.state.transform, rotate: degrees % 360 };\n this.notify();\n }\n\n public flipHorizontal(): void {\n this.recordHistory();\n this.state.transform = { ...this.state.transform, flipH: !this.state.transform.flipH };\n this.notify();\n }\n\n public flipVertical(): void {\n this.recordHistory();\n this.state.transform = { ...this.state.transform, flipV: !this.state.transform.flipV };\n this.notify();\n }\n\n // --- Adjustments ---\n\n public setAdjustments(partial: Partial<ImageAdjustments>, commitToHistory = true): void {\n if (commitToHistory) {\n this.recordHistory();\n }\n const next: ImageAdjustments = {\n ...this.state.adjustments,\n ...partial,\n };\n if ('layers' in partial) {\n const layers = normalizeAdjustmentLayers(partial.layers);\n if (layers.length) next.layers = layers;\n else delete next.layers;\n }\n this.state.adjustments = next;\n this.notify();\n }\n\n /** True when the adjustments use an older rendering process than {@link LATEST_PROCESS_VERSION}. */\n public get isProcessOutdated(): boolean {\n return normalizeProcessVersion(this.state.adjustments.process) < LATEST_PROCESS_VERSION;\n }\n\n /**\n * Update to Current Process: re-interprets the current adjustment values with the latest\n * rendering process (one undo step). Returns false when already current.\n */\n public upgradeProcess(): boolean {\n if (!this.isProcessOutdated) return false;\n this.setAdjustments({ process: LATEST_PROCESS_VERSION });\n return true;\n }\n\n /** Resets the base sliders (latest process). Adjustment layers are kept; see `clearAdjustmentLayers`. */\n public resetAdjustments(): void {\n this.recordHistory();\n const layers = this.state.adjustments.layers;\n this.state.adjustments = { ...DEFAULT_ADJUSTMENTS };\n if (layers?.length) this.state.adjustments.layers = layers;\n this.notify();\n }\n\n // --- Adjustment layers ---\n\n /** The adjustment layers, bottom (first) to top (last). */\n public getAdjustmentLayers(): AdjustmentLayer[] {\n return this.state.adjustments.layers ?? [];\n }\n\n public getAdjustmentLayer(id: string): AdjustmentLayer | undefined {\n return this.getAdjustmentLayers().find((l) => l.id === id);\n }\n\n private setLayers(layers: AdjustmentLayer[]): void {\n const next: ImageAdjustments = { ...this.state.adjustments };\n if (layers.length) next.layers = layers;\n else delete next.layers;\n this.state.adjustments = next;\n }\n\n /**\n * Adds an adjustment layer on top (or at `index`, 0 = bottom) as one undo step and returns\n * its id. `kind` alone gives neutral parameters.\n */\n public addAdjustmentLayer<K extends AdjustmentKind>(init: K | AdjustmentLayerInit<K>, index?: number): string {\n const spec: AdjustmentLayerInit<K> = typeof init === 'string' ? { kind: init } : init;\n const layers = [...this.getAdjustmentLayers()];\n const layer = createAdjustmentLayer(spec.kind, {\n id: spec.id && !layers.some((l) => l.id === spec.id) ? spec.id : undefined,\n name: spec.name,\n params: spec.params,\n enabled: spec.enabled,\n opacity: spec.opacity,\n blend: spec.blend,\n mask: spec.mask ?? undefined,\n });\n this.recordHistory();\n const at = index === undefined ? layers.length : Math.max(0, Math.min(layers.length, Math.round(index)));\n layers.splice(at, 0, layer);\n this.setLayers(layers);\n this.notify();\n return layer.id;\n }\n\n /**\n * Updates a layer (`params` merged into the current ones, then normalised). Pass\n * `commitToHistory = false` for the moves of a drag after recording its start once.\n * Returns false for an unknown id.\n */\n public updateAdjustmentLayer(id: string, update: AdjustmentLayerUpdate, commitToHistory = true): boolean {\n const layers = this.getAdjustmentLayers();\n const index = layers.findIndex((l) => l.id === id);\n if (index === -1) return false;\n const current = layers[index];\n const merged = normalizeAdjustmentLayer({\n ...current,\n ...(update.enabled !== undefined ? { enabled: update.enabled } : {}),\n ...(update.opacity !== undefined ? { opacity: update.opacity } : {}),\n ...(update.blend !== undefined ? { blend: update.blend } : {}),\n ...(update.name !== undefined ? { name: update.name } : {}),\n ...(update.mask !== undefined ? { mask: update.mask ?? undefined } : {}),\n params: { ...current.params, ...(update.params ?? {}) },\n });\n if (!merged) return false;\n if (commitToHistory) this.recordHistory();\n const next = [...layers];\n next[index] = merged;\n this.setLayers(next);\n this.notify();\n return true;\n }\n\n /** Removes a layer as one undo step. Returns false for an unknown id. */\n public removeAdjustmentLayer(id: string): boolean {\n const layers = this.getAdjustmentLayers();\n if (!layers.some((l) => l.id === id)) return false;\n this.recordHistory();\n this.setLayers(layers.filter((l) => l.id !== id));\n this.notify();\n return true;\n }\n\n /** Moves a layer to `toIndex` (0 = bottom) as one undo step. Returns false if nothing moved. */\n public moveAdjustmentLayer(id: string, toIndex: number): boolean {\n const layers = [...this.getAdjustmentLayers()];\n const from = layers.findIndex((l) => l.id === id);\n if (from === -1) return false;\n const to = Math.max(0, Math.min(layers.length - 1, Math.round(toIndex)));\n if (to === from) return false;\n this.recordHistory();\n const [layer] = layers.splice(from, 1);\n layers.splice(to, 0, layer);\n this.setLayers(layers);\n this.notify();\n return true;\n }\n\n /** Shows or hides a layer (flips it without `enabled`) as one undo step. */\n public toggleAdjustmentLayer(id: string, enabled?: boolean): boolean {\n const layer = this.getAdjustmentLayer(id);\n if (!layer) return false;\n const next = enabled ?? !layer.enabled;\n if (next === layer.enabled) return false;\n return this.updateAdjustmentLayer(id, { enabled: next });\n }\n\n /** Removes every adjustment layer as one undo step. */\n public clearAdjustmentLayers(): void {\n if (!this.getAdjustmentLayers().length) return;\n this.recordHistory();\n this.setLayers([]);\n this.notify();\n }\n\n // --- Selection ---\n\n /** The active selection, or `null`. */\n public getSelection(): SelectionMask | null {\n return this.state.selection ?? null;\n }\n\n public get hasSelection(): boolean {\n return Boolean(this.state.selection?.bounds);\n }\n\n private get naturalSize(): { width: number; height: number } {\n return {\n width: Math.max(1, Math.round(this.state.imageDimensions.width)),\n height: Math.max(1, Math.round(this.state.imageDimensions.height)),\n };\n }\n\n private dropMismatchedSelection(): void {\n const sel = this.state.selection;\n if (!sel) return;\n const { width, height } = this.naturalSize;\n if (sel.width !== width || sel.height !== height) this.state.selection = null;\n }\n\n /**\n * Replaces the selection, or combines `mask` with it by `mode`, as one undo step. A mask of a\n * different size (e.g. an AI segmentation at another resolution) is resampled to the image.\n * Returns false when nothing changed.\n */\n public setSelection(mask: SelectionMask | null, mode: SelectionMode = 'replace'): boolean {\n const { width, height } = this.naturalSize;\n let next: SelectionMask | null = null;\n if (mask) {\n const sized = mask.width === width && mask.height === height ? mask : resizeSelection(mask, width, height);\n next = combineSelections(this.state.selection, sized, mode);\n } else if (mode !== 'replace') {\n return false;\n }\n const prev = normalizeSelection(this.state.selection ?? null);\n if (prev === next || (prev && next && sameSelection(prev, next))) return false;\n this.recordHistory();\n this.state.selection = next;\n this.notify();\n return true;\n }\n\n /** Select › All. */\n public selectAll(): boolean {\n const { width, height } = this.naturalSize;\n return this.setSelection(fullSelection(width, height));\n }\n\n /** Select › Deselect. */\n public deselect(): boolean {\n return this.setSelection(null);\n }\n\n /** Select › Inverse (with nothing selected, selects everything). */\n public invertSelection(): boolean {\n const { width, height } = this.naturalSize;\n const current = this.state.selection ?? createSelectionMask(width, height);\n return this.setSelection(invertSelectionMask(current));\n }\n\n private shapeCommand(mask: SelectionMask, options: SelectionCommandOptions): boolean {\n const shaped = options.feather && options.feather > 0 ? modifySelectionMask(mask, 'feather', options.feather) : mask;\n return this.setSelection(shaped, options.mode ?? 'replace');\n }\n\n /** Rectangular marquee in natural image pixels. */\n public selectRect(rect: CropBox, options: SelectionCommandOptions & ShapeSelectionOptions = {}): boolean {\n const { width, height } = this.naturalSize;\n return this.shapeCommand(rectSelection(width, height, rect, options), options);\n }\n\n /** Elliptical marquee inscribed in `rect`. */\n public selectEllipse(rect: CropBox, options: SelectionCommandOptions & ShapeSelectionOptions = {}): boolean {\n const { width, height } = this.naturalSize;\n return this.shapeCommand(ellipseSelection(width, height, rect, options), options);\n }\n\n /** Lasso / polygonal lasso. */\n public selectPolygon(points: ImagePoint[], options: SelectionCommandOptions & ShapeSelectionOptions = {}): boolean {\n const { width, height } = this.naturalSize;\n return this.shapeCommand(polygonSelection(width, height, points, options), options);\n }\n\n /**\n * Supplies the pixels the selection tools sample (natural size RGBA), e.g. decoded in a worker\n * or in a test; `null` goes back to reading the source image. A new source image clears it.\n */\n public setSamplePixels(pixels: PixelBuffer | null): void {\n this.samplePixels = pixels;\n this.samplePixelsOverride = pixels !== null;\n }\n\n /**\n * The pixels the selection tools sample: the source image at natural size, or with\n * `sampleMerged` the source after the base adjustments and adjustment layers (no crop,\n * rotation or annotations). `null` without pixel access (no DOM, tainted canvas).\n */\n public async getSamplePixels(options: SampleOptions = {}): Promise<PixelBuffer | null> {\n const { width, height } = this.naturalSize;\n let base = options.pixels ?? this.samplePixels;\n if (!base) {\n try {\n const canvas = await this.renderSource();\n const ctx = canvas.getContext('2d');\n const data = ctx?.getImageData?.(0, 0, width, height);\n if (data && data.data && data.data.length >= width * height * 4) {\n base = { width, height, data: data.data };\n this.samplePixels = base;\n this.samplePixelsOverride = false;\n }\n } catch {\n base = null;\n }\n }\n if (!base) return null;\n if (base.width !== width || base.height !== height) {\n if (!this.samplePixelsOverride && !options.pixels) this.samplePixels = null;\n return null;\n }\n if (!options.sampleMerged) return base;\n const copy = { width: base.width, height: base.height, data: new Uint8ClampedArray(base.data as ArrayLike<number>) };\n applyAdjustments(copy as unknown as ImageData, this.state.adjustments);\n return copy;\n }\n\n private async requirePixels(options: SampleOptions): Promise<PixelBuffer> {\n const pixels = await this.getSamplePixels(options);\n if (!pixels) throw new Error('The image pixels are not available (no canvas access); pass `pixels`.');\n return pixels;\n }\n\n /**\n * Magic wand at `point` (natural image pixels). Resolves to the resulting selection (null when\n * nothing is selected).\n */\n public async magicWand(\n point: ImagePoint,\n options: MagicWandOptions & SelectionCommandOptions & SampleOptions = {}\n ): Promise<SelectionMask | null> {\n const pixels = await this.requirePixels(options);\n this.shapeCommand(magicWand(pixels, point, options), options);\n return this.getSelection();\n }\n\n /** Select › Color Range with colour samples (`#rrggbb` or `[r, g, b]`, optionally where they were picked). */\n public async selectColorRange(\n samples: ColorRangeSample[],\n options: ColorRangeOptions & SelectionCommandOptions & SampleOptions = {}\n ): Promise<SelectionMask | null> {\n const pixels = await this.requirePixels(options);\n this.shapeCommand(colorRange(pixels, samples, options), options);\n return this.getSelection();\n }\n\n /** Select › Modify: grow, shrink, feather, border or smooth by `radius` pixels (one undo step). */\n public modifySelection(op: SelectionModifyOp, radius: number): boolean {\n const sel = this.state.selection;\n if (!sel?.bounds) return false;\n return this.setSelection(modifySelectionMask(sel, op, radius));\n }\n\n /**\n * Refine Edge: snaps the selection (e.g. a coarse AI mask loaded with `loadSelectionFromImage`)\n * to the image's edges with a guided filter, then smooth / feather / contrast / shift edge.\n */\n public async refineSelection(params: RefineEdgeParams, options: SampleOptions = {}): Promise<boolean> {\n const sel = this.state.selection;\n if (!sel?.bounds) return false;\n const pixels = (params.radius ?? 0) > 0 ? await this.requirePixels(options) : null;\n return this.setSelection(refineSelectionMask(pixels, sel, params));\n }\n\n /**\n * Loads a selection from a mask image (an AI segmentation, a saved mask): a data URL / URL or\n * RGBA pixels, by luminance (white = selected) or a channel. Any size; it is resampled.\n */\n public async loadSelectionFromImage(\n source: string | PixelBuffer,\n options: { channel?: SelectionChannel; invert?: boolean; threshold?: number; mode?: SelectionMode } = {}\n ): Promise<SelectionMask | null> {\n let pixels: PixelBuffer;\n if (typeof source === 'string') {\n const img = await this.renderer.imageCache.get(source);\n const w = img.naturalWidth || img.width;\n const h = img.naturalHeight || img.height;\n const canvas = this.renderer.createCanvas(w, h);\n const ctx = canvas.getContext('2d');\n if (ctx) ctx.drawImage(img, 0, 0, w, h);\n const data = ctx?.getImageData?.(0, 0, w, h);\n if (!data) throw new Error('The mask image pixels are not available (no canvas access); pass pixels.');\n pixels = { width: w, height: h, data: data.data };\n } else {\n pixels = source;\n }\n this.setSelection(selectionFromPixels(pixels, options), options.mode ?? 'replace');\n return this.getSelection();\n }\n\n /** Quick Mask view (tints the unselected area). View state: no undo step. */\n public setQuickMask(on: boolean): void {\n if (Boolean(this.state.quickMask) === on) return;\n this.state.quickMask = on;\n this.notify();\n }\n\n // --- Layer masks ---\n\n /**\n * Adds the selection as the layer's mask (Reveal Selection), replacing any mask, as one undo\n * step. Without a selection, returns false.\n */\n public applySelectionAsLayerMask(layerId: string, props: LayerMaskProps = {}): boolean {\n const sel = this.state.selection;\n if (!sel?.bounds || !this.getAdjustmentLayer(layerId)) return false;\n return this.updateAdjustmentLayer(layerId, { mask: layerMaskFromSelection(sel, props) });\n }\n\n /** Sets (from a selection-shaped mask) or removes (`null`) a layer's mask as one undo step. */\n public setAdjustmentLayerMask(layerId: string, mask: SelectionMask | null, props: LayerMaskProps = {}): boolean {\n return this.updateAdjustmentLayer(layerId, { mask: mask ? layerMaskFromSelection(mask, props) : null });\n }\n\n /** Changes a layer mask's density (0..1), feather (px) or enabled flag; the mask pixels are kept. */\n public setAdjustmentLayerMaskProps(layerId: string, props: LayerMaskProps, commitToHistory = true): boolean {\n const layer = this.getAdjustmentLayer(layerId);\n if (!layer?.mask) return false;\n return this.updateAdjustmentLayer(layerId, { mask: updateLayerMaskProps(layer.mask, props) }, commitToHistory);\n }\n\n /** Load Selection from a layer mask (its pixels; density and feather are not applied). */\n public selectionFromLayerMask(layerId: string, mode: SelectionMode = 'replace'): boolean {\n const layer = this.getAdjustmentLayer(layerId);\n const sel = layer?.mask ? decodeLayerMask(layer.mask) : null;\n if (!sel) return false;\n return this.setSelection(sel, mode);\n }\n\n // --- Histogram ---\n\n /**\n * Histogram of the last rendered preview (after adjustments and layers, before annotations),\n * or `null` before the first render or without canvas pixel access.\n */\n public getHistogram(): ImageHistogram | null {\n return this.renderer.previewHistogram;\n }\n\n /** Calls `listener` now and whenever a render produces a new preview histogram. */\n public subscribeHistogram(listener: (histogram: ImageHistogram | null) => void): () => void {\n this.histogramListeners.add(listener);\n listener(this.renderer.previewHistogram);\n return () => {\n this.histogramListeners.delete(listener);\n };\n }\n\n // --- Depth Masking (Gleamforge) ---\n\n public setDepthMask(partial: Partial<DepthMaskOptions>): void {\n this.recordHistory();\n this.state.depthMask = {\n ...this.state.depthMask,\n ...partial,\n };\n this.notify();\n }\n\n public resetDepthMask(): void {\n this.recordHistory();\n this.state.depthMask = { ...DEFAULT_DEPTH_MASK };\n this.notify();\n }\n\n // --- Annotations & Layers ---\n\n public addAnnotation(annotation: CreateAnnotationPayload): string {\n this.recordHistory();\n const id = `ann_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;\n const fullAnnotation = { ...annotation, id } as Annotation;\n this.state.annotations = [...this.state.annotations, fullAnnotation];\n this.state.selectedAnnotationId = id;\n this.notify();\n return id;\n }\n\n public updateAnnotation(id: string, partial: Partial<Annotation>, commitToHistory = true): void {\n if (commitToHistory) {\n this.recordHistory();\n }\n this.state.annotations = this.state.annotations.map((ann) => {\n if (ann.id === id) {\n return { ...ann, ...partial } as Annotation;\n }\n return ann;\n });\n this.notify();\n }\n\n public removeAnnotation(id: string): void {\n this.recordHistory();\n this.state.annotations = this.state.annotations.filter((ann) => ann.id !== id);\n if (this.state.selectedAnnotationId === id) {\n this.state.selectedAnnotationId = null;\n }\n this.notify();\n }\n\n public clearAnnotations(): void {\n this.recordHistory();\n this.state.annotations = [];\n this.state.selectedAnnotationId = null;\n this.notify();\n }\n\n public selectAnnotation(id: string | null): void {\n this.state.selectedAnnotationId = id;\n this.notify();\n }\n\n // --- Zoom & Pan ---\n\n public setZoom(zoom: number): void {\n this.state.zoom = Math.max(0.1, Math.min(10, zoom));\n this.notify();\n }\n\n public zoomIn(factor = 1.2): void {\n this.setZoom(this.state.zoom * factor);\n }\n\n public zoomOut(factor = 1.2): void {\n this.setZoom(this.state.zoom / factor);\n }\n\n public resetZoom(): void {\n this.state.zoom = 1;\n this.state.pan = { x: 0, y: 0 };\n this.notify();\n }\n\n public setPan(pan: ImagePoint): void {\n this.state.pan = pan;\n this.notify();\n }\n\n public setComparing(comparing: boolean): void {\n if (this.state.isOriginalCompared === comparing) return;\n this.state.isOriginalCompared = comparing;\n this.notify();\n }\n\n // --- Rendering & Export ---\n\n public async render(targetCanvas: HTMLCanvasElement, options?: RenderOptions): Promise<void> {\n const source = this.imageElement || this.state.sourceUrl;\n if (!source) return;\n try {\n await this.renderer.renderToCanvas(targetCanvas, source, this.state, options);\n } catch {\n // In non-DOM or test mock environments without image loading, safely ignore\n }\n }\n\n public async renderExport(options?: ExportOptions): Promise<HTMLCanvasElement> {\n const source = this.imageElement || this.state.sourceUrl;\n if (!source) {\n return this.renderer.createCanvas(1, 1);\n }\n return this.renderer.renderExport(source, this.state, options);\n }\n\n public async toDataURL(options: ExportOptions = {}): Promise<string> {\n const canvas = await this.renderExport(options);\n const format = options.format || 'image/png';\n const quality = options.quality ?? 0.92;\n return canvas.toDataURL(format, quality);\n }\n\n public async toBlob(options: ExportOptions = {}): Promise<Blob> {\n const canvas = await this.renderExport(options);\n const format = options.format || 'image/png';\n const quality = options.quality ?? 0.92;\n\n return new Promise((resolve, reject) => {\n if (canvas.toBlob) {\n canvas.toBlob((blob) => {\n if (blob) resolve(blob);\n else reject(new Error('Failed to create Blob from canvas'));\n }, format, quality);\n } else {\n // Fallback for environments lacking canvas.toBlob\n try {\n const dataUrl = canvas.toDataURL(format, quality);\n const parts = dataUrl.split(',');\n const byteStr = atob(parts[1]);\n const ab = new ArrayBuffer(byteStr.length);\n const ia = new Uint8Array(ab);\n for (let i = 0; i < byteStr.length; i++) {\n ia[i] = byteStr.charCodeAt(i);\n }\n resolve(new Blob([ab], { type: format }));\n } catch (err) {\n reject(err);\n }\n }\n });\n }\n\n // --- AI Masking & Transformation Helpers ---\n\n public async renderMask(options?: { useAnnotations?: boolean; useCrop?: boolean; useSelection?: boolean }): Promise<HTMLCanvasElement> {\n return this.renderer.renderMask(this.state, options);\n }\n\n public async toMaskDataURL(options?: { useAnnotations?: boolean; useCrop?: boolean; useSelection?: boolean }): Promise<string> {\n const canvas = await this.renderMask(options);\n return canvas.toDataURL('image/png');\n }\n\n /**\n * Renders the current source image at natural size with no crop, rotation, flip,\n * adjustments or annotations. This is the image that `toMaskDataURL()` is aligned with\n * and the space that `applyInpaintedImage` / `applyBackgroundRemovedImage` expect back.\n */\n public async renderSource(): Promise<HTMLCanvasElement> {\n const { width, height } = this.state.imageDimensions;\n const canvas = this.renderer.createCanvas(width, height);\n const source = this.imageElement || this.state.sourceUrl;\n const ctx = canvas.getContext('2d');\n if (!ctx || !source) return canvas;\n const img = typeof source === 'string' ? await this.renderer.imageCache.get(source) : source;\n ctx.drawImage(img, 0, 0, width, height);\n return canvas;\n }\n\n public async toSourceDataURL(options: Pick<ExportOptions, 'format' | 'quality'> = {}): Promise<string> {\n const canvas = await this.renderSource();\n return canvas.toDataURL(options.format || 'image/png', options.quality ?? 0.92);\n }\n\n /**\n * Replaces the source image with an inpainted result (natural image space, see\n * `toSourceDataURL`) and clears the mask annotations, as ONE undoable step.\n */\n public async applyInpaintedImage(newDataUrl: string): Promise<void> {\n await this.replaceSource(newDataUrl, true);\n }\n\n /**\n * Replaces the source image with a background-removed result as ONE undoable step.\n * Crop and annotations are kept (rescaled if the new image has different dimensions).\n */\n public async applyBackgroundRemovedImage(newDataUrl: string): Promise<void> {\n await this.replaceSource(newDataUrl, false);\n }\n\n private async replaceSource(src: string, clearAnnotations: boolean): Promise<void> {\n const next = await this.resolveSource(src);\n this.recordHistory();\n\n const prev = this.state.imageDimensions;\n const sx = next.dimensions.width / (prev.width || next.dimensions.width);\n const sy = next.dimensions.height / (prev.height || next.dimensions.height);\n\n this.imageElement = next.element;\n this.state.sourceUrl = next.sourceUrl;\n this.state.imageDimensions = next.dimensions;\n this.samplePixels = null;\n if (this.state.selection && (sx !== 1 || sy !== 1)) {\n this.state.selection = normalizeSelection(\n resizeSelection(this.state.selection, Math.round(next.dimensions.width), Math.round(next.dimensions.height))\n );\n }\n\n if (sx !== 1 || sy !== 1) {\n if (this.state.crop) {\n this.state.crop = clampCropToImage(\n {\n x: Math.round(this.state.crop.x * sx),\n y: Math.round(this.state.crop.y * sy),\n width: Math.round(this.state.crop.width * sx),\n height: Math.round(this.state.crop.height * sy),\n },\n next.dimensions.width,\n next.dimensions.height\n );\n }\n this.state.annotations = this.state.annotations.map((ann) => scaleAnnotation(ann, sx, sy));\n }\n\n if (clearAnnotations) {\n this.state.annotations = [];\n this.state.selectedAnnotationId = null;\n }\n this.notify();\n }\n\n // --- Serialization ---\n\n /** The serializable state; `selection` is included (run-length encoded) only when something is selected. */\n public toJSON(): SerializedImageEditorState {\n const out = this.serializeState();\n if (this.state.selection?.bounds) out.selection = serializeSelection(this.state.selection);\n return out;\n }\n\n public loadJSON(data: SerializedImageEditorState): void {\n this.recordHistory();\n this.applySerializedState(migrateSerializedImageEditorState(data));\n let selection: SelectionMask | null = null;\n if (data.selection) {\n try {\n selection = normalizeSelection(deserializeSelection(data.selection));\n } catch {\n selection = null;\n }\n }\n this.state.selection = selection;\n this.dropMismatchedSelection();\n this.notify();\n }\n\n private serializeState(): SerializedImageEditorState {\n return {\n // States without adjustment layers keep schema 1, so they round-trip unchanged.\n version: this.state.adjustments.layers?.length ? IMAGE_EDITOR_SCHEMA_VERSION : 1,\n crop: this.state.crop ? { ...this.state.crop } : null,\n transform: { ...this.state.transform },\n adjustments: serializeAdjustments(this.state.adjustments),\n depthMask: {\n ...this.state.depthMask,\n depthRange: [...this.state.depthMask.depthRange] as [number, number],\n },\n annotations: JSON.parse(JSON.stringify(this.state.annotations)),\n };\n }\n\n private applySerializedState(data: SerializedImageEditorState): void {\n this.state.crop = data.crop ? { ...data.crop } : null;\n this.state.transform = { ...data.transform };\n this.state.adjustments = normalizeStoredAdjustments(data.adjustments);\n this.state.depthMask = {\n ...data.depthMask,\n depthRange: [...data.depthMask.depthRange] as [number, number],\n };\n this.state.annotations = JSON.parse(JSON.stringify(data.annotations || []));\n }\n}\n\n/**\n * Legacy-process adjustments are saved without `process` (and without an unused zero `tint`), so\n * they serialize exactly as they did before process versions existed.\n */\nfunction serializeAdjustments(adjustments: ImageAdjustments): ImageAdjustments {\n const out: ImageAdjustments = { ...adjustments };\n if (out.layers?.length) out.layers = JSON.parse(JSON.stringify(out.layers));\n else delete out.layers;\n if (normalizeProcessVersion(out.process) === LEGACY_PROCESS_VERSION) {\n delete out.process;\n if (!out.tint) delete out.tint;\n }\n return out;\n}\n\n/** `null` for an empty selection, so \"nothing selected\" has one representation. */\nfunction normalizeSelection(mask: SelectionMask | null): SelectionMask | null {\n return mask?.bounds ? mask : null;\n}\n\nfunction sameSelection(a: SelectionMask, b: SelectionMask): boolean {\n if (a.width !== b.width || a.height !== b.height) return false;\n const x = a.data;\n const y = b.data;\n for (let i = 0; i < x.length; i++) if (x[i] !== y[i]) return false;\n return true;\n}\n\n/** Scales an annotation's geometry from one image size to another. */\nfunction scaleAnnotation(ann: Annotation, sx: number, sy: number): Annotation {\n const k = Math.sqrt(Math.abs(sx * sy));\n const base = { ...ann, x: ann.x * sx, y: ann.y * sy } as Annotation;\n switch (base.type) {\n case 'pen':\n return { ...base, points: base.points.map((p) => ({ x: p.x * sx, y: p.y * sy })), strokeWidth: base.strokeWidth * k };\n case 'rect':\n return { ...base, width: base.width * sx, height: base.height * sy, strokeWidth: base.strokeWidth * k };\n case 'image':\n return { ...base, width: base.width * sx, height: base.height * sy };\n case 'circle':\n return { ...base, radiusX: base.radiusX * sx, radiusY: base.radiusY * sy, strokeWidth: base.strokeWidth * k };\n case 'arrow':\n case 'line':\n return { ...base, endX: base.endX * sx, endY: base.endY * sy, strokeWidth: base.strokeWidth * k };\n case 'text':\n return { ...base, fontSize: base.fontSize * k };\n }\n}\n","import {\n loadDocument,\n type JsonObject,\n type LoadReport,\n type MigrationStep,\n} from '../persistence/migrate';\nimport { DEFAULT_DEPTH_MASK, DEFAULT_TRANSFORM, normalizeStoredAdjustments } from './controller';\nimport type {\n Annotation,\n CropBox,\n DepthMaskOptions,\n ImageAdjustments,\n ImageTransform,\n SerializedImageEditorState,\n} from './types';\nimport { deserializeSelection } from './selection/mask';\n\n/** The `version` that `ImageEditorController.toJSON()` writes. */\nexport const IMAGE_EDITOR_STATE_VERSION = 1;\n\n/**\n * Migration steps for `SerializedImageEditorState`, keyed by the version they\n * start from. Empty while only version 1 exists.\n */\nexport const imageEditorStateMigrations: Record<number, MigrationStep> = {};\n\nexport interface ImageEditorDocumentLoad {\n /** State to pass to `loadJSON` / `initialState`. */\n state: SerializedImageEditorState;\n report: LoadReport;\n /** Top-level keys this build does not know; spread them into the saved JSON to keep them. */\n unknown: JsonObject;\n}\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\nconst isNumber = (value: unknown): value is number =>\n typeof value === 'number' && Number.isFinite(value);\n\nfunction expectObject(value: unknown, what: string): Record<string, unknown> {\n if (!isObject(value)) throw new Error(`${what} must be an object`);\n return value;\n}\n\nfunction checkFields(\n value: Record<string, unknown>,\n types: Record<string, (v: unknown) => boolean>,\n what: string,\n) {\n for (const [field, ok] of Object.entries(types)) {\n if (field in value && value[field] !== undefined && !ok(value[field])) {\n throw new Error(`${what}.${field} has an invalid value`);\n }\n }\n}\n\nconst isBoolean = (v: unknown) => typeof v === 'boolean';\n\nfunction parseCrop(value: unknown): CropBox | null {\n if (value === null) return null;\n const crop = expectObject(value, 'crop');\n for (const field of ['x', 'y', 'width', 'height'] as const) {\n if (!isNumber(crop[field])) throw new Error(`crop.${field} must be a number`);\n }\n return { ...(crop as unknown as CropBox) };\n}\n\nfunction parseTransform(value: unknown): ImageTransform {\n const transform = expectObject(value, 'transform');\n checkFields(transform, { rotate: isNumber, flipH: isBoolean, flipV: isBoolean }, 'transform');\n return { ...DEFAULT_TRANSFORM, ...(transform as Partial<ImageTransform>) };\n}\n\nconst ADJUSTMENT_NUMBERS = [\n 'brightness',\n 'contrast',\n 'saturation',\n 'exposure',\n 'temperature',\n 'tint',\n 'blur',\n 'opacity',\n] as const;\n\nfunction parseAdjustments(value: unknown): ImageAdjustments {\n const adjustments = expectObject(value, 'adjustments');\n checkFields(\n adjustments,\n {\n ...Object.fromEntries(ADJUSTMENT_NUMBERS.map((k) => [k, isNumber])),\n process: (v) => v === 1 || v === 2,\n },\n 'adjustments',\n );\n // Kept as stored: `loadJSON` fills defaults and keeps a missing `process` legacy.\n return { ...(adjustments as unknown as ImageAdjustments) };\n}\n\nfunction parseDepthMask(value: unknown): DepthMaskOptions {\n const mask = expectObject(value, 'depthMask');\n checkFields(\n mask,\n {\n enabled: isBoolean,\n maskSource: (v) => v === null || typeof v === 'string',\n mode: (v) => v === 'threshold' || v === 'brightness',\n depthRange: (v) => Array.isArray(v) && v.length === 2 && v.every(isNumber),\n softness: isNumber,\n invert: isBoolean,\n },\n 'depthMask',\n );\n const merged = { ...DEFAULT_DEPTH_MASK, ...(mask as Partial<DepthMaskOptions>) };\n return { ...merged, depthRange: [...merged.depthRange] as [number, number] };\n}\n\nconst ANNOTATION_TYPES = new Set(['pen', 'rect', 'circle', 'arrow', 'line', 'text', 'image']);\n\nconst isAnnotation = (value: unknown): value is Annotation =>\n isObject(value) &&\n typeof value.id === 'string' &&\n typeof value.type === 'string' &&\n ANNOTATION_TYPES.has(value.type) &&\n isNumber(value.x) &&\n isNumber(value.y);\n\n/**\n * Loads stored image editor state (a JSON string or object) with a `LoadReport`:\n *\n * - Runs `imageEditorStateMigrations` up to `IMAGE_EDITOR_STATE_VERSION`; a missing\n * `version` is taken as current.\n * - A newer `version` is still loaded but reported `readOnly`: do not save over it.\n * - Each section (`crop`, `transform`, `adjustments`, `depthMask`, `annotations`, and the\n * optional run-length encoded `selection`)\n * falls back to its default on its own; invalid annotations are dropped one by one.\n * - Unknown top-level keys are returned in `unknown`.\n *\n * Valid state from `toJSON()` comes back unchanged, so `loadJSON(state)` behaves\n * exactly as with the raw object.\n */\nexport function loadImageEditorDocument(input: unknown): ImageEditorDocumentLoad {\n let dropped = 0;\n const result = loadDocument<Omit<SerializedImageEditorState, 'version'>>(\n input,\n {\n crop: { parse: parseCrop, defaults: null },\n transform: { parse: parseTransform, defaults: () => ({ ...DEFAULT_TRANSFORM }) },\n adjustments: {\n parse: parseAdjustments,\n // Same as what `loadJSON` derives from missing adjustments.\n defaults: () => normalizeStoredAdjustments(undefined),\n },\n depthMask: {\n parse: parseDepthMask,\n defaults: () => ({ ...DEFAULT_DEPTH_MASK, depthRange: [...DEFAULT_DEPTH_MASK.depthRange] as [number, number] }),\n },\n annotations: {\n parse: (value) => {\n if (!Array.isArray(value)) throw new Error('annotations must be an array');\n const kept = value.filter(isAnnotation);\n dropped = value.length - kept.length;\n return JSON.parse(JSON.stringify(kept)) as Annotation[];\n },\n defaults: () => [],\n },\n // Optional: only present when something was selected when saving.\n selection: {\n parse: (value) => {\n const mask = deserializeSelection(value);\n const v = value as { rle: string };\n return { width: mask.width, height: mask.height, rle: v.rle };\n },\n defaults: undefined,\n },\n },\n {\n currentVersion: IMAGE_EDITOR_STATE_VERSION,\n steps: imageEditorStateMigrations,\n },\n );\n if (dropped > 0) {\n result.report.problems.push({\n section: 'annotations',\n message: `${dropped} invalid annotation${dropped === 1 ? '' : 's'} dropped`,\n });\n }\n const state = { version: 1, ...result.value } as SerializedImageEditorState;\n if (state.selection === undefined) delete state.selection;\n return { state, report: result.report, unknown: result.unknown };\n}\n","// Portions ported from lightcraft-main/crates/develop/src/controls.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\nimport type { AdjustmentKind, ImageAdjustments } from './types';\n\n/**\n * Control specs: one table describes every numeric adjustment slider (id, label, section, range,\n * default, step, display precision and track style). The React and Svelte panels render from it,\n * the agent tools expose it as a schema, and values are addressed by id.\n */\n\nexport type ControlSection = 'light' | 'color' | 'effects' | 'layer';\n\n/** How a slider track is drawn. */\nexport type ControlTrack =\n /** Plain track, fill from the minimum. */\n | { kind: 'plain' }\n /** Zero in the middle. */\n | { kind: 'centered' }\n /** Blue → yellow (white-balance temperature). */\n | { kind: 'temp' }\n /** Green → magenta (tint). */\n | { kind: 'tint' }\n /** A two-colour gradient. */\n | { kind: 'gradient'; from: string; to: string }\n /** Full hue rainbow. */\n | { kind: 'rainbow' };\n\nexport interface ControlSpec {\n /** Dotted path of the value (`exposure`; inside a layer's params: `midtones.0`, `ranges.4.hue`). */\n id: string;\n label: string;\n section: ControlSection;\n min: number;\n max: number;\n step: number;\n default: number;\n /** Decimal places shown (after `displayScale`). */\n decimals: number;\n track: ControlTrack;\n /** Multiplier for display (opacity 0..1 shows as 0..100 %). */\n displayScale?: number;\n /** Unit suffix for display (`px`, `%`, `°`). */\n unit?: string;\n /** The rendering process the control needs (tint: process 2). */\n requiresProcess?: 1 | 2;\n}\n\nconst plain: ControlTrack = { kind: 'plain' };\nconst centered: ControlTrack = { kind: 'centered' };\n\n/** Every numeric base adjustment, in panel order. */\nexport const IMAGE_ADJUSTMENT_CONTROLS: readonly ControlSpec[] = [\n { id: 'brightness', label: 'Brightness', section: 'light', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: centered },\n { id: 'contrast', label: 'Contrast', section: 'light', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: centered },\n {\n id: 'saturation', label: 'Saturation', section: 'color', min: -100, max: 100, step: 1, default: 0, decimals: 0,\n track: { kind: 'gradient', from: '#7a7a7a', to: '#e04a3a' },\n },\n { id: 'exposure', label: 'Exposure', section: 'light', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: centered },\n { id: 'temperature', label: 'Warmth / Temperature', section: 'color', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'temp' } },\n { id: 'tint', label: 'Tint', section: 'color', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'tint' }, requiresProcess: 2 },\n { id: 'blur', label: 'Blur', section: 'effects', min: 0, max: 30, step: 1, default: 0, decimals: 0, track: plain, unit: 'px' },\n { id: 'opacity', label: 'Opacity', section: 'effects', min: 0, max: 1, step: 0.05, default: 1, decimals: 0, track: plain, displayScale: 100, unit: '%' },\n];\n\nconst tone = (prefix: string, label: string): ControlSpec[] =>\n [\n ['0', 'Cyan – Red', '#00b7c7', '#e0343a'],\n ['1', 'Magenta – Green', '#d23ad2', '#2fb34a'],\n ['2', 'Yellow – Blue', '#e0c63a', '#3a5be0'],\n ].map(([i, l, from, to]) => ({\n id: `${prefix}.${i}`, label: `${label} ${l}`, section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0,\n track: { kind: 'gradient', from, to },\n }));\n\nconst levelsRecord = (ch: string, label: string): ControlSpec[] => [\n { id: `${ch}.inBlack`, label: `${label} input black`, section: 'layer', min: 0, max: 253, step: 1, default: 0, decimals: 0, track: plain },\n { id: `${ch}.gamma`, label: `${label} gamma`, section: 'layer', min: 0.1, max: 9.99, step: 0.01, default: 1, decimals: 2, track: plain },\n { id: `${ch}.inWhite`, label: `${label} input white`, section: 'layer', min: 2, max: 255, step: 1, default: 255, decimals: 0, track: plain },\n { id: `${ch}.outBlack`, label: `${label} output black`, section: 'layer', min: 0, max: 255, step: 1, default: 0, decimals: 0, track: plain },\n { id: `${ch}.outWhite`, label: `${label} output white`, section: 'layer', min: 0, max: 255, step: 1, default: 255, decimals: 0, track: plain },\n];\n\nconst RANGE_NAMES = ['Reds', 'Yellows', 'Greens', 'Cyans', 'Blues', 'Magentas'];\n\n/**\n * Numeric parameters of each adjustment-layer kind, addressed inside `layer.params`. Curves points\n * and booleans / colours (colorize, preserve luminosity, tint, filter colour) are edited by the\n * dedicated controls, not sliders.\n */\nexport const ADJUSTMENT_LAYER_CONTROLS: Readonly<Record<AdjustmentKind, readonly ControlSpec[]>> = {\n curves: [],\n levels: [\n ...levelsRecord('master', 'RGB'),\n ...levelsRecord('red', 'Red'),\n ...levelsRecord('green', 'Green'),\n ...levelsRecord('blue', 'Blue'),\n ],\n hueSaturation: [\n { id: 'hue', label: 'Hue', section: 'layer', min: -180, max: 180, step: 1, default: 0, decimals: 0, track: { kind: 'rainbow' }, unit: '°' },\n { id: 'saturation', label: 'Saturation', section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'gradient', from: '#7a7a7a', to: '#e04a3a' } },\n { id: 'lightness', label: 'Lightness', section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'gradient', from: '#000000', to: '#ffffff' } },\n ...RANGE_NAMES.flatMap((name, i): ControlSpec[] => [\n { id: `ranges.${i}.hue`, label: `${name} hue`, section: 'layer', min: -180, max: 180, step: 1, default: 0, decimals: 0, track: { kind: 'rainbow' }, unit: '°' },\n { id: `ranges.${i}.saturation`, label: `${name} saturation`, section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: centered },\n { id: `ranges.${i}.lightness`, label: `${name} lightness`, section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: centered },\n ]),\n ],\n vibrance: [\n { id: 'vibrance', label: 'Vibrance', section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'gradient', from: '#7a7a7a', to: '#d8406a' } },\n { id: 'saturation', label: 'Saturation', section: 'layer', min: -100, max: 100, step: 1, default: 0, decimals: 0, track: { kind: 'gradient', from: '#7a7a7a', to: '#e04a3a' } },\n ],\n colorBalance: [...tone('shadows', 'Shadows'), ...tone('midtones', 'Midtones'), ...tone('highlights', 'Highlights')],\n blackWhite: [\n ['reds', 'Reds', 40, '#e0343a'],\n ['yellows', 'Yellows', 60, '#e0c63a'],\n ['greens', 'Greens', 40, '#2fb34a'],\n ['cyans', 'Cyans', 60, '#00b7c7'],\n ['blues', 'Blues', 20, '#3a5be0'],\n ['magentas', 'Magentas', 80, '#d23ad2'],\n ].map(([id, label, def, to]) => ({\n id: id as string, label: label as string, section: 'layer' as const, min: -200, max: 300, step: 1, default: def as number, decimals: 0,\n track: { kind: 'gradient' as const, from: '#000000', to: to as string }, unit: '%',\n })),\n invert: [],\n posterize: [{ id: 'levels', label: 'Levels', section: 'layer', min: 2, max: 255, step: 1, default: 4, decimals: 0, track: plain }],\n threshold: [{ id: 'level', label: 'Threshold level', section: 'layer', min: 1, max: 255, step: 1, default: 128, decimals: 0, track: { kind: 'gradient', from: '#000000', to: '#ffffff' } }],\n photoFilter: [{ id: 'density', label: 'Density', section: 'layer', min: 0, max: 100, step: 1, default: 25, decimals: 0, track: plain, unit: '%' }],\n};\n\n/** Opacity of any adjustment layer (0..1, shown as %). */\nexport const ADJUSTMENT_LAYER_OPACITY_CONTROL: ControlSpec = {\n id: 'opacity', label: 'Opacity', section: 'layer', min: 0, max: 1, step: 0.01, default: 1, decimals: 0, track: plain, displayScale: 100, unit: '%',\n};\n\nconst BASE_BY_ID = new Map(IMAGE_ADJUSTMENT_CONTROLS.map((c) => [c.id, c]));\n\n/** The base-adjustment control with this id. */\nexport function findAdjustmentControl(id: string): ControlSpec | undefined {\n return BASE_BY_ID.get(id);\n}\n\n/** The control of a layer parameter (`opacity` included). */\nexport function findLayerControl(kind: AdjustmentKind, id: string): ControlSpec | undefined {\n if (id === 'opacity') return ADJUSTMENT_LAYER_OPACITY_CONTROL;\n return ADJUSTMENT_LAYER_CONTROLS[kind]?.find((c) => c.id === id);\n}\n\n/** `v` clamped to the control's range and snapped to its step; non-finite values give the default. */\nexport function clampControlValue(spec: ControlSpec, v: unknown): number {\n if (typeof v !== 'number' || !Number.isFinite(v)) return spec.default;\n const clamped = Math.min(spec.max, Math.max(spec.min, v));\n const steps = Math.round((clamped - spec.min) / spec.step);\n const snapped = spec.min + steps * spec.step;\n // Trim float noise from the step arithmetic.\n return Math.min(spec.max, Number(snapped.toFixed(6)));\n}\n\n/** A value as the slider shows it (`+12`, `35%`, `4px`). */\nexport function formatControlValue(spec: ControlSpec, v: number): string {\n const shown = (Number.isFinite(v) ? v : spec.default) * (spec.displayScale ?? 1);\n const s = shown.toFixed(spec.decimals);\n return `${s}${spec.unit ?? ''}`;\n}\n\n/** Where `v` sits on the track, 0 (left) to 1 (right). */\nexport function controlPosition(spec: ControlSpec, v: number): number {\n const p = (clampControlValue(spec, v) - spec.min) / (spec.max - spec.min || 1);\n return Math.min(1, Math.max(0, p));\n}\n\n/** CSS background for a control's track. */\nexport function controlTrackBackground(spec: ControlSpec): string | undefined {\n const t = spec.track;\n switch (t.kind) {\n case 'temp':\n return 'linear-gradient(to right, #3a7bd5, #d8d8d8, #f2c94c)';\n case 'tint':\n return 'linear-gradient(to right, #3fbf4f, #d8d8d8, #d23ad2)';\n case 'gradient':\n return `linear-gradient(to right, ${t.from}, ${t.to})`;\n case 'rainbow':\n return 'linear-gradient(to right, #00ffff, #0000ff, #ff00ff, #ff0000, #ffff00, #00ff00, #00ffff)';\n default:\n return undefined;\n }\n}\n\n/** Reads a dotted path (`ranges.2.hue`) from an object. */\nexport function getControlPath(obj: unknown, path: string): unknown {\n let cur: any = obj;\n for (const part of path.split('.')) {\n if (cur === null || cur === undefined) return undefined;\n cur = cur[part];\n }\n return cur;\n}\n\n/** A copy of `obj` with the dotted path set (arrays and objects along the path are cloned). */\nexport function setControlPath<T>(obj: T, path: string, value: unknown): T {\n const parts = path.split('.');\n const root: any = Array.isArray(obj) ? [...(obj as unknown[])] : { ...(obj as object) };\n let cur = root;\n for (let i = 0; i < parts.length - 1; i++) {\n const next = cur[parts[i]];\n cur[parts[i]] = Array.isArray(next) ? [...next] : next && typeof next === 'object' ? { ...next } : {};\n cur = cur[parts[i]];\n }\n cur[parts[parts.length - 1]] = value;\n return root as T;\n}\n\n/** The base adjustment values the control table describes. */\nexport function readAdjustmentControls(adjustments: ImageAdjustments): Record<string, number> {\n const out: Record<string, number> = {};\n for (const c of IMAGE_ADJUSTMENT_CONTROLS) {\n const v = (adjustments as unknown as Record<string, unknown>)[c.id];\n out[c.id] = typeof v === 'number' && Number.isFinite(v) ? v : c.default;\n }\n return out;\n}\n","import type { SelectionMask, SelectionMode } from './mask';\nimport type { ColorDistance } from './wand';\nimport type { RefineEdgeParams } from './refine';\n\n/** Selection tools of the image editor UI. */\nexport type SelectionToolKind = 'wand' | 'rect' | 'ellipse' | 'lasso';\n\nexport const SELECTION_TOOLS: readonly { id: SelectionToolKind; label: string }[] = [\n { id: 'wand', label: 'Magic Wand' },\n { id: 'rect', label: 'Rectangle' },\n { id: 'ellipse', label: 'Ellipse' },\n { id: 'lasso', label: 'Lasso' },\n];\n\nexport const SELECTION_MODE_LABELS: Record<SelectionMode, string> = {\n replace: 'New',\n add: 'Add',\n subtract: 'Subtract',\n intersect: 'Intersect',\n};\n\n/** The options bar of the selection tools (shared by the React and Svelte UIs). */\nexport interface SelectionToolOptions {\n tool: SelectionToolKind;\n mode: SelectionMode;\n /** Magic wand tolerance, 0..255. */\n tolerance: number;\n contiguous: boolean;\n antiAlias: boolean;\n /** Sample the adjusted image instead of the source. */\n sampleMerged: boolean;\n distance: ColorDistance;\n}\n\nexport const DEFAULT_SELECTION_TOOL_OPTIONS: SelectionToolOptions = {\n tool: 'wand',\n mode: 'replace',\n tolerance: 32,\n contiguous: true,\n antiAlias: true,\n sampleMerged: false,\n distance: 'rgb',\n};\n\n/**\n * Photoshop's modifier keys: Shift adds, Alt/Option subtracts, both intersect; otherwise the\n * options bar mode.\n */\nexport function selectionModeFromModifiers(\n modifiers: { shiftKey?: boolean; altKey?: boolean },\n fallback: SelectionMode\n): SelectionMode {\n if (modifiers.shiftKey && modifiers.altKey) return 'intersect';\n if (modifiers.shiftKey) return 'add';\n if (modifiers.altKey) return 'subtract';\n return fallback;\n}\n\nexport interface RefineEdgeControl {\n id: keyof Omit<RefineEdgeParams, 'smartRadius'>;\n label: string;\n min: number;\n max: number;\n step: number;\n unit: string;\n}\n\n/** Sliders of the Refine Edge panel. */\nexport const REFINE_EDGE_CONTROLS: readonly RefineEdgeControl[] = [\n { id: 'radius', label: 'Radius', min: 0, max: 64, step: 1, unit: 'px' },\n { id: 'smooth', label: 'Smooth', min: 0, max: 100, step: 1, unit: '' },\n { id: 'feather', label: 'Feather', min: 0, max: 50, step: 0.5, unit: 'px' },\n { id: 'contrast', label: 'Contrast', min: 0, max: 100, step: 1, unit: '%' },\n { id: 'shiftEdge', label: 'Shift Edge', min: -100, max: 100, step: 1, unit: '%' },\n];\n\n/** A one-line status: \"No selection\" or \"W × H px selected (n % of the image)\". */\nexport function describeSelection(mask: SelectionMask | null | undefined): string {\n if (!mask || !mask.bounds) return 'No selection';\n let sum = 0;\n for (let i = 0; i < mask.data.length; i++) sum += mask.data[i];\n const pct = (sum / 255 / mask.data.length) * 100;\n const shown = pct >= 10 ? Math.round(pct) : Math.round(pct * 10) / 10;\n return `${mask.bounds.width} × ${mask.bounds.height} px selected (${shown}% of the image)`;\n}\n","import type { AgentTool } from '../agent/registry';\nimport type { JsonSchema } from '../agent/schema';\nimport type { ImageEditorController } from './controller';\nimport type { AdjustmentKind } from './types';\nimport { ADJUSTMENT_KINDS, isAdjustmentKind } from './adjustment-layers';\nimport { describeSelection } from './selection/tool-options';\nimport { SELECTION_MODES, parseSelectionMode, selectionArea } from './selection/mask';\nimport { SELECTION_MODIFY_OPS, type SelectionModifyOp } from './selection/modify';\nimport { layerMaskFromSelection } from './selection/layer-mask';\n\nconst modeSchema: JsonSchema = {\n type: 'string',\n enum: [...SELECTION_MODES],\n description: 'How the result combines with the current selection (default replace).',\n};\n\nconst num = (v: unknown, d: number) => (typeof v === 'number' && Number.isFinite(v) ? v : d);\n\nfunction summary(controller: ImageEditorController) {\n const sel = controller.getSelection();\n const { width, height } = controller.getState().imageDimensions;\n const area = selectionArea(sel);\n return {\n empty: !sel,\n bounds: sel?.bounds ?? null,\n /** Σ coverage in pixels. */\n area: Math.round(area),\n percent: Math.round((area / Math.max(1, width * height)) * 10000) / 100,\n description: describeSelection(sel),\n };\n}\n\nconst writeAnnotations = (title: string, idempotent = false) => ({\n title,\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: idempotent,\n openWorldHint: false,\n});\n\n/**\n * Agent tools for selections and masks (part of `createImageEditorToolProvider`):\n * `get_selection`, `select_region`, `select_by_color`, `modify_selection`, `refine_selection`\n * and `apply_selection_as_mask`. Coordinates are natural pixels of the source image.\n */\nexport function createImageSelectionTools(controller: ImageEditorController): AgentTool[] {\n const getSelection: AgentTool = {\n name: 'get_selection',\n title: 'Read the selection',\n description:\n 'Returns the active selection: whether it is empty, its bounds (natural image pixels), its area in pixels and percent of the image.',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n annotations: { title: 'Read the selection', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },\n handler: () => summary(controller),\n };\n\n const selectRegion: AgentTool = {\n name: 'select_region',\n title: 'Select a region',\n description:\n 'Selects a rectangle or ellipse (x, y, width, height in natural image pixels), everything (\"all\"), nothing (\"none\") or the inverse of the current selection (\"invert\"). One undoable step.',\n inputSchema: {\n type: 'object',\n properties: {\n shape: { type: 'string', enum: ['rect', 'ellipse', 'all', 'none', 'invert'] },\n x: { type: 'number' },\n y: { type: 'number' },\n width: { type: 'number' },\n height: { type: 'number' },\n mode: modeSchema,\n feather: { type: 'number', minimum: 0, description: 'Feather radius in pixels (default 0).' },\n },\n required: ['shape'],\n additionalProperties: false,\n },\n annotations: writeAnnotations('Select a region', true),\n handler: ({ shape, x, y, width, height, mode, feather }) => {\n const opts = { mode: parseSelectionMode(mode), feather: num(feather, 0) };\n switch (shape) {\n case 'all':\n controller.selectAll();\n break;\n case 'none':\n controller.deselect();\n break;\n case 'invert':\n controller.invertSelection();\n break;\n case 'rect':\n case 'ellipse': {\n const rect = { x: num(x, NaN), y: num(y, NaN), width: num(width, NaN), height: num(height, NaN) };\n if (![rect.x, rect.y, rect.width, rect.height].every(Number.isFinite)) {\n throw new Error('rect and ellipse need numeric x, y, width and height.');\n }\n if (shape === 'rect') controller.selectRect(rect, opts);\n else controller.selectEllipse(rect, opts);\n break;\n }\n default:\n throw new Error(`Unknown shape \"${String(shape)}\". Use rect, ellipse, all, none or invert.`);\n }\n return summary(controller);\n },\n };\n\n const selectByColor: AgentTool = {\n name: 'select_by_color',\n title: 'Select by colour',\n description:\n 'Magic wand at (x, y) with tolerance (0-255) and contiguous, or with \"color\" (\"#rrggbb\") every pixel of a similar colour (Color Range, fuzziness 0-200). One undoable step.',\n inputSchema: {\n type: 'object',\n properties: {\n x: { type: 'number' },\n y: { type: 'number' },\n color: { type: 'string', description: '#rrggbb: select this colour everywhere instead of a seed point.' },\n tolerance: { type: 'number', minimum: 0, maximum: 255, description: 'Magic wand tolerance (default 32).' },\n contiguous: { type: 'boolean', description: 'Only the connected region around (x, y) (default true).' },\n fuzziness: { type: 'number', minimum: 0, maximum: 200, description: 'Color Range fuzziness (default 40).' },\n sampleMerged: { type: 'boolean', description: 'Sample the adjusted image rather than the source.' },\n mode: modeSchema,\n },\n additionalProperties: false,\n },\n annotations: writeAnnotations('Select by colour', true),\n handler: async ({ x, y, color, tolerance, contiguous, fuzziness, sampleMerged, mode }) => {\n const common = { mode: parseSelectionMode(mode), sampleMerged: sampleMerged === true };\n if (typeof color === 'string') {\n await controller.selectColorRange([{ color }], { ...common, fuzziness: num(fuzziness, 40) });\n } else if (typeof x === 'number' && typeof y === 'number') {\n await controller.magicWand({ x, y }, { ...common, tolerance: num(tolerance, 32), contiguous: contiguous !== false });\n } else {\n throw new Error('Pass x and y (magic wand) or color (#rrggbb).');\n }\n return summary(controller);\n },\n };\n\n const modify: AgentTool = {\n name: 'modify_selection',\n title: 'Modify the selection',\n description: 'Select › Modify: grow, shrink, feather, border or smooth the selection by radius pixels. One undoable step.',\n inputSchema: {\n type: 'object',\n properties: {\n op: { type: 'string', enum: [...SELECTION_MODIFY_OPS] },\n radius: { type: 'number', minimum: 0, maximum: 500 },\n },\n required: ['op', 'radius'],\n additionalProperties: false,\n },\n annotations: writeAnnotations('Modify the selection'),\n handler: ({ op, radius }) => {\n if (!(SELECTION_MODIFY_OPS as readonly string[]).includes(op as string)) throw new Error(`Unknown op \"${String(op)}\".`);\n if (!controller.getSelection()) throw new Error('Nothing is selected.');\n controller.modifySelection(op as SelectionModifyOp, Math.min(500, Math.max(0, num(radius, 0))));\n return summary(controller);\n },\n };\n\n const refine: AgentTool = {\n name: 'refine_selection',\n title: 'Refine the selection edge',\n description:\n 'Refine Edge: snaps the selection edge to the image within radius pixels (edge-aware guided filter), then smooth (0-100), feather (px), contrast (0-100) and shiftEdge (-100..100 %). Use it after loading a coarse AI mask. One undoable step.',\n inputSchema: {\n type: 'object',\n properties: {\n radius: { type: 'number', minimum: 0, maximum: 64 },\n smartRadius: { type: 'boolean' },\n smooth: { type: 'number', minimum: 0, maximum: 100 },\n feather: { type: 'number', minimum: 0, maximum: 250 },\n contrast: { type: 'number', minimum: 0, maximum: 100 },\n shiftEdge: { type: 'number', minimum: -100, maximum: 100 },\n },\n additionalProperties: false,\n },\n annotations: writeAnnotations('Refine the selection edge'),\n handler: async (params) => {\n if (!controller.getSelection()) throw new Error('Nothing is selected.');\n await controller.refineSelection({\n radius: num(params.radius, 8),\n smartRadius: params.smartRadius === true,\n smooth: num(params.smooth, 0),\n feather: num(params.feather, 0),\n contrast: num(params.contrast, 0),\n shiftEdge: num(params.shiftEdge, 0),\n });\n return summary(controller);\n },\n };\n\n const applyMask: AgentTool = {\n name: 'apply_selection_as_mask',\n title: 'Mask a layer with the selection',\n description:\n 'Uses the selection as an adjustment layer mask: on layerId, or on a new layer of kind (with optional params), so the adjustment only affects the selected area. density (0-1) and feather (px) soften the mask non-destructively. One undoable step.',\n inputSchema: {\n type: 'object',\n properties: {\n layerId: { type: 'string' },\n kind: { type: 'string', enum: ADJUSTMENT_KINDS.map((k) => k.kind) },\n params: { type: 'object' },\n density: { type: 'number', minimum: 0, maximum: 1 },\n feather: { type: 'number', minimum: 0, maximum: 1000 },\n },\n additionalProperties: false,\n },\n annotations: writeAnnotations('Mask a layer with the selection'),\n handler: ({ layerId, kind, params, density, feather }) => {\n const sel = controller.getSelection();\n if (!sel) throw new Error('Nothing is selected.');\n const props = {\n ...(typeof density === 'number' ? { density } : {}),\n ...(typeof feather === 'number' ? { feather } : {}),\n };\n let id: string;\n if (typeof layerId === 'string') {\n if (!controller.getAdjustmentLayer(layerId)) throw new Error(`No adjustment layer \"${layerId}\".`);\n controller.applySelectionAsLayerMask(layerId, props);\n id = layerId;\n } else if (isAdjustmentKind(kind)) {\n id = controller.addAdjustmentLayer({\n kind: kind as AdjustmentKind,\n params: params as never,\n mask: layerMaskFromSelection(sel, props),\n });\n } else {\n throw new Error('Pass layerId (an existing layer) or kind (a new adjustment layer).');\n }\n const layer = controller.getAdjustmentLayer(id)!;\n const { rle: _rle, ...mask } = layer.mask!;\n return { layerId: id, kind: layer.kind, mask, selection: summary(controller) };\n },\n };\n\n return [getSelection, selectRegion, selectByColor, modify, refine, applyMask];\n}\n","import type { AgentTool, AgentToolProvider } from '../agent/registry';\nimport type { ImageEditorController } from './controller';\nimport type { AdjustmentKind, ImageAdjustments } from './types';\nimport { normalizeProcessVersion } from './color';\nimport {\n ADJUSTMENT_KINDS,\n isAdjustmentKind,\n} from './adjustment-layers';\nimport { BLEND_MODES, isBlendMode } from './blend';\nimport {\n ADJUSTMENT_LAYER_CONTROLS,\n ADJUSTMENT_LAYER_OPACITY_CONTROL,\n IMAGE_ADJUSTMENT_CONTROLS,\n clampControlValue,\n findAdjustmentControl,\n findLayerControl,\n readAdjustmentControls,\n setControlPath,\n} from './controls';\nimport { createImageSelectionTools } from './selection-tools';\n\nexport interface ImageEditorToolProviderOptions {\n /** Provider id (unique per registry). Default `image-editor`. */\n id?: string;\n /** Always prefix tool names with `<namespace>__`. */\n namespace?: string;\n}\n\nconst LAYER_PATH = /^layers\\.([^.]+)\\.(.+)$/;\n\nfunction adjustmentsSummary(adjustments: ImageAdjustments) {\n return {\n process: normalizeProcessVersion(adjustments.process),\n values: readAdjustmentControls(adjustments),\n layers: (adjustments.layers ?? []).map((l) => JSON.parse(JSON.stringify(l))),\n };\n}\n\n/**\n * Agent tools for an image editor, for a `ToolRegistry`:\n *\n * - `get_adjustments`: base slider values (by control id), process version and adjustment layers.\n * - `list_controls`: the control table (ids, ranges, defaults, steps), layer kinds and blend modes.\n * - `set_adjustments {values, label}`: sets base controls (`exposure`) and layer parameters\n * (`layers.<id>.vibrance`, `layers.<id>.opacity`) in one undo step; values are clamped to the\n * control ranges and the applied values are echoed.\n * - `add_adjustment_layer {kind, params?, opacity?, blend?, name?}`.\n * - `render_preview {maxSide}`: the rendered image as a PNG, longest side at most `maxSide`.\n * - Selections and masks: `get_selection`, `select_region`, `select_by_color`, `modify_selection`,\n * `refine_selection`, `apply_selection_as_mask` (see `createImageSelectionTools`).\n */\nexport function createImageEditorToolProvider(\n controller: ImageEditorController,\n options: ImageEditorToolProviderOptions = {}\n): AgentToolProvider {\n const getAdjustments: AgentTool = {\n name: 'get_adjustments',\n title: 'Read image adjustments',\n description:\n 'Returns the image editor adjustment values by control id, the rendering process version and the adjustment layers (bottom to top).',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n annotations: {\n title: 'Read image adjustments',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n handler: () => adjustmentsSummary(controller.getState().adjustments),\n };\n\n const listControls: AgentTool = {\n name: 'list_controls',\n title: 'List adjustment controls',\n description:\n 'Lists every adjustment control (id, label, section, min, max, step, default), the parameters of each adjustment-layer kind, and the blend modes.',\n inputSchema: { type: 'object', properties: {}, additionalProperties: false },\n annotations: {\n title: 'List adjustment controls',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n handler: () => ({\n controls: IMAGE_ADJUSTMENT_CONTROLS.map(({ id, label, section, min, max, step, default: def, requiresProcess }) => ({\n id, label, section, min, max, step, default: def, ...(requiresProcess ? { requiresProcess } : {}),\n })),\n layerKinds: ADJUSTMENT_KINDS.map(({ kind, label }) => ({\n kind,\n label,\n controls: [...ADJUSTMENT_LAYER_CONTROLS[kind], ADJUSTMENT_LAYER_OPACITY_CONTROL].map(({ id, label: l, min, max, step, default: def }) => ({\n id, label: l, min, max, step, default: def,\n })),\n })),\n blendModes: BLEND_MODES.map((m) => m.id),\n layerPathFormat: 'layers.<layerId>.<controlId>',\n }),\n };\n\n const setAdjustments: AgentTool = {\n name: 'set_adjustments',\n title: 'Set image adjustments',\n description:\n 'Sets adjustment values by control id in one undoable step. Base controls use their id (e.g. \"exposure\"); layer parameters use \"layers.<layerId>.<controlId>\" (e.g. \"layers.adj_1.vibrance\"). Values are clamped to each control range; the applied values are returned.',\n inputSchema: {\n type: 'object',\n properties: {\n values: {\n type: 'object',\n description: 'Map of control id to number. See list_controls for ids and ranges.',\n additionalProperties: { type: 'number' },\n },\n label: { type: 'string', description: 'Short description of the change (echoed back).' },\n },\n required: ['values'],\n additionalProperties: false,\n },\n annotations: {\n title: 'Set image adjustments',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n handler: ({ values, label }) => {\n const entries = Object.entries((values ?? {}) as Record<string, unknown>);\n if (!entries.length) throw new Error('No values given. Pass {\"values\": {\"<control id>\": number}}.');\n const state = controller.getState();\n const base: Partial<ImageAdjustments> = {};\n const layers = (state.adjustments.layers ?? []).map((l) => ({ ...l }));\n const applied: Record<string, number> = {};\n const clamped: string[] = [];\n const unknown: string[] = [];\n for (const [id, raw] of entries) {\n const m = LAYER_PATH.exec(id);\n if (m) {\n const layer = layers.find((l) => l.id === m[1]);\n const spec = layer ? findLayerControl(layer.kind, m[2]) : undefined;\n if (!layer || !spec) {\n unknown.push(id);\n continue;\n }\n const v = clampControlValue(spec, raw);\n if (v !== raw) clamped.push(id);\n if (spec.id === 'opacity') layer.opacity = v;\n else layer.params = setControlPath(layer.params, spec.id, v) as typeof layer.params;\n applied[id] = v;\n continue;\n }\n const spec = findAdjustmentControl(id);\n if (!spec) {\n unknown.push(id);\n continue;\n }\n const v = clampControlValue(spec, raw);\n if (v !== raw) clamped.push(id);\n (base as Record<string, number>)[id] = v;\n applied[id] = v;\n }\n if (unknown.length) {\n const accepted = IMAGE_ADJUSTMENT_CONTROLS.map((c) => c.id).join(', ');\n throw new Error(\n `Unknown control id(s): ${unknown.join(', ')}. Accepted: ${accepted}, or layers.<layerId>.<controlId> for an existing layer.`\n );\n }\n const changedLayers = Object.keys(applied).some((id) => id.startsWith('layers.'));\n controller.setAdjustments(changedLayers ? { ...base, layers } : base);\n const result: Record<string, unknown> = { applied, clamped };\n if (typeof label === 'string' && label) result.label = label;\n const notes: string[] = [];\n if ('tint' in applied && normalizeProcessVersion(controller.getState().adjustments.process) < 2) {\n notes.push('Tint has no effect on process 1 edits.');\n }\n if (notes.length) result.notes = notes;\n return result;\n },\n };\n\n const addLayer: AgentTool = {\n name: 'add_adjustment_layer',\n title: 'Add an adjustment layer',\n description:\n 'Adds a non-destructive adjustment layer on top of the stack (one undoable step) and returns it. Kinds: ' +\n ADJUSTMENT_KINDS.map((k) => k.kind).join(', ') +\n '. Omitted params are neutral.',\n inputSchema: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: ADJUSTMENT_KINDS.map((k) => k.kind) },\n params: { type: 'object', description: 'Initial parameters (see list_controls); merged with neutral defaults.' },\n opacity: { type: 'number', minimum: 0, maximum: 1 },\n blend: { type: 'string', enum: BLEND_MODES.map((m) => m.id) },\n name: { type: 'string' },\n },\n required: ['kind'],\n additionalProperties: false,\n },\n annotations: {\n title: 'Add an adjustment layer',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n handler: ({ kind, params, opacity, blend, name }) => {\n if (!isAdjustmentKind(kind)) throw new Error(`Unknown adjustment kind \"${kind}\".`);\n if (blend !== undefined && !isBlendMode(blend)) throw new Error(`Unknown blend mode \"${blend}\".`);\n const id = controller.addAdjustmentLayer({ kind: kind as AdjustmentKind, params, opacity, blend, name });\n const layer = controller.getAdjustmentLayer(id)!;\n return { layer: JSON.parse(JSON.stringify(layer)), index: controller.getAdjustmentLayers().length - 1 };\n },\n };\n\n const renderPreview: AgentTool = {\n name: 'render_preview',\n title: 'Render a preview',\n description: 'Renders the edited image (crop, adjustments, layers, annotations) as a PNG whose longest side is at most maxSide pixels.',\n inputSchema: {\n type: 'object',\n properties: {\n maxSide: { type: 'integer', minimum: 16, maximum: 2048, description: 'Longest side in pixels (default 512).' },\n },\n additionalProperties: false,\n },\n annotations: {\n title: 'Render a preview',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n handler: async ({ maxSide }) => {\n const side = Math.max(16, Math.min(2048, Math.round(typeof maxSide === 'number' ? maxSide : 512)));\n const state = controller.getState();\n const crop = state.crop ?? { x: 0, y: 0, ...state.imageDimensions };\n const quarter = Math.abs(Math.round((state.transform.rotate % 180) / 90)) % 2 === 1;\n const w = quarter ? crop.height : crop.width;\n const h = quarter ? crop.width : crop.height;\n const k = Math.min(1, side / Math.max(w, h, 1));\n const dataUrl = await controller.toDataURL({\n format: 'image/png',\n width: Math.max(1, Math.round(w * k)),\n height: Math.max(1, Math.round(h * k)),\n });\n const comma = dataUrl.indexOf(',');\n if (!dataUrl.startsWith('data:image/png') || comma < 0 || comma === dataUrl.length - 1) {\n throw new Error('Rendering is not available in this environment.');\n }\n return {\n content: [\n { type: 'image', data: dataUrl.slice(comma + 1), mimeType: 'image/png' },\n { type: 'text', text: `Preview ${Math.round(w * k)}×${Math.round(h * k)}` },\n ],\n };\n },\n };\n\n return {\n id: options.id ?? 'image-editor',\n namespace: options.namespace,\n tools: [getAdjustments, listControls, setAdjustments, addLayer, renderPreview, ...createImageSelectionTools(controller)],\n };\n}\n\n","import type { CurvePoint } from './types';\nimport { curveLutFromLevels } from './adjustment-layers';\n\n/**\n * Framework-neutral helpers for a Curves editor drawn in a `width` × `height` box (levels 0..255\n * on both axes, output up). The React and Svelte curve editors share them.\n */\n\nconst clampLevel = (v: number) => Math.min(255, Math.max(0, Math.round(v)));\n\n/** Box coordinates of a curve point. */\nexport function curvePointToBox(p: CurvePoint, width: number, height: number): { x: number; y: number } {\n return { x: (p.input / 255) * width, y: height - (p.output / 255) * height };\n}\n\n/** The curve point (whole levels, clamped) under box coordinates. */\nexport function boxToCurvePoint(x: number, y: number, width: number, height: number): CurvePoint {\n return { input: clampLevel((x / (width || 1)) * 255), output: clampLevel(((height - y) / (height || 1)) * 255) };\n}\n\n/** An SVG polyline path of the evaluated curve (spline, clamped, constant beyond the end points). */\nexport function curveSvgPath(points: readonly CurvePoint[], width: number, height: number, samples = 64): string {\n const lut = curveLutFromLevels(points);\n const n = lut.length - 1;\n let d = '';\n for (let i = 0; i <= samples; i++) {\n const t = i / samples;\n const y = lut[Math.round(t * n)];\n d += `${i === 0 ? 'M' : ' L'}${round2(t * width)} ${round2(height - y * height)}`;\n }\n return d;\n}\n\n/** Index of the point within `radius` box units of (x, y), nearest first; -1 for none. */\nexport function hitTestCurvePoint(\n points: readonly CurvePoint[],\n x: number,\n y: number,\n width: number,\n height: number,\n radius = 8\n): number {\n let best = -1;\n let bestD = radius * radius;\n points.forEach((p, i) => {\n const b = curvePointToBox(p, width, height);\n const d = (b.x - x) ** 2 + (b.y - y) ** 2;\n if (d <= bestD) {\n best = i;\n bestD = d;\n }\n });\n return best;\n}\n\n/** Inserts a point in input order (replacing one at the same input). Returns the new list and its index. */\nexport function insertCurvePoint(points: readonly CurvePoint[], p: CurvePoint): { points: CurvePoint[]; index: number } {\n const point = { input: clampLevel(p.input), output: clampLevel(p.output) };\n const out = points.filter((q) => q.input !== point.input).map((q) => ({ ...q }));\n let index = out.findIndex((q) => q.input > point.input);\n if (index === -1) index = out.length;\n out.splice(index, 0, point);\n return { points: out, index };\n}\n\n/** Moves point `index`, keeping its input strictly between its neighbours'. */\nexport function moveCurvePoint(points: readonly CurvePoint[], index: number, p: CurvePoint): CurvePoint[] {\n const out = points.map((q) => ({ ...q }));\n if (index < 0 || index >= out.length) return out;\n const lo = index > 0 ? out[index - 1].input + 1 : 0;\n const hi = index < out.length - 1 ? out[index + 1].input - 1 : 255;\n out[index] = { input: Math.min(hi, Math.max(lo, clampLevel(p.input))), output: clampLevel(p.output) };\n return out;\n}\n\n/** Removes point `index`; a curve keeps at least two points. */\nexport function removeCurvePoint(points: readonly CurvePoint[], index: number): CurvePoint[] {\n if (points.length <= 2 || index < 0 || index >= points.length) return points.map((q) => ({ ...q }));\n return points.filter((_, i) => i !== index).map((q) => ({ ...q }));\n}\n\nconst round2 = (v: number) => Math.round(v * 100) / 100;\n","import type { ImagePoint } from '../types';\nimport type { ImageEditorController } from '../controller';\nimport { ellipsePoints, normalizeRect } from './shapes';\nimport { selectionModeFromModifiers, type SelectionToolOptions } from './tool-options';\n\nexport interface GestureModifiers {\n shiftKey?: boolean;\n altKey?: boolean;\n}\n\n/**\n * Pointer gestures of the selection tools, shared by the React and Svelte image editors: feed\n * it pointer positions in natural image pixels (`canvasToImagePoint(..., false)`).\n *\n * - Magic wand: selects on `begin` (async, as it may read pixels).\n * - Rectangle / ellipse: drag a box; a click without a drag deselects (replace mode).\n * - Lasso: drag a free-hand path, closed on `end`.\n *\n * Shift adds, Alt subtracts, both intersect (overriding the options bar mode). While dragging,\n * {@link draftPath} is the outline to show (`RenderOptions.draftSelectionPath`).\n */\nexport class SelectionGesture {\n private start: ImagePoint | null = null;\n private points: ImagePoint[] = [];\n private current: ImagePoint | null = null;\n private modifiers: GestureModifiers = {};\n /** The last error (e.g. pixels unavailable for the wand), for the UI to show. */\n public error: string | null = null;\n\n constructor(\n readonly controller: ImageEditorController,\n private readonly getOptions: () => SelectionToolOptions\n ) {}\n\n get active(): boolean {\n return this.start !== null;\n }\n\n /** The outline of the shape being drawn, or `null`. */\n get draftPath(): ImagePoint[] | null {\n if (!this.start || !this.current) return null;\n const { tool } = this.getOptions();\n if (tool === 'lasso') return this.points.length > 1 ? this.points.slice() : null;\n const rect = normalizeRect({\n x: this.start.x,\n y: this.start.y,\n width: this.current.x - this.start.x,\n height: this.current.y - this.start.y,\n });\n if (rect.width < 1 && rect.height < 1) return null;\n if (tool === 'ellipse') return ellipsePoints(rect);\n return [\n { x: rect.x, y: rect.y },\n { x: rect.x + rect.width, y: rect.y },\n { x: rect.x + rect.width, y: rect.y + rect.height },\n { x: rect.x, y: rect.y + rect.height },\n ];\n }\n\n /** Pointer down. Resolves once a wand click has been applied. */\n async begin(point: ImagePoint, modifiers: GestureModifiers = {}): Promise<void> {\n const options = this.getOptions();\n this.error = null;\n this.modifiers = modifiers;\n if (options.tool === 'wand') {\n this.start = null;\n try {\n await this.controller.magicWand(point, {\n tolerance: options.tolerance,\n contiguous: options.contiguous,\n antiAlias: options.antiAlias,\n distance: options.distance,\n sampleMerged: options.sampleMerged,\n mode: selectionModeFromModifiers(modifiers, options.mode),\n });\n } catch (err) {\n this.error = err instanceof Error ? err.message : String(err);\n }\n return;\n }\n this.start = point;\n this.current = point;\n this.points = [point];\n }\n\n /** Pointer move; returns true when the draft changed (re-render). */\n move(point: ImagePoint): boolean {\n if (!this.start) return false;\n this.current = point;\n if (this.getOptions().tool === 'lasso') {\n const last = this.points[this.points.length - 1];\n if (Math.hypot(point.x - last.x, point.y - last.y) < 0.5) return false;\n this.points.push(point);\n }\n return true;\n }\n\n /** Pointer up: commits the shape. Returns true when the selection changed. */\n end(point?: ImagePoint, modifiers?: GestureModifiers): boolean {\n if (!this.start) return false;\n if (point) this.move(point);\n const options = this.getOptions();\n const mode = selectionModeFromModifiers(modifiers ?? this.modifiers, options.mode);\n const path = this.draftPath;\n const rect = normalizeRect({\n x: this.start.x,\n y: this.start.y,\n width: this.current!.x - this.start.x,\n height: this.current!.y - this.start.y,\n });\n this.start = null;\n this.current = null;\n this.points = [];\n if (!path) return mode === 'replace' ? this.controller.deselect() : false;\n const opts = { mode, antiAlias: options.antiAlias };\n if (options.tool === 'lasso') return path.length >= 3 ? this.controller.selectPolygon(path, opts) : false;\n return options.tool === 'ellipse' ? this.controller.selectEllipse(rect, opts) : this.controller.selectRect(rect, opts);\n }\n\n /** Abandons a drag without changing the selection. */\n cancel(): void {\n this.start = null;\n this.current = null;\n this.points = [];\n }\n}\n"],"mappings":"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","names":["lu","lv","clamp","x","y","a","MAX_SIDE","v","ll","tone","sat","op","b","spec","v","round2"]}
|