{
  "kind": "shaderera.registry/1",
  "items": {
    "audio-beat-clock": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "audio-beat-clock",
            "type": "component",
            "title": "Beat clock",
            "description": "Measure a song (tempo fitted to its onsets, beat grid, downbeats, onsets, band energy, sections) and cut the picture to it: bars, beats, 1/16s, band levels, hit pulses at t",
            "category": "Audio & Music",
            "tags": [
              "music",
              "beat sync",
              "bpm",
              "beat grid",
              "onsets",
              "audio reactive",
              "analysis"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "shaderera": ">=0.1.0",
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "tools/analyze-music.ts",
              "src/music/beat.ts"
            ]
          },
          "sha256": "525d7839ab576ec1d59a12cc9b39d200c3a38885c69e3e35f49768b6d13f28d0",
          "published": "2026-10-13T15:21:29.841Z",
          "symbols": [
            "Analysis",
            "loadAnalysis",
            "Clock",
            "clockOf",
            "clockFromAnalysis",
            "bandsOf",
            "hitsOf",
            "fitGrid",
            "Fit",
            "pulse",
            "# What tools/analyze-music.ts writes. */",
            "# How the grid was fitted to the song's strong onsets (fitGrid); absent in older analyses. */",
            "# Reads an analysis, and refuses it when it was measured from other bytes than `song`: a changed",
            "# Seconds per beat, per bar and per 1/16. */",
            "# When bar 1 starts (it may be negative when the film starts inside the song). */",
            "# The time of bar n (1-based), plus beats and sixteenths into it. */",
            "# The index of the 1/16 that t falls in (0 at bar 1). */",
            "# Seconds since the 1/16 that t falls in began. */",
            "# Where t is, 1-based: bar, beat in the bar, 1/16 in the beat. */",
            "# A clock from a tempo and the time of bar 1. `beatsPerBar` is 4 unless the song says otherwise. */",
            "# The clock of an analysed song. The song's first measured downbeat is bar `firstBar` (1 unless",
            "# The song's four bands at t, each 0–1 over its loudest `range` dB (sub, low, mid, high). `trim`",
            "# The song's onsets at least `strength` strong, in film time. */",
            "# Fits a beat grid to the song's own hits. Autocorrelation finds a tempo only to within its step,",
            "# The steps the grid was fitted on: 1 a beat, 2 eighths, 4 sixteenths. */",
            "# The onsets near `g`, each with its beat number and its distance to the grid. */",
            "# An envelope that jumps to 1 on each of `times` and decays with time constant `decay` seconds:",
            "# Measure the song once, then cut every change to its grid: bars, beats, 1/16s, band levels and hits at t."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/music/beat.ts",
            "tools/analyze-music.ts"
          ]
        }
      }
    },
    "audio-hall-ending": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "audio-hall-ending",
            "type": "component",
            "title": "Hall ending",
            "description": "Give a song that stops dead an ending: its last chord rings out in a synthetic hall, dies to digital silence, and the film holds",
            "category": "Audio & Music",
            "tags": [
              "ending",
              "reverb",
              "tail",
              "outro",
              "silence",
              "ffmpeg",
              "audio conform"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "tools/hall-ending.ts"
            ]
          },
          "sha256": "675764889655bb577083607325ab1f4e5eec1020f9a911c66fffe9784b7a5f66",
          "published": "2026-10-13T15:21:30.148Z",
          "symbols": [
            "# An ending that rings out in a hall and dies to silence, for a song that stops dead."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "tools/hall-ending.ts"
          ]
        }
      }
    },
    "camera-keyframes": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "camera-keyframes",
            "type": "component",
            "title": "Camera keys",
            "description": "A 3D camera as keyframed shots (eye, target, lens, roll) eased over time: dolly, yaw, crane, roll, snap; WebGPU view and projection matrices or a three.js camera; the lens opens for vertical variants",
            "category": "Animation & Camera",
            "tags": [
              "camera",
              "3d",
              "keyframes",
              "dolly",
              "orbit",
              "look at",
              "fov",
              "three.js",
              "webgpu",
              "choreography",
              "framing",
              "fit",
              "rule of thirds",
              "lens",
              "35mm",
              "shot"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {
                "motion-keyframes": "^0.1.0",
                "format-safe-areas": "^0.1.0"
              },
              "packages": {}
            },
            "files": [
              "src/motion/camera.ts"
            ]
          },
          "sha256": "acc4e2faee704db39864c9b2d64e71ba3c7b7e43a1fa3c2a284f9b32bcefba61",
          "published": "2026-10-13T15:21:30.477Z",
          "symbols": [
            "Shot",
            "shot",
            "lens",
            "FILL",
            "fit",
            "bounds",
            "blendShots",
            "CameraOptions",
            "cameraTrack",
            "cameraPath",
            "upOf",
            "viewMatrix",
            "projectionMatrix",
            "viewProjection",
            "matricesOf",
            "cameraCapability",
            "applyToThree",
            "# Vertical field of view in degrees (see `lens` to work in millimetres). */",
            "# Turn about the line of sight, in radians. */",
            "# Moves the picture without changing perspective, in frame widths and heights: [-1/6, 0] puts a",
            "# Focus distance from the eye, for depth of field. */",
            "# Aperture, for depth of field: smaller is shallower. */",
            "# How the camera arrives at this shot from the one before. 'orbit' (the default) swings round",
            "# The vertical field of view (degrees) of a lens of `mm` on 35 mm film, for a frame of `aspect`",
            "# How much of the frame a subject fills, for `fit`: a wide shot, a medium shot, a close-up. */",
            "# A shot that frames a subject (a sphere: `center`, `radius`) from a direction: `azimuth` degrees",
            "# The bounding sphere of points or of a box's corners, for `fit`. */",
            "# The eye's offset from the target, swung on an arc: the shorter way round, distance eased on a log scale. */",
            "# Shot `a` moved toward shot `b` by `u` (0–1), the way `b` says it is reached. */",
            "# How far a narrower frame opens the lens: 0 keeps the height, 1 keeps the width (see widenFov). */",
            "# The aspect the shots were designed for. */",
            "# The camera at any t from shots at times, `[t, shot, ease?]`: held between keys, and moved into",
            "# One continuous move from `from` to `to` through all the shots, never stopping at the ones",
            "# The camera's up direction with its roll. Looking straight down, \"up\" on screen eases to far (−z),",
            "# The view matrix (world to camera; the camera looks down −z). */",
            "# The perspective projection for WebGPU (clip z from 0 at `near` to 1 at `far`), with the shot's",
            "# projection × view, column-major, for a uniform buffer. */",
            "# The shot in core's camera contract: matrices, as every renderer and the CLI/MCP exchange them. */",
            "# Core's CameraCapability for a camera: `get` reports what the film looks through at t, `override`",
            "# The matrices to render with at t: the host's camera if it passed one, else the film's. */",
            "# The part of a three.js PerspectiveCamera this sets; three itself is not imported. */",
            "# Puts a three.js PerspectiveCamera where the shot says, shift and focus included. */",
            "# A 3D camera as keyframed shots (eye, target, lens, roll, shift, focus) that orbit, dolly, crane and cut over time; exact framing of a subject, lenses in millimetres, WebGPU matrices or a three.js camera, and a lens that opens for vertical variants."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/motion/camera.ts"
          ]
        }
      }
    },
    "camera-shake": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "camera-shake",
            "type": "component",
            "title": "Camera shake",
            "description": "A camera that breathes, is handheld, or kicks on the hits of the music: seeded noise and hit envelopes as formulas of t, applied in camera space",
            "category": "Animation & Camera",
            "tags": [
              "camera shake",
              "handheld",
              "impact",
              "noise",
              "breathing",
              "3d",
              "deterministic"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {
                "camera-keyframes": "^0.1.0"
              },
              "packages": {}
            },
            "files": [
              "src/motion/shake.ts"
            ]
          },
          "sha256": "28138507023f64679685c0e846672a0da7126a0696721ad25065c23dfd6b53ca",
          "published": "2026-10-13T15:21:30.804Z",
          "symbols": [
            "noise1",
            "ShakeStyle",
            "SHAKE",
            "hit",
            "hits",
            "shake",
            "# Smooth 1D gradient noise in about [-1, 1], fixed for a seed. */",
            "# Two octaves of noise, for a less mechanical wander. */",
            "# Largest turn, in degrees (yaw and pitch; roll is a third of it). */",
            "# How fast it wanders, in cycles per second. */",
            "# Sideways and vertical drift of the eye, in world units. */",
            "# Presets, from a camera on a tripod that is still alive to a camera that takes a hit. */",
            "# 1 at `at`, decaying with time constant `decay` seconds after it; 0 before: a hit's envelope. */",
            "# The sum of hits at `times`: a camera that takes every hit of the music. */",
            "# The shot shaken at t. `amount` scales it (an envelope such as `hit`, or 1 for a steady",
            "# Camera shake as a formula of t: a camera that breathes, is handheld, or takes the hits of the music, the same on every render."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/motion/shake.ts"
          ]
        }
      }
    },
    "font-ibm-plex-mono": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "font-ibm-plex-mono",
            "type": "media",
            "title": "IBM Plex Mono",
            "description": "A monospace with an engineered, technical voice: Light, Regular and SemiBold, for data, code, captions and ASCII looks",
            "category": "Fonts",
            "tags": [
              "monospace",
              "mono",
              "code",
              "technical",
              "latin",
              "ofl"
            ],
            "version": "0.1.0",
            "licence": "OFL-1.1",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "assets/fonts/IBMPlexMono-Light.ttf",
              "assets/fonts/IBMPlexMono-Regular.ttf",
              "assets/fonts/IBMPlexMono-SemiBold.ttf",
              "assets/fonts/OFL-ibmplexmono.txt"
            ],
            "source": {
              "origin": "https://github.com/IBM/plex"
            }
          },
          "sha256": "eca8ca4d2a2caf09701eeadfde58a9ef4ed7f1b590b7b4f8e49c5cd877139559",
          "published": "2026-10-13T15:21:31.054Z",
          "symbols": [
            "# IBM Plex Mono (OFL 1.1): Light, Regular and SemiBold, for data, code, captions and ASCII looks."
          ],
          "files": [
            "README.md",
            "assets/fonts/IBMPlexMono-Light.ttf",
            "assets/fonts/IBMPlexMono-Regular.ttf",
            "assets/fonts/IBMPlexMono-SemiBold.ttf",
            "assets/fonts/OFL-ibmplexmono.txt",
            "shaderera.item.json"
          ]
        }
      }
    },
    "font-ibm-plex-sans": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "font-ibm-plex-sans",
            "type": "media",
            "title": "IBM Plex Sans",
            "description": "A restrained grotesque sans, Light, Regular and Medium, for names, dates, labels and captions beside a display serif; Latin, Greek and Cyrillic",
            "category": "Fonts",
            "tags": [
              "sans serif",
              "grotesque",
              "labels",
              "captions",
              "editorial",
              "latin",
              "greek",
              "cyrillic",
              "ofl"
            ],
            "version": "0.1.0",
            "licence": "OFL-1.1",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "assets/fonts/IBMPlexSans-Light.ttf",
              "assets/fonts/IBMPlexSans-Regular.ttf",
              "assets/fonts/IBMPlexSans-Medium.ttf",
              "assets/fonts/IBMPlexSans-OFL.txt"
            ],
            "source": {
              "origin": "https://github.com/IBM/plex"
            }
          },
          "sha256": "78c61f5c5030026bc9096a84d28e62fb1a4087d1c19a9137cdaaf8833fc4346b",
          "published": "2026-10-13T15:21:31.306Z",
          "symbols": [
            "# IBM Plex Sans (OFL 1.1): Light, Regular and Medium, for names, dates, labels and captions, in Latin, Greek and Cyrillic."
          ],
          "files": [
            "README.md",
            "assets/fonts/IBMPlexSans-Light.ttf",
            "assets/fonts/IBMPlexSans-Medium.ttf",
            "assets/fonts/IBMPlexSans-OFL.txt",
            "assets/fonts/IBMPlexSans-Regular.ttf",
            "shaderera.item.json"
          ]
        }
      }
    },
    "font-instrument-serif": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "font-instrument-serif",
            "type": "media",
            "title": "Instrument Serif",
            "description": "A condensed editorial display serif, regular and italic, for titles and main phrases in an art-publication or magazine voice",
            "category": "Fonts",
            "tags": [
              "serif",
              "display",
              "editorial",
              "italic",
              "title",
              "magazine",
              "latin",
              "ofl"
            ],
            "version": "0.1.0",
            "licence": "OFL-1.1",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "assets/fonts/InstrumentSerif-Regular.ttf",
              "assets/fonts/InstrumentSerif-Italic.ttf",
              "assets/fonts/InstrumentSerif-OFL.txt"
            ],
            "source": {
              "origin": "https://github.com/google/fonts/tree/main/ofl/instrumentserif"
            }
          },
          "sha256": "da08a3c31ed47252660aa0230ba27b7fb8679c18addad733e1c64559331f5440",
          "published": "2026-10-13T15:21:31.601Z",
          "symbols": [
            "# Instrument Serif (OFL 1.1): a condensed editorial display serif, regular and italic, for titles and main phrases."
          ],
          "files": [
            "README.md",
            "assets/fonts/InstrumentSerif-Italic.ttf",
            "assets/fonts/InstrumentSerif-OFL.txt",
            "assets/fonts/InstrumentSerif-Regular.ttf",
            "shaderera.item.json"
          ]
        }
      }
    },
    "font-stix-two-text": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "font-stix-two-text",
            "type": "media",
            "title": "STIX Two Text",
            "description": "A scientific serif, roman and italic (variable weight), for notes and annotation beside a monospace",
            "category": "Fonts",
            "tags": [
              "serif",
              "italic",
              "scientific",
              "editorial",
              "variable",
              "latin",
              "ofl"
            ],
            "version": "0.1.0",
            "licence": "OFL-1.1",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "assets/fonts/STIXTwoText[wght].ttf",
              "assets/fonts/STIXTwoText-Italic[wght].ttf",
              "assets/fonts/OFL-stixtwotext.txt"
            ],
            "source": {
              "origin": "https://github.com/stipub/stixfonts"
            }
          },
          "sha256": "0fe3f5b991298fe5d445574fa704b9fecc6d245a7f2cd450b8c0fef2ec1f928f",
          "published": "2026-10-13T15:21:31.860Z",
          "symbols": [
            "# STIX Two Text (OFL 1.1): a scientific serif, roman and italic, for notes and annotation beside a monospace."
          ],
          "files": [
            "README.md",
            "assets/fonts/OFL-stixtwotext.txt",
            "assets/fonts/STIXTwoText-Italic[wght].ttf",
            "assets/fonts/STIXTwoText[wght].ttf",
            "shaderera.item.json"
          ]
        }
      }
    },
    "format-broadcast-slate": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "format-broadcast-slate",
            "type": "component",
            "title": "Broadcast slate",
            "description": "A clock slate for a broadcast preroll (fill: 'source'): the spot's details and a countdown in seconds, going to black before the programme, drawn on a 2D canvas at negative t",
            "category": "Layout & Formats",
            "tags": [
              "slate",
              "clock",
              "preroll",
              "broadcast",
              "countdown",
              "clearcast"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "src/delivery/slate.ts"
            ]
          },
          "sha256": "cdad312c4c534495cbd08047ca83bd79d03f5f9cc43e2357321ff018c7fe94a1",
          "published": "2026-10-13T15:21:32.118Z",
          "symbols": [
            "SlateFields",
            "drawSlate",
            "# What a slate states: one line each, in order. Values are the delivery's, never invented. */",
            "# Draws the slate at t < 0 (a preroll with `fill: 'source'`): the fields as label and value",
            "# A clock slate for a broadcast preroll: the spot's details and a countdown, drawn by the film at negative t when its variant declares `preroll: { seconds, fill: 'source' }`."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/delivery/slate.ts"
          ]
        }
      }
    },
    "format-placement-specs": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "format-placement-specs",
            "type": "preset",
            "title": "Placement specs",
            "description": "What Reels ads, YouTube, Amazon CTV, US and EU broadcast and a DOOH screen accept, as requirements.json placements that deliver checks the file against, each with its source and the date it was read",
            "category": "Layout & Formats",
            "tags": [
              "placement",
              "delivery",
              "reels",
              "meta",
              "youtube",
              "ctv",
              "amazon",
              "dooh",
              "loudness",
              "bitrate",
              "spec"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "delivery/placements.json"
            ]
          },
          "sha256": "7273ef50bbb9344233e6c5cd7dd36ba8e1641f159427ef315e83e1be7097e56a",
          "published": "2026-10-13T15:21:32.403Z",
          "symbols": [
            "# What a placement accepts, as data for requirements.json `placements`: `deliver` checks each delivered file against the placement its variant declares, and review judges text against its safe area."
          ],
          "files": [
            "README.md",
            "delivery/placements.json",
            "shaderera.item.json"
          ]
        }
      }
    },
    "format-safe-areas": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "format-safe-areas",
            "type": "component",
            "title": "Safe areas and the tall-frame lens",
            "description": "Where text may go in 16:9, 1:1 and 9:16, clear of YouTube Shorts, Reels and TikTok UI; and the lens rule that keeps a 16:9 shot reading in a vertical variant",
            "category": "Layout & Formats",
            "tags": [
              "safe area",
              "vertical",
              "9:16",
              "shorts",
              "reels",
              "tiktok",
              "variants",
              "fov",
              "lens"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "src/layout/frame.ts"
            ]
          },
          "sha256": "2739d0511c1edb618c0b5b94123f57880cb73caed5970e2dc8c29c9caba20f00",
          "published": "2026-10-13T15:21:32.630Z",
          "symbols": [
            "Platform",
            "Area",
            "safeArea",
            "widenFov",
            "# Margins in pixels, and the box inside them. */",
            "# The safe area of a W×H frame. With no platform, generic title-safe margins (not a platform",
            "# A vertical field of view (radians) designed for a `designed` aspect (16:9), opened for a",
            "# Safe areas for text per format and platform, and the lens rule that keeps a 16:9 shot reading in 9:16."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/layout/frame.ts"
          ]
        }
      }
    },
    "look-screen-passes": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "look-screen-passes",
            "type": "component",
            "title": "Screen looks",
            "description": "The frame in another medium, one WebGPU pass over a texture or a canvas: ascii, halftone, ordered dither, heat map, contours, pixelate, inverse, and a row glitch with pixel sorting",
            "category": "Looks",
            "tags": [
              "ascii",
              "halftone",
              "dither",
              "heat map",
              "contours",
              "pixelate",
              "glitch",
              "pixel sort",
              "post",
              "shader",
              "wgsl"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "src/looks/looks.ts",
              "src/looks/looks.wgsl.ts"
            ]
          },
          "sha256": "1fd1268e9caa9651be95faebd398d7f119e103b9ae498187550c5ae288ae1167",
          "published": "2026-10-13T15:21:32.873Z",
          "symbols": [
            "LookName",
            "LOOKS",
            "LookParams",
            "createLooks",
            "# How much of the look, 0–1, over the plain frame. */",
            "# Cell size in px for halftone and pixels. */",
            "# Share of rows thrown sideways (0 for none, 0.3 is a hard glitch). */",
            "# Share of thrown rows that are also sorted. */",
            "# How far a thrown row moves, as a share of the width. */",
            "# Changes the glitch's rows and the grain; pass options.frame so they change every frame. */",
            "# The looks pass for a W×H frame. `face` is a monospace family registered with host.io.font, for",
            "# The frame in `source` with the look applied, as a texture of host.gpu at the frame's size.",
            "LOOKS_WGSL",
            "fullVs",
            "hash",
            "rowHash",
            "scene",
            "luma",
            "heat",
            "bayer",
            "look",
            "lookFs",
            "# Screen looks over any frame, as one WebGPU pass: ascii, halftone, dither, heat, contours, pixels, inverse, and a row glitch with pixel sorting."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/looks/looks.ts",
            "src/looks/looks.wgsl.ts"
          ]
        }
      }
    },
    "motion-keyframes": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "motion-keyframes",
            "type": "component",
            "title": "Keyframes",
            "description": "Values over time: numbers and 3D points held between keys and eased into each, smooth paths through many points at even speed, and eases from strike and glide to a stateless spring settle and CSS-style bezier",
            "category": "Animation & Camera",
            "tags": [
              "keyframes",
              "animation",
              "easing",
              "tween",
              "track",
              "timeline",
              "motion"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "src/motion/keyframes.ts"
            ]
          },
          "sha256": "f1da61ae1d737922b60b1a06df79e981a9e3cb03018e31956847889c1aaad701",
          "published": "2026-10-13T15:21:33.122Z",
          "symbols": [
            "Ease",
            "linear",
            "smooth",
            "strike",
            "accel",
            "glide",
            "hold",
            "sine",
            "expo",
            "circ",
            "back",
            "settle",
            "bezier",
            "Key",
            "clamp",
            "lerp",
            "track",
            "V3",
            "track3",
            "path3",
            "progress",
            "between",
            "# Smoothstep: eases in and out. The default. */",
            "# Fast start, long settle: a hit, a cut, a snap into place. */",
            "# Slow start, fast end: a fall, a build into a drop. */",
            "# A long, even glide in and out (cubic in-out). */",
            "# Holds the old value to the key, then jumps: a cut. */",
            "# Sine in-out: the gentlest start and stop. */",
            "# Exponential in-out: still, then fast, then still. */",
            "# Circular in-out. */",
            "# Overshoots the key a little, then comes back to it. */",
            "# A critically damped spring, as a formula of u rather than a step per frame: the feel of damping",
            "# A CSS-style cubic bezier, (x1, y1, x2, y2), as in a motion designer's curve editor. */",
            "# A key: at time t the value is v, reached from the key before with `ease` (smooth by default). */",
            "# A number over time. Keys must be in time order. */",
            "# A point over time, each axis its own track with the same keys and eases. */",
            "# One move through several points that never stops at the ones between: a smooth curve through",
            "# 0 before `from`, 1 after `to`, eased between: a fade, a reveal, a wipe. */",
            "# Whether t is in [a, b). */",
            "# Keyframed values over time with easing: numbers, points and progress, asked for their value at t."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/motion/keyframes.ts"
          ]
        }
      }
    },
    "render-gaussian-splats": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "render-gaussian-splats",
            "type": "component",
            "title": "Gaussian splats",
            "description": "3D Gaussian splats (.splat and 3DGS .ply) rendered on host.gpu with EWA splatting, sorted back to front deterministically every frame, the frame as a premultiplied GPU texture layer; raw WebGPU, no packages",
            "category": "Rendering",
            "tags": [
              "gaussian splatting",
              "3dgs",
              "splats",
              "ply",
              "point cloud",
              "radiance field",
              "ewa",
              "webgpu",
              "wgsl",
              "3d",
              "deterministic"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "src/render/splats.ts"
            ]
          },
          "sha256": "4953adec416b538dda374911337b8eb25c46443f279ce326fe325eba7a2d9241",
          "published": "2026-10-13T15:21:33.369Z",
          "symbols": [
            "Splats",
            "parseSplat",
            "parsePly",
            "parseSplats",
            "loadSplats",
            "SplatRendererOptions",
            "SplatRenderer",
            "createSplatRenderer",
            "splatVs",
            "splatFs",
            "# Splats as plain typed arrays, one entry (or 3, or 4) per splat. */",
            "# x, y, z in world units. */",
            "# The Gaussian's standard deviation along its own x, y, z, in world units (linear, not log). */",
            "# Unit quaternion w, x, y, z (the 3DGS order: rot_0 is w). */",
            "# r, g, b as display values (0–1, may exceed 1 from a .ply) and a = opacity 0–1, straight. */",
            "# The common `.splat` format (antimatter15): 32 bytes a splat, little-endian. Position f32×3,",
            "# A binary little-endian 3DGS `.ply` (the training output): x, y, z; f_dc_0..2 to colour as",
            "# `.ply` by its header, `.splat` otherwise. */",
            "# Reads and parses a splat file of the project: `await loadSplats(host, 'assets/garden.ply')`. */",
            "# 'rgba16float' (default) keeps precision while thousands of splats blend into one pixel;",
            "# Replaces the splats on the GPU. */",
            "# Sorts, draws, and returns the frame-size texture: premultiplied alpha, transparent where there",
            "# The splats in back-to-front order from the last render (in front of the camera only). */",
            "# The 3D covariance R S Sᵀ Rᵀ of every splat, upper triangle, into the GPU layout. */",
            "# A splat renderer for a W×H frame on `device` (host.gpu). Upload splats once in `open`, render",
            "# Back to front: view depth as Float32, keyed so that a far splat sorts first, through a stable",
            "# 3D Gaussian splats from a `.splat` or 3DGS `.ply` file, drawn on the host's GPU with EWA splatting and returned as a layer, the same pixels for the same camera every time."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/render/splats.ts"
          ]
        }
      }
    },
    "render-image-textures": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "render-image-textures",
            "type": "component",
            "title": "Image textures",
            "description": "Artwork and photos as three.js textures decoded identically in Node and the browser (pure-JS PNG and JPEG), an atlas of many images for instanced cards, and a tool that converts WebP, AVIF, GIF or video frames to PNG once",
            "category": "Rendering",
            "tags": [
              "images",
              "textures",
              "photos",
              "artwork",
              "atlas",
              "cards",
              "webp",
              "png",
              "jpeg",
              "three.js",
              "decode"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {
                "three": "0.186.1",
                "fast-png": "8.0.0",
                "jpeg-js": "0.4.4"
              }
            },
            "files": [
              "src/three/images.ts",
              "tools/to-png.ts"
            ]
          },
          "sha256": "6fd3a9cef5c12717a51a0552e40dc89b0855256fd66c5c4f36e887fd21614648",
          "published": "2026-10-13T15:21:33.688Z",
          "symbols": [
            "Decoded",
            "decodeImage",
            "textureOf",
            "loadTexture",
            "loadAtlas",
            "# RGBA bytes, rows top-down, from PNG or JPEG bytes. */",
            "# A texture for an image's pixels: sRGB, mipmapped, flipped so v = 0 is the image's bottom. Its",
            "# Reads, decodes and uploads one image: its texture and its aspect (width over height). */",
            "# Several images packed into one atlas texture (rows of cells, each image fitted inside its cell",
            "# Images as three.js textures, the same pixels in Node and the browser; an atlas for many cards; WebP and video frames converted to PNG once."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/three/images.ts",
            "tools/to-png.ts"
          ]
        }
      }
    },
    "render-three-host": {
      "versions": {
        "0.1.1": {
          "item": {
            "name": "render-three-host",
            "type": "component",
            "title": "three.js on the host GPU",
            "description": "three.js WebGPURenderer on host.gpu, deterministic: node clock set to t (never the wall clock), HDR scene tone-mapped and sRGB-encoded into the frame, handed to the host as a GPU texture layer with no copy; works in Node and the browser",
            "category": "Rendering",
            "tags": [
              "three.js",
              "webgpu",
              "3d",
              "renderer",
              "scene",
              "render target",
              "tone mapping",
              "deterministic",
              "node"
            ],
            "version": "0.1.1",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {
                "three": "0.186.1",
                "@types/three": "0.186.0"
              }
            },
            "files": [
              "src/three/host.ts"
            ]
          },
          "sha256": "1cfcd138d88aa27d017b281547171482a6da7227671cbebb0f115a250fc3bb38",
          "published": "2026-10-13T15:21:33.986Z",
          "symbols": [
            "ThreeHostOptions",
            "threeCamera",
            "createThreeHost",
            "# Tone mapping for the output pass. None by default: colours come out as written (a paper",
            "# MSAA samples for the scene: 4 smooths geometry edges, but see the note on blending above. */",
            "# 'texture' (default) hands the host the frame's GPU texture with no copy; 'bytes' reads it back",
            "# A camera in WebGPU's clip space. Set it with camera-keyframes' applyToThree or by hand. */",
            "# WebGPU pads read-back rows to 256 bytes: the rows without the padding. */",
            "# Renders `world` through `camera` at t and returns the frame as an opaque layer. Pass the",
            "# three.js on the host's GPU, deterministic, in Node and the browser: render a scene at t and return it as a layer."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/three/host.ts"
          ]
        }
      }
    },
    "review-av-timeline": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "review-av-timeline",
            "type": "component",
            "title": "Sound and motion review",
            "description": "For a reviewer who cannot hear or watch: the film's sound as a spectrogram and waveform with its onsets, how much the picture changes every frame on the same timeline, frame strips around chosen moments, and the measured offset between picture and sound",
            "category": "Analysis & Tracking",
            "tags": [
              "review",
              "audio sync",
              "lip sync",
              "beat sync",
              "spectrogram",
              "waveform",
              "motion",
              "pacing",
              "frames",
              "ffmpeg",
              "listen",
              "hear",
              "watch",
              "playback",
              "speed",
              "density",
              "timing",
              "on beat",
              "check sync"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {
                "@napi-rs/canvas": "1.0.10"
              }
            },
            "files": [
              "tools/av-review.ts"
            ]
          },
          "sha256": "d04d7c5a3bc3bd400cc660a2263874dd1242b29cb2449e42669e0775ceee42f5",
          "published": "2026-10-13T15:21:34.219Z",
          "symbols": [
            "# See the sound and the motion of a rendered film: spectrogram, waveform, onsets and picture change on one timeline; every frame around a moment; the picture-to-sound offset in ms."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "tools/av-review.ts"
          ]
        }
      }
    },
    "text-code-wall": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "text-code-wall",
            "type": "component",
            "title": "Code wall",
            "description": "The project's own source as a wall of text that scrolls and jumps on the beat, glitched and scrambled, with a claim cut out of the middle",
            "category": "Typography",
            "tags": [
              "code",
              "source",
              "glitch",
              "matrix",
              "tech",
              "launch",
              "ending",
              "claim"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {
                "text-kinetic": "^0.1.0"
              },
              "packages": {}
            },
            "files": [
              "src/type/code-wall.ts"
            ]
          },
          "sha256": "8c99a5e524d0bfa94a097b95a1baae31afeb7bc73d171cb4eadd5bd6d1fc6966",
          "published": "2026-10-13T15:21:34.442Z",
          "symbols": [
            "CodeFile",
            "readCode",
            "CodeWallOptions",
            "createCodeWall",
            "# Reads source files through the host (paths from the project root), without blank lines. */",
            "# The jump period: a 1/16 of the music reads as the machine running. */",
            "# The claim, a line each; none for the wall alone. */",
            "# A small line under the claim; by default the files and their line count. */",
            "# CSS font families, quoted. */",
            "# Draws the wall at t onto ctx, if t is inside it (it does not clear the canvas). */",
            "# The film's own source as a scrolling, glitching wall of text, with a claim cut out of the middle: \"everything is source code\"."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/type/code-wall.ts"
          ]
        }
      }
    },
    "text-feature-captions": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "text-feature-captions",
            "type": "component",
            "title": "Feature captions",
            "description": "Huge titles with a small note, several to a scene, swapping on the beat through ASCII noise, each placed anew in one of four layouts inside the safe area",
            "category": "Typography",
            "tags": [
              "captions",
              "titles",
              "lower thirds",
              "glitch",
              "launch",
              "feature list",
              "kinetic typography"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {
                "text-kinetic": "^0.1.0",
                "format-safe-areas": "^0.1.0"
              },
              "packages": {}
            },
            "files": [
              "src/type/captions.ts"
            ]
          },
          "sha256": "208347e4d6e05ef9a4d120fc2c9be8d735afc2a12be8105035f1ee8c02d5a377",
          "published": "2026-10-13T15:21:34.705Z",
          "symbols": [
            "Caption",
            "Layout",
            "CaptionOptions",
            "createCaptions",
            "# CSS font families, quoted: '\"IBM Plex Mono SemiBold\"'. */",
            "# Seconds each item holds before the next swaps in (two beats of the music reads well). */",
            "# Show the running number (\"03 / 12\") and the huge hollow numeral. */",
            "# Draws the caption showing at t, if any, onto ctx (it does not clear it). */",
            "# Big feature captions that swap through ASCII noise, several to a scene, each set somewhere new in one of four layouts (edge, split, column, spine)."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/type/captions.ts"
          ]
        }
      }
    },
    "text-glyph-morph": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "text-glyph-morph",
            "type": "component",
            "title": "Glyph morph",
            "description": "One glyph outline or word morphing into another: contours resampled by arc length, paired outer to outer and hole to hole, a contour with no partner grown from a point, the in-between a pure function of k",
            "category": "Typography",
            "tags": [
              "morph",
              "tween",
              "glyph",
              "outlines",
              "letters",
              "shape morph",
              "kinetic typography",
              "vector"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {
                "text-glyph-outlines": "^0.1.0"
              },
              "packages": {}
            },
            "files": [
              "src/type/glyph-morph.ts"
            ]
          },
          "sha256": "6fc296239d1dbf803b16966ae896a58363a88e18b445fd7e874d395f2b238561",
          "published": "2026-10-13T15:21:34.953Z",
          "symbols": [
            "Ring",
            "Shape",
            "Morph",
            "ShapeOptions",
            "shapeOf",
            "lettersOf",
            "morphOf",
            "morphLetters",
            "boundsOf",
            "PathSink",
            "tracePath",
            "# One closed contour: `points` x, y pairs. */",
            "# Contours ready to morph, every one with the same number of points, and the advance width. */",
            "# A morph from one shape to another: `at(0)` is `a`, `at(1)` is `b`, and between, both. */",
            "# Points per contour (default 160); shapes morph only with the same count. */",
            "# Furthest a flattened curve strays from the true curve, in ems (default 0.0015). */",
            "# A variable font's axes: `{ wght: 700 }`. */",
            "# A closed polyline (points `[a, b)` of `pts`) resampled to `n` points evenly by arc length. */",
            "# `text` (a glyph or a word) as one shape: its contours resampled, the word's width. */",
            "# `text` as one shape per glyph, each where it sits in the word; `width` is its advance. */",
            "# `b` wound like `a` and turned so its points lie nearest a's (compared about their centroids). */",
            "# Pairs of ring indices, outers with outers and holes with holes, nearest first; -1 for none. */",
            "# The morph from shape `a` to shape `b`. The pairing is worked out once, here; `at(k)` is then a",
            "# Letter i of `a` into letter i of `b`; a letter with no partner grows from, or shrinks to, points. */",
            "# The rings' extent: [xMin, yMin, xMax, yMax], or undefined for no rings. */",
            "# The part of a Canvas2D context (or Path2D) that `tracePath` draws with. */",
            "# Adds the rings to a Canvas2D path: the pen at `x`, the baseline at `y`, `size` px per em (y",
            "# One glyph outline or word morphing into another, letter by letter or as a whole."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/type/glyph-morph.ts"
          ]
        }
      }
    },
    "text-glyph-outlines": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "text-glyph-outlines",
            "type": "component",
            "title": "Glyph outlines",
            "description": "Text from a font file as geometry: contours flattened to polylines with the original curves kept, fill triangles with holes cut correctly, and a closed extruded mesh with normals, each with per-glyph ranges so letters can move apart",
            "category": "Typography",
            "tags": [
              "text",
              "font",
              "outlines",
              "vector",
              "triangulate",
              "extrude",
              "3d text",
              "mesh",
              "typography",
              "geometry"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {
                "opentype.js": "2.0.0",
                "earcut": "3.2.3"
              }
            },
            "files": [
              "src/type/outlines.ts",
              "src/type/opentype.d.ts"
            ]
          },
          "sha256": "a8f8ddd6957f9efa5485fc16e73fb9fc03b56ae00e0ef6b660e609e17a4e5693",
          "published": "2026-10-13T15:21:35.217Z",
          "symbols": [
            "PathCommand",
            "GlyphOutline",
            "Outlines",
            "GlyphRange",
            "Fill",
            "Solid",
            "loadFont",
            "glyphOutlines",
            "triangulate",
            "extrude",
            "# One outline command in output units, y up, already placed at its glyph's pen position. */",
            "# The glyph's index in the font. */",
            "# Pen position: where this glyph's advance box starts, in output units. */",
            "# The glyph's own advance width (without kerning or letter spacing). */",
            "# Contours `[first, end)` of this glyph in `Outlines.contours`. */",
            "# Of its flattened points: [xMin, yMin, xMax, yMax]; [x, 0, x, 0] for a glyph with no ink. */",
            "# The curves as the font has them (quadratic for TrueType, cubic for CFF), scaled and placed. */",
            "# x, y pairs of every contour, flattened, one after another. */",
            "# Contour i is points (pairs) `[contours[i], contours[i + 1])`; length is contour count + 1. */",
            "# From the first pen position to the end of the last glyph's advance. */",
            "# The font's ascender and descender at `size` (descender is negative). */",
            "# Triangles of a set of index ranges: `[start, start + count)` in `indices`, one per glyph. */",
            "# x, y pairs: the outline points (a copy of `Outlines.points`). */",
            "# Triangles, counter-clockwise seen from +z. */",
            "# x, y, z: front cap at z = 0, back cap at z = -depth, then the side walls. */",
            "# Unit normals per vertex: (0, 0, 1) front, (0, 0, -1) back, flat per wall segment. */",
            "# Triangles, counter-clockwise seen from outside. */",
            "# Reads a TTF, OTF or WOFF file at `path` (relative to the project) and parses it. */",
            "# `text` in `font` as outlines. `letterSpacing` is in ems, added between glyphs. `tolerance` is",
            "# Fill triangles of the outlines (earcut), holes cut from the outer that contains them. */",
            "# The outlines as a closed solid `depth` deep: front cap at z = 0 facing +z, back cap at",
            "Path",
            "Glyph",
            "Font",
            "parse",
            "# In font units, y up. */",
            "# Present for a variable font. */",
            "# Text from a font file as geometry: outlines, fill triangles and a closed extruded mesh."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/type/opentype.d.ts",
            "src/type/outlines.ts"
          ]
        }
      }
    },
    "text-glyph-points": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "text-glyph-points",
            "type": "component",
            "title": "Glyph points",
            "description": "Text set in a font as a fixed point set for particles to form, with the position of every character so parts of a word can move apart",
            "category": "Procedural & Particles",
            "tags": [
              "particles",
              "text to points",
              "wordmark",
              "morph",
              "typography",
              "point cloud"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "src/procedural/glyph-points.ts"
            ]
          },
          "sha256": "92defb5743dbae440485bb3bf77ce37dfe3db54c4a506438815d5be3d40d4126",
          "published": "2026-10-13T15:21:35.562Z",
          "symbols": [
            "GlyphPoints",
            "glyphPoints",
            "# x, y pairs in text widths. */",
            "# The inked width over the raster height (how wide the text is for its height). */",
            "# Where each character boundary falls, in the same x units: marks[i] is the left edge of character i. */",
            "# `text` in `family` (registered with host.io.font first) as `count` points. `weight` is a CSS",
            "# Text as a fixed point set, for particles that form a word or a name."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/procedural/glyph-points.ts"
          ]
        }
      }
    },
    "text-kinetic": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "text-kinetic",
            "type": "component",
            "title": "Kinetic type",
            "description": "Canvas2D text primitives: ASCII scramble, decode in and scramble out, horizontal band glitch, fit to width, hollow outlines, timecode",
            "category": "Typography",
            "tags": [
              "glitch",
              "scramble",
              "decode",
              "ascii",
              "text",
              "kinetic typography",
              "captions"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "src/type/kinetic.ts"
            ]
          },
          "sha256": "34a0c725bf5e1b04fb1cd3d1f1f034ddbbc26d43ed27ffea0e179fae6918ff5e",
          "published": "2026-10-13T15:21:35.823Z",
          "symbols": [
            "hash",
            "rnd",
            "GLYPHS",
            "scramble",
            "decoded",
            "Draw",
            "fill",
            "glitched",
            "fitWidth",
            "fitSize",
            "hollow",
            "timecode",
            "# A 32-bit hash (PCG). */",
            "# A hash as a number in [0, 1). */",
            "# Each character is replaced by noise on this frame with probability `share`. */",
            "# Text that decodes into place character by character over its first `rise` seconds, and",
            "# Fills text in the current fillStyle. */",
            "# Text cut into horizontal bands, each thrown sideways by its own amount on each frame. `font` is",
            "# The size at which `text` in `font` (a family alone, as in glitched) is `width` wide. */",
            "# `size`, or smaller if text at that size would be wider than `room`. */",
            "# Outlined text, for a number or word set huge and quiet behind the rest. */",
            "# Seconds as `SS.mmm`. */",
            "# Canvas2D text that moves like data: ASCII scramble, decode-in and scramble-out, band glitch, fit to width, hollow outlines."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/type/kinetic.ts"
          ]
        }
      }
    },
    "text-timed-cues": {
      "versions": {
        "0.1.0": {
          "item": {
            "name": "text-timed-cues",
            "type": "component",
            "title": "Timed cues",
            "description": "Lyrics, subtitles and word timings read from LRC (with word times), SRT, WebVTT and JSON (rows, cues or Whisper segments with words): the line and the word at t, times only",
            "category": "Typography",
            "tags": [
              "lyrics",
              "subtitles",
              "captions",
              "lrc",
              "srt",
              "vtt",
              "webvtt",
              "whisper",
              "word timing",
              "karaoke",
              "timed text"
            ],
            "version": "0.1.0",
            "licence": "MIT",
            "requires": {
              "shaderera": ">=0.1.0",
              "extensions": {},
              "items": {},
              "packages": {}
            },
            "files": [
              "src/type/timed-text.ts"
            ]
          },
          "sha256": "a44cf72252f729e7be70be47ae5436fe3fb3852f33118a49402e0159ce9d1107",
          "published": "2026-10-13T15:21:36.198Z",
          "symbols": [
            "Word",
            "Cue",
            "parseLrc",
            "parseSrt",
            "parseTimedJson",
            "parseTimedText",
            "trimCues",
            "loadTimedText",
            "cueAt",
            "wordAt",
            "# When the next cue starts, for formats that give only starts (LRC); Infinity for the last. */",
            "# Word times, when the source has them. */",
            "# Ends each cue where the next starts, unless it already has an end. */",
            "# LRC: `[mm:ss.xx] line`, several stamps on one line for a repeated line, and enhanced LRC's",
            "# SRT and WebVTT: numbered or unnumbered blocks of `start --> end` and their text lines. */",
            "# JSON timings: rows of `[start, end, \"line\"]`; cues `{ start, end?, text, words? }`; or Whisper's",
            "# Reads timed text by its extension: `.lrc`, `.srt`, `.vtt` or `.json`. */",
            "# Shifts every time by `-trim`: the seconds of the source the film leaves out at its start. */",
            "# Reads a project file of timed text in `open`, its times shifted by `-trim` (see trimCues). */",
            "# The cue showing at t, or undefined between cues. */",
            "# The word being sung at t: the last word of the cue at t that has started. */",
            "# Lyrics and subtitles by time: read LRC, SRT, WebVTT or Whisper JSON once, then ask for the line and the word at t."
          ],
          "files": [
            "README.md",
            "shaderera.item.json",
            "src/type/timed-text.ts"
          ]
        }
      }
    }
  }
}
