/**
 * Shared pure timing resolver — WS-C.
 *
 * resolveTimings() is the single intended implementation of word-anchored
 * elastic timing, designed to be the one code path that BOTH the preview
 * (session layer in @hyperframes/sdk) and render (timingCompiler.ts +
 * htmlBundler) sides call so they cannot drift apart.
 *
 * NOT YET WIRED: neither path consumes it yet — the anchor-producing inputs
 * (TTS word timings) arrive on the Pacific/backend side, which is deferred.
 * Until a real caller lands, the "preview == render" parity below is a property
 * of the resolver (one pure function) rather than a guarantee the two live
 * paths currently share. Wire it into timingCompiler and session before
 * relying on it for parity.
 *
 * Constraints:
 * - Deterministic + pure: no Date.now(), no Math.random(), no DOM, no I/O.
 * - Never timescale animated content: elastic hold extends the hold window,
 *   not tween durations.
 * - Align-on-adjust: only explicitly anchored elements become word-locked;
 *   un-anchored elements keep their authored start/duration unchanged.
 * - Elastic hold: holdDuration = max(0, slot − (enter + exit)), clamped ≥ 0.
 */
export interface WordTiming {
    /** Word index (0-based) */
    index: number;
    /** Absolute start time of this word in seconds */
    start: number;
    /** Absolute end time of this word in seconds */
    end: number;
}
export interface ElementAnchor {
    /** Which element this anchor applies to */
    hfId: string;
    /**
     * Index of the word in `wordTimings` this element is anchored to.
     * The element's enterAt = wordTimings[wordIndex].start + enterOffset.
     */
    wordIndex: number;
    /**
     * Offset in seconds from the anchored word's start time to the element's enter.
     * Defaults to 0.
     */
    enterOffset?: number;
    /**
     * The authored enter duration (time from element start until hold begins).
     * Used to compute the hold slot.
     */
    enterDuration: number;
    /**
     * The authored exit duration (time from hold end until element exits).
     * Used to compute the hold slot.
     */
    exitDuration: number;
    /**
     * The "slot" end time: the element must finish by this time.
     * holdDuration = max(0, slotEnd - (enterAt + enterDuration + exitDuration))
     */
    slotEnd: number;
}
export interface AuthoredTiming {
    hfId: string;
    /** Authored data-start value in seconds */
    start: number;
    /** Authored duration in seconds (data-duration or data-end - data-start) */
    duration: number;
}
export interface ResolvedTiming {
    enterAt: number;
    exitAt: number;
    /** Computed elastic hold duration (>= 0). Non-anchored elements have holdDuration = 0. */
    holdDuration: number;
}
export interface ResolveTimingsInput {
    /** All authored element timings (both anchored and un-anchored). */
    elements: AuthoredTiming[];
    /** TTS word timings from the backend. */
    wordTimings: WordTiming[];
    /** The set of elements that are word-anchored. Only these get word-locked. */
    anchors: ElementAnchor[];
}
export type ResolveTimingsResult = Record<string, ResolvedTiming>;
/**
 * Resolve element timings for a composition with optional word-anchored elements.
 *
 * Align-on-adjust rule: only elements with an explicit anchor in `anchors` are
 * word-locked. All others keep their authored start/duration unchanged.
 *
 * Elastic hold: for anchored elements, the hold window is expanded to fill the
 * slot without timescaling animated content. The hold duration is:
 *   holdDuration = max(0, slotEnd - (enterAt + enterDuration + exitDuration))
 *
 * @param input - Elements, word timings, and anchor map.
 * @returns A map from hfId to resolved { enterAt, exitAt, holdDuration }.
 */
export declare function resolveTimings(input: ResolveTimingsInput): ResolveTimingsResult;
//# sourceMappingURL=timingResolver.d.ts.map