@pixerate/editor 0.248.0 → 0.250.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 +1 -0
- package/dist/animation-editor/index.cjs +118 -114
- package/dist/animation-editor/index.js +11 -7
- package/dist/{brushstrokeRender-QLCXROJK.js → brushstrokeRender-2FHFLSEG.js} +8 -4
- package/dist/{brushstrokeRender-DTDPFBLC.cjs → brushstrokeRender-QGRXOKDA.cjs} +15 -11
- package/dist/canvas/index.cjs +71 -15
- package/dist/canvas/index.d.cts +1 -0
- package/dist/canvas/index.d.ts +1 -0
- package/dist/canvas/index.js +58 -2
- package/dist/canvas/stickers.d.cts +35 -0
- package/dist/canvas/stickers.d.ts +35 -0
- package/dist/{chunk-RXZL4NG5.js → chunk-226QDRO3.js} +1 -1
- package/dist/{chunk-SC2RZ5EF.js → chunk-2VJAVXLI.js} +2 -2
- package/dist/{chunk-OLNIPTB3.cjs → chunk-2VX55NFM.cjs} +1 -320
- package/dist/chunk-3K6HWEXZ.cjs +92 -0
- package/dist/{chunk-UOOK7HTX.js → chunk-3PPJRMIG.js} +1 -1
- package/dist/{chunk-ZFSLEOSQ.js → chunk-3TWOCSCY.js} +11 -9
- package/dist/chunk-4D6KP5BV.js +92 -0
- package/dist/chunk-4JNWA3VT.cjs +302 -0
- package/dist/{chunk-L3JFOTBQ.js → chunk-5E2Q7ZHI.js} +1 -1
- package/dist/{chunk-2ONK3ERD.cjs → chunk-75K3W4D6.cjs} +20 -20
- package/dist/{chunk-AU6MWQKZ.js → chunk-ABL7IWFZ.js} +1 -1
- package/dist/chunk-ATK6ABN3.cjs +303 -0
- package/dist/{chunk-7T7JWTVE.cjs → chunk-BOHDJJ2O.cjs} +8 -8
- package/dist/{chunk-2PBZBRP5.js → chunk-D5KGAO4Z.js} +10 -92
- package/dist/{chunk-HB4ICNNA.cjs → chunk-DPYAO5U6.cjs} +42 -42
- package/dist/{chunk-6G6ZDDDB.cjs → chunk-GT77U7QG.cjs} +303 -149
- package/dist/{chunk-PQ3H2AAN.cjs → chunk-I7NJPHWV.cjs} +122 -204
- package/dist/{chunk-42TWUPNJ.js → chunk-IRSTHLQQ.js} +1 -320
- package/dist/{chunk-GHCSC2WP.cjs → chunk-ISIO63Q5.cjs} +21 -15
- package/dist/{chunk-OFH6Q67U.js → chunk-JA57JIT5.js} +9 -3
- package/dist/{chunk-VMROIWLL.cjs → chunk-KBYB7OWB.cjs} +3 -3
- package/dist/{chunk-Q2HA52V4.js → chunk-KDLBJ6QR.js} +2 -2
- package/dist/{chunk-WVS5KQDH.cjs → chunk-M2VKFE5L.cjs} +246 -244
- package/dist/{chunk-5GLYUSNT.js → chunk-NOHJP5TK.js} +1 -1
- package/dist/{chunk-XNRBMYNB.js → chunk-NTRAVM2I.js} +1 -1
- package/dist/{chunk-VNBUDVD4.js → chunk-OTEPAQJX.js} +228 -74
- package/dist/chunk-OTTT5N3K.js +322 -0
- package/dist/{chunk-QOBCBGGI.cjs → chunk-QKXO6JPP.cjs} +14 -14
- package/dist/{chunk-NZ3O3A5C.js → chunk-SMSGP2HQ.js} +1 -1
- package/dist/chunk-SZTI6EER.js +13 -0
- package/dist/chunk-U4NUOKBT.js +303 -0
- package/dist/chunk-U67EN7GG.cjs +13 -0
- package/dist/chunk-W5M3J7PV.cjs +322 -0
- package/dist/{chunk-4P6H35HU.js → chunk-WA44NKPF.js} +2 -2
- package/dist/chunk-WKH5ZAUA.js +302 -0
- package/dist/{chunk-L6REDLNB.cjs → chunk-WPUXGDH4.cjs} +7 -7
- package/dist/{chunk-P3NIPIKS.js → chunk-WQCNC4DK.js} +1 -1
- package/dist/{chunk-IBDU6EGZ.cjs → chunk-X7WRL5ZZ.cjs} +35 -35
- package/dist/{chunk-XWTRATIM.cjs → chunk-YM6ZBTXG.cjs} +23 -23
- package/dist/{chunk-TPWB4Y6L.cjs → chunk-YW43M56C.cjs} +1 -1
- package/dist/{chunk-K5DS2JTA.cjs → chunk-Z3BRH4JK.cjs} +6 -6
- package/dist/{chunk-XNZFVYC2.cjs → chunk-ZBCT5MEA.cjs} +7 -7
- package/dist/effects/helpers.d.cts +6 -0
- package/dist/effects/helpers.d.ts +6 -0
- package/dist/effects/index.cjs +62 -60
- package/dist/effects/index.js +5 -3
- package/dist/effects/tools.d.cts +6 -0
- package/dist/effects/tools.d.ts +6 -0
- package/dist/image-editor/effects.d.cts +1 -1
- package/dist/image-editor/effects.d.ts +1 -1
- package/dist/image-editor/index.cjs +1097 -1069
- package/dist/image-editor/index.d.cts +1 -0
- package/dist/image-editor/index.d.ts +1 -0
- package/dist/image-editor/index.js +58 -30
- package/dist/image-editor/stickers.d.cts +9 -0
- package/dist/image-editor/stickers.d.ts +9 -0
- package/dist/paint/index.cjs +8 -5
- package/dist/paint/index.js +13 -10
- package/dist/paint-editor/controller.d.cts +37 -1
- package/dist/paint-editor/controller.d.ts +37 -1
- package/dist/paint-editor/index.cjs +753 -609
- package/dist/paint-editor/index.d.cts +3 -0
- package/dist/paint-editor/index.d.ts +3 -0
- package/dist/paint-editor/index.js +187 -43
- package/dist/paint-editor/sticker-art.d.cts +55 -0
- package/dist/paint-editor/sticker-art.d.ts +55 -0
- package/dist/paint-editor/stickers.d.cts +30 -17
- package/dist/paint-editor/stickers.d.ts +30 -17
- package/dist/paint-editor/stroke.d.cts +4 -0
- package/dist/paint-editor/stroke.d.ts +4 -0
- package/dist/paint-editor/ui.d.cts +10 -2
- package/dist/paint-editor/ui.d.ts +10 -2
- package/dist/raster/index.cjs +6 -4
- package/dist/raster/index.js +12 -10
- package/dist/stickers/browser.d.cts +48 -0
- package/dist/stickers/browser.d.ts +48 -0
- package/dist/stickers/combine.d.cts +10 -0
- package/dist/stickers/combine.d.ts +10 -0
- package/dist/stickers/conformance.d.cts +18 -0
- package/dist/stickers/conformance.d.ts +18 -0
- package/dist/stickers/editor.d.cts +14 -0
- package/dist/stickers/editor.d.ts +14 -0
- package/dist/stickers/errors.d.cts +6 -0
- package/dist/stickers/errors.d.ts +6 -0
- package/dist/stickers/fake.d.cts +16 -0
- package/dist/stickers/fake.d.ts +16 -0
- package/dist/stickers/helpers.d.cts +51 -0
- package/dist/stickers/helpers.d.ts +51 -0
- package/dist/stickers/index.cjs +337 -0
- package/dist/stickers/index.d.cts +16 -0
- package/dist/stickers/index.d.ts +16 -0
- package/dist/stickers/index.js +337 -0
- package/dist/stickers/stamps.d.cts +13 -0
- package/dist/stickers/stamps.d.ts +13 -0
- package/dist/stickers/tools.d.cts +81 -0
- package/dist/stickers/tools.d.ts +81 -0
- package/dist/stickers/types.d.cts +123 -0
- package/dist/stickers/types.d.ts +123 -0
- package/dist/vector/index.cjs +1018 -981
- package/dist/vector/index.d.cts +1 -0
- package/dist/vector/index.d.ts +1 -0
- package/dist/vector/index.js +44 -7
- package/dist/vector/stickers.d.cts +11 -0
- package/dist/vector/stickers.d.ts +11 -0
- package/dist/video-editor/index.cjs +344 -344
- package/dist/video-editor/index.js +4 -4
- package/package.json +11 -1
- package/skills/README.md +1 -0
- package/skills/pixerate-image-editor/SKILL.md +1 -1
- package/skills/pixerate-paint-editor/SKILL.md +8 -5
- package/skills/pixerate-stickers/SKILL.md +57 -0
|
@@ -6,10 +6,6 @@ import {
|
|
|
6
6
|
tileKey,
|
|
7
7
|
tilesInRect
|
|
8
8
|
} from "./chunk-HVVR5PZW.js";
|
|
9
|
-
import {
|
|
10
|
-
deflate,
|
|
11
|
-
inflate
|
|
12
|
-
} from "./chunk-QGHEDC7B.js";
|
|
13
9
|
|
|
14
10
|
// src/raster/pigment.ts
|
|
15
11
|
var PIGMENT_BANDS = 36;
|
|
@@ -990,314 +986,6 @@ function keepDeepSamples(before, after) {
|
|
|
990
986
|
return tiles ? new TiledSurface(ch, tiles, after.defaultValue) : after;
|
|
991
987
|
}
|
|
992
988
|
|
|
993
|
-
// src/raster/png.ts
|
|
994
|
-
var SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
995
|
-
var crcTable = null;
|
|
996
|
-
function crc32(bytes, start, end) {
|
|
997
|
-
if (!crcTable) {
|
|
998
|
-
crcTable = new Uint32Array(256);
|
|
999
|
-
for (let n = 0; n < 256; n++) {
|
|
1000
|
-
let c2 = n;
|
|
1001
|
-
for (let k = 0; k < 8; k++) c2 = c2 & 1 ? 3988292384 ^ c2 >>> 1 : c2 >>> 1;
|
|
1002
|
-
crcTable[n] = c2 >>> 0;
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
let c = 4294967295;
|
|
1006
|
-
for (let i = start; i < end; i++) c = crcTable[(c ^ bytes[i]) & 255] ^ c >>> 8;
|
|
1007
|
-
return (c ^ 4294967295) >>> 0;
|
|
1008
|
-
}
|
|
1009
|
-
function paeth(a, b, c) {
|
|
1010
|
-
const p = a + b - c;
|
|
1011
|
-
const pa = Math.abs(p - a);
|
|
1012
|
-
const pb = Math.abs(p - b);
|
|
1013
|
-
const pc = Math.abs(p - c);
|
|
1014
|
-
return pa <= pb && pa <= pc ? a : pb <= pc ? b : c;
|
|
1015
|
-
}
|
|
1016
|
-
function encodePng(width, height, data, channels = 4) {
|
|
1017
|
-
const stride = width * channels;
|
|
1018
|
-
const raw = new Uint8Array((stride + 1) * height);
|
|
1019
|
-
const bpp = channels;
|
|
1020
|
-
const cand = [new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride)];
|
|
1021
|
-
for (let y = 0; y < height; y++) {
|
|
1022
|
-
const row = y * stride;
|
|
1023
|
-
const prevRow = (y - 1) * stride;
|
|
1024
|
-
let best = 0;
|
|
1025
|
-
let bestScore = Infinity;
|
|
1026
|
-
for (let f = 0; f < 5; f++) {
|
|
1027
|
-
const out2 = cand[f];
|
|
1028
|
-
let score = 0;
|
|
1029
|
-
for (let x = 0; x < stride; x++) {
|
|
1030
|
-
const v = data[row + x];
|
|
1031
|
-
const a = x >= bpp ? data[row + x - bpp] : 0;
|
|
1032
|
-
const b = y > 0 ? data[prevRow + x] : 0;
|
|
1033
|
-
const c = x >= bpp && y > 0 ? data[prevRow + x - bpp] : 0;
|
|
1034
|
-
let r;
|
|
1035
|
-
switch (f) {
|
|
1036
|
-
case 0:
|
|
1037
|
-
r = v;
|
|
1038
|
-
break;
|
|
1039
|
-
case 1:
|
|
1040
|
-
r = v - a;
|
|
1041
|
-
break;
|
|
1042
|
-
case 2:
|
|
1043
|
-
r = v - b;
|
|
1044
|
-
break;
|
|
1045
|
-
case 3:
|
|
1046
|
-
r = v - (a + b >> 1);
|
|
1047
|
-
break;
|
|
1048
|
-
default:
|
|
1049
|
-
r = v - paeth(a, b, c);
|
|
1050
|
-
}
|
|
1051
|
-
r &= 255;
|
|
1052
|
-
out2[x] = r;
|
|
1053
|
-
score += r < 128 ? r : 256 - r;
|
|
1054
|
-
if (score >= bestScore) break;
|
|
1055
|
-
}
|
|
1056
|
-
if (score < bestScore) {
|
|
1057
|
-
bestScore = score;
|
|
1058
|
-
best = f;
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
const o = y * (stride + 1);
|
|
1062
|
-
raw[o] = best;
|
|
1063
|
-
raw.set(cand[best], o + 1);
|
|
1064
|
-
}
|
|
1065
|
-
const idat = deflate(raw);
|
|
1066
|
-
const chunks = [];
|
|
1067
|
-
const ihdr = new Uint8Array(13);
|
|
1068
|
-
writeU32(ihdr, 0, width);
|
|
1069
|
-
writeU32(ihdr, 4, height);
|
|
1070
|
-
ihdr[8] = 8;
|
|
1071
|
-
ihdr[9] = channels === 1 ? 0 : 6;
|
|
1072
|
-
chunks.push(["IHDR", ihdr], ["IDAT", idat], ["IEND", new Uint8Array(0)]);
|
|
1073
|
-
let size = 8;
|
|
1074
|
-
for (const [, d] of chunks) size += 12 + d.length;
|
|
1075
|
-
const out = new Uint8Array(size);
|
|
1076
|
-
out.set(SIGNATURE, 0);
|
|
1077
|
-
let p = 8;
|
|
1078
|
-
for (const [type, d] of chunks) {
|
|
1079
|
-
writeU32(out, p, d.length);
|
|
1080
|
-
for (let i = 0; i < 4; i++) out[p + 4 + i] = type.charCodeAt(i);
|
|
1081
|
-
out.set(d, p + 8);
|
|
1082
|
-
writeU32(out, p + 8 + d.length, crc32(out, p + 4, p + 8 + d.length));
|
|
1083
|
-
p += 12 + d.length;
|
|
1084
|
-
}
|
|
1085
|
-
return out;
|
|
1086
|
-
}
|
|
1087
|
-
function writeU32(b, o, v) {
|
|
1088
|
-
b[o] = v >>> 24;
|
|
1089
|
-
b[o + 1] = v >>> 16 & 255;
|
|
1090
|
-
b[o + 2] = v >>> 8 & 255;
|
|
1091
|
-
b[o + 3] = v & 255;
|
|
1092
|
-
}
|
|
1093
|
-
function readU32(b, o) {
|
|
1094
|
-
return (b[o] << 24 | b[o + 1] << 16 | b[o + 2] << 8 | b[o + 3]) >>> 0;
|
|
1095
|
-
}
|
|
1096
|
-
function isPng(bytes) {
|
|
1097
|
-
return bytes.length > 8 && SIGNATURE.every((v, i) => bytes[i] === v);
|
|
1098
|
-
}
|
|
1099
|
-
function decodePng(bytes, options = {}) {
|
|
1100
|
-
if (!isPng(bytes)) throw new Error("Not a PNG image.");
|
|
1101
|
-
let p = 8;
|
|
1102
|
-
let width = 0;
|
|
1103
|
-
let height = 0;
|
|
1104
|
-
let depth = 0;
|
|
1105
|
-
let type = 0;
|
|
1106
|
-
let interlace = 0;
|
|
1107
|
-
let palette = null;
|
|
1108
|
-
let trns = null;
|
|
1109
|
-
const idat = [];
|
|
1110
|
-
while (p + 8 <= bytes.length) {
|
|
1111
|
-
const len = readU32(bytes, p);
|
|
1112
|
-
const t = String.fromCharCode(bytes[p + 4], bytes[p + 5], bytes[p + 6], bytes[p + 7]);
|
|
1113
|
-
const body = bytes.subarray(p + 8, p + 8 + len);
|
|
1114
|
-
if (p + 12 + len > bytes.length) throw new Error("Truncated PNG.");
|
|
1115
|
-
if (t === "IHDR") {
|
|
1116
|
-
width = readU32(body, 0);
|
|
1117
|
-
height = readU32(body, 4);
|
|
1118
|
-
depth = body[8];
|
|
1119
|
-
type = body[9];
|
|
1120
|
-
interlace = body[12];
|
|
1121
|
-
} else if (t === "PLTE") palette = body;
|
|
1122
|
-
else if (t === "tRNS") trns = body;
|
|
1123
|
-
else if (t === "IDAT") idat.push(body);
|
|
1124
|
-
else if (t === "IEND") break;
|
|
1125
|
-
p += 12 + len;
|
|
1126
|
-
}
|
|
1127
|
-
if (!width || !height) throw new Error("PNG has no image header.");
|
|
1128
|
-
if (interlace) throw new Error("Interlaced PNGs are not supported here; decode them with a canvas.");
|
|
1129
|
-
const maxPixels = options.maxPixels ?? 1 << 28;
|
|
1130
|
-
if (width * height > maxPixels) throw new Error(`PNG is too large (${width}\xD7${height}).`);
|
|
1131
|
-
const samples = type === 0 ? 1 : type === 2 ? 3 : type === 3 ? 1 : type === 4 ? 2 : type === 6 ? 4 : 0;
|
|
1132
|
-
if (!samples || ![1, 2, 4, 8, 16].includes(depth)) throw new Error(`Unsupported PNG format (type ${type}, depth ${depth}).`);
|
|
1133
|
-
let total = 0;
|
|
1134
|
-
for (const c of idat) total += c.length;
|
|
1135
|
-
const z = new Uint8Array(total);
|
|
1136
|
-
let o = 0;
|
|
1137
|
-
for (const c of idat) {
|
|
1138
|
-
z.set(c, o);
|
|
1139
|
-
o += c.length;
|
|
1140
|
-
}
|
|
1141
|
-
const bitsPerPixel = samples * depth;
|
|
1142
|
-
const stride = Math.ceil(width * bitsPerPixel / 8);
|
|
1143
|
-
const raw = inflate(z, { maxOutput: (stride + 1) * height, sizeHint: (stride + 1) * height });
|
|
1144
|
-
if (raw.length < (stride + 1) * height) throw new Error("PNG image data is truncated.");
|
|
1145
|
-
const bpp = Math.max(1, bitsPerPixel >> 3);
|
|
1146
|
-
const lines = new Uint8Array(stride * height);
|
|
1147
|
-
for (let y = 0; y < height; y++) {
|
|
1148
|
-
const f = raw[y * (stride + 1)];
|
|
1149
|
-
const src = y * (stride + 1) + 1;
|
|
1150
|
-
const dst = y * stride;
|
|
1151
|
-
const up = dst - stride;
|
|
1152
|
-
for (let x = 0; x < stride; x++) {
|
|
1153
|
-
const v = raw[src + x];
|
|
1154
|
-
const a = x >= bpp ? lines[dst + x - bpp] : 0;
|
|
1155
|
-
const b = y > 0 ? lines[up + x] : 0;
|
|
1156
|
-
const c = x >= bpp && y > 0 ? lines[up + x - bpp] : 0;
|
|
1157
|
-
let r;
|
|
1158
|
-
switch (f) {
|
|
1159
|
-
case 0:
|
|
1160
|
-
r = v;
|
|
1161
|
-
break;
|
|
1162
|
-
case 1:
|
|
1163
|
-
r = v + a;
|
|
1164
|
-
break;
|
|
1165
|
-
case 2:
|
|
1166
|
-
r = v + b;
|
|
1167
|
-
break;
|
|
1168
|
-
case 3:
|
|
1169
|
-
r = v + (a + b >> 1);
|
|
1170
|
-
break;
|
|
1171
|
-
case 4:
|
|
1172
|
-
r = v + paeth(a, b, c);
|
|
1173
|
-
break;
|
|
1174
|
-
default:
|
|
1175
|
-
throw new Error(`Invalid PNG filter ${f}.`);
|
|
1176
|
-
}
|
|
1177
|
-
lines[dst + x] = r & 255;
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1180
|
-
const sample = (y, i) => {
|
|
1181
|
-
const row = y * stride;
|
|
1182
|
-
if (depth === 8) return lines[row + i];
|
|
1183
|
-
if (depth === 16) return lines[row + i * 2];
|
|
1184
|
-
const perByte = 8 / depth;
|
|
1185
|
-
const byte = lines[row + Math.floor(i / perByte)];
|
|
1186
|
-
const shift = 8 - depth * (i % perByte + 1);
|
|
1187
|
-
const v = byte >> shift & (1 << depth) - 1;
|
|
1188
|
-
return type === 3 ? v : Math.round(v * 255 / ((1 << depth) - 1));
|
|
1189
|
-
};
|
|
1190
|
-
const gray = options.keepGray && type === 0 && !trns;
|
|
1191
|
-
const channels = gray ? 1 : 4;
|
|
1192
|
-
const out = new Uint8ClampedArray(width * height * channels);
|
|
1193
|
-
const trnsGray = trns && type === 0 ? depth === 16 ? trns[0] : sample16(trns, 0, depth) : -1;
|
|
1194
|
-
const trnsRgb = trns && type === 2 ? [0, 1, 2].map((k) => depth === 16 ? trns[k * 2] : sample16(trns, k, depth)) : null;
|
|
1195
|
-
for (let y = 0; y < height; y++) {
|
|
1196
|
-
for (let x = 0; x < width; x++) {
|
|
1197
|
-
const d = (y * width + x) * channels;
|
|
1198
|
-
if (type === 0) {
|
|
1199
|
-
const v = sample(y, x);
|
|
1200
|
-
if (gray) out[d] = v;
|
|
1201
|
-
else {
|
|
1202
|
-
out[d] = out[d + 1] = out[d + 2] = v;
|
|
1203
|
-
out[d + 3] = v === trnsGray && trns ? 0 : 255;
|
|
1204
|
-
}
|
|
1205
|
-
} else if (type === 2) {
|
|
1206
|
-
const r = sample(y, x * 3);
|
|
1207
|
-
const g = sample(y, x * 3 + 1);
|
|
1208
|
-
const b = sample(y, x * 3 + 2);
|
|
1209
|
-
out[d] = r;
|
|
1210
|
-
out[d + 1] = g;
|
|
1211
|
-
out[d + 2] = b;
|
|
1212
|
-
out[d + 3] = trnsRgb && r === trnsRgb[0] && g === trnsRgb[1] && b === trnsRgb[2] ? 0 : 255;
|
|
1213
|
-
} else if (type === 3) {
|
|
1214
|
-
const i = sample(y, x);
|
|
1215
|
-
if (!palette || i * 3 + 2 >= palette.length) throw new Error("PNG palette index out of range.");
|
|
1216
|
-
out[d] = palette[i * 3];
|
|
1217
|
-
out[d + 1] = palette[i * 3 + 1];
|
|
1218
|
-
out[d + 2] = palette[i * 3 + 2];
|
|
1219
|
-
out[d + 3] = trns && i < trns.length ? trns[i] : 255;
|
|
1220
|
-
} else if (type === 4) {
|
|
1221
|
-
const v = sample(y, x * 2);
|
|
1222
|
-
out[d] = out[d + 1] = out[d + 2] = v;
|
|
1223
|
-
out[d + 3] = sample(y, x * 2 + 1);
|
|
1224
|
-
} else {
|
|
1225
|
-
out[d] = sample(y, x * 4);
|
|
1226
|
-
out[d + 1] = sample(y, x * 4 + 1);
|
|
1227
|
-
out[d + 2] = sample(y, x * 4 + 2);
|
|
1228
|
-
out[d + 3] = sample(y, x * 4 + 3);
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
return { width, height, channels, data: out };
|
|
1233
|
-
}
|
|
1234
|
-
function sample16(trns, k, depth) {
|
|
1235
|
-
const v = trns[k * 2] << 8 | trns[k * 2 + 1];
|
|
1236
|
-
if (depth === 8) return v & 255;
|
|
1237
|
-
return Math.round((v & (1 << depth) - 1) * 255 / ((1 << depth) - 1));
|
|
1238
|
-
}
|
|
1239
|
-
var B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1240
|
-
var B64_INV = null;
|
|
1241
|
-
function bytesToBase64(bytes) {
|
|
1242
|
-
const parts = [];
|
|
1243
|
-
const CHUNK = 3 * 4096;
|
|
1244
|
-
for (let start = 0; start < bytes.length; start += CHUNK) {
|
|
1245
|
-
const end = Math.min(bytes.length, start + CHUNK);
|
|
1246
|
-
let s = "";
|
|
1247
|
-
let i = start;
|
|
1248
|
-
for (; i + 2 < end; i += 3) {
|
|
1249
|
-
const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
|
1250
|
-
s += B64[n >> 18] + B64[n >> 12 & 63] + B64[n >> 6 & 63] + B64[n & 63];
|
|
1251
|
-
}
|
|
1252
|
-
if (i < end) {
|
|
1253
|
-
const n = bytes[i] << 16 | (i + 1 < end ? bytes[i + 1] << 8 : 0);
|
|
1254
|
-
s += B64[n >> 18] + B64[n >> 12 & 63] + (i + 1 < end ? B64[n >> 6 & 63] : "=") + "=";
|
|
1255
|
-
}
|
|
1256
|
-
parts.push(s);
|
|
1257
|
-
}
|
|
1258
|
-
return parts.join("");
|
|
1259
|
-
}
|
|
1260
|
-
function base64ToBytes(text) {
|
|
1261
|
-
if (!B64_INV) {
|
|
1262
|
-
B64_INV = new Int16Array(128).fill(-1);
|
|
1263
|
-
for (let i = 0; i < 64; i++) B64_INV[B64.charCodeAt(i)] = i;
|
|
1264
|
-
B64_INV["-".charCodeAt(0)] = 62;
|
|
1265
|
-
B64_INV["_".charCodeAt(0)] = 63;
|
|
1266
|
-
}
|
|
1267
|
-
const inv = B64_INV;
|
|
1268
|
-
const clean = text.replace(/[\s=]/g, "");
|
|
1269
|
-
const out = new Uint8Array(Math.floor(clean.length * 3 / 4));
|
|
1270
|
-
let bits = 0;
|
|
1271
|
-
let acc = 0;
|
|
1272
|
-
let o = 0;
|
|
1273
|
-
for (let i = 0; i < clean.length; i++) {
|
|
1274
|
-
const c = clean.charCodeAt(i);
|
|
1275
|
-
const v = c < 128 ? inv[c] : -1;
|
|
1276
|
-
if (v < 0) throw new Error("Invalid base64 data.");
|
|
1277
|
-
acc = acc << 6 | v;
|
|
1278
|
-
bits += 6;
|
|
1279
|
-
if (bits >= 8) {
|
|
1280
|
-
bits -= 8;
|
|
1281
|
-
out[o++] = acc >> bits & 255;
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
return out.subarray(0, o);
|
|
1285
|
-
}
|
|
1286
|
-
function parseDataUrl(url) {
|
|
1287
|
-
const m = /^data:([^;,]*)((?:;[^;,]*)*?),/i.exec(url);
|
|
1288
|
-
if (!m) return null;
|
|
1289
|
-
const body = url.slice(m[0].length);
|
|
1290
|
-
const isBase64 = /;base64/i.test(m[2]);
|
|
1291
|
-
if (isBase64) return { mime: m[1] || "text/plain", bytes: base64ToBytes(body) };
|
|
1292
|
-
const text = decodeURIComponent(body);
|
|
1293
|
-
const bytes = new Uint8Array(text.length);
|
|
1294
|
-
for (let i = 0; i < text.length; i++) bytes[i] = text.charCodeAt(i) & 255;
|
|
1295
|
-
return { mime: m[1] || "text/plain", bytes };
|
|
1296
|
-
}
|
|
1297
|
-
function pngDataUrl(width, height, data, channels = 4) {
|
|
1298
|
-
return `data:image/png;base64,${bytesToBase64(encodePng(width, height, data, channels))}`;
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
989
|
export {
|
|
1302
990
|
PIGMENT_BANDS,
|
|
1303
991
|
PIGMENT_LAMBDA_MIN,
|
|
@@ -1350,12 +1038,5 @@ export {
|
|
|
1350
1038
|
surfaceFromDeepPixels,
|
|
1351
1039
|
convertSurfaceDepth,
|
|
1352
1040
|
deepBytes,
|
|
1353
|
-
keepDeepSamples
|
|
1354
|
-
encodePng,
|
|
1355
|
-
isPng,
|
|
1356
|
-
decodePng,
|
|
1357
|
-
bytesToBase64,
|
|
1358
|
-
base64ToBytes,
|
|
1359
|
-
parseDataUrl,
|
|
1360
|
-
pngDataUrl
|
|
1041
|
+
keepDeepSamples
|
|
1361
1042
|
};
|
|
@@ -168,6 +168,10 @@ function applyEffectMask(result, mask, source) {
|
|
|
168
168
|
}
|
|
169
169
|
return result;
|
|
170
170
|
}
|
|
171
|
+
function layerImageInput(d) {
|
|
172
|
+
const images = d.inputs.filter((i) => i.kind === "image");
|
|
173
|
+
return _nullishCoalesce(_optionalChain([(_nullishCoalesce(_nullishCoalesce(images.find((i) => i.name === "source"), () => ( images.find((i) => i.required))), () => ( images[0]))), 'optionalAccess', _9 => _9.name]), () => ( null));
|
|
174
|
+
}
|
|
171
175
|
var EffectsSlot = (_class = class {constructor() { _class.prototype.__init.call(this);_class.prototype.__init2.call(this); }
|
|
172
176
|
__init() {this.current = null}
|
|
173
177
|
__init2() {this.listeners = /* @__PURE__ */ new Set()}
|
|
@@ -234,7 +238,7 @@ async function sampleEffectCameraMove(provider, id, request) {
|
|
|
234
238
|
}
|
|
235
239
|
var cameraMoveField = (role) => role === "transition" ? "in" : "during";
|
|
236
240
|
function cameraMovesFor(catalog, role) {
|
|
237
|
-
return catalog.filter((e) => e.kind === "camera" && _optionalChain([e, 'access',
|
|
241
|
+
return catalog.filter((e) => e.kind === "camera" && _optionalChain([e, 'access', _10 => _10.camera, 'optionalAccess', _11 => _11.role]) === role);
|
|
238
242
|
}
|
|
239
243
|
function cameraMoveIdList(catalog, role) {
|
|
240
244
|
const ids = cameraMovesFor(catalog, role).map((e) => JSON.stringify(e.id));
|
|
@@ -324,12 +328,12 @@ var summaryOut = (e) => ({
|
|
|
324
328
|
category: e.category,
|
|
325
329
|
uses: e.uses,
|
|
326
330
|
...e.description ? { description: e.description } : {},
|
|
327
|
-
..._optionalChain([e, 'access',
|
|
331
|
+
..._optionalChain([e, 'access', _12 => _12.tags, 'optionalAccess', _13 => _13.length]) ? { tags: e.tags } : {},
|
|
328
332
|
transparent: e.transparent,
|
|
329
333
|
loop: e.loop,
|
|
330
334
|
...e.duration !== void 0 ? { duration: e.duration } : {},
|
|
331
335
|
...e.camera ? { camera: e.camera } : {},
|
|
332
|
-
..._optionalChain([e, 'access',
|
|
336
|
+
..._optionalChain([e, 'access', _14 => _14.accepts, 'optionalAccess', _15 => _15.length]) ? { accepts: e.accepts } : {}
|
|
333
337
|
});
|
|
334
338
|
function createEffectToolProvider(host) {
|
|
335
339
|
let catalog = null;
|
|
@@ -337,7 +341,7 @@ function createEffectToolProvider(host) {
|
|
|
337
341
|
const notify = () => listeners.forEach((l) => l());
|
|
338
342
|
const catalogFor = (provider) => {
|
|
339
343
|
if (!provider) return null;
|
|
340
|
-
if (_optionalChain([catalog, 'optionalAccess',
|
|
344
|
+
if (_optionalChain([catalog, 'optionalAccess', _16 => _16.provider]) !== provider) {
|
|
341
345
|
const entry = { provider, effects: null };
|
|
342
346
|
catalog = entry;
|
|
343
347
|
Promise.resolve().then(() => provider.list()).then((effects) => {
|
|
@@ -373,8 +377,9 @@ function createEffectToolProvider(host) {
|
|
|
373
377
|
description: `${what}: control name \u2192 value, as listed by describe_effect (its "controls" schema: types, ranges, units and defaults). Only the given controls change; colours are "#rrggbb".${keyframes ? " A number control may instead be keyframes { keys: [{ t: ms from the start, v, ease }] }." : ""} Unknown controls and out-of-range values are refused with the valid ones.`
|
|
374
378
|
});
|
|
375
379
|
const effectIdSchema = (uses) => {
|
|
376
|
-
const
|
|
377
|
-
const
|
|
380
|
+
const open = host.applyImageInputs && uses === host.applyUses;
|
|
381
|
+
const effects = open ? void 0 : _optionalChain([catalogFor, 'call', _17 => _17(host.provider()), 'optionalAccess', _18 => _18.filter, 'call', _19 => _19((e) => effectOffered(e, uses))]);
|
|
382
|
+
const base = `An effect id from search_effects (use ${uses.map((u) => `"${u}"`).join(" or ")}${open ? `, or any effect whose describe_effect inputs take an image: the ${host.target.noun} is its picture` : ""}).`;
|
|
378
383
|
return effects && effects.length && effects.length <= ENUM_LIMIT ? { type: "string", enum: effects.map((e) => e.id), description: `${base} One of: ${effects.map((e) => `${e.id} (${e.name})`).join(", ")}.` } : { type: "string", minLength: 1, description: base };
|
|
379
384
|
};
|
|
380
385
|
const context = { requireProvider: writable, valuesSchema, effectIdSchema, annotations: ANNOTATIONS };
|
|
@@ -403,8 +408,8 @@ function createEffectToolProvider(host) {
|
|
|
403
408
|
if (!p) return { available: false, reason: NO_PROVIDER, effects: [], total: 0 };
|
|
404
409
|
const tags = args.tags;
|
|
405
410
|
const accepts = args.accepts;
|
|
406
|
-
let found = (await explain(async () => p.search(_nullishCoalesce(args.query, () => ( "")), { kind: args.kind, category: args.category, use: args.use, tags, ..._optionalChain([accepts, 'optionalAccess',
|
|
407
|
-
if (_optionalChain([accepts, 'optionalAccess',
|
|
411
|
+
let found = (await explain(async () => p.search(_nullishCoalesce(args.query, () => ( "")), { kind: args.kind, category: args.category, use: args.use, tags, ..._optionalChain([accepts, 'optionalAccess', _20 => _20.length]) ? { accepts } : {} }))).filter((e) => hasEffectTags(e, tags));
|
|
412
|
+
if (_optionalChain([accepts, 'optionalAccess', _21 => _21.includes, 'call', _22 => _22("path")])) {
|
|
408
413
|
const kept = [];
|
|
409
414
|
for (const e of found) {
|
|
410
415
|
if (e.accepts) {
|
|
@@ -415,7 +420,7 @@ function createEffectToolProvider(host) {
|
|
|
415
420
|
}
|
|
416
421
|
const limit = _nullishCoalesce(args.limit, () => ( 20));
|
|
417
422
|
const out = { available: true, provider: { id: p.id, name: p.name, capabilities: p.capabilities }, effects: found.slice(0, limit).map(summaryOut), total: found.length, tags: countEffectTags(found).slice(0, TAG_LIMIT) };
|
|
418
|
-
if (_optionalChain([tags, 'optionalAccess',
|
|
423
|
+
if (_optionalChain([tags, 'optionalAccess', _23 => _23.length]) && !found.length) {
|
|
419
424
|
const known = countEffectTags(await explain(async () => p.list()));
|
|
420
425
|
const have = new Set(known.map((k) => k.tag));
|
|
421
426
|
const unknown = tags.filter((t) => !have.has(normaliseEffectTag(t)));
|
|
@@ -435,7 +440,7 @@ function createEffectToolProvider(host) {
|
|
|
435
440
|
if (!p) return { available: false, reason: NO_PROVIDER };
|
|
436
441
|
const d = await explain(async () => p.describe(args.effect));
|
|
437
442
|
const pathControls = pathControlsOf(d);
|
|
438
|
-
return { available: true, ...summaryOut(d), controls: d.controls, defaults: d.defaults, presets: d.presets, inputs: d.inputs, appliesHere: effectOffered(d, host.applyUses), ...pathControls.length ? { pathControls } : {} };
|
|
443
|
+
return { available: true, ...summaryOut(d), controls: d.controls, defaults: d.defaults, presets: d.presets, inputs: d.inputs, appliesHere: effectOffered(d, host.applyUses) || !!host.applyImageInputs && d.kind !== "motion" && layerImageInput(d) !== null, ...pathControls.length ? { pathControls } : {} };
|
|
439
444
|
}
|
|
440
445
|
},
|
|
441
446
|
{
|
|
@@ -531,16 +536,16 @@ function createEffectToolProvider(host) {
|
|
|
531
536
|
...host.description ? { description: host.description } : {},
|
|
532
537
|
...host.skill ? { skill: host.skill } : {},
|
|
533
538
|
tools: () => {
|
|
534
|
-
const extra = _nullishCoalesce(_optionalChain([host, 'access',
|
|
535
|
-
if (host.readOnlyReason()) return [...readTools(), ...extra.filter((t) => _optionalChain([t, 'access',
|
|
539
|
+
const extra = _nullishCoalesce(_optionalChain([host, 'access', _24 => _24.extraTools, 'optionalCall', _25 => _25(context)]), () => ( []));
|
|
540
|
+
if (host.readOnlyReason()) return [...readTools(), ...extra.filter((t) => _optionalChain([t, 'access', _26 => _26.annotations, 'optionalAccess', _27 => _27.readOnlyHint]))];
|
|
536
541
|
return [...readTools(), ...writeTools(), ...extra];
|
|
537
542
|
},
|
|
538
543
|
subscribe: (l) => {
|
|
539
544
|
listeners.add(l);
|
|
540
|
-
const off = _optionalChain([host, 'access',
|
|
545
|
+
const off = _optionalChain([host, 'access', _28 => _28.subscribe, 'optionalCall', _29 => _29(l)]);
|
|
541
546
|
return () => {
|
|
542
547
|
listeners.delete(l);
|
|
543
|
-
_optionalChain([off, 'optionalCall',
|
|
548
|
+
_optionalChain([off, 'optionalCall', _30 => _30()]);
|
|
544
549
|
};
|
|
545
550
|
}
|
|
546
551
|
};
|
|
@@ -592,4 +597,5 @@ function createEffectToolProvider(host) {
|
|
|
592
597
|
|
|
593
598
|
|
|
594
599
|
|
|
595
|
-
|
|
600
|
+
|
|
601
|
+
exports.EFFECT_KINDS = EFFECT_KINDS; exports.EFFECT_USES = EFFECT_USES; exports.CAMERA_MOVE_ROLES = CAMERA_MOVE_ROLES; exports.EFFECT_ACCEPTS = EFFECT_ACCEPTS; exports.EFFECT_PATH_FORMAT = EFFECT_PATH_FORMAT; exports.EFFECT_SUBJECT_KINDS = EFFECT_SUBJECT_KINDS; exports.EFFECT_LAYER_ROLES = EFFECT_LAYER_ROLES; exports.EFFECT_TRANSITION_MS = EFFECT_TRANSITION_MS; exports.EFFECT_TEMPLATE_SLOT_TYPES = EFFECT_TEMPLATE_SLOT_TYPES; exports.EFFECT_ERROR_CODES = EFFECT_ERROR_CODES; exports.EffectError = EffectError; exports.UnknownEffectError = UnknownEffectError; exports.UnknownTemplateError = UnknownTemplateError; exports.EffectControlError = EffectControlError; exports.EffectUnsupportedError = EffectUnsupportedError; exports.EffectDisposedError = EffectDisposedError; exports.NoEffectsProviderError = NoEffectsProviderError; exports.isEffectError = isEffectError; exports.effectValueErrors = effectValueErrors; exports.resolveEffectValues = resolveEffectValues; exports.effectOffered = effectOffered; exports.normaliseEffectTag = normaliseEffectTag; exports.hasEffectTags = hasEffectTags; exports.countEffectTags = countEffectTags; exports.pathControlsOf = pathControlsOf; exports.searchEffectSummaries = searchEffectSummaries; exports.createEffectPixels = createEffectPixels; exports.isEffectPixels = isEffectPixels; exports.srgbToLinear = srgbToLinear; exports.linearToSrgb = linearToSrgb; exports.encodeEffectFloat = encodeEffectFloat; exports.applyEffectMask = applyEffectMask; exports.layerImageInput = layerImageInput; exports.EffectsSlot = EffectsSlot; exports.isCameraView = isCameraView; exports.sampleCameraViews = sampleCameraViews; exports.sampleEffectCameraMove = sampleEffectCameraMove; exports.cameraMoveField = cameraMoveField; exports.cameraMovesFor = cameraMovesFor; exports.cameraMoveIdList = cameraMoveIdList; exports.cameraMoveParts = cameraMoveParts; exports.CAMERA_MOVE_MAX_MS = CAMERA_MOVE_MAX_MS; exports.resolveCameraMoveSpec = resolveCameraMoveSpec; exports.cameraViewOfBox = cameraViewOfBox; exports.cameraBoxOfView = cameraBoxOfView; exports.createEffectToolProvider = createEffectToolProvider;
|
|
@@ -168,6 +168,10 @@ function applyEffectMask(result, mask, source) {
|
|
|
168
168
|
}
|
|
169
169
|
return result;
|
|
170
170
|
}
|
|
171
|
+
function layerImageInput(d) {
|
|
172
|
+
const images = d.inputs.filter((i) => i.kind === "image");
|
|
173
|
+
return (images.find((i) => i.name === "source") ?? images.find((i) => i.required) ?? images[0])?.name ?? null;
|
|
174
|
+
}
|
|
171
175
|
var EffectsSlot = class {
|
|
172
176
|
current = null;
|
|
173
177
|
listeners = /* @__PURE__ */ new Set();
|
|
@@ -373,8 +377,9 @@ function createEffectToolProvider(host) {
|
|
|
373
377
|
description: `${what}: control name \u2192 value, as listed by describe_effect (its "controls" schema: types, ranges, units and defaults). Only the given controls change; colours are "#rrggbb".${keyframes ? " A number control may instead be keyframes { keys: [{ t: ms from the start, v, ease }] }." : ""} Unknown controls and out-of-range values are refused with the valid ones.`
|
|
374
378
|
});
|
|
375
379
|
const effectIdSchema = (uses) => {
|
|
376
|
-
const
|
|
377
|
-
const
|
|
380
|
+
const open = host.applyImageInputs && uses === host.applyUses;
|
|
381
|
+
const effects = open ? void 0 : catalogFor(host.provider())?.filter((e) => effectOffered(e, uses));
|
|
382
|
+
const base = `An effect id from search_effects (use ${uses.map((u) => `"${u}"`).join(" or ")}${open ? `, or any effect whose describe_effect inputs take an image: the ${host.target.noun} is its picture` : ""}).`;
|
|
378
383
|
return effects && effects.length && effects.length <= ENUM_LIMIT ? { type: "string", enum: effects.map((e) => e.id), description: `${base} One of: ${effects.map((e) => `${e.id} (${e.name})`).join(", ")}.` } : { type: "string", minLength: 1, description: base };
|
|
379
384
|
};
|
|
380
385
|
const context = { requireProvider: writable, valuesSchema, effectIdSchema, annotations: ANNOTATIONS };
|
|
@@ -435,7 +440,7 @@ function createEffectToolProvider(host) {
|
|
|
435
440
|
if (!p) return { available: false, reason: NO_PROVIDER };
|
|
436
441
|
const d = await explain(async () => p.describe(args.effect));
|
|
437
442
|
const pathControls = pathControlsOf(d);
|
|
438
|
-
return { available: true, ...summaryOut(d), controls: d.controls, defaults: d.defaults, presets: d.presets, inputs: d.inputs, appliesHere: effectOffered(d, host.applyUses), ...pathControls.length ? { pathControls } : {} };
|
|
443
|
+
return { available: true, ...summaryOut(d), controls: d.controls, defaults: d.defaults, presets: d.presets, inputs: d.inputs, appliesHere: effectOffered(d, host.applyUses) || !!host.applyImageInputs && d.kind !== "motion" && layerImageInput(d) !== null, ...pathControls.length ? { pathControls } : {} };
|
|
439
444
|
}
|
|
440
445
|
},
|
|
441
446
|
{
|
|
@@ -579,6 +584,7 @@ export {
|
|
|
579
584
|
linearToSrgb,
|
|
580
585
|
encodeEffectFloat,
|
|
581
586
|
applyEffectMask,
|
|
587
|
+
layerImageInput,
|
|
582
588
|
EffectsSlot,
|
|
583
589
|
isCameraView,
|
|
584
590
|
sampleCameraViews,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3;
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var _chunk2VX55NFMcjs = require('./chunk-2VX55NFM.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
@@ -64,8 +64,8 @@ function createPigmentTools() {
|
|
|
64
64
|
const rgbs = items.map((item, i) => parseHex(item.color, i));
|
|
65
65
|
const total = items.reduce((sum, item) => sum + item.weight, 0);
|
|
66
66
|
if (!(total > 0)) throw new Error("Every weight is 0; give at least one colour a weight above 0.");
|
|
67
|
-
const pigments = rgbs.map((rgb2, i) =>
|
|
68
|
-
const mixed =
|
|
67
|
+
const pigments = rgbs.map((rgb2, i) => _chunk2VX55NFMcjs.createPigment.call(void 0, rgb2, { strength: items[i].strength }));
|
|
68
|
+
const mixed = _chunk2VX55NFMcjs.mixPigments.call(void 0, pigments, items.map((item) => item.weight));
|
|
69
69
|
const lerp = [0, 1, 2].map((c) => rgbs.reduce((sum, rgb2, i) => sum + rgb2[c] * items[i].weight, 0) / total);
|
|
70
70
|
const rgb = args.model === "rgb";
|
|
71
71
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BUILTIN_BRUSHES
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OTEPAQJX.js";
|
|
4
4
|
import {
|
|
5
5
|
parseProvenance
|
|
6
6
|
} from "./chunk-M6DNZNVY.js";
|
|
@@ -47,7 +47,7 @@ import {
|
|
|
47
47
|
GRAIN_PATTERNS,
|
|
48
48
|
brushstrokeDataUrl,
|
|
49
49
|
isBrushstrokeBrush
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-D5KGAO4Z.js";
|
|
51
51
|
import {
|
|
52
52
|
oklabToRgb,
|
|
53
53
|
rgbToOklab
|