import { AnyResolvedKeyframe, UnresolvedValueKeyframe, AnimationOptions, MotionValue, Transition, ElementOrSelector, DOMKeyframesDefinition, AnimationPlaybackOptions, AnimationPlaybackControlsWithThen, AnimationScope, TimelineWithFallback, ValueAnimationTransition, addEffect, removeEffect, AnimationPlaybackControls } from 'motion-dom';
export * from 'motion-dom';
export { DelayedFunction, delayInSeconds as delay } from 'motion-dom';
import { Easing } from 'motion-utils';
export * from 'motion-utils';

/**
 * Lifecycle callbacks are not supported on individual sequence segments
 * because segments are consolidated into a single animation per subject.
 * Use sequence-level options (e.g. SequenceOptions.onComplete) instead.
 */
type LifecycleCallbacks = "onUpdate" | "onPlay" | "onComplete" | "onRepeat" | "onStop";
/**
 * Distributive Omit preserves union branches (unlike plain Omit).
 */
type DistributiveOmit<T, K extends string> = T extends any ? Omit<T, K> : never;
type SegmentTransitionOptions = DistributiveOmit<AnimationOptions, LifecycleCallbacks> & At;
type SegmentValueTransitionOptions = DistributiveOmit<Transition, LifecycleCallbacks> & At;
/**
 * Known keys of the object are suggested, but any key is accepted so
 * effects registered via `animate.addEffect()` can expose shorthands like
 * `rotateY` or `"params.time"` on subjects that don't have those properties.
 */
type ObjectTarget<O> = {
    [K in keyof O]?: O[K] | UnresolvedValueKeyframe | UnresolvedValueKeyframe[];
} & {
    [key: string]: unknown;
};
type SequenceTime = number | "<" | `+${number}` | `-${number}` | `${string}`;
type SequenceLabel = string;
interface SequenceLabelWithTime {
    name: SequenceLabel;
    at: SequenceTime;
}
interface At {
    at?: SequenceTime;
}
type MotionValueSegment = [
    MotionValue,
    UnresolvedValueKeyframe | UnresolvedValueKeyframe[]
];
type MotionValueSegmentWithTransition = [
    MotionValue,
    UnresolvedValueKeyframe | UnresolvedValueKeyframe[],
    SegmentValueTransitionOptions
];
type DOMSegment = [ElementOrSelector, DOMKeyframesDefinition];
type DOMSegmentWithTransition = [
    ElementOrSelector,
    DOMKeyframesDefinition,
    SegmentTransitionOptions
];
type ObjectSegment<O extends {} = {}> = [O, ObjectTarget<O>];
type ObjectSegmentWithTransition<O extends {} = {}> = [
    O,
    ObjectTarget<O>,
    SegmentTransitionOptions
];
type SequenceProgressCallback = (value: any) => void;
type FunctionSegment = [SequenceProgressCallback] | [SequenceProgressCallback, SegmentTransitionOptions] | [
    SequenceProgressCallback,
    UnresolvedValueKeyframe | UnresolvedValueKeyframe[],
    SegmentTransitionOptions
];
/**
 * A sequence placed inside another sequence. Numeric `at` values inside
 * it are relative to where it starts.
 */
interface NestedSequence {
    sequence: AnimationSequence;
    at?: SequenceTime;
}
type Segment = NestedSequence | ObjectSegment | ObjectSegmentWithTransition | SequenceLabel | SequenceLabelWithTime | MotionValueSegment | MotionValueSegmentWithTransition | DOMSegment | DOMSegmentWithTransition | FunctionSegment;
type AnimationSequence = Segment[];
interface SequenceOptions extends AnimationPlaybackOptions {
    delay?: number;
    duration?: number;
    defaultTransition?: Transition;
    reduceMotion?: boolean;
    skipAnimations?: boolean;
    onComplete?: () => void;
}
/**
 * Filled by createAnimationsFromSequence with the resolved total
 * duration and label times, in seconds.
 */
interface SequenceInfo {
    duration?: number;
    labels?: Map<string, number>;
}
interface AbsoluteKeyframe {
    value: AnyResolvedKeyframe | null;
    at: number;
    easing?: Easing;
}
type ValueSequence = AbsoluteKeyframe[];
interface SequenceMap {
    [key: string]: ValueSequence;
}
type ResolvedAnimationDefinition = {
    keyframes: {
        [key: string]: UnresolvedValueKeyframe[];
    };
    transition: {
        [key: string]: Transition;
    };
};
type ResolvedAnimationDefinitions = Map<Element | MotionValue, ResolvedAnimationDefinition>;

type TimelineItem = Segment | Timeline;
/**
 * Called with the playback direction: 1 forwards, -1 backwards.
 */
type TimelineCallback = (direction: 1 | -1) => void;
interface TimelineOptions extends SequenceOptions {
    /**
     * Start paused. Defaults to `true` (plays as soon as it's built).
     */
    autoplay?: boolean;
    /**
     * Resolve selectors within this scope, and stop when it's torn
     * down. Pass the scope from useAnimate() in React.
     */
    scope?: AnimationScope;
    /**
     * Called every frame while the playhead moves, with its time in
     * seconds within the current repeat.
     */
    onUpdate?: (time: number) => void;
    /**
     * Called each time the timeline starts a repeat.
     */
    onRepeat?: () => void;
    /**
     * Called instead of `onComplete` when the timeline finishes
     * playing backwards, at its start.
     */
    onReverseComplete?: () => void;
}
/**
 * A sequence that can be changed after it's created. Segments, labels,
 * callbacks, pauses and other timelines can be added, moved and removed
 * at any point, including while it plays.
 *
 * Changes are batched and applied once per microtask. Each change
 * rebuilds the underlying animations from the timeline's starting
 * values, then restores the playhead, speed and play state, so changes
 * made while playing take effect without a jump.
 */
declare class Timeline implements AnimationPlaybackControlsWithThen {
    private options;
    finished: Promise<any>;
    private entries;
    private group?;
    /**
     * Tracks the playhead in seconds. Used to fire callbacks, pauses and
     * playTo(). Only created when one of those needs it.
     */
    private clock?;
    private clockAnimation?;
    /**
     * The repeat the playhead is in, to detect when it starts another.
     */
    private repeatIndex;
    private prevTime;
    private markers;
    private labels;
    private totalDuration;
    private isDirty;
    private isPaused;
    private isDone;
    private isRebuilding;
    private playbackSpeed;
    private stopAt?;
    private parent?;
    private scrollTimeline?;
    private detachScroll?;
    private resolveFinished;
    /**
     * True while this plays the animations it was created with, before
     * any change compiles it as a sequence.
     */
    private isWrapped;
    /**
     * `animations` are already running animations of `items`, as
     * animate() makes them. The timeline plays these until it's first
     * changed, so it costs nothing over the animations themselves until
     * then.
     */
    constructor(items?: TimelineItem[], options?: TimelineOptions, animations?: AnimationPlaybackControlsWithThen[]);
    /**
     * Add a segment, label or timeline. `at` overrides any `at` already
     * on the segment. The item itself is the handle for `move()` and
     * `remove()`.
     */
    add(item: TimelineItem, at?: SequenceTime): this;
    /**
     * Fire a callback when the playhead crosses `at`, in either direction.
     * It receives the direction: 1 forwards, -1 backwards.
     */
    call(callback: TimelineCallback, at?: SequenceTime): this;
    /**
     * Pause when the playhead reaches `at`.
     */
    addPause(at?: SequenceTime, callback?: TimelineCallback): this;
    /**
     * Change where an item starts.
     */
    move(item: TimelineItem | TimelineCallback, at: SequenceTime): this;
    /**
     * Remove a segment, label, callback or timeline.
     */
    remove(item: TimelineItem | TimelineCallback): this;
    clear(): this;
    /**
     * The time of a label in seconds, or `undefined` if there's no label
     * with this name.
     */
    getLabelTime(name: string): number | undefined;
    /**
     * Jump to a time in seconds or a label.
     */
    seek(position: SequenceTime): this;
    /**
     * Play forwards or backwards to a time or label, then pause there.
     */
    playTo(position: SequenceTime): this;
    reverse(): this;
    get progress(): number;
    set progress(progress: number);
    get time(): number;
    set time(time: number);
    get speed(): number;
    set speed(speed: number);
    get duration(): number;
    get iterationDuration(): number;
    get state(): any;
    get startTime(): any;
    play(): void;
    pause(): void;
    stop: () => void;
    cancel(): void;
    complete(): void;
    attachTimeline(timeline: TimelineWithFallback): () => void;
    then(onResolve: VoidFunction, onReject?: VoidFunction): Promise<void>;
    /**
     * The current animations, if any are running. Skipped animations
     * (skipAnimations, reduced motion) can leave the group empty.
     */
    private active;
    private push;
    /**
     * Schedule a rebuild. A nested timeline passes changes up, as it's
     * built as part of its parent.
     */
    private invalidate;
    /**
     * Apply pending changes now, so reads straight after a change
     * reflect it.
     */
    private flush;
    private adopt;
    private build;
    private toSequence;
    private resolve;
    /**
     * The repeat the clock is in, from its time across all repeats.
     */
    private currentRepeat;
    private onClock;
    /**
     * Fire markers between two playhead times. Returns `true` if it
     * paused.
     */
    private cross;
    private pauseAt;
    private watch;
    private newFinished;
}

interface ScopedAnimateOptions {
    scope?: AnimationScope;
    reduceMotion?: boolean;
    skipAnimations?: boolean;
}
/**
 * Creates an animation function that is optionally scoped
 * to a specific element.
 */
declare function createScopedAnimate(options?: ScopedAnimateOptions): {
    (sequence: AnimationSequence, options?: Omit<TimelineOptions, "scope">): Timeline;
    (value: string | MotionValue<string>, keyframes: string | UnresolvedValueKeyframe<string>[], options?: ValueAnimationTransition<string>): Timeline;
    (value: number | MotionValue<number>, keyframes: number | UnresolvedValueKeyframe<number>[], options?: ValueAnimationTransition<number>): Timeline;
    <V extends string | number>(value: V | MotionValue<V>, keyframes: V | UnresolvedValueKeyframe<V>[], options?: ValueAnimationTransition<V>): Timeline;
    (element: ElementOrSelector, keyframes: DOMKeyframesDefinition, options?: AnimationOptions): Timeline;
    <O extends {}>(object: O | O[], keyframes: ObjectTarget<O>, options?: AnimationOptions): Timeline;
};
declare const animate: {
    (sequence: AnimationSequence, options?: Omit<TimelineOptions, "scope">): Timeline;
    (value: string | MotionValue<string>, keyframes: string | UnresolvedValueKeyframe<string>[], options?: ValueAnimationTransition<string>): Timeline;
    (value: number | MotionValue<number>, keyframes: number | UnresolvedValueKeyframe<number>[], options?: ValueAnimationTransition<number>): Timeline;
    <V extends string | number>(value: V | MotionValue<V>, keyframes: V | UnresolvedValueKeyframe<V>[], options?: ValueAnimationTransition<V>): Timeline;
    (element: ElementOrSelector, keyframes: DOMKeyframesDefinition, options?: AnimationOptions): Timeline;
    <O extends {}>(object: O | O[], keyframes: ObjectTarget<O>, options?: AnimationOptions): Timeline;
} & {
    /**
     * Register an effect so `animate()` can animate the subjects it
     * claims, for instance `animate.addEffect(threeEffect)`. The most
     * recently added effect is tested first. DOM elements are always
     * animated directly.
     */
    addEffect: typeof addEffect;
    removeEffect: typeof removeEffect;
};

declare const animateMini: (elementOrSelector: ElementOrSelector, keyframes: DOMKeyframesDefinition, options?: AnimationOptions) => AnimationPlaybackControlsWithThen;

interface ScrollOptions {
    source?: HTMLElement;
    container?: Element;
    target?: Element;
    axis?: "x" | "y";
    offset?: ScrollOffset;
}
type OnScroll = (progress: number, info: ScrollInfo) => void;
interface AxisScrollInfo {
    current: number;
    offset: number[];
    progress: number;
    scrollLength: number;
    velocity: number;
    targetOffset: number;
    targetLength: number;
    containerLength: number;
}
interface ScrollInfo {
    time: number;
    x: AxisScrollInfo;
    y: AxisScrollInfo;
}
type OnScrollInfo = (info: ScrollInfo) => void;
type SupportedEdgeUnit = "px" | "vw" | "vh" | "%";
type EdgeUnit = `${number}${SupportedEdgeUnit}`;
type NamedEdges = "start" | "end" | "center";
type EdgeString = NamedEdges | EdgeUnit | `${number}`;
type Edge = EdgeString | number;
type ProgressIntersection = [number, number];
type Intersection = `${Edge} ${Edge}`;
type ScrollOffset = Array<Edge | Intersection | ProgressIntersection>;
interface ScrollInfoOptions {
    container?: Element;
    target?: Element;
    axis?: "x" | "y";
    offset?: ScrollOffset;
    /**
     * When true, enables per-frame checking of scrollWidth/scrollHeight
     * to detect content size changes and recalculate scroll progress.
     *
     * @default false
     */
    trackContentSize?: boolean;
}

declare function scroll(onScroll: OnScroll | AnimationPlaybackControls, { axis, source, container, ...options }?: ScrollOptions): VoidFunction;

declare function scrollInfo(onScroll: OnScrollInfo, { container, trackContentSize, ...options }?: ScrollInfoOptions): VoidFunction;

type ViewChangeHandler = (entry: IntersectionObserverEntry) => void;
type MarginValue = `${number}${"px" | "%"}`;
type MarginType = MarginValue | `${MarginValue} ${MarginValue}` | `${MarginValue} ${MarginValue} ${MarginValue}` | `${MarginValue} ${MarginValue} ${MarginValue} ${MarginValue}`;
interface InViewOptions {
    root?: Element | Document;
    margin?: MarginType;
    amount?: "some" | "all" | number;
}
declare function inView(elementOrSelector: ElementOrSelector, onStart: (element: Element, entry: IntersectionObserverEntry) => void | ViewChangeHandler, { root, margin: rootMargin, amount }?: InViewOptions): VoidFunction;

interface HTMLElements {
    a: HTMLAnchorElement;
    abbr: HTMLElement;
    address: HTMLElement;
    area: HTMLAreaElement;
    article: HTMLElement;
    aside: HTMLElement;
    audio: HTMLAudioElement;
    b: HTMLElement;
    base: HTMLBaseElement;
    bdi: HTMLElement;
    bdo: HTMLElement;
    big: HTMLElement;
    blockquote: HTMLQuoteElement;
    body: HTMLBodyElement;
    br: HTMLBRElement;
    button: HTMLButtonElement;
    canvas: HTMLCanvasElement;
    caption: HTMLElement;
    center: HTMLElement;
    cite: HTMLElement;
    code: HTMLElement;
    col: HTMLTableColElement;
    colgroup: HTMLTableColElement;
    data: HTMLDataElement;
    datalist: HTMLDataListElement;
    dd: HTMLElement;
    del: HTMLModElement;
    details: HTMLDetailsElement;
    dfn: HTMLElement;
    dialog: HTMLDialogElement;
    div: HTMLDivElement;
    dl: HTMLDListElement;
    dt: HTMLElement;
    em: HTMLElement;
    embed: HTMLEmbedElement;
    fieldset: HTMLFieldSetElement;
    figcaption: HTMLElement;
    figure: HTMLElement;
    footer: HTMLElement;
    form: HTMLFormElement;
    h1: HTMLHeadingElement;
    h2: HTMLHeadingElement;
    h3: HTMLHeadingElement;
    h4: HTMLHeadingElement;
    h5: HTMLHeadingElement;
    h6: HTMLHeadingElement;
    head: HTMLHeadElement;
    header: HTMLElement;
    hgroup: HTMLElement;
    hr: HTMLHRElement;
    html: HTMLHtmlElement;
    i: HTMLElement;
    iframe: HTMLIFrameElement;
    img: HTMLImageElement;
    input: HTMLInputElement;
    ins: HTMLModElement;
    kbd: HTMLElement;
    keygen: HTMLElement;
    label: HTMLLabelElement;
    legend: HTMLLegendElement;
    li: HTMLLIElement;
    link: HTMLLinkElement;
    main: HTMLElement;
    map: HTMLMapElement;
    mark: HTMLElement;
    menu: HTMLElement;
    menuitem: HTMLElement;
    meta: HTMLMetaElement;
    meter: HTMLMeterElement;
    nav: HTMLElement;
    noindex: HTMLElement;
    noscript: HTMLElement;
    object: HTMLObjectElement;
    ol: HTMLOListElement;
    optgroup: HTMLOptGroupElement;
    option: HTMLOptionElement;
    output: HTMLOutputElement;
    p: HTMLParagraphElement;
    param: HTMLParamElement;
    picture: HTMLElement;
    pre: HTMLPreElement;
    progress: HTMLProgressElement;
    q: HTMLQuoteElement;
    rp: HTMLElement;
    rt: HTMLElement;
    ruby: HTMLElement;
    s: HTMLElement;
    samp: HTMLElement;
    search: HTMLElement;
    slot: HTMLSlotElement;
    script: HTMLScriptElement;
    section: HTMLElement;
    select: HTMLSelectElement;
    small: HTMLElement;
    source: HTMLSourceElement;
    span: HTMLSpanElement;
    strong: HTMLElement;
    style: HTMLStyleElement;
    sub: HTMLElement;
    summary: HTMLElement;
    sup: HTMLElement;
    table: HTMLTableElement;
    template: HTMLTemplateElement;
    tbody: HTMLTableSectionElement;
    td: HTMLTableDataCellElement;
    textarea: HTMLTextAreaElement;
    tfoot: HTMLTableSectionElement;
    th: HTMLTableHeaderCellElement;
    thead: HTMLTableSectionElement;
    time: HTMLTimeElement;
    title: HTMLTitleElement;
    tr: HTMLTableRowElement;
    track: HTMLTrackElement;
    u: HTMLElement;
    ul: HTMLUListElement;
    var: HTMLElement;
    video: HTMLVideoElement;
    wbr: HTMLElement;
    webview: HTMLWebViewElement;
}

export { type AbsoluteKeyframe, type AnimationSequence, type At, type DOMSegment, type DOMSegmentWithTransition, type FunctionSegment, type HTMLElements, type MotionValueSegment, type MotionValueSegmentWithTransition, type NestedSequence, type ObjectSegment, type ObjectSegmentWithTransition, type ObjectTarget, type ResolvedAnimationDefinition, type ResolvedAnimationDefinitions, type Segment, type SegmentTransitionOptions, type SegmentValueTransitionOptions, type SequenceInfo, type SequenceLabel, type SequenceLabelWithTime, type SequenceMap, type SequenceOptions, type SequenceProgressCallback, type SequenceTime, Timeline, type TimelineCallback, type TimelineItem, type TimelineOptions, type ValueSequence, animate, animateMini, createScopedAnimate, inView, scroll, scrollInfo };
