fundus 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/build-CZYFLLvl.js +191 -0
  2. package/dist/cli.d.ts +1 -0
  3. package/dist/cli.js +1420 -0
  4. package/dist/config.d.ts +2 -0
  5. package/dist/config.js +2 -0
  6. package/dist/core/image-Dqmz8FXS.js +54 -0
  7. package/dist/core/index.d.ts +499 -0
  8. package/dist/core/index.js +962 -0
  9. package/dist/core/reference-graph-CjuHbLDw.d.ts +280 -0
  10. package/dist/core/testing.d.ts +27 -0
  11. package/dist/core/testing.js +80 -0
  12. package/dist/editor/200.html +37 -0
  13. package/dist/editor/_app/immutable/assets/0.DLhIsYA_.css +1 -0
  14. package/dist/editor/_app/immutable/assets/2.DIbbW7U1.css +1 -0
  15. package/dist/editor/_app/immutable/assets/3.C-9vFQ9A.css +1 -0
  16. package/dist/editor/_app/immutable/assets/4.BS8ElpOV.css +1 -0
  17. package/dist/editor/_app/immutable/assets/ConfirmDialog.CHEISE-L.css +1 -0
  18. package/dist/editor/_app/immutable/assets/LibraryContextMenu.CDjCmdV-.css +1 -0
  19. package/dist/editor/_app/immutable/chunks/BfPE5wdt.js +1 -0
  20. package/dist/editor/_app/immutable/chunks/Bjy-W4x2.js +81 -0
  21. package/dist/editor/_app/immutable/chunks/CNRz3sSw.js +3 -0
  22. package/dist/editor/_app/immutable/chunks/CO4RBJfa.js +1 -0
  23. package/dist/editor/_app/immutable/chunks/Cx6qtxJg.js +1 -0
  24. package/dist/editor/_app/immutable/chunks/DjdrdRzT.js +1 -0
  25. package/dist/editor/_app/immutable/chunks/DjvOiDmq.js +1 -0
  26. package/dist/editor/_app/immutable/chunks/n7mvYc42.js +5 -0
  27. package/dist/editor/_app/immutable/chunks/xihTtKlq.js +1 -0
  28. package/dist/editor/_app/immutable/entry/app.BkqbfI8n.js +2 -0
  29. package/dist/editor/_app/immutable/entry/start.C8HHOLly.js +1 -0
  30. package/dist/editor/_app/immutable/nodes/0.xdMI5GEU.js +2 -0
  31. package/dist/editor/_app/immutable/nodes/1.D9p2tfoJ.js +1 -0
  32. package/dist/editor/_app/immutable/nodes/2.BrA0Hyzu.js +3 -0
  33. package/dist/editor/_app/immutable/nodes/3.WO7tZH_d.js +104 -0
  34. package/dist/editor/_app/immutable/nodes/4.DQtx17aW.js +2 -0
  35. package/dist/editor/_app/version.json +1 -0
  36. package/dist/index.d.ts +370 -0
  37. package/dist/index.js +4 -0
  38. package/dist/operations-DYM-5KVl.js +1797 -0
  39. package/dist/runtime/chroma-key-gl.d.ts +23 -0
  40. package/dist/runtime/chroma-key-gl.js +290 -0
  41. package/dist/runtime/components/ChromaKeyVideo.svelte +225 -0
  42. package/dist/runtime/components/Image.svelte +18 -0
  43. package/dist/runtime/components/Slice.svelte +35 -0
  44. package/dist/runtime/components/SliceCanvas.svelte +162 -0
  45. package/dist/runtime/components/SliceDom.svelte +104 -0
  46. package/dist/runtime/components/Video.svelte +60 -0
  47. package/dist/runtime/geometry.d.ts +75 -0
  48. package/dist/runtime/geometry.js +209 -0
  49. package/dist/runtime/index.d.ts +9 -0
  50. package/dist/runtime/index.js +9 -0
  51. package/dist/runtime/kind-handlers.d.ts +46 -0
  52. package/dist/runtime/kind-handlers.js +86 -0
  53. package/dist/runtime/manifest.d.ts +60 -0
  54. package/dist/runtime/manifest.js +117 -0
  55. package/dist/runtime/observe-border-box-size.d.ts +5 -0
  56. package/dist/runtime/observe-border-box-size.js +12 -0
  57. package/dist/runtime/preload-registry.d.ts +26 -0
  58. package/dist/runtime/preload-registry.js +68 -0
  59. package/dist/start-Bhnqt9Dc.js +279 -0
  60. package/dist/start-D2IXOrni.js +2 -0
  61. package/package.json +65 -0
@@ -0,0 +1,2 @@
1
+ import { FundusConfig, defineConfig } from "#fundus/core";
2
+ export { type FundusConfig, defineConfig };
package/dist/config.js ADDED
@@ -0,0 +1,2 @@
1
+ import { defineConfig } from "#fundus/core";
2
+ export { defineConfig };
@@ -0,0 +1,54 @@
1
+ //#region src/asset-reference.ts
2
+ /** Whether a value is a well-formed asset-reference marker. */
3
+ function isAssetReference(value) {
4
+ return typeof value === "object" && value !== null && !Array.isArray(value) && typeof value.$asset === "string" && value.$asset !== "";
5
+ }
6
+ //#endregion
7
+ //#region src/plugins/image.ts
8
+ const IMAGE_FORMATS = [
9
+ "webp",
10
+ "png",
11
+ "avif",
12
+ "jpeg"
13
+ ];
14
+ /** Built-in presets, always available; host config merges over them. */
15
+ const IMAGE_BUILT_IN_PRESETS = { default: {
16
+ format: "webp",
17
+ quality: 82
18
+ } };
19
+ function validateImagePreset(name, value) {
20
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`Image preset "${name}" must be an object.`);
21
+ const record = value;
22
+ if (typeof record.format !== "string" || !IMAGE_FORMATS.includes(record.format)) throw new Error(`Image preset "${name}" needs a "format" of ${IMAGE_FORMATS.map((format) => `'${format}'`).join(" | ")}.`);
23
+ if (record.quality !== void 0 && typeof record.quality !== "number") throw new Error(`Image preset "${name}" has a non-number "quality".`);
24
+ return {
25
+ format: record.format,
26
+ quality: record.quality
27
+ };
28
+ }
29
+ const RASTER_IMAGE_EXTENSIONS = [
30
+ "png",
31
+ "jpg",
32
+ "jpeg",
33
+ "webp",
34
+ "avif"
35
+ ];
36
+ const imagePlugin = {
37
+ type: "image",
38
+ accepts: [...RASTER_IMAGE_EXTENSIONS],
39
+ defaultParameters: () => ({ preset: "default" }),
40
+ validateParameters(value) {
41
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error("Image parameters must be an object.");
42
+ const record = value;
43
+ if (typeof record.preset !== "string" || record.preset.length === 0) throw new Error("Image parameters need a non-empty string \"preset\".");
44
+ if (record.targetWidth !== void 0) {
45
+ if (typeof record.targetWidth !== "number" || !Number.isInteger(record.targetWidth) || record.targetWidth <= 0) throw new Error("Image \"targetWidth\" must be a positive integer when set.");
46
+ }
47
+ return {
48
+ preset: record.preset,
49
+ ...record.targetWidth !== void 0 ? { targetWidth: record.targetWidth } : {}
50
+ };
51
+ }
52
+ };
53
+ //#endregion
54
+ export { isAssetReference as a, validateImagePreset as i, RASTER_IMAGE_EXTENSIONS as n, imagePlugin as r, IMAGE_BUILT_IN_PRESETS as t };
@@ -0,0 +1,499 @@
1
+ import { A as Library, C as ValidationIssueDto, D as isAssetReference, E as CollectedReference, F as serializeLibrary, M as ManifestRecord, N as createEmptyLibrary, O as AssetId, P as parseLibrary, S as ProxyStateDto, T as AssetReference, _ as PassiveManifestMembershipDto, a as referenceErrors, b as PatchFolderRequestDto, c as AssetReferenceLinkDto, d as CreateFolderRequestDto, f as CreateManifestRequestDto, g as MoveAssetsRequestDto, h as ManifestMembershipDto, i as referenceClosure, j as ManifestName, k as AssetRecord, l as AssetReferencesDto, m as FundusStateDto, n as ReferencesByAsset, o as topologicalReferenceOrder, p as DeleteAssetsRequestDto, r as collectAllReferences, s as ApiErrorDto, t as PluginDescriptorRegistry, u as AssetStateDto, v as PassiveMemberDto, w as AssetTypePluginDescriptor, x as PatchManifestRequestDto, y as PatchAssetRequestDto } from "./reference-graph-CjuHbLDw.js";
2
+
3
+ //#region src/folder-path.d.ts
4
+ /** The implicit raw/proxy root. Explicit folders are always non-empty paths. */
5
+ declare const ROOT_FOLDER = "";
6
+ /** Fundus-owned file that preserves explicit empty folders in source control. */
7
+ declare const FOLDER_SENTINEL = ".gitkeep";
8
+ /** Validate one human-facing folder name (a single path segment). */
9
+ declare function folderNameError(name: string): string | null;
10
+ /** Normalize a validated, portable relative folder path to NFC + POSIX separators. */
11
+ declare function normalizeFolderPath(path: string): string;
12
+ /** Validate a non-root, POSIX-relative folder path. */
13
+ declare function folderPathError(path: string): string | null;
14
+ /** Case-insensitive, Unicode-normalized key used to prevent portable path collisions. */
15
+ declare function portableFolderPathKey(path: string): string;
16
+ declare function parentFolderPath(path: string): string;
17
+ declare function folderNameOf(path: string): string;
18
+ declare function joinFolderPath(parent: string, name: string): string;
19
+ declare function folderOfRawPath(rawPath: string): string;
20
+ declare function rawFileNameOfPath(rawPath: string): string;
21
+ declare function isFolderOrDescendant(path: string, ancestor: string): boolean;
22
+ declare function replaceFolderPrefix(path: string, from: string, to: string): string;
23
+ //#endregion
24
+ //#region src/asset-id.d.ts
25
+ /**
26
+ * Asset ids are the SSOT keys and the generated property names on manifests
27
+ * are stable, human-readable camelCase slugs that must be valid JS
28
+ * identifiers and must not collide with `Manifest` class members.
29
+ */
30
+ /**
31
+ * Names an asset id may never take: current and future members of the runtime
32
+ * `Manifest` class (entries become direct properties on it), plus inherited
33
+ * `Object.prototype` members that would shadow-collide, plus keys that are
34
+ * prototype-pollution hazards when used as record keys (`prototype`;
35
+ * `__proto__` already fails the camelCase pattern).
36
+ */
37
+ declare const RESERVED_ASSET_IDS: readonly string[];
38
+ /**
39
+ * Whether `id` is a valid asset id: a camelCase JS identifier (lowercase
40
+ * letter, then letters/digits) that is not a reserved `Manifest` member name.
41
+ */
42
+ declare function isValidAssetId(id: string): boolean;
43
+ /**
44
+ * Why an id is invalid, as a human-readable message — or `null` when valid.
45
+ * Lets the editor and the validator surface the precise reason.
46
+ */
47
+ declare function assetIdError(id: string): string | null;
48
+ /**
49
+ * Manifest names deliberately share the asset-id grammar because each name
50
+ * becomes a generated JavaScript module export.
51
+ */
52
+ declare function manifestNameError(name: string): string | null;
53
+ //#endregion
54
+ //#region src/manifest-appearance.d.ts
55
+ /**
56
+ * Manifest appearance: each manifest may carry a color and an emoji,
57
+ * chosen from these fixed sets, so the editor can tag its label everywhere and
58
+ * make asset↔manifest membership visually scannable. The sets are the closed
59
+ * palette both the editor pickers and the CLI validate against — storing a
60
+ * value outside them is rejected at every mutation entry point.
61
+ */
62
+ /** One selectable manifest color: a stable display name and its hex value. */
63
+ interface ManifestColor {
64
+ /** Human-readable palette name (used by the CLI's `--color <name|hex>`). */
65
+ name: string;
66
+ /** The stored value — a lowercase `#rrggbb` hex string. */
67
+ value: string;
68
+ }
69
+ /**
70
+ * The fixed color palette. Values are the SSOT stored in the library; names are
71
+ * an ergonomic CLI alias. A Figma-like spread of distinct, saturated hues.
72
+ */
73
+ declare const MANIFEST_COLORS: readonly ManifestColor[];
74
+ /** The fixed emoji set — 63 visually distinct choices (an 8×8 picker grid with a clear cell). */
75
+ declare const MANIFEST_EMOJIS: readonly string[];
76
+ /** Whether `value` is one of the fixed color values (`#rrggbb`, lowercased). */
77
+ declare function isManifestColor(value: string): boolean;
78
+ /** Whether `emoji` is one of the fixed emojis. */
79
+ declare function isManifestEmoji(emoji: string): boolean;
80
+ /**
81
+ * Resolve a CLI-supplied color token (either a palette name like `blue` or a
82
+ * hex value like `#3b82f6`, case-insensitively) to its stored hex value, or
83
+ * `null` when it matches no palette entry.
84
+ */
85
+ declare function resolveManifestColor(token: string): string | null;
86
+ /** Why a color value is invalid, as a human-readable message — or `null` when valid. */
87
+ declare function manifestColorError(value: string): string | null;
88
+ /** Why an emoji is invalid, as a human-readable message — or `null` when valid. */
89
+ declare function manifestEmojiError(emoji: string): string | null;
90
+ //#endregion
91
+ //#region src/ingest.d.ts
92
+ /** Unique HTML file-picker accept extensions derived from descriptor claims. */
93
+ declare function acceptedExtensions(descriptors?: AssetTypePluginDescriptor<unknown, unknown>[]): string[];
94
+ /**
95
+ * Types an ingested file of this extension could become — derived from the
96
+ * descriptors' `accepts` claims. Raster images and video containers are
97
+ * ambiguous (image/slice, video/chroma-key-video) — the editor dialog prompts
98
+ * once, the CLI requires `--type`; audio is unambiguous.
99
+ */
100
+ declare function typesForFileName(fileName: string, descriptors?: AssetTypePluginDescriptor<unknown, unknown>[]): string[];
101
+ /**
102
+ * Propose a camelCase asset id from a file name: split on non-alphanumeric
103
+ * runs and case boundaries, drop a `@2x`-style scale suffix, lowercase the
104
+ * first word, capitalize the rest, strip leading digits.
105
+ */
106
+ declare function proposeAssetId(fileName: string): string;
107
+ //#endregion
108
+ //#region src/canonicalize.d.ts
109
+ /**
110
+ * Stable JSON for hash inputs: recursively sorted keys, no whitespace,
111
+ * `undefined` object values dropped. Two parameter objects that differ only in
112
+ * key order (or in explicitly-undefined optionals) canonicalize identically,
113
+ * so the derived job hash — and thus the proxy file name — stays stable.
114
+ */
115
+ declare function canonicalizeParameters(parameters: unknown): string;
116
+ /** Deterministic UTF-16 code-unit ordering, independent of host locale. */
117
+ declare function compareCodeUnits(left: string, right: string): number;
118
+ //#endregion
119
+ //#region src/plugins/audio.d.ts
120
+ interface AudioPreset {
121
+ codec: 'opus' | 'aac';
122
+ /** Target bitrate in kilobits per second (`-b:a`). */
123
+ bitrateKbps: number;
124
+ container: 'webm' | 'm4a';
125
+ }
126
+ interface AudioPluginConfig {
127
+ /** Named presets; merged over the built-in defaults. */
128
+ presets?: Record<string, AudioPreset>;
129
+ }
130
+ interface AudioParameters {
131
+ /** Preset name, resolved against the audio plugin config's presets. */
132
+ preset: string;
133
+ }
134
+ /** Built-in presets, always available; host config merges over them. */
135
+ declare const AUDIO_BUILT_IN_PRESETS: Record<string, AudioPreset>;
136
+ declare function validateAudioPreset(name: string, value: unknown): AudioPreset;
137
+ declare const AUDIO_EXTENSIONS: readonly string[];
138
+ declare const audioPlugin: AssetTypePluginDescriptor<AudioParameters, AudioPluginConfig>;
139
+ //#endregion
140
+ //#region src/plugins/image.d.ts
141
+ declare const IMAGE_FORMATS: readonly ["webp", "png", "avif", "jpeg"];
142
+ type ImageFormat = (typeof IMAGE_FORMATS)[number];
143
+ interface ImagePreset {
144
+ format: ImageFormat;
145
+ /** Encoder quality (format-dependent semantics); omitted = encoder default. */
146
+ quality?: number;
147
+ }
148
+ interface ImagePluginConfig {
149
+ /** Named presets; merged over the built-in defaults. */
150
+ presets?: Record<string, ImagePreset>;
151
+ }
152
+ interface ImageParameters {
153
+ /** Preset name, resolved against the plugin config's presets. */
154
+ preset: string;
155
+ /** Resize to this width (keeping aspect ratio); omitted = keep source size. */
156
+ targetWidth?: number;
157
+ }
158
+ /** Built-in presets, always available; host config merges over them. */
159
+ declare const IMAGE_BUILT_IN_PRESETS: Record<string, ImagePreset>;
160
+ declare function validateImagePreset(name: string, value: unknown): ImagePreset;
161
+ declare const RASTER_IMAGE_EXTENSIONS: readonly string[];
162
+ declare const imagePlugin: AssetTypePluginDescriptor<ImageParameters, ImagePluginConfig>;
163
+ //#endregion
164
+ //#region src/slice-data.d.ts
165
+ /**
166
+ * The slice data model keeps the source image separate from slicing metadata
167
+ * (Fundus tracks raw files and
168
+ * proxy dimensions separately), so there is no `SliceSource` here.
169
+ *
170
+ * The geometry is stored as **insets** (border thickness in source pixels), the
171
+ * canonical, render-ready form — equivalent to CSS `border-image-slice`.
172
+ * `slicedAxesFor` is the single source of truth for which axes each mode uses.
173
+ */
174
+ declare const SLICE_MODES: readonly ["nine", "three-horizontal", "three-vertical", "one"];
175
+ type SliceMode = (typeof SLICE_MODES)[number];
176
+ /** Border thickness in source pixels. Always integers (pixel-precise). */
177
+ interface SliceInsets {
178
+ top: number;
179
+ right: number;
180
+ bottom: number;
181
+ left: number;
182
+ }
183
+ /**
184
+ * Full slicing description for an image, independent of which image it applies
185
+ * to. Stored in the library as (part of) the slice plugin's parameters and
186
+ * emitted into generated manifest entries.
187
+ */
188
+ interface Slicing {
189
+ mode: SliceMode;
190
+ insets: SliceInsets;
191
+ /**
192
+ * Source pixels per CSS pixel — the scale the asset was exported at
193
+ * (`1` = @1x, `2` = @2x, `3` = @3x). All fixed slice dimensions (9-slice
194
+ * corners) are divided by this when rendering, so a high-resolution asset
195
+ * displays at its intended logical size.
196
+ */
197
+ pixelRatio: number;
198
+ /**
199
+ * Per-side thickness (in source pixels) of the image's baked-in overdraw — a
200
+ * drop shadow / glow painted around the actual element. The renderers treat
201
+ * the image **minus** the overdraw as the element: that core fills the layout
202
+ * box, and the overdraw band is painted outside it (like a CSS `box-shadow`).
203
+ * Optional: absent means no overdraw.
204
+ */
205
+ overdraw?: SliceInsets;
206
+ }
207
+ /** All-zero insets — the "no overdraw" value. */
208
+ declare function createZeroInsets(): SliceInsets;
209
+ /**
210
+ * Default insets for a freshly ingested image: each border a quarter of the
211
+ * corresponding dimension (at least 1px where the image is large enough),
212
+ * always clamped so a center of at least one source pixel remains on each
213
+ * axis. For an axis too small for insets + a 1px center (width/height ≤ 2)
214
+ * the insets on that axis are 0 — structurally valid slicing for any size ≥ 1.
215
+ */
216
+ declare function defaultInsetsForSize(width: number, height: number): SliceInsets;
217
+ /** Which source-image axes are sliced for a mode. */
218
+ declare function slicedAxesFor(mode: SliceMode): {
219
+ horizontal: boolean;
220
+ vertical: boolean;
221
+ };
222
+ /** Maximum inset on one side while preserving the opposite inset. */
223
+ declare function maxInset(insets: SliceInsets, side: keyof SliceInsets, width: number, height: number): number;
224
+ /** Maximum overdraw on one side while preserving at least one core source pixel. */
225
+ declare function maxOverdraw(overdraw: SliceInsets, side: keyof SliceInsets, width: number, height: number): number;
226
+ //#endregion
227
+ //#region src/plugins/slice.d.ts
228
+ interface SliceParameters {
229
+ mode: SliceMode;
230
+ insets: SliceInsets;
231
+ pixelRatio: number;
232
+ overdraw?: SliceInsets;
233
+ /** Output format preset name, resolved against the slice plugin config's presets. */
234
+ preset: string;
235
+ }
236
+ /** Same shape as the image plugin's config: named output-format presets. */
237
+ type SlicePluginConfig = ImagePluginConfig;
238
+ /** Built-in presets, always available; host config merges over them. */
239
+ declare const SLICE_BUILT_IN_PRESETS: Record<string, ImagePreset>;
240
+ declare const slicePlugin: AssetTypePluginDescriptor<SliceParameters, SlicePluginConfig>;
241
+ //#endregion
242
+ //#region src/plugins/video.d.ts
243
+ interface VideoPreset {
244
+ codec: 'h264';
245
+ /** x264 constant rate factor (quality; lower = better/larger). */
246
+ crf: number;
247
+ /** x264 speed/efficiency preset (`-preset`), e.g. 'slow'. */
248
+ encoderPreset: string;
249
+ /** x264 content tuning (`-tune`), e.g. 'animation'; omitted = none. */
250
+ tune?: string;
251
+ /** Output pixel format (`-pix_fmt`), e.g. 'yuv420p'. */
252
+ pixelFormat: string;
253
+ container: 'mp4';
254
+ }
255
+ interface VideoPluginConfig {
256
+ /** Named presets; merged over the built-in defaults. */
257
+ presets?: Record<string, VideoPreset>;
258
+ /** Absolute path of a system ffmpeg binary; omitted = the bundled `ffmpeg-static`. */
259
+ ffmpegPath?: string;
260
+ /** Absolute path of a system ffprobe binary; omitted = the bundled `ffprobe-static`. */
261
+ ffprobePath?: string;
262
+ }
263
+ interface VideoParameters {
264
+ /** Preset name, resolved against the video plugin config's presets. */
265
+ preset: string;
266
+ /** Downscale-only width cap (keeping aspect ratio); omitted = source resolution. */
267
+ maxWidth?: number;
268
+ }
269
+ /**
270
+ * Built-in presets, always available; host config merges over them. The
271
+ * default is the proven committed-video formula: H.264, slow preset, animation
272
+ * tune, CRF 28, yuv420p, faststart MP4.
273
+ */
274
+ declare const VIDEO_BUILT_IN_PRESETS: Record<string, VideoPreset>;
275
+ declare function validateVideoPreset(name: string, value: unknown): VideoPreset;
276
+ declare const VIDEO_EXTENSIONS: readonly string[];
277
+ /** Shared by the video and chroma-key-video plugins (identical transcode inputs). */
278
+ declare function validateVideoParameters(label: string, value: unknown): VideoParameters;
279
+ declare const videoPlugin: AssetTypePluginDescriptor<VideoParameters, VideoPluginConfig>;
280
+ //#endregion
281
+ //#region src/config.d.ts
282
+ interface FundusConfig {
283
+ /** Directory holding the raw originals (never delivered). */
284
+ rawDir: string;
285
+ /** Directory processed proxies are written to (conventionally under `static/`). */
286
+ proxyDir: string;
287
+ /** URL prefix baked into generated proxy `src` values, e.g. '/fundus/'. */
288
+ proxyBasePath: string;
289
+ /** Path of the library JSON file (the SSOT). */
290
+ library: string;
291
+ /** Directory the generated manifest modules land in. */
292
+ manifestsDir: string;
293
+ /**
294
+ * Per-plugin configuration; each plugin owns its namespace and schema.
295
+ * chroma-key-video has no namespace — it shares the video plugin's presets
296
+ * (and ffmpeg/ffprobe path overrides) .
297
+ */
298
+ plugins?: {
299
+ image?: ImagePluginConfig;
300
+ slice?: SlicePluginConfig;
301
+ video?: VideoPluginConfig;
302
+ audio?: AudioPluginConfig;
303
+ };
304
+ }
305
+ /** Identity helper so the host config file gets full typing + completion. */
306
+ declare function defineConfig(config: FundusConfig): FundusConfig;
307
+ //#endregion
308
+ //#region src/chroma-key.d.ts
309
+ /**
310
+ * Chroma-key parameter data: the keying values the chroma-key-video plugin
311
+ * stores per asset and the runtime's WebGL renderer consumes. The parameter
312
+ * names and defaults follow the public UnityChromakey shader; this module is
313
+ * environment-free data only — the GL engine lives in `@fundus/runtime`.
314
+ */
315
+ interface ChromaKeyParameters {
316
+ /** RGB 0–1 each. The greenscreen color to key out. */
317
+ keyColor: [number, number, number];
318
+ /** Chroma distance below which a pixel is fully keyed. */
319
+ colorCutoff: number;
320
+ /** Chroma distance band over which the key fades out. */
321
+ colorFeathering: number;
322
+ /** Blend toward the 3×3-blurred mask, 0 = unfeathered. */
323
+ maskFeathering: number;
324
+ /** Lower smoothstep edge re-hardening the feathered mask. */
325
+ sharpening: number;
326
+ /** How strongly green spill is pulled toward the red/blue average. */
327
+ despill: number;
328
+ /** Luminance removed by the despill that is added back. */
329
+ despillLuminanceAdd: number;
330
+ }
331
+ /** The upstream shader's property defaults — a freshly ingested asset starts here. */
332
+ declare const DEFAULT_CHROMA_KEY_PARAMETERS: ChromaKeyParameters;
333
+ /**
334
+ * Validate an unknown chroma-key blob: every field required, every channel and
335
+ * scalar a finite number. Values are clamped into 0–1 (slider float artifacts
336
+ * must not invalidate a library), non-numbers throw.
337
+ */
338
+ declare function validateChromaKeyParameters(value: unknown): ChromaKeyParameters;
339
+ //#endregion
340
+ //#region src/manifest-entry.d.ts
341
+ /**
342
+ * Pre-inline manifest-entry data. Reference fields may still contain
343
+ * `{ $asset }` markers; codegen narrows this to `ManifestEntry` after inlining.
344
+ */
345
+ type ManifestEntryData = {
346
+ kind: string;
347
+ src: string;
348
+ } & Record<string, unknown>;
349
+ interface ImageManifestEntry {
350
+ kind: 'image';
351
+ /** Delivered proxy URL (`proxyBasePath` + proxy file name). */
352
+ src: string;
353
+ /** Intrinsic pixel dimensions of the delivered proxy. */
354
+ width: number;
355
+ height: number;
356
+ }
357
+ interface SliceManifestEntry {
358
+ kind: 'slice';
359
+ /** Delivered proxy URL (`proxyBasePath` + proxy file name). */
360
+ src: string;
361
+ slicing: Slicing;
362
+ /** Pixel dimensions of the delivered image the insets are measured in. */
363
+ sourceWidth: number;
364
+ sourceHeight: number;
365
+ }
366
+ interface VideoManifestEntry {
367
+ kind: 'video';
368
+ /** Delivered proxy URL (`proxyBasePath` + proxy file name). */
369
+ src: string;
370
+ /** Intrinsic pixel dimensions of the delivered proxy. */
371
+ width: number;
372
+ height: number;
373
+ durationMs: number;
374
+ }
375
+ interface ChromaKeyVideoManifestEntry {
376
+ kind: 'chroma-key-video';
377
+ /** Delivered proxy URL (`proxyBasePath` + proxy file name). */
378
+ src: string;
379
+ /** Intrinsic pixel dimensions of the delivered proxy. */
380
+ width: number;
381
+ height: number;
382
+ durationMs: number;
383
+ chromaKey: ChromaKeyParameters;
384
+ /** Grayscale shape mask — the referenced image's entry, inlined by codegen. */
385
+ mask?: ImageManifestEntry;
386
+ /** WebGL2-unavailable fallback — the referenced image's entry, inlined by codegen. */
387
+ fallback?: ImageManifestEntry;
388
+ }
389
+ interface AudioManifestEntry {
390
+ kind: 'audio';
391
+ /** Delivered proxy URL (`proxyBasePath` + proxy file name). */
392
+ src: string;
393
+ durationMs: number;
394
+ }
395
+ type ManifestEntry = ImageManifestEntry | SliceManifestEntry | VideoManifestEntry | ChromaKeyVideoManifestEntry | AudioManifestEntry;
396
+ /** Preload options of the image kind: decode the fetched file up front. */
397
+ interface ImagePreloadOptions {
398
+ /** Decode via an HTMLImageElement after fetching (default true). */
399
+ decode?: boolean;
400
+ }
401
+ /**
402
+ * Preload options of the slice kind. A slice is image-backed, so it carries
403
+ * the same decode switch — typed per kind (not shared), so kinds can diverge.
404
+ */
405
+ interface SlicePreloadOptions {
406
+ /** Decode via an HTMLImageElement after fetching (default true). */
407
+ decode?: boolean;
408
+ }
409
+ /**
410
+ * Preload options of the video kind. Retention (full fetch + object URL) is
411
+ * always on — no options yet; the namespaced slot is the API.
412
+ */
413
+ interface VideoPreloadOptions {}
414
+ /**
415
+ * Preload options of the chroma-key-video kind. No options yet; the
416
+ * namespaced slot is the API.
417
+ */
418
+ interface ChromaKeyVideoPreloadOptions {}
419
+ /** Preload options of the audio kind. Retention is always on — no options yet. */
420
+ interface AudioPreloadOptions {}
421
+ /**
422
+ * Options for `Manifest.preload()`, namespaced per asset kind exactly like
423
+ * plugin configuration lives under `plugins.<type>` in `fundus.config.ts`
424
+ *; each kind that has preload options declares its own type here,
425
+ * and adding a kind is purely additive. An option applies to every entry of
426
+ * that kind, including entries reached via the inlined reference closure.
427
+ */
428
+ interface PreloadOptions {
429
+ image?: ImagePreloadOptions;
430
+ slice?: SlicePreloadOptions;
431
+ video?: VideoPreloadOptions;
432
+ chromaKeyVideo?: ChromaKeyVideoPreloadOptions;
433
+ audio?: AudioPreloadOptions;
434
+ }
435
+ //#endregion
436
+ //#region src/manifest-membership.d.ts
437
+ /** One derived passive membership, with the attribution that explains it. */
438
+ interface PassiveMember {
439
+ assetId: AssetId;
440
+ /**
441
+ * The explicit members of the manifest whose reference closure contains
442
+ * this asset — the answer to "why is this here". Attribution is to the
443
+ * explicit-member *roots*, so a chain `a → b → c` attributes both `b` and
444
+ * `c` to `a` (sorted, at least one entry).
445
+ */
446
+ via: AssetId[];
447
+ }
448
+ /** One manifest's full membership picture: explicit (stored) + passive (derived). */
449
+ interface ManifestMembership {
450
+ /** Members stored in the library — the manifest's typed API surface (sorted). */
451
+ explicitMemberIds: AssetId[];
452
+ /**
453
+ * Members derived from the reference graph: in the explicit members'
454
+ * reference closure without being explicit themselves. Delivered and
455
+ * preloaded with the manifest, but inlined-only in the generated module —
456
+ * never a top-level typed property. Sorted by asset id. An asset that is
457
+ * both explicit and referenced is an explicit member, full stop.
458
+ */
459
+ passiveMembers: PassiveMember[];
460
+ /** The delivery set: explicit ∪ passive. */
461
+ deliveredAssetIds: Set<AssetId>;
462
+ }
463
+ /**
464
+ * Membership per manifest name. Covers every name in `library.manifests` plus
465
+ * any name an asset record points at — a record referencing an unknown
466
+ * manifest is a validation error, but delivery semantics must not silently
467
+ * flip on a hand-edited library, so such names still deliver here.
468
+ */
469
+ type LibraryMembership = Record<ManifestName, ManifestMembership>;
470
+ /**
471
+ * Compute the full membership picture from a library and its collected
472
+ * references: for each manifest the explicit members, the passive members
473
+ * (`referenceClosure(explicit) − explicit`) with their via-attribution, and
474
+ * the resulting delivery set.
475
+ */
476
+ declare function computeLibraryMembership(library: Library, referencesByAsset: ReferencesByAsset): LibraryMembership;
477
+ /**
478
+ * Every asset delivered by at least one manifest, explicitly or passively —
479
+ * the processing set (assets outside it are inert). An asset is
480
+ * *unreachable* (nothing delivers it) exactly when it is missing here.
481
+ */
482
+ declare function allDeliveredAssetIds(membership: LibraryMembership): Set<AssetId>;
483
+ //#endregion
484
+ //#region src/plugins/chroma-key-video.d.ts
485
+ interface ChromaKeyVideoParameters extends VideoParameters {
486
+ chromaKey: ChromaKeyParameters;
487
+ /** Grayscale shape mask multiplied onto the keyed alpha (an `image` asset). */
488
+ mask?: AssetReference;
489
+ /** Static image rendered when WebGL2 is unavailable (an `image` asset). */
490
+ fallback?: AssetReference;
491
+ }
492
+ /**
493
+ * Shares the video plugin's preset namespace (chroma-key-video builds
494
+ * on video's processing) — it has no config namespace of its own in M3.
495
+ */
496
+ type ChromaKeyVideoPluginConfig = VideoPluginConfig;
497
+ declare const chromaKeyVideoPlugin: AssetTypePluginDescriptor<ChromaKeyVideoParameters, ChromaKeyVideoPluginConfig>;
498
+ //#endregion
499
+ export { AUDIO_BUILT_IN_PRESETS, AUDIO_EXTENSIONS, type ApiErrorDto, type AssetId, type AssetRecord, type AssetReference, type AssetReferenceLinkDto, type AssetReferencesDto, type AssetStateDto, type AssetTypePluginDescriptor, type AudioManifestEntry, type AudioParameters, type AudioPluginConfig, type AudioPreloadOptions, type AudioPreset, type ChromaKeyParameters, type ChromaKeyVideoManifestEntry, type ChromaKeyVideoParameters, type ChromaKeyVideoPreloadOptions, type CollectedReference, type CreateFolderRequestDto, type CreateManifestRequestDto, DEFAULT_CHROMA_KEY_PARAMETERS, type DeleteAssetsRequestDto, FOLDER_SENTINEL, type FundusConfig, type FundusStateDto, IMAGE_BUILT_IN_PRESETS, type ImageFormat, type ImageManifestEntry, type ImageParameters, type ImagePluginConfig, type ImagePreloadOptions, type ImagePreset, type Library, type LibraryMembership, MANIFEST_COLORS, MANIFEST_EMOJIS, type ManifestColor, type ManifestEntry, type ManifestEntryData, type ManifestMembership, type ManifestMembershipDto, type ManifestName, type ManifestRecord, type MoveAssetsRequestDto, type PassiveManifestMembershipDto, type PassiveMember, type PassiveMemberDto, type PatchAssetRequestDto, type PatchFolderRequestDto, type PatchManifestRequestDto, type PluginDescriptorRegistry, type PreloadOptions, type ProxyStateDto, RASTER_IMAGE_EXTENSIONS, RESERVED_ASSET_IDS, ROOT_FOLDER, type ReferencesByAsset, SLICE_BUILT_IN_PRESETS, type SliceInsets, type SliceManifestEntry, type SliceMode, type SliceParameters, type SlicePluginConfig, type SlicePreloadOptions, type Slicing, VIDEO_BUILT_IN_PRESETS, VIDEO_EXTENSIONS, type ValidationIssueDto, type VideoManifestEntry, type VideoParameters, type VideoPluginConfig, type VideoPreloadOptions, type VideoPreset, acceptedExtensions, allDeliveredAssetIds, assetIdError, audioPlugin, canonicalizeParameters, chromaKeyVideoPlugin, collectAllReferences, compareCodeUnits, computeLibraryMembership, createEmptyLibrary, createZeroInsets, defaultInsetsForSize, defineConfig, folderNameError, folderNameOf, folderOfRawPath, folderPathError, imagePlugin, isAssetReference, isFolderOrDescendant, isManifestColor, isManifestEmoji, isValidAssetId, joinFolderPath, manifestColorError, manifestEmojiError, manifestNameError, maxInset, maxOverdraw, normalizeFolderPath, parentFolderPath, parseLibrary, portableFolderPathKey, proposeAssetId, rawFileNameOfPath, referenceClosure, referenceErrors, replaceFolderPrefix, resolveManifestColor, serializeLibrary, slicePlugin, slicedAxesFor, topologicalReferenceOrder, typesForFileName, validateAudioPreset, validateChromaKeyParameters, validateImagePreset, validateVideoParameters, validateVideoPreset, videoPlugin };