import { type BrowserKey } from '../screenshot/captureScreenshots'; import { type HarnessConfig } from './harnessPage'; import { type InspectAttachSpec } from './inspect'; export declare const VIEW_NAMES: readonly ["front", "back", "right", "left", "three-quarter"]; export type ViewName = typeof VIEW_NAMES[number]; export declare const MAX_VIEWS = 2; /** * Camera azimuth around Y, 0 = front. left/right are the CHARACTER's own, matching the readback's * character-left / character-right — a viewer-relative reading would invert them, which is the trap to avoid. * `three-quarter` follows the clip's ACTIVE side: from the wrong side it occludes as badly as a lateral view. */ export declare function viewAzimuth(view: ViewName, side: 'left' | 'right'): number; export declare function viewLabel(view: ViewName, side: 'left' | 'right'): string; export type CaptureGestureOptions = { worldDir: string; clip: string; out: string; frames?: number; /** Up to two of front | back | left | right. Omitted, the side is derived from which side the clip keys. */ views?: ViewName[]; /** One moment instead of a sequence: seconds, or a percentage of duration like '60%'. Views go side by * side at roughly 1.8x the cell size, for inspecting a specific detail rather than comparing over time. */ at?: number | string; /** Render a prop attached while the clip plays — same spec as inspect's, resolved against the world's presets. */ attach?: InspectAttachSpec; cellHeight?: number; timeoutMs?: number; browser?: BrowserKey; onProgress?: (message: string) => void; }; export type CaptureGestureResult = { file: string; clip: string; duration: number; times: number[]; views: ViewName[]; /** True when a single moment was captured, so views are columns rather than rows. */ moment: boolean; /** True when both views look down the same axis, so neither reveals depth — worth telling the caller. */ sharedAxis: boolean; warnings: string[]; /** What was attached, when a prop was requested. */ attachment: { prop: string; socket: string; preset: string | null; } | null; }; export declare function captureGesture(opts: CaptureGestureOptions): Promise; type ClipShape = { duration?: unknown; mask?: unknown; overrideMask?: unknown; keys?: unknown; }; /** * A sequence reads best with time across and views stacked; a single moment reads best with the views SIDE BY * SIDE, so the two renders of the same instant sit next to each other for comparison. */ export declare function arrangeGrid(times: number[], views: ViewName[], moment: boolean, side: 'left' | 'right'): Omit; /** `--at` takes seconds or a percentage of duration, matching `inspect --t`. */ export declare function parseMoment(at: number | string, duration: number): number; /** * Which side of the body a clip actually works on, so a left-handed gesture is never rendered from the side * its own torso hides. The clip already declares this, so it is derived rather than asked for. * * KEYED BONES ARE THE GROUND TRUTH — most masks say nothing about sidedness. Of the authorable set * (upperBody, lowerBody, leftArm, rightArm, spine, armsHead) only two are one-sided; the rest are bilateral, * so a left-handed clip masked `upperBody` is identified by its bones, not its mask. The mask is consulted * only as a tiebreaker, and by PATTERN rather than an exact name, so a future one-sided mask works untouched. */ export declare function clipSide(source: ClipShape): 'left' | 'right'; /** * Defaults differ by MODE, because the modes answer different questions. A sequence is compared over time, so * it wants the ORTHOGONAL pair — front plus a lateral — which is what makes "moves side-to-side, not * front-to-back" readable; a 3/4 there would conflate the two axes it exists to separate. A single moment is * being disambiguated, so it wants the 3/4, which lifts a limb clear of the torso instead of hiding it behind * it. Every view stays legal in both modes: a mode-dependent enum would be a footgun to document, and neither * pairing is actually invalid. */ export declare function resolveViews(requested: ViewName[] | undefined, source: ClipShape, moment?: boolean): ViewName[]; /** front+back and left+right are each a single axis seen twice: both are frontal projections of the same plane. */ export declare function sharesAxis(views: ViewName[]): boolean; export {};