@pixerate/editor 0.266.2 → 0.268.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/dist/agent/index.cjs +2 -2
- package/dist/agent/index.js +1 -1
- package/dist/animation-editor/controller.d.cts +8 -0
- package/dist/animation-editor/controller.d.ts +8 -0
- package/dist/animation-editor/effect-tools.d.cts +1 -1
- package/dist/animation-editor/effect-tools.d.ts +1 -1
- package/dist/animation-editor/index.cjs +175 -108
- package/dist/animation-editor/index.js +94 -27
- package/dist/brushes/index.cjs +201 -75
- package/dist/brushes/index.d.cts +4 -3
- package/dist/brushes/index.d.ts +4 -3
- package/dist/brushes/index.js +138 -12
- package/dist/brushes/library.d.cts +27 -1
- package/dist/brushes/library.d.ts +27 -1
- package/dist/brushes/profiles.d.cts +10 -1
- package/dist/brushes/profiles.d.ts +10 -1
- package/dist/brushes/schema.d.cts +4 -0
- package/dist/brushes/schema.d.ts +4 -0
- package/dist/brushes/sources.d.cts +114 -0
- package/dist/brushes/sources.d.ts +114 -0
- package/dist/brushes/types.d.cts +37 -5
- package/dist/brushes/types.d.ts +37 -5
- package/dist/brushes/ui.d.cts +40 -4
- package/dist/brushes/ui.d.ts +40 -4
- package/dist/{brushstrokeRender-KD453OBX.js → brushstrokeRender-A727TTNQ.js} +7 -7
- package/dist/{brushstrokeRender-FSUWXUZY.cjs → brushstrokeRender-WR2N5HHY.cjs} +23 -23
- package/dist/canvas/brushTypes.d.cts +12 -0
- package/dist/canvas/brushTypes.d.ts +12 -0
- package/dist/canvas/brushstroke.d.cts +1 -1
- package/dist/canvas/brushstroke.d.ts +1 -1
- package/dist/canvas/drawController.d.cts +19 -4
- package/dist/canvas/drawController.d.ts +19 -4
- package/dist/canvas/index.cjs +144 -105
- package/dist/canvas/index.js +46 -7
- package/dist/{chunk-TOID45I2.cjs → chunk-2WOGXEDX.cjs} +1 -1
- package/dist/{chunk-XORJ7UZO.cjs → chunk-3VHH6V67.cjs} +13 -12
- package/dist/{chunk-3C33YTNN.js → chunk-3XDSNIGF.js} +73 -6
- package/dist/chunk-62MFUHSI.cjs +802 -0
- package/dist/{chunk-R44Y3EFS.js → chunk-74ODPZLX.js} +17 -345
- package/dist/{chunk-GCVFEPJG.js → chunk-ACTHSQOI.js} +182 -0
- package/dist/chunk-ADMRNWR7.js +340 -0
- package/dist/{chunk-MVUQSK5J.cjs → chunk-B3G7BKUV.cjs} +111 -439
- package/dist/{chunk-DXYHQ2VN.js → chunk-BAZMCFVL.js} +1 -1
- package/dist/{chunk-VRK322ZC.cjs → chunk-BPJSI4NT.cjs} +2 -2
- package/dist/{chunk-RFJZGTHA.cjs → chunk-EU2ZZA6L.cjs} +400 -69
- package/dist/{chunk-XC6DPRYI.js → chunk-GSTSZPSR.js} +154 -949
- package/dist/{chunk-EZOJBP4D.js → chunk-HFY5LG5J.js} +1 -1
- package/dist/chunk-HVO6XCI4.js +802 -0
- package/dist/{chunk-YHDHFJUC.cjs → chunk-J5VQYK7T.cjs} +217 -1012
- package/dist/{chunk-XRXFVRGY.cjs → chunk-JBB3GDBB.cjs} +2483 -208
- package/dist/{chunk-ACFSFUQH.js → chunk-JL6YH5WD.js} +4 -0
- package/dist/{chunk-CIJBSUM5.js → chunk-KZI3YWKW.js} +353 -22
- package/dist/{chunk-4ODRXQRW.js → chunk-LETF75CA.js} +1 -1
- package/dist/{chunk-FQPUF2W2.cjs → chunk-NIBFKXMD.cjs} +217 -35
- package/dist/{chunk-AQZQWXEU.cjs → chunk-NPWWSCWT.cjs} +35 -35
- package/dist/{chunk-DOZ6F2K2.js → chunk-NSETJI74.js} +3 -2
- package/dist/{chunk-PE6YJMQT.cjs → chunk-PFHJS4HE.cjs} +20 -19
- package/dist/{chunk-7KNW3WXZ.cjs → chunk-QEVLRLUN.cjs} +63 -0
- package/dist/{chunk-LK4SXL3V.js → chunk-QNY7BDFP.js} +1 -1
- package/dist/{chunk-OTN6VB5S.cjs → chunk-RDFHWAHL.cjs} +5 -1
- package/dist/{chunk-PXDIAYB6.cjs → chunk-STLTOISW.cjs} +34 -214
- package/dist/{chunk-T2LDTEXK.js → chunk-UVTO3D4E.js} +2333 -58
- package/dist/{chunk-6JL2D5SG.js → chunk-VE6UKYQ2.js} +3 -2
- package/dist/{chunk-TXFWZ5ZJ.js → chunk-W6JDUXP3.js} +4 -184
- package/dist/{chunk-3SBLVGOM.cjs → chunk-YOVXQHA3.cjs} +23 -23
- package/dist/{chunk-WLUVZKVD.cjs → chunk-YXP6X3SY.cjs} +103 -36
- package/dist/chunk-YZWM6ZIP.cjs +340 -0
- package/dist/{chunk-472INMWH.js → chunk-ZA7L5YJB.js} +63 -0
- package/dist/commands/builtins.d.cts +12 -1
- package/dist/commands/builtins.d.ts +12 -1
- package/dist/commands/index.cjs +2 -2
- package/dist/commands/index.js +1 -1
- package/dist/image-editor/controller.d.cts +1 -1
- package/dist/image-editor/controller.d.ts +1 -1
- package/dist/image-editor/index.cjs +868 -864
- package/dist/image-editor/index.js +123 -119
- package/dist/paint/index.cjs +8 -6
- package/dist/paint/index.js +56 -54
- package/dist/paint-editor/brush-library-tools.d.cts +12 -2
- package/dist/paint-editor/brush-library-tools.d.ts +12 -2
- package/dist/paint-editor/brush-model.d.cts +29 -1
- package/dist/paint-editor/brush-model.d.ts +29 -1
- package/dist/paint-editor/brush-source-art.d.cts +32 -0
- package/dist/paint-editor/brush-source-art.d.ts +32 -0
- package/dist/paint-editor/controller.d.cts +11 -4
- package/dist/paint-editor/controller.d.ts +11 -4
- package/dist/paint-editor/dab-stroke.d.cts +2 -0
- package/dist/paint-editor/dab-stroke.d.ts +2 -0
- package/dist/paint-editor/engine.d.cts +11 -2
- package/dist/paint-editor/engine.d.ts +11 -2
- package/dist/paint-editor/index.cjs +967 -2335
- package/dist/paint-editor/index.d.cts +3 -1
- package/dist/paint-editor/index.d.ts +3 -1
- package/dist/paint-editor/index.js +394 -1762
- package/dist/paint-editor/path-samples.d.cts +2 -0
- package/dist/paint-editor/path-samples.d.ts +2 -0
- package/dist/paint-editor/presence.d.cts +20 -1
- package/dist/paint-editor/presence.d.ts +20 -1
- package/dist/paint-editor/stamp-tip.d.cts +8 -5
- package/dist/paint-editor/stamp-tip.d.ts +8 -5
- package/dist/paint-editor/thumbnails.d.cts +6 -0
- package/dist/paint-editor/thumbnails.d.ts +6 -0
- package/dist/paint-editor/tip-grain.d.cts +34 -0
- package/dist/paint-editor/tip-grain.d.ts +34 -0
- package/dist/raster/index.cjs +2 -2
- package/dist/raster/index.js +9 -9
- package/dist/stickers/helpers.d.cts +2 -0
- package/dist/stickers/helpers.d.ts +2 -0
- package/dist/stickers/index.cjs +41 -35
- package/dist/stickers/index.js +22 -16
- package/dist/stickers/types.d.cts +4 -2
- package/dist/stickers/types.d.ts +4 -2
- package/dist/vector/backdrop.d.cts +13 -0
- package/dist/vector/backdrop.d.ts +13 -0
- package/dist/vector/brushstroke.d.cts +54 -7
- package/dist/vector/brushstroke.d.ts +54 -7
- package/dist/vector/brushstrokeMedia.d.cts +96 -0
- package/dist/vector/brushstrokeMedia.d.ts +96 -0
- package/dist/vector/controller.d.cts +17 -3
- package/dist/vector/controller.d.ts +17 -3
- package/dist/vector/index.cjs +1850 -1390
- package/dist/vector/index.d.cts +2 -0
- package/dist/vector/index.d.ts +2 -0
- package/dist/vector/index.js +520 -60
- package/dist/vector/render.d.cts +6 -0
- package/dist/vector/render.d.ts +6 -0
- package/dist/vector/types.d.cts +14 -0
- package/dist/vector/types.d.ts +14 -0
- package/package.json +1 -1
- package/skills/pixerate-animation-editor/SKILL.md +1 -0
- package/skills/pixerate-brushes/SKILL.md +37 -10
- package/skills/pixerate-brushes-design/SKILL.md +15 -5
- package/skills/pixerate-brushes-design/evals/port-to-vector.json +8 -8
- package/skills/pixerate-canvas/SKILL.md +11 -1
- package/skills/pixerate-image-editor/SKILL.md +19 -64
- package/skills/pixerate-image-editor/references/color-management.md +2 -1
- package/skills/pixerate-image-editor/references/free-transform.md +12 -0
- package/skills/pixerate-image-editor/references/layer-effects.md +10 -0
- package/skills/pixerate-image-editor/references/painting.md +17 -0
- package/skills/pixerate-image-editor/references/photoshop-files.md +1 -1
- package/skills/pixerate-image-editor/references/shapes-and-type.md +14 -0
- package/skills/pixerate-image-editor/references/smart-objects.md +10 -0
- package/skills/pixerate-paint-editor/SKILL.md +14 -4
- package/skills/pixerate-paint-editor/references/brush-facets.md +3 -1
- package/skills/pixerate-paint-editor/references/wet-media.md +9 -0
- package/skills/pixerate-paint-sketch-to-finish/SKILL.md +1 -0
- package/skills/pixerate-vector/SKILL.md +16 -6
- package/skills/pixerate-vector/references/best-practices.md +1 -0
- package/skills/pixerate-vector/references/commands.md +19 -0
package/dist/canvas/index.js
CHANGED
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
resolveCanvasBrushSpec,
|
|
47
47
|
validateCanvasBrush,
|
|
48
48
|
validateCanvasBrushPaint
|
|
49
|
-
} from "../chunk-
|
|
49
|
+
} from "../chunk-BAZMCFVL.js";
|
|
50
50
|
import {
|
|
51
51
|
PATHFINDER_OPERATIONS,
|
|
52
52
|
PlanarMap,
|
|
@@ -8080,6 +8080,8 @@ function createCanvasDrawController(options) {
|
|
|
8080
8080
|
};
|
|
8081
8081
|
let activeStroke = null;
|
|
8082
8082
|
let colorScheme = options.colorScheme === "dark" ? "dark" : "light";
|
|
8083
|
+
let colorLocked = !!options.colorLocked;
|
|
8084
|
+
let brushColour = null;
|
|
8083
8085
|
const erasedInDrag = /* @__PURE__ */ new Map();
|
|
8084
8086
|
let dragStartNodes = null;
|
|
8085
8087
|
function setTool(tool) {
|
|
@@ -8091,11 +8093,16 @@ function createCanvasDrawController(options) {
|
|
|
8091
8093
|
...createDefaultStrokeStyle(tool),
|
|
8092
8094
|
...options.style
|
|
8093
8095
|
};
|
|
8096
|
+
brushColour = null;
|
|
8094
8097
|
options.onStyleChange?.(currentStyle);
|
|
8095
8098
|
}
|
|
8096
8099
|
options.onToolChange?.(tool);
|
|
8097
8100
|
}
|
|
8098
8101
|
function setStyle(style) {
|
|
8102
|
+
if (style.color !== void 0) brushColour = null;
|
|
8103
|
+
applyStyle(style);
|
|
8104
|
+
}
|
|
8105
|
+
function applyStyle(style) {
|
|
8099
8106
|
currentStyle = { ...currentStyle, ...style };
|
|
8100
8107
|
options.onStyleChange?.(currentStyle);
|
|
8101
8108
|
}
|
|
@@ -8312,8 +8319,10 @@ function createCanvasDrawController(options) {
|
|
|
8312
8319
|
/**
|
|
8313
8320
|
* A brush picker's choice: brushes the pen and highlighter with `id` (`null`: a plain vector
|
|
8314
8321
|
* stroke) at the brush's own size, embedding a saved brush, and makes its default colour
|
|
8315
|
-
* (resolved for the colour scheme) the stroke colour unless `keepColour
|
|
8316
|
-
*
|
|
8322
|
+
* (resolved for the colour scheme) the stroke colour unless `keepColour` or the colour is
|
|
8323
|
+
* locked (`setColorLocked`). A light / dark default resolves again when the scheme changes,
|
|
8324
|
+
* until another colour is set. Throws for a brush the canvas can't paint. Resolves with the
|
|
8325
|
+
* brush chosen.
|
|
8317
8326
|
*/
|
|
8318
8327
|
async selectBrush(id, choice = {}) {
|
|
8319
8328
|
if (id === null) {
|
|
@@ -8325,13 +8334,43 @@ function createCanvasDrawController(options) {
|
|
|
8325
8334
|
await validateCanvasBrush(id);
|
|
8326
8335
|
throw new Error(`Brush '${id}' is not one the canvas can paint; listBrushes lists them.`);
|
|
8327
8336
|
}
|
|
8328
|
-
const hex = !choice.keepColour && preset.defaultColor !== void 0 ? brushColourHex(preset.defaultColor, colorScheme) : null;
|
|
8329
|
-
|
|
8337
|
+
const hex = !choice.keepColour && !colorLocked && preset.defaultColor !== void 0 ? brushColourHex(preset.defaultColor, colorScheme) : null;
|
|
8338
|
+
if (hex) brushColour = preset.defaultColor ?? null;
|
|
8339
|
+
applyStyle({ brush: id, brushSize: preset.size, brushSpec: preset.spec, ...hex ? { color: hex } : {} });
|
|
8330
8340
|
return preset;
|
|
8331
8341
|
},
|
|
8332
|
-
|
|
8342
|
+
get colorScheme() {
|
|
8343
|
+
return colorScheme;
|
|
8344
|
+
},
|
|
8345
|
+
/**
|
|
8346
|
+
* The host's colour scheme, for brushes' light / dark default colours: a stroke colour that
|
|
8347
|
+
* came from one (`selectBrush`) resolves to the new side. Strokes already drawn keep theirs.
|
|
8348
|
+
*/
|
|
8333
8349
|
setColorScheme(scheme) {
|
|
8334
|
-
|
|
8350
|
+
const next = scheme === "dark" ? "dark" : "light";
|
|
8351
|
+
if (next === colorScheme) return;
|
|
8352
|
+
colorScheme = next;
|
|
8353
|
+
const hex = brushColour ? brushColourHex(brushColour, next) : null;
|
|
8354
|
+
if (hex && hex !== currentStyle.color) applyStyle({ color: hex });
|
|
8355
|
+
},
|
|
8356
|
+
get colorLocked() {
|
|
8357
|
+
return colorLocked;
|
|
8358
|
+
},
|
|
8359
|
+
/** Locks the stroke colour ("Keep my colour"): choosing a brush with a default colour keeps it. */
|
|
8360
|
+
setColorLocked(locked) {
|
|
8361
|
+
if (colorLocked === !!locked) return;
|
|
8362
|
+
colorLocked = !!locked;
|
|
8363
|
+
options.onColorLockChange?.(colorLocked);
|
|
8364
|
+
},
|
|
8365
|
+
/** What the brush picker is set to: the brush, colour, scheme and lock (a snapshot). */
|
|
8366
|
+
brushSettings() {
|
|
8367
|
+
return {
|
|
8368
|
+
brush: typeof currentStyle.brush === "string" ? currentStyle.brush : null,
|
|
8369
|
+
color: typeof currentStyle.color === "string" ? currentStyle.color : null,
|
|
8370
|
+
colorScheme,
|
|
8371
|
+
colorLocked,
|
|
8372
|
+
colorFollowsScheme: brushColour !== null && typeof brushColour === "object"
|
|
8373
|
+
};
|
|
8335
8374
|
},
|
|
8336
8375
|
/** The saved brush to embed for a brush id (undefined for presets and tip settings); for a brush picker. */
|
|
8337
8376
|
brushSpec: (brush) => resolveCanvasBrushSpec(brush, options.brushLibrary)
|
|
@@ -74,7 +74,7 @@ function profileAlongPolyline(points, values, count = 32) {
|
|
|
74
74
|
var round3 = (v) => Math.round(v * 1e3) / 1e3;
|
|
75
75
|
var loading = null;
|
|
76
76
|
function loadCanvasBrushstrokeRenderer() {
|
|
77
|
-
loading ??= Promise.resolve().then(() => _interopRequireWildcard(require("./brushstrokeRender-
|
|
77
|
+
loading ??= Promise.resolve().then(() => _interopRequireWildcard(require("./brushstrokeRender-WR2N5HHY.cjs"))).catch((error) => {
|
|
78
78
|
loading = null;
|
|
79
79
|
throw error;
|
|
80
80
|
});
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
var _chunkRDFHWAHLcjs = require('./chunk-RDFHWAHL.cjs');
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
var _chunkU67EN7GGcjs = require('./chunk-U67EN7GG.cjs');
|
|
@@ -33,7 +34,7 @@ var HEX = /^#[0-9a-fA-F]{6}$/;
|
|
|
33
34
|
function stampOutline(kind) {
|
|
34
35
|
const n = GRID;
|
|
35
36
|
const f = new Float32Array((n + 1) * (n + 1));
|
|
36
|
-
for (let j = 0; j <= n; j++) for (let i = 0; i <= n; i++) f[j * (n + 1) + i] =
|
|
37
|
+
for (let j = 0; j <= n; j++) for (let i = 0; i <= n; i++) f[j * (n + 1) + i] = _chunkRDFHWAHLcjs.stampCoverage.call(void 0, kind, i / n * 2 - 1, j / n * 2 - 1, SHAPE_SEED) - 0.5;
|
|
37
38
|
const at = (i, j) => f[j * (n + 1) + i];
|
|
38
39
|
const points = /* @__PURE__ */ new Map();
|
|
39
40
|
const point = (key, i0, j0, i1, j1) => {
|
|
@@ -170,7 +171,7 @@ function stampPixels(kind, size, colour) {
|
|
|
170
171
|
for (let y = 0; y < size; y++) {
|
|
171
172
|
for (let x = 0; x < size; x++) {
|
|
172
173
|
let c = 0;
|
|
173
|
-
for (let sy = 0; sy < ss; sy++) for (let sx = 0; sx < ss; sx++) c +=
|
|
174
|
+
for (let sy = 0; sy < ss; sy++) for (let sx = 0; sx < ss; sx++) c += _chunkRDFHWAHLcjs.stampCoverage.call(void 0, kind, (x + (sx + 0.5) / ss) / size * 2 - 1, (y + (sy + 0.5) / ss) / size * 2 - 1, SHAPE_SEED);
|
|
174
175
|
const a = Math.round(c / (ss * ss) * 255);
|
|
175
176
|
if (!a) continue;
|
|
176
177
|
const i = (y * size + x) * 4;
|
|
@@ -192,25 +193,25 @@ function editorStickers() {
|
|
|
192
193
|
return { id: k, name: m.name, category: m.category, tags: m.tags, description: m.description, width: BOX, height: BOX, thumbnail: thumbs.get(k), formats: ["svg", "png"], licence: { ...LICENCE }, tintable: true };
|
|
193
194
|
};
|
|
194
195
|
const kind = (id) => {
|
|
195
|
-
if (!
|
|
196
|
+
if (!_chunkRDFHWAHLcjs.STAMP_KINDS.includes(id)) throw new (0, _chunkU67EN7GGcjs.StickerError)("unknown_sticker", `The editor has no sticker "${id}"; its stickers are ${_chunkRDFHWAHLcjs.STAMP_KINDS.join(", ")}.`);
|
|
196
197
|
return id;
|
|
197
198
|
};
|
|
198
199
|
return {
|
|
199
|
-
id:
|
|
200
|
+
id: _chunkRDFHWAHLcjs.EDITOR_STICKERS_ID,
|
|
200
201
|
name: "Editor stickers",
|
|
201
202
|
version: "1",
|
|
202
203
|
capabilities: { supportsSearch: true, supportsSvg: true, supportsRaster: true, maxSize: 1024 },
|
|
203
|
-
list: (options) =>
|
|
204
|
-
search: (query, options) =>
|
|
204
|
+
list: (options) => _chunkRDFHWAHLcjs.stickerPage.call(void 0, _chunkRDFHWAHLcjs.STAMP_KINDS.map(summary), options),
|
|
205
|
+
search: (query, options) => _chunkRDFHWAHLcjs.stickerPage.call(void 0, _chunkRDFHWAHLcjs.STAMP_KINDS.map(summary), options, query),
|
|
205
206
|
describe(id) {
|
|
206
|
-
if (!
|
|
207
|
+
if (!_chunkRDFHWAHLcjs.STAMP_KINDS.includes(id)) return void 0;
|
|
207
208
|
const k = id;
|
|
208
209
|
return { ...summary(k), silhouette: outline(k), colours: [META[k].colour] };
|
|
209
210
|
},
|
|
210
|
-
categories: () => [...new Set(
|
|
211
|
+
categories: () => [...new Set(_chunkRDFHWAHLcjs.STAMP_KINDS.map((k) => META[k].category))].map((c) => ({ id: c, name: c[0].toUpperCase() + c.slice(1), count: _chunkRDFHWAHLcjs.STAMP_KINDS.filter((k) => META[k].category === c).length })),
|
|
211
212
|
load(id, options = {}) {
|
|
212
213
|
const k = kind(id);
|
|
213
|
-
|
|
214
|
+
_chunkRDFHWAHLcjs.checkStickerVariant.call(void 0, { id: k }, options.variant);
|
|
214
215
|
const colour = _nullishCoalesce(options.colour, () => ( META[k].colour));
|
|
215
216
|
if (!HEX.test(colour)) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `colour ${JSON.stringify(colour)} must be #rrggbb.`);
|
|
216
217
|
if (options.format === "png") {
|
|
@@ -258,7 +259,7 @@ var StickerBrowser = (_class = class {
|
|
|
258
259
|
this.set({ loading: true, error: null, items: [], total: 0, hasMore: false, provider: p.name });
|
|
259
260
|
try {
|
|
260
261
|
const categories = await _asyncNullishCoalesce(await _optionalChain([p, 'access', _2 => _2.categories, 'optionalCall', _3 => _3()]), async () => ( []));
|
|
261
|
-
const collections = await _asyncNullishCoalesce(await
|
|
262
|
+
const collections = await _asyncNullishCoalesce(await _chunkRDFHWAHLcjs.providerCollections.call(void 0, p), async () => ( []));
|
|
262
263
|
if (run !== this.run) return;
|
|
263
264
|
this.set({ categories, collections, ...this.s.collection && !collections.some((c) => c.id === this.s.collection) ? { collection: "" } : {} });
|
|
264
265
|
await this.page(run, p, true);
|
|
@@ -298,7 +299,7 @@ var StickerBrowser = (_class = class {
|
|
|
298
299
|
const res = q && p.capabilities.supportsSearch ? await p.search(q, options) : await p.list(options);
|
|
299
300
|
if (run !== this.run) return;
|
|
300
301
|
this.next = res.next;
|
|
301
|
-
const items = res.items.map((s) => ({ ...s, ref:
|
|
302
|
+
const items = res.items.map((s) => ({ ...s, ref: _chunkRDFHWAHLcjs.stickerRefOf.call(void 0, p, s.id) }));
|
|
302
303
|
this.set({ items: first ? items : [...this.s.items, ...items], total: res.total, hasMore: Boolean(res.next), loading: false });
|
|
303
304
|
}
|
|
304
305
|
}, _class);
|
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
2
|
describeStickerRef
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VE6UKYQ2.js";
|
|
4
4
|
import {
|
|
5
5
|
BRUSH_HOST_PROFILES,
|
|
6
6
|
BRUSH_JSON_SCHEMA,
|
|
7
7
|
BRUSH_KINDS,
|
|
8
8
|
BRUSH_MEDIA,
|
|
9
|
+
BRUSH_SOURCE_CHANNELS,
|
|
9
10
|
BRUSH_TOOLS,
|
|
10
11
|
BrushLibraryError,
|
|
12
|
+
MAX_BRUSH_SOURCE_INPUT_PIXELS,
|
|
13
|
+
MAX_BRUSH_SOURCE_SIZE,
|
|
11
14
|
PAINT_PROFILE,
|
|
15
|
+
brushSourceIdOf,
|
|
16
|
+
brushSourceIds,
|
|
17
|
+
brushSourceRef,
|
|
12
18
|
checkBrush,
|
|
13
19
|
closest,
|
|
14
20
|
degrade,
|
|
21
|
+
isBrushSourceRef,
|
|
15
22
|
normalizeBrushSpec,
|
|
16
23
|
resolveCategory,
|
|
17
24
|
resolveEngine,
|
|
25
|
+
summarizeBrushSource,
|
|
18
26
|
withKeptIssues
|
|
19
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-KZI3YWKW.js";
|
|
20
28
|
|
|
21
29
|
// src/brushes/patch.ts
|
|
22
30
|
var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
@@ -101,11 +109,18 @@ function createBrushLibraryTools(library, options = {}) {
|
|
|
101
109
|
};
|
|
102
110
|
const checkFor = async (brush, p) => {
|
|
103
111
|
const check2 = checkBrush(brush, p);
|
|
104
|
-
const provider = options.stickers?.();
|
|
105
|
-
if (!provider || brush.tip.shape !== "stamp") return check2;
|
|
106
112
|
const issues = [...check2.issues];
|
|
113
|
+
const refs = [...(brush.tip.stamps ?? []).map((r) => ["tip.stamps", r]), ...brush.tip.grain ? [["tip.grain.source", brush.tip.grain.source]] : []];
|
|
114
|
+
for (const [facet, ref] of refs) {
|
|
115
|
+
const id = brushSourceIdOf(ref);
|
|
116
|
+
if (id === null || await library.getSource(id)) continue;
|
|
117
|
+
const ids = (await library.listSources()).map((x) => x.id);
|
|
118
|
+
issues.push({ facet, severity: "error", reason: `There is no image source "${id}" in the brush library. ${closest(id, ids)}`.trim(), fix: "Add it with add_brush_source, or use a ref list_brush_sources lists." });
|
|
119
|
+
}
|
|
120
|
+
const provider = options.stickers?.();
|
|
121
|
+
if (!provider || brush.tip.shape !== "stamp") return { ok: !issues.some((i) => i.severity === "error"), issues };
|
|
107
122
|
for (const ref of brush.tip.stamps ?? []) {
|
|
108
|
-
if (ref.startsWith("editor:")) continue;
|
|
123
|
+
if (ref.startsWith("editor:") || isBrushSourceRef(ref)) continue;
|
|
109
124
|
try {
|
|
110
125
|
await describeStickerRef(provider, ref);
|
|
111
126
|
} catch (e) {
|
|
@@ -207,7 +222,34 @@ function createBrushLibraryTools(library, options = {}) {
|
|
|
207
222
|
annotations: { title: "Export brushes", ...READ },
|
|
208
223
|
handler: async ({ ids }) => ({ file: await library.exportFile(ids) })
|
|
209
224
|
};
|
|
210
|
-
const
|
|
225
|
+
const listSources = {
|
|
226
|
+
name: "list_brush_sources",
|
|
227
|
+
title: "List brush image sources",
|
|
228
|
+
description: "Lists the image sources in the brush library: the images image tips and image grain are made from. Returns each source's id, ref (source:<id>, for tip.stamps of a stamp tip or tip.grain.source in create_brush / update_brush), name, width and height in px, licence and origin when it has them, and usedBy (the saved brushes that name it), plus total. Built-in grain patterns need no source. Changes nothing.",
|
|
229
|
+
inputSchema: {
|
|
230
|
+
type: "object",
|
|
231
|
+
properties: {
|
|
232
|
+
text: { type: "string", maxLength: 200, description: "Words in the id, name or origin (each word must match the start of one)." },
|
|
233
|
+
offset: { type: "integer", minimum: 0, description: "Skip this many (default 0)." },
|
|
234
|
+
limit: { type: "integer", minimum: 1, maximum: 200, description: "At most this many (default 100)." }
|
|
235
|
+
},
|
|
236
|
+
additionalProperties: false
|
|
237
|
+
},
|
|
238
|
+
annotations: { title: "List brush image sources", ...READ },
|
|
239
|
+
handler: async ({ text, offset, limit }) => {
|
|
240
|
+
const brushes = (await library.list({ source: "user" })).map((e) => e.brush);
|
|
241
|
+
const wordsOf = (v) => v.toLowerCase().split(/[^\p{L}\p{N}]+/u).filter(Boolean);
|
|
242
|
+
const want = typeof text === "string" ? wordsOf(text) : [];
|
|
243
|
+
const found = (await library.listSources()).filter((x) => {
|
|
244
|
+
const have = wordsOf([x.id, x.name, x.origin ?? ""].join(" "));
|
|
245
|
+
return want.every((w) => have.some((h) => h.startsWith(w)));
|
|
246
|
+
});
|
|
247
|
+
const start = offset ?? 0;
|
|
248
|
+
const page = found.slice(start, start + (limit ?? 100));
|
|
249
|
+
return { total: found.length, sources: page.map((x) => ({ ...summarizeBrushSource(x), usedBy: brushes.filter((b) => brushSourceIds(b).includes(x.id)).map((b) => b.id) })) };
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
const tools = [list, describe, check, exportTool, listSources];
|
|
211
253
|
if (options.renderPreview) {
|
|
212
254
|
const render = options.renderPreview;
|
|
213
255
|
tools.push({
|
|
@@ -288,6 +330,31 @@ function createBrushLibraryTools(library, options = {}) {
|
|
|
288
330
|
return { id, brush: saved.brush, changed: changedPaths(e.brush, saved.brush), problems: saved.problems, warnings: warnings(saved.check), ...saved.check.kept.length ? { kept: saved.check.kept } : {} };
|
|
289
331
|
}
|
|
290
332
|
},
|
|
333
|
+
{
|
|
334
|
+
name: "add_brush_source",
|
|
335
|
+
title: "Add a brush image source",
|
|
336
|
+
description: `Adds an image to the brush library as a source for image tips and image grain (as Procreate's shape and grain sources). The image is a PNG data: URL; the marks are read from its transparency, its dark parts (a scan of marks on paper) or its light parts (white on black), as channel says, and kept as a grey mask at most ${MAX_BRUSH_SOURCE_SIZE} px on a side. Returns id, ref (source:<id>), the stored source's width and height, problems (the channel auto picked, scaling) and replaced. Then make the brush: create_brush or update_brush with tip { shape: "stamp", stamps: [ref] } for an image tip, or tip.grain { source: ref } for grain. A taken id is refused unless overwrite.`,
|
|
337
|
+
inputSchema: {
|
|
338
|
+
type: "object",
|
|
339
|
+
properties: {
|
|
340
|
+
name: { type: "string", minLength: 1, maxLength: 80, description: 'Display name, e.g. "Charcoal scan".' },
|
|
341
|
+
image: { type: "string", pattern: "^data:image/png;base64,", maxLength: 4e7, description: `The image: a PNG data: URL, at most ${MAX_BRUSH_SOURCE_INPUT_PIXELS} pixels; larger than ${MAX_BRUSH_SOURCE_SIZE} px it is scaled down.` },
|
|
342
|
+
id: { type: "string", pattern: String(FACETS2.id.pattern), description: "The source id (default: from the name, made unique): lowercase letters, digits and dashes." },
|
|
343
|
+
channel: { type: "string", enum: [...BRUSH_SOURCE_CHANNELS], description: "Where the marks are: auto (default: the transparency when the image has any, else the dark parts), alpha, darkness (dark marks on light paper) or lightness (light marks on black)." },
|
|
344
|
+
invert: { type: "boolean", description: "Swap painted and empty parts (default false)." },
|
|
345
|
+
licence: { type: "string", maxLength: 2e3, description: "The licence or terms the image came with, kept with the source." },
|
|
346
|
+
origin: { type: "string", maxLength: 200, description: "Where it came from: a file name, a pack or a URL." },
|
|
347
|
+
overwrite: { type: "boolean", description: "Replace the image of a source with the same id (default false); brushes using it change with it." }
|
|
348
|
+
},
|
|
349
|
+
required: ["name", "image"],
|
|
350
|
+
additionalProperties: false
|
|
351
|
+
},
|
|
352
|
+
annotations: { title: "Add a brush image source", ...WRITE },
|
|
353
|
+
handler: async ({ overwrite, ...input }) => {
|
|
354
|
+
const r = await library.addSource(input, { overwrite: !!overwrite });
|
|
355
|
+
return { id: r.source.id, ref: brushSourceRef(r.source.id), width: r.source.width, height: r.source.height, problems: r.problems, replaced: r.replaced };
|
|
356
|
+
}
|
|
357
|
+
},
|
|
291
358
|
{
|
|
292
359
|
name: "duplicate_brush",
|
|
293
360
|
title: "Duplicate a brush",
|