/** * Turning pixels into something a language model can actually read. * * A 32×32 sprite rendered as a PNG is ~8 screen pixels wide once a vision model * downsamples it; the model then guesses. Two representations fix that: * - an upscaled preview PNG (done inside Aseprite, see the `preview` tool); * - a text grid, one glyph per pixel, which is exact and works on clients * with no vision at all. * * The text grid is the verification half of the draw → look → fix loop. */ export interface PixelRegion { x: number; y: number; width: number; height: number; /** Distinct colours in the region. Index 0 is always fully transparent. */ colors: string[]; /** Row-major indices into `colors`, length = width * height. */ grid: number[]; } export declare const GLYPH_COUNT: number; export interface AsciiOptions { /** The sprite's palette, in index order. Glyphs follow it; omitted, every colour counts as off-palette. */ palette?: readonly string[]; showRulers?: boolean; } export interface AsciiView { text: string; /** The grid alone, no rulers or row labels — exactly what `draw` kind `grid` takes as `rows`. */ rows: string[]; legend: Record; /** Glyphs for colours outside the palette — the only ones not stable between reads. */ offPalette: string[]; width: number; height: number; originX: number; originY: number; } /** * No size cap: the region is already clamped to the canvas, and the text grid * is the read half of `draw` kind 'grid', which accepts the whole canvas too. */ export declare function renderAscii(region: PixelRegion, opts?: AsciiOptions): AsciiView; export interface DiffView { text: string; legend: Record; /** Glyphs for colours outside the palette — the only ones not stable between reads. */ offPalette: string[]; changed: number; total: number; /** Tight bounding box of every changed pixel, absolute coordinates. Null when nothing changed. */ changedBounds: { x: number; y: number; width: number; height: number; } | null; /** `changed / total * 100`, rounded to two decimals. */ percentChanged: number; } /** * Pixel-level diff between two regions of equal size. * `.` unchanged `-` became transparent glyph = the *new* colour * This answers "what did my edit actually touch", which a before/after image * pair does not, at small sizes. */ export declare function renderDiff(before: PixelRegion, after: PixelRegion, palette?: readonly string[]): DiffView; /** * Pick an integer upscale factor that lands a sprite's long edge near `target`. * Nearest-neighbour only — any smoothing destroys the thing being reviewed. * * The bound is on the OUTPUT size, not the factor. Capping the factor at 16 — * as this once did — renders an 8px sprite at 128px and a 16px one at 256px, * which are precisely the cases where a vision model is otherwise guessing. */ export declare function previewScale(width: number, height: number, target?: number, maxEdge?: number): number; /** Grid layout for a filmstrip: as close to square as whole cells allow. */ export declare function filmstripLayout(frames: number): { cols: number; rows: number; };