@pixerate/editor 0.172.0 → 0.174.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/animation-editor/index.cjs +9 -9
- package/dist/animation-editor/index.js +1 -1
- package/dist/canvas/index.cjs +7 -7
- package/dist/canvas/index.js +1 -1
- package/dist/{chunk-CYKWYP6D.cjs → chunk-6DUEV36F.cjs} +14 -14
- package/dist/{chunk-7KWJEYIK.js → chunk-6G2NLMVK.js} +36 -4
- package/dist/{chunk-RUZQMYXH.cjs → chunk-A3A5TI6R.cjs} +43 -11
- package/dist/chunk-NZ3CTY7K.js +260 -0
- package/dist/{chunk-YN4AYYBJ.js → chunk-OZSA5YEJ.js} +1 -1
- package/dist/chunk-VCL7CB56.cjs +260 -0
- package/dist/{chunk-HCC2LBCW.js → chunk-WMVEYSOA.js} +1 -1
- package/dist/{chunk-3OSXHLIT.cjs → chunk-Z64NRDEH.cjs} +7 -7
- package/dist/commands/format.d.cts +43 -0
- package/dist/commands/format.d.ts +43 -0
- package/dist/commands/index.cjs +7 -1
- package/dist/commands/index.d.cts +1 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.js +6 -0
- package/dist/effects/helpers.d.cts +11 -2
- package/dist/effects/helpers.d.ts +11 -2
- package/dist/effects/index.cjs +40 -34
- package/dist/effects/index.js +8 -2
- package/dist/effects/types.d.cts +2 -0
- package/dist/effects/types.d.ts +2 -0
- package/dist/image-editor/index.cjs +13 -13
- package/dist/image-editor/index.js +1 -1
- package/dist/index.cjs +7 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -0
- package/dist/paint-editor/index.cjs +7 -7
- package/dist/paint-editor/index.js +2 -2
- package/dist/vector/index.cjs +6 -6
- package/dist/vector/index.js +1 -1
- package/dist/video-editor/index.cjs +309 -309
- package/dist/video-editor/index.js +3 -3
- package/package.json +4 -1
|
@@ -48,7 +48,7 @@ require('../chunk-NM3G4VQT.cjs');
|
|
|
48
48
|
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
var
|
|
51
|
+
var _chunkA3A5TI6Rcjs = require('../chunk-A3A5TI6R.cjs');
|
|
52
52
|
require('../chunk-WOFXZ3XU.cjs');
|
|
53
53
|
require('../chunk-EBDCRTZI.cjs');
|
|
54
54
|
require('../chunk-YQGCPL5X.cjs');
|
|
@@ -3827,7 +3827,7 @@ var AnimationEditorController = (_class = class {
|
|
|
3827
3827
|
|
|
3828
3828
|
|
|
3829
3829
|
/** The effects provider slot (see `setEffectsProvider`). */
|
|
3830
|
-
__init() {this.effects = new (0,
|
|
3830
|
+
__init() {this.effects = new (0, _chunkA3A5TI6Rcjs.EffectsSlot)()}
|
|
3831
3831
|
|
|
3832
3832
|
|
|
3833
3833
|
__init2() {this.selection = null}
|
|
@@ -4012,7 +4012,7 @@ var AnimationEditorController = (_class = class {
|
|
|
4012
4012
|
try {
|
|
4013
4013
|
plan = await work();
|
|
4014
4014
|
} catch (error) {
|
|
4015
|
-
if (
|
|
4015
|
+
if (_chunkA3A5TI6Rcjs.isEffectError.call(void 0, error) || error instanceof Error) return this.refuse(error.message);
|
|
4016
4016
|
throw error;
|
|
4017
4017
|
}
|
|
4018
4018
|
const r = this.apply({ op: "replace_scene", scene: plan.scene }, plan.label, { merge });
|
|
@@ -4023,11 +4023,11 @@ var AnimationEditorController = (_class = class {
|
|
|
4023
4023
|
}
|
|
4024
4024
|
async describeFor(effect, kinds) {
|
|
4025
4025
|
const provider = this.effects.require();
|
|
4026
|
-
if (!provider.applyVectorEffect) throw new (0,
|
|
4026
|
+
if (!provider.applyVectorEffect) throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`${provider.name} has no vector or motion effects.`);
|
|
4027
4027
|
const d = await provider.describe(effect);
|
|
4028
4028
|
if (!kinds.includes(d.kind)) {
|
|
4029
4029
|
const hint = d.kind === "motion" ? "apply it to nodes with apply_effect" : d.kind === "vector" ? "add it with add_vector_effect" : "it draws pixels, which scenes cannot hold";
|
|
4030
|
-
throw new (0,
|
|
4030
|
+
throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`"${d.id}" (${d.name}) is a ${d.kind} effect: ${hint}.`, d.id);
|
|
4031
4031
|
}
|
|
4032
4032
|
return d;
|
|
4033
4033
|
}
|
|
@@ -4048,7 +4048,7 @@ var AnimationEditorController = (_class = class {
|
|
|
4048
4048
|
return this.effectEdit(async () => {
|
|
4049
4049
|
this.knownNodes(targets);
|
|
4050
4050
|
const d = await this.describeFor(effect, ["motion"]);
|
|
4051
|
-
const values =
|
|
4051
|
+
const values = _chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, d, options.values);
|
|
4052
4052
|
const instance = _nullishCoalesce(options.instance, () => ( nextMotionEffectInstance(this.scene)));
|
|
4053
4053
|
const motion = await this.effects.require().applyVectorEffect(d.id, { svg: motionArtworkSvg(this.scene.artwork), nodeIds: [...targets] }, values);
|
|
4054
4054
|
const source = { instance, effect: d.id, provider: this.effects.require().id, name: d.name, values };
|
|
@@ -4070,7 +4070,7 @@ var AnimationEditorController = (_class = class {
|
|
|
4070
4070
|
addVectorEffect(effect, options = {}) {
|
|
4071
4071
|
return this.effectEdit(async () => {
|
|
4072
4072
|
const d = await this.describeFor(effect, ["vector"]);
|
|
4073
|
-
const values =
|
|
4073
|
+
const values = _chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, d, options.values);
|
|
4074
4074
|
const instance = _nullishCoalesce(options.instance, () => ( nextMotionEffectInstance(this.scene)));
|
|
4075
4075
|
const motion = await this.effects.require().applyVectorEffect(d.id, motionArtworkSvg(this.scene.artwork), values);
|
|
4076
4076
|
const source = { instance, effect: d.id, provider: this.effects.require().id, name: d.name, values };
|
|
@@ -4094,7 +4094,7 @@ var AnimationEditorController = (_class = class {
|
|
|
4094
4094
|
else if (k in d.controls.properties) base[k] = d.defaults[k];
|
|
4095
4095
|
else throw new Error(`"${k}" is not a control of "${d.id}"; its controls are ${Object.keys(d.controls.properties).join(", ")}.`);
|
|
4096
4096
|
}
|
|
4097
|
-
const merged = { ...base, ...
|
|
4097
|
+
const merged = { ...base, ..._chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, { ...d, defaults: base }, given) };
|
|
4098
4098
|
const { scene: bare, place } = withoutMotionEffect(this.scene, instance);
|
|
4099
4099
|
const provider = this.effects.require();
|
|
4100
4100
|
const source = { instance, effect: d.id, provider: provider.id, name: d.name, values: merged };
|
|
@@ -5867,7 +5867,7 @@ function createAnimationEffectsToolProvider(controller, options = {}) {
|
|
|
5867
5867
|
if (!r.ok) throw new Error(r.error);
|
|
5868
5868
|
return { target, effect: info(r.effect), effects: controller.appliedEffects().filter((e) => e.targets.includes(target)).map(info), ...r.notes.length ? { notes: r.notes } : {} };
|
|
5869
5869
|
};
|
|
5870
|
-
return withAnimationPlayback(
|
|
5870
|
+
return withAnimationPlayback(_chunkA3A5TI6Rcjs.createEffectToolProvider.call(void 0, {
|
|
5871
5871
|
id: _nullishCoalesce(options.id, () => ( "animation-effects")),
|
|
5872
5872
|
namespace: options.namespace,
|
|
5873
5873
|
title: "Animation effects",
|
package/dist/canvas/index.cjs
CHANGED
|
@@ -209,7 +209,7 @@ var _chunkNM3G4VQTcjs = require('../chunk-NM3G4VQT.cjs');
|
|
|
209
209
|
|
|
210
210
|
|
|
211
211
|
|
|
212
|
-
var
|
|
212
|
+
var _chunkA3A5TI6Rcjs = require('../chunk-A3A5TI6R.cjs');
|
|
213
213
|
require('../chunk-WOFXZ3XU.cjs');
|
|
214
214
|
|
|
215
215
|
|
|
@@ -11396,14 +11396,14 @@ function canvasNodeEffect(node) {
|
|
|
11396
11396
|
return _chunkNM3G4VQTcjs.isShapeDescription.call(void 0, shape) ? shape.effect : void 0;
|
|
11397
11397
|
}
|
|
11398
11398
|
function createCanvasEffectsController(options) {
|
|
11399
|
-
const slot = new (0,
|
|
11399
|
+
const slot = new (0, _chunkA3A5TI6Rcjs.EffectsSlot)();
|
|
11400
11400
|
if (options.effects) slot.set(options.effects);
|
|
11401
11401
|
const describe = async (effect, place2) => {
|
|
11402
11402
|
const d = await slot.require().describe(effect);
|
|
11403
11403
|
const allowed = CANVAS_EFFECT_PLACES[place2];
|
|
11404
11404
|
if (d.kind === "motion" || !d.uses.some((u) => allowed.includes(u))) {
|
|
11405
11405
|
const where = place2 === "transition" ? "a scene transition" : place2 === "fill" ? "a fill" : "an overlay";
|
|
11406
|
-
throw new (0,
|
|
11406
|
+
throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(`"${d.id}" (${d.name}) is a ${d.uses.join(" / ")} effect and cannot be ${where}, which takes ${allowed.join(" or ")} effects; search_effects with use "${allowed[0]}" lists ones that fit.`, d.id);
|
|
11407
11407
|
}
|
|
11408
11408
|
return d;
|
|
11409
11409
|
};
|
|
@@ -11434,7 +11434,7 @@ function createCanvasEffectsController(options) {
|
|
|
11434
11434
|
else if (k in d.controls.properties) base[k] = d.defaults[k];
|
|
11435
11435
|
else throw new Error(`"${k}" is not a control of "${d.id}"; its controls are ${Object.keys(d.controls.properties).join(", ")}.`);
|
|
11436
11436
|
}
|
|
11437
|
-
return { ...base, ...
|
|
11437
|
+
return { ...base, ..._chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, { ...d, defaults: base }, given) };
|
|
11438
11438
|
};
|
|
11439
11439
|
return {
|
|
11440
11440
|
/** The provider slot. */
|
|
@@ -11464,7 +11464,7 @@ function createCanvasEffectsController(options) {
|
|
|
11464
11464
|
const mode = _nullishCoalesce(opts.mode, () => ( "fill"));
|
|
11465
11465
|
const d = await describe(effect, mode);
|
|
11466
11466
|
if (opts.opacity !== void 0 && !(opts.opacity >= 0 && opts.opacity <= 1)) throw new Error("opacity must be from 0 to 1.");
|
|
11467
|
-
const next = { effect: d.id, provider: slot.require().id, name: d.name, values:
|
|
11467
|
+
const next = { effect: d.id, provider: slot.require().id, name: d.name, values: _chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, d, opts.values), mode, ...opts.opacity !== void 0 && opts.opacity !== 1 ? { opacity: opts.opacity } : {} };
|
|
11468
11468
|
commit(`Add effect ${d.name}`, withEffect(nodeId, next));
|
|
11469
11469
|
return next;
|
|
11470
11470
|
},
|
|
@@ -11521,7 +11521,7 @@ function createCanvasEffectsController(options) {
|
|
|
11521
11521
|
const d = await describe(effect, "transition");
|
|
11522
11522
|
const duration = _nullishCoalesce(_nullishCoalesce(opts.duration, () => ( d.duration)), () => ( 600));
|
|
11523
11523
|
if (!(duration > 0)) throw new Error("duration must be a number of ms above 0.");
|
|
11524
|
-
const transition = { effect: d.id, provider: slot.require().id, name: d.name, values:
|
|
11524
|
+
const transition = { effect: d.id, provider: slot.require().id, name: d.name, values: _chunkA3A5TI6Rcjs.resolveEffectValues.call(void 0, d, opts.values), duration };
|
|
11525
11525
|
scenes2.update(sceneId, { transition });
|
|
11526
11526
|
return transition;
|
|
11527
11527
|
}
|
|
@@ -11665,7 +11665,7 @@ function createCanvasEffectsToolProvider(controller, options = {}) {
|
|
|
11665
11665
|
const once = (instance) => {
|
|
11666
11666
|
if (instance !== "effect") throw new Error('A shape node has one effect, "effect".');
|
|
11667
11667
|
};
|
|
11668
|
-
return
|
|
11668
|
+
return _chunkA3A5TI6Rcjs.createEffectToolProvider.call(void 0, {
|
|
11669
11669
|
id: _nullishCoalesce(options.id, () => ( "canvas-effects")),
|
|
11670
11670
|
namespace: options.namespace,
|
|
11671
11671
|
title: "Canvas effects",
|
package/dist/canvas/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkA3A5TI6Rcjs = require('./chunk-A3A5TI6R.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
var _chunkFJ2MSI43cjs = require('./chunk-FJ2MSI43.cjs');
|
|
@@ -26,7 +26,7 @@ function documentErrors(doc, description) {
|
|
|
26
26
|
const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
27
27
|
if (doc.values !== void 0) {
|
|
28
28
|
if (!isRecord(doc.values)) errors.push({ path: "/values", message: "must be an object of control values" });
|
|
29
|
-
else errors.push(...
|
|
29
|
+
else errors.push(..._chunkA3A5TI6Rcjs.effectValueErrors.call(void 0, description, doc.values).map((e) => ({ ...e, path: `/values${e.path}` })));
|
|
30
30
|
}
|
|
31
31
|
if (doc.tracks !== void 0) {
|
|
32
32
|
if (!isRecord(doc.tracks)) errors.push({ path: "/tracks", message: "must be an object of keyframe lists" });
|
|
@@ -39,7 +39,7 @@ function documentErrors(doc, description) {
|
|
|
39
39
|
kfs.forEach((kf, i) => {
|
|
40
40
|
if (!isRecord(kf)) return errors.push({ path: `${at}/${i}`, message: "must be a keyframe object" });
|
|
41
41
|
if (typeof kf.time !== "number" || !Number.isFinite(kf.time) || kf.time < 0) errors.push({ path: `${at}/${i}/time`, message: "must be a finite number of ms >= 0" });
|
|
42
|
-
errors.push(...
|
|
42
|
+
errors.push(..._chunkA3A5TI6Rcjs.effectValueErrors.call(void 0, description, { [control]: kf.value }).map((e) => ({ ...e, path: `${at}/${i}/value` })));
|
|
43
43
|
if (kf.easing !== void 0 && !_chunkDWJJI6RTcjs.isAnimationEasing.call(void 0, kf.easing)) errors.push({ path: `${at}/${i}/easing`, message: "is not a valid easing" });
|
|
44
44
|
});
|
|
45
45
|
}
|
|
@@ -49,7 +49,7 @@ function documentErrors(doc, description) {
|
|
|
49
49
|
else
|
|
50
50
|
doc.presets.forEach((p, i) => {
|
|
51
51
|
if (!isRecord(p) || typeof p.name !== "string" || !p.name) return errors.push({ path: `/presets/${i}`, message: "must have a name" });
|
|
52
|
-
errors.push(...
|
|
52
|
+
errors.push(..._chunkA3A5TI6Rcjs.effectValueErrors.call(void 0, description, p.values).map((e) => ({ ...e, path: `/presets/${i}/values${e.path}` })));
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
if (doc.duration !== void 0 && (typeof doc.duration !== "number" || !Number.isFinite(doc.duration) || !(doc.duration > 0))) {
|
|
@@ -170,7 +170,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
170
170
|
if (isDocumentSource(source)) {
|
|
171
171
|
const doc = source.document;
|
|
172
172
|
if (doc.version !== 1 || !doc.effectId) {
|
|
173
|
-
throw new (0,
|
|
173
|
+
throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)("Invalid effect authoring document: version 1 required");
|
|
174
174
|
}
|
|
175
175
|
effectId = doc.effectId;
|
|
176
176
|
initialDoc = doc;
|
|
@@ -178,15 +178,15 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
178
178
|
effectId = source.effectId;
|
|
179
179
|
requestedPreset = source.preset;
|
|
180
180
|
} else {
|
|
181
|
-
throw new (0,
|
|
181
|
+
throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)("Invalid effect authoring source");
|
|
182
182
|
}
|
|
183
183
|
const description = await provider.describe(effectId);
|
|
184
184
|
if (initialDoc) {
|
|
185
185
|
const problems = documentErrors(initialDoc, description);
|
|
186
|
-
if (problems.length) throw new (0,
|
|
186
|
+
if (problems.length) throw new (0, _chunkA3A5TI6Rcjs.EffectControlError)(effectId, problems);
|
|
187
187
|
}
|
|
188
188
|
if (description.kind === "motion") {
|
|
189
|
-
throw new (0,
|
|
189
|
+
throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)("Motion effects cannot be authored as pixel effects", effectId);
|
|
190
190
|
}
|
|
191
191
|
let disposed = false;
|
|
192
192
|
let playing = false;
|
|
@@ -207,7 +207,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
207
207
|
const found = description.presets.find((p) => p.name === requestedPreset);
|
|
208
208
|
if (!found) {
|
|
209
209
|
const validNames = description.presets.map((p) => `"${p.name}"`).join(", ");
|
|
210
|
-
throw new (0,
|
|
210
|
+
throw new (0, _chunkA3A5TI6Rcjs.EffectUnsupportedError)(
|
|
211
211
|
`Unknown preset "${requestedPreset}" for effect "${effectId}". Valid presets are: ${validNames || "none"}`,
|
|
212
212
|
effectId
|
|
213
213
|
);
|
|
@@ -321,7 +321,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
321
321
|
if (!validNames.includes(name)) {
|
|
322
322
|
return { ok: false, message: `there is no control "${name}"; the controls are ${validNames.join(", ")}` };
|
|
323
323
|
}
|
|
324
|
-
const errors =
|
|
324
|
+
const errors = _chunkA3A5TI6Rcjs.effectValueErrors.call(void 0, description, { [name]: value });
|
|
325
325
|
if (errors.length > 0) {
|
|
326
326
|
return { ok: false, message: valueErrorMessage(errors) };
|
|
327
327
|
}
|
|
@@ -391,7 +391,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
391
391
|
if (!validNames.includes(k)) {
|
|
392
392
|
return { ok: false, message: `there is no control "${k}"; the controls are ${validNames.join(", ")}` };
|
|
393
393
|
}
|
|
394
|
-
const errors =
|
|
394
|
+
const errors = _chunkA3A5TI6Rcjs.effectValueErrors.call(void 0, description, { [k]: v });
|
|
395
395
|
if (errors.length > 0) {
|
|
396
396
|
return { ok: false, message: valueErrorMessage(errors) };
|
|
397
397
|
}
|
|
@@ -528,7 +528,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
528
528
|
return { ok: false, message: `invalid easing: ${String(easing)}` };
|
|
529
529
|
}
|
|
530
530
|
const targetValue = value !== void 0 ? value : valuesAtTime(time, baseValues, tracks)[name];
|
|
531
|
-
const errors =
|
|
531
|
+
const errors = _chunkA3A5TI6Rcjs.effectValueErrors.call(void 0, description, { [name]: targetValue });
|
|
532
532
|
if (errors.length > 0) {
|
|
533
533
|
return { ok: false, message: valueErrorMessage(errors) };
|
|
534
534
|
}
|
|
@@ -705,7 +705,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
705
705
|
},
|
|
706
706
|
async createPreview(opts) {
|
|
707
707
|
if (disposed) {
|
|
708
|
-
throw new (0,
|
|
708
|
+
throw new (0, _chunkA3A5TI6Rcjs.EffectDisposedError)(effectId);
|
|
709
709
|
}
|
|
710
710
|
let renderer;
|
|
711
711
|
try {
|
|
@@ -730,7 +730,7 @@ async function createEffectAuthoringSession(source, options) {
|
|
|
730
730
|
height: renderer.height,
|
|
731
731
|
depth: renderer.depth,
|
|
732
732
|
render: async (req) => {
|
|
733
|
-
if (disposed) throw new (0,
|
|
733
|
+
if (disposed) throw new (0, _chunkA3A5TI6Rcjs.EffectDisposedError)(effectId);
|
|
734
734
|
const effectiveValues = _nullishCoalesce(req.values, () => ( valuesAtTime(req.time, baseValues, tracks)));
|
|
735
735
|
const pixels = await renderer.render({
|
|
736
736
|
...req,
|
|
@@ -68,7 +68,20 @@ function resolveEffectValues(description, values) {
|
|
|
68
68
|
if (errors.length) throw new EffectControlError(description.id, errors);
|
|
69
69
|
return { ...description.defaults, ...values ?? {} };
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
function normaliseEffectTag(tag) {
|
|
72
|
+
return tag.trim().toLowerCase().replace(/[\s_-]+/g, "-");
|
|
73
|
+
}
|
|
74
|
+
function hasEffectTags(e, tags) {
|
|
75
|
+
if (!tags?.length) return true;
|
|
76
|
+
const own = new Set((e.tags ?? []).map(normaliseEffectTag));
|
|
77
|
+
return tags.every((t) => own.has(normaliseEffectTag(t)));
|
|
78
|
+
}
|
|
79
|
+
function countEffectTags(effects) {
|
|
80
|
+
const counts = /* @__PURE__ */ new Map();
|
|
81
|
+
for (const e of effects) for (const tag of new Set((e.tags ?? []).map(normaliseEffectTag))) if (tag) counts.set(tag, (counts.get(tag) ?? 0) + 1);
|
|
82
|
+
return [...counts].map(([tag, count]) => ({ tag, count })).sort((a, b) => b.count - a.count || a.tag.localeCompare(b.tag));
|
|
83
|
+
}
|
|
84
|
+
var matchesFilters = (e, o) => (!o.kind || e.kind === o.kind) && (!o.category || e.category === o.category) && (!o.use || e.uses.includes(o.use)) && hasEffectTags(e, o.tags);
|
|
72
85
|
function searchEffectSummaries(catalog, query = "", options = {}) {
|
|
73
86
|
const words = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
74
87
|
const scored = [];
|
|
@@ -174,6 +187,12 @@ var object = (properties, required = []) => ({
|
|
|
174
187
|
additionalProperties: false
|
|
175
188
|
});
|
|
176
189
|
var ENUM_LIMIT = 60;
|
|
190
|
+
var TAG_LIMIT = 40;
|
|
191
|
+
function nearestTags(tag, known) {
|
|
192
|
+
const t = normaliseEffectTag(tag);
|
|
193
|
+
const stem = t.slice(0, 4);
|
|
194
|
+
return known.filter((k) => k.tag.includes(t) || t.includes(k.tag) || stem.length === 4 && k.tag.startsWith(stem)).slice(0, 5).map((k) => k.tag);
|
|
195
|
+
}
|
|
177
196
|
var summaryOut = (e) => ({
|
|
178
197
|
id: e.id,
|
|
179
198
|
name: e.name,
|
|
@@ -181,6 +200,7 @@ var summaryOut = (e) => ({
|
|
|
181
200
|
category: e.category,
|
|
182
201
|
uses: e.uses,
|
|
183
202
|
...e.description ? { description: e.description } : {},
|
|
203
|
+
...e.tags?.length ? { tags: e.tags } : {},
|
|
184
204
|
transparent: e.transparent,
|
|
185
205
|
loop: e.loop,
|
|
186
206
|
...e.duration !== void 0 ? { duration: e.duration } : {}
|
|
@@ -241,21 +261,30 @@ function createEffectToolProvider(host) {
|
|
|
241
261
|
{
|
|
242
262
|
name: "search_effects",
|
|
243
263
|
title: "Search effects",
|
|
244
|
-
description: `Searches the effects provider's catalog. Every word of query must appear in an effect's id, name, category, tags or description; filter by kind (shader, vector, motion), category
|
|
264
|
+
description: `Searches the effects provider's catalog. Every word of query must appear in an effect's id, name, category, tags or description; filter by kind (shader, vector, motion), category, use (${EFFECT_USES.join(", ")}) or tags (effects carrying every one). For this editor, apply_effect takes uses ${host.applyUses.join(" or ")}. Returns { provider, effects: [{ id, name, kind, category, uses, description, tags, transparent, loop, duration (ms) }], total, tags: [{ tag, count }] }: tags lists the tags of every match, the most used first, so a broad search (or none) shows the tags to narrow by. A tag the catalog does not have comes back in unknownTags with the nearest ones. With no provider registered it returns available: false and the reason. Call describe_effect next for an effect's controls.`,
|
|
245
265
|
inputSchema: object({
|
|
246
266
|
query: { type: "string", description: "Words to match (default: every effect)." },
|
|
247
267
|
kind: { type: "string", enum: [...EFFECT_KINDS], description: "shader (pixels), vector (animated SVG) or motion (animates vector art)." },
|
|
248
268
|
category: { type: "string", minLength: 1, description: `The provider's category, e.g. "gradient", "light", "transition".` },
|
|
249
269
|
use: { type: "string", enum: [...EFFECT_USES], description: "What the effect is for: filter changes a picture, transition blends two, generator draws a background, overlay draws over content, title draws a title, motion animates vector art, interactive reacts to input." },
|
|
270
|
+
tags: { type: "array", items: { type: "string", minLength: 1 }, description: "Only effects carrying every one of these tags, as search_effects lists them (any case; spaces count as hyphens)." },
|
|
250
271
|
limit: { type: "integer", minimum: 1, maximum: 200, description: "Most effects to return (default 20)." }
|
|
251
272
|
}),
|
|
252
273
|
annotations: { title: "Search effects", ...ANNOTATIONS.read },
|
|
253
274
|
handler: async (args) => {
|
|
254
275
|
const p = host.provider();
|
|
255
276
|
if (!p) return { available: false, reason: NO_PROVIDER, effects: [], total: 0 };
|
|
256
|
-
const
|
|
277
|
+
const tags = args.tags;
|
|
278
|
+
const found = (await explain(async () => p.search(args.query ?? "", { kind: args.kind, category: args.category, use: args.use, tags }))).filter((e) => hasEffectTags(e, tags));
|
|
257
279
|
const limit = args.limit ?? 20;
|
|
258
|
-
|
|
280
|
+
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) };
|
|
281
|
+
if (tags?.length && !found.length) {
|
|
282
|
+
const known = countEffectTags(await explain(async () => p.list()));
|
|
283
|
+
const have = new Set(known.map((k) => k.tag));
|
|
284
|
+
const unknown = tags.filter((t) => !have.has(normaliseEffectTag(t)));
|
|
285
|
+
if (unknown.length) out.unknownTags = unknown.map((tag) => ({ tag, nearest: nearestTags(tag, known) }));
|
|
286
|
+
}
|
|
287
|
+
return out;
|
|
259
288
|
}
|
|
260
289
|
},
|
|
261
290
|
{
|
|
@@ -374,6 +403,9 @@ export {
|
|
|
374
403
|
isEffectError,
|
|
375
404
|
effectValueErrors,
|
|
376
405
|
resolveEffectValues,
|
|
406
|
+
normaliseEffectTag,
|
|
407
|
+
hasEffectTags,
|
|
408
|
+
countEffectTags,
|
|
377
409
|
searchEffectSummaries,
|
|
378
410
|
createEffectPixels,
|
|
379
411
|
isEffectPixels,
|
|
@@ -68,7 +68,20 @@ function resolveEffectValues(description, values) {
|
|
|
68
68
|
if (errors.length) throw new EffectControlError(description.id, errors);
|
|
69
69
|
return { ...description.defaults, ..._nullishCoalesce(values, () => ( {})) };
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
function normaliseEffectTag(tag) {
|
|
72
|
+
return tag.trim().toLowerCase().replace(/[\s_-]+/g, "-");
|
|
73
|
+
}
|
|
74
|
+
function hasEffectTags(e, tags) {
|
|
75
|
+
if (!_optionalChain([tags, 'optionalAccess', _ => _.length])) return true;
|
|
76
|
+
const own = new Set((_nullishCoalesce(e.tags, () => ( []))).map(normaliseEffectTag));
|
|
77
|
+
return tags.every((t) => own.has(normaliseEffectTag(t)));
|
|
78
|
+
}
|
|
79
|
+
function countEffectTags(effects) {
|
|
80
|
+
const counts = /* @__PURE__ */ new Map();
|
|
81
|
+
for (const e of effects) for (const tag of new Set((_nullishCoalesce(e.tags, () => ( []))).map(normaliseEffectTag))) if (tag) counts.set(tag, (_nullishCoalesce(counts.get(tag), () => ( 0))) + 1);
|
|
82
|
+
return [...counts].map(([tag, count]) => ({ tag, count })).sort((a, b) => b.count - a.count || a.tag.localeCompare(b.tag));
|
|
83
|
+
}
|
|
84
|
+
var matchesFilters = (e, o) => (!o.kind || e.kind === o.kind) && (!o.category || e.category === o.category) && (!o.use || e.uses.includes(o.use)) && hasEffectTags(e, o.tags);
|
|
72
85
|
function searchEffectSummaries(catalog, query = "", options = {}) {
|
|
73
86
|
const words = query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
74
87
|
const scored = [];
|
|
@@ -174,6 +187,12 @@ var object = (properties, required = []) => ({
|
|
|
174
187
|
additionalProperties: false
|
|
175
188
|
});
|
|
176
189
|
var ENUM_LIMIT = 60;
|
|
190
|
+
var TAG_LIMIT = 40;
|
|
191
|
+
function nearestTags(tag, known) {
|
|
192
|
+
const t = normaliseEffectTag(tag);
|
|
193
|
+
const stem = t.slice(0, 4);
|
|
194
|
+
return known.filter((k) => k.tag.includes(t) || t.includes(k.tag) || stem.length === 4 && k.tag.startsWith(stem)).slice(0, 5).map((k) => k.tag);
|
|
195
|
+
}
|
|
177
196
|
var summaryOut = (e) => ({
|
|
178
197
|
id: e.id,
|
|
179
198
|
name: e.name,
|
|
@@ -181,6 +200,7 @@ var summaryOut = (e) => ({
|
|
|
181
200
|
category: e.category,
|
|
182
201
|
uses: e.uses,
|
|
183
202
|
...e.description ? { description: e.description } : {},
|
|
203
|
+
..._optionalChain([e, 'access', _2 => _2.tags, 'optionalAccess', _3 => _3.length]) ? { tags: e.tags } : {},
|
|
184
204
|
transparent: e.transparent,
|
|
185
205
|
loop: e.loop,
|
|
186
206
|
...e.duration !== void 0 ? { duration: e.duration } : {}
|
|
@@ -191,7 +211,7 @@ function createEffectToolProvider(host) {
|
|
|
191
211
|
const notify = () => listeners.forEach((l) => l());
|
|
192
212
|
const catalogFor = (provider) => {
|
|
193
213
|
if (!provider) return null;
|
|
194
|
-
if (_optionalChain([catalog, 'optionalAccess',
|
|
214
|
+
if (_optionalChain([catalog, 'optionalAccess', _4 => _4.provider]) !== provider) {
|
|
195
215
|
const entry = { provider, effects: null };
|
|
196
216
|
catalog = entry;
|
|
197
217
|
Promise.resolve().then(() => provider.list()).then((effects) => {
|
|
@@ -227,7 +247,7 @@ function createEffectToolProvider(host) {
|
|
|
227
247
|
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.`
|
|
228
248
|
});
|
|
229
249
|
const effectIdSchema = (uses) => {
|
|
230
|
-
const effects = _optionalChain([catalogFor, 'call',
|
|
250
|
+
const effects = _optionalChain([catalogFor, 'call', _5 => _5(host.provider()), 'optionalAccess', _6 => _6.filter, 'call', _7 => _7((e) => (e.kind !== "motion" || uses.includes("motion")) && e.uses.some((u) => uses.includes(u)))]);
|
|
231
251
|
const base = `An effect id from search_effects (use ${uses.map((u) => `"${u}"`).join(" or ")}).`;
|
|
232
252
|
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 };
|
|
233
253
|
};
|
|
@@ -241,21 +261,30 @@ function createEffectToolProvider(host) {
|
|
|
241
261
|
{
|
|
242
262
|
name: "search_effects",
|
|
243
263
|
title: "Search effects",
|
|
244
|
-
description: `Searches the effects provider's catalog. Every word of query must appear in an effect's id, name, category, tags or description; filter by kind (shader, vector, motion), category
|
|
264
|
+
description: `Searches the effects provider's catalog. Every word of query must appear in an effect's id, name, category, tags or description; filter by kind (shader, vector, motion), category, use (${EFFECT_USES.join(", ")}) or tags (effects carrying every one). For this editor, apply_effect takes uses ${host.applyUses.join(" or ")}. Returns { provider, effects: [{ id, name, kind, category, uses, description, tags, transparent, loop, duration (ms) }], total, tags: [{ tag, count }] }: tags lists the tags of every match, the most used first, so a broad search (or none) shows the tags to narrow by. A tag the catalog does not have comes back in unknownTags with the nearest ones. With no provider registered it returns available: false and the reason. Call describe_effect next for an effect's controls.`,
|
|
245
265
|
inputSchema: object({
|
|
246
266
|
query: { type: "string", description: "Words to match (default: every effect)." },
|
|
247
267
|
kind: { type: "string", enum: [...EFFECT_KINDS], description: "shader (pixels), vector (animated SVG) or motion (animates vector art)." },
|
|
248
268
|
category: { type: "string", minLength: 1, description: `The provider's category, e.g. "gradient", "light", "transition".` },
|
|
249
269
|
use: { type: "string", enum: [...EFFECT_USES], description: "What the effect is for: filter changes a picture, transition blends two, generator draws a background, overlay draws over content, title draws a title, motion animates vector art, interactive reacts to input." },
|
|
270
|
+
tags: { type: "array", items: { type: "string", minLength: 1 }, description: "Only effects carrying every one of these tags, as search_effects lists them (any case; spaces count as hyphens)." },
|
|
250
271
|
limit: { type: "integer", minimum: 1, maximum: 200, description: "Most effects to return (default 20)." }
|
|
251
272
|
}),
|
|
252
273
|
annotations: { title: "Search effects", ...ANNOTATIONS.read },
|
|
253
274
|
handler: async (args) => {
|
|
254
275
|
const p = host.provider();
|
|
255
276
|
if (!p) return { available: false, reason: NO_PROVIDER, effects: [], total: 0 };
|
|
256
|
-
const
|
|
277
|
+
const tags = args.tags;
|
|
278
|
+
const found = (await explain(async () => p.search(_nullishCoalesce(args.query, () => ( "")), { kind: args.kind, category: args.category, use: args.use, tags }))).filter((e) => hasEffectTags(e, tags));
|
|
257
279
|
const limit = _nullishCoalesce(args.limit, () => ( 20));
|
|
258
|
-
|
|
280
|
+
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) };
|
|
281
|
+
if (_optionalChain([tags, 'optionalAccess', _8 => _8.length]) && !found.length) {
|
|
282
|
+
const known = countEffectTags(await explain(async () => p.list()));
|
|
283
|
+
const have = new Set(known.map((k) => k.tag));
|
|
284
|
+
const unknown = tags.filter((t) => !have.has(normaliseEffectTag(t)));
|
|
285
|
+
if (unknown.length) out.unknownTags = unknown.map((tag) => ({ tag, nearest: nearestTags(tag, known) }));
|
|
286
|
+
}
|
|
287
|
+
return out;
|
|
259
288
|
}
|
|
260
289
|
},
|
|
261
290
|
{
|
|
@@ -348,16 +377,16 @@ function createEffectToolProvider(host) {
|
|
|
348
377
|
...host.description ? { description: host.description } : {},
|
|
349
378
|
...host.skill ? { skill: host.skill } : {},
|
|
350
379
|
tools: () => {
|
|
351
|
-
const extra = _nullishCoalesce(_optionalChain([host, 'access',
|
|
352
|
-
if (host.readOnlyReason()) return [...readTools(), ...extra.filter((t) => _optionalChain([t, 'access',
|
|
380
|
+
const extra = _nullishCoalesce(_optionalChain([host, 'access', _9 => _9.extraTools, 'optionalCall', _10 => _10(context)]), () => ( []));
|
|
381
|
+
if (host.readOnlyReason()) return [...readTools(), ...extra.filter((t) => _optionalChain([t, 'access', _11 => _11.annotations, 'optionalAccess', _12 => _12.readOnlyHint]))];
|
|
353
382
|
return [...readTools(), ...writeTools(), ...extra];
|
|
354
383
|
},
|
|
355
384
|
subscribe: (l) => {
|
|
356
385
|
listeners.add(l);
|
|
357
|
-
const off = _optionalChain([host, 'access',
|
|
386
|
+
const off = _optionalChain([host, 'access', _13 => _13.subscribe, 'optionalCall', _14 => _14(l)]);
|
|
358
387
|
return () => {
|
|
359
388
|
listeners.delete(l);
|
|
360
|
-
_optionalChain([off, 'optionalCall',
|
|
389
|
+
_optionalChain([off, 'optionalCall', _15 => _15()]);
|
|
361
390
|
};
|
|
362
391
|
}
|
|
363
392
|
};
|
|
@@ -385,4 +414,7 @@ function createEffectToolProvider(host) {
|
|
|
385
414
|
|
|
386
415
|
|
|
387
416
|
|
|
388
|
-
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
exports.EFFECT_ERROR_CODES = EFFECT_ERROR_CODES; exports.EffectError = EffectError; exports.UnknownEffectError = UnknownEffectError; exports.EffectControlError = EffectControlError; exports.EffectUnsupportedError = EffectUnsupportedError; exports.EffectDisposedError = EffectDisposedError; exports.NoEffectsProviderError = NoEffectsProviderError; exports.isEffectError = isEffectError; exports.effectValueErrors = effectValueErrors; exports.resolveEffectValues = resolveEffectValues; exports.normaliseEffectTag = normaliseEffectTag; exports.hasEffectTags = hasEffectTags; exports.countEffectTags = countEffectTags; exports.searchEffectSummaries = searchEffectSummaries; exports.createEffectPixels = createEffectPixels; exports.isEffectPixels = isEffectPixels; exports.srgbToLinear = srgbToLinear; exports.linearToSrgb = linearToSrgb; exports.encodeEffectFloat = encodeEffectFloat; exports.applyEffectMask = applyEffectMask; exports.EffectsSlot = EffectsSlot; exports.EFFECT_KINDS = EFFECT_KINDS; exports.EFFECT_USES = EFFECT_USES; exports.createEffectToolProvider = createEffectToolProvider;
|