import { assetSchema as AssetSchema } from '@shotstack/schemas/zod';
import { audioAssetSchema as AudioAssetSchema } from '@shotstack/schemas/zod';
import { captionAssetSchema as CaptionAssetSchema } from '@shotstack/schemas/zod';
import { clipSchema as ClipSchema } from '@shotstack/schemas/zod';
import { components } from '@shotstack/schemas';
import { Container } from 'pixi.js';
import { cropSchema as CropSchema } from '@shotstack/schemas/zod';
import { editSchema as EditSchema } from '@shotstack/schemas/zod';
import { htmlAssetSchema as HtmlAssetSchema } from '@shotstack/schemas/zod';
import { imageAssetSchema as ImageAssetSchema } from '@shotstack/schemas/zod';
import { lumaAssetSchema as LumaAssetSchema } from '@shotstack/schemas/zod';
import { offsetSchema as OffsetSchema } from '@shotstack/schemas/zod';
import { outputSchema as OutputSchema } from '@shotstack/schemas/zod';
import * as pixi from 'pixi.js';
import { richTextAssetSchema as RichTextAssetSchema } from '@shotstack/schemas/zod';
import { shapeAssetSchema as ShapeAssetSchema } from '@shotstack/schemas/zod';
import { textAssetSchema as TextAssetSchema } from '@shotstack/schemas/zod';
import { timelineSchema as TimelineSchema } from '@shotstack/schemas/zod';
import { trackSchema as TrackSchema } from '@shotstack/schemas/zod';
import { transformationSchema as TransformationSchema } from '@shotstack/schemas/zod';
import { transitionSchema as TransitionSchema } from '@shotstack/schemas/zod';
import { tweenSchema } from '@shotstack/schemas/zod';
import { videoAssetSchema as VideoAssetSchema } from '@shotstack/schemas/zod';
import { z } from 'zod';

export declare type Asset = components["schemas"]["Asset"];

declare type AssetEventMap = {
    onAssetLoadInfoUpdated: AssetLoadInfoUpdatedPayload;
};

declare class AssetLoader {
    private static readonly VIDEO_EXTENSIONS;
    private static readonly VIDEO_MIME;
    readonly loadTracker: AssetLoadTracker;
    /** Reference counts for loaded assets - prevents premature unloading during transforms */
    private refCounts;
    /**
     * Increment reference count for an asset.
     * Called when a player starts loading an asset.
     */
    incrementRef(src: string): void;
    /**
     * Decrement reference count for an asset.
     * @returns true if asset can be safely unloaded (count reached zero)
     */
    decrementRef(src: string): boolean;
    constructor();
    load<TResolvedAsset>(identifier: string, loadOptions: pixi.UnresolvedAsset): Promise<TResolvedAsset | null>;
    /**
     * Load a video with a unique HTMLVideoElement (not cached).
     * Each call creates an independent video element, allowing multiple VideoPlayers
     * to control playback independently even when using the same video URL.
     */
    loadVideoUnique(identifier: string, loadOptions: pixi.UnresolvedAsset): Promise<pixi.Texture<pixi.VideoSource> | null>;
    getProgress(): number;
    private extractUrl;
    private hasVideoExtension;
    private getContentType;
    private canPlayVideo;
    private isPlayableVideo;
    private shouldUseSafariVideoLoader;
    private loadVideoForSafari;
    private updateAssetLoadMetadata;
}

declare type AssetLoadInfo = {
    progress: number;
    status: AssetLoadInfoStatus;
};

declare type AssetLoadInfoStatus = "pending" | "loading" | "success" | "failed";

declare type AssetLoadInfoUpdatedPayload = {
    registry: Record<string, AssetLoadInfo>;
};

declare class AssetLoadTracker extends EventEmitter<AssetEventMap> {
    registry: Record<string, AssetLoadInfo>;
    constructor();
}

export { AssetSchema }

export declare class AssetToolbar {
    private container;
    private ui;
    private unsubscribe;
    constructor(ui: UIController);
    setPosition(screenX: number, screenY: number): void;
    mount(parent: HTMLElement): void;
    private render;
    private setupEventListeners;
    dispose(): void;
}

export declare type AudioAsset = components["schemas"]["AudioAsset"];

export { AudioAssetSchema }

declare type BackgroundChangeCallback = (color: string) => void;

/**
 * Abstract base class for toolbars providing shared lifecycle, popup management,
 * and UI helper methods.
 */
declare abstract class BaseToolbar {
    protected container: HTMLDivElement | null;
    protected edit: Edit;
    protected selectedTrackIdx: number;
    protected selectedClipIdx: number;
    protected clickOutsideHandler: ((e: MouseEvent) => void) | null;
    constructor(edit: Edit);
    /**
     * Mount the toolbar to a parent element.
     * Subclasses must implement to build their specific HTML structure.
     */
    abstract mount(parent: HTMLElement): void;
    /**
     * Show the toolbar for a specific clip.
     * Subclasses can override to add custom behavior.
     */
    show(trackIndex: number, clipIndex: number): void;
    /**
     * Hide the toolbar.
     */
    hide(): void;
    /**
     * Dispose the toolbar and clean up resources.
     * Subclasses should call super.dispose() and then null their own references.
     */
    dispose(): void;
    /**
     * Check if a popup is currently visible (handles both CSS class and inline style patterns).
     */
    protected isPopupOpen(popup: HTMLElement | null): boolean;
    /**
     * Toggle a popup's visibility, closing all others first.
     * Uses CSS class-based visibility. Optional callback fires when popup opens.
     */
    protected togglePopup(popup: HTMLElement | null, onOpen?: () => void): void;
    /**
     * Close all popups.
     * Uses CSS class-based visibility.
     */
    protected closeAllPopups(): void;
    /**
     * Set up a document click handler to close popups when clicking outside.
     */
    protected setupOutsideClickHandler(): void;
    /**
     * Create a slider input handler with value display update.
     */
    protected createSliderHandler(slider: HTMLInputElement | null, valueDisplay: HTMLSpanElement | null, callback: (value: number) => void, formatter?: (value: number) => string): void;
    /**
     * Set active state on a button element.
     */
    protected setButtonActive(btn: HTMLElement | null, active: boolean): void;
    /**
     * Sync UI state with current clip configuration.
     * Subclasses must implement.
     */
    protected abstract syncState(): void;
    /**
     * Get the list of popup elements for popup management.
     * Subclasses must implement.
     */
    protected abstract getPopupList(): (HTMLElement | null)[];
}

/**
 * Payload passed to button click handlers.
 */
export declare interface ButtonClickPayload {
    /** Current playback position in seconds */
    position: number;
    /** Currently selected clip, if any */
    selectedClip: {
        trackIndex: number;
        clipIndex: number;
    } | null;
}

export declare class Canvas {
    private static extensionsRegistered;
    private viewportSize;
    private readonly edit;
    /** Container for interactive overlays (handles, guides). Renders above content. */
    readonly overlayContainer: pixi.Container;
    private container?;
    private background?;
    private timeline?;
    private uiController;
    private minZoom;
    private maxZoom;
    private currentZoom;
    private onTickBound;
    private onBackgroundClickBound;
    constructor(edit: Edit);
    /**
     * Register a UIController to receive tick updates for canvas overlays.
     * @deprecated Use `new UIController(edit, canvas)` instead - auto-registers.
     */
    registerUIController(controller: UIController): void;
    load(): Promise<void>;
    private setupTouchHandling;
    centerEdit(): void;
    zoomToFit(padding?: number): void;
    resize(): void;
    setZoom(zoom: number): void;
    getZoom(): number;
    /**
     * Sync overlay container and toolbar positions after content transforms change.
     * Single point of update for all position-dependent UI elements.
     */
    private syncContentTransforms;
    /**
     * Get the pixel bounds of the canvas content (edit area) within the viewport.
     * Used for positioning toolbars adjacent to the canvas content.
     */
    getContentBounds(): {
        left: number;
        right: number;
        top: number;
        bottom: number;
    };
    registerTimeline(timeline: Timeline): void;
    private registerExtensions;
    private configureApplication;
    private onTick;
    private configureStage;
    private onBackgroundClick;
    pauseTicker(): void;
    resumeTicker(): void;
    dispose(): void;
}

/**
 * Interface for PixiJS-based overlays that render on the canvas.
 * Used for interactive elements like selection handles, alignment guides, etc.
 */
export declare interface CanvasOverlayRegistration {
    /** Mount to PixiJS container */
    mount(container: pixi.Container, app: pixi.Application): void;
    /** Called each frame to update state */
    update(deltaTime: number, elapsed: number): void;
    /** Called each frame to render */
    draw(): void;
    /** Clean up resources */
    dispose(): void;
}

export declare class CanvasToolbar {
    private container;
    private edit;
    private currentWidth;
    private currentHeight;
    private currentFps;
    private currentBgColor;
    private resolutionPopup;
    private backgroundPopup;
    private fpsPopup;
    private variablesPopup;
    private resolutionBtn;
    private backgroundBtn;
    private fpsBtn;
    private variablesBtn;
    private variablesList;
    private variablesEmpty;
    private resolutionLabel;
    private fpsLabel;
    private bgColorDot;
    private customWidthInput;
    private customHeightInput;
    private colorInput;
    private resolutionChangeCallback;
    private fpsChangeCallback;
    private backgroundChangeCallback;
    private clickOutsideHandler;
    private showMergeFields;
    constructor(edit?: Edit, options?: {
        mergeFields?: boolean;
    });
    /** Get the edit as ShotstackEdit if it has merge field capabilities */
    private getShotstackEdit;
    setPosition(screenX: number, screenY: number): void;
    mount(parent: HTMLElement): void;
    private setupEventListeners;
    private togglePopup;
    private closeAllPopups;
    private handleResolutionSelect;
    private handleCustomSizeChange;
    private handleFpsSelect;
    private handleColorChange;
    private updateResolutionLabel;
    private updateFpsLabel;
    private updateColorPreview;
    private updateActiveStates;
    private renderVariablesList;
    private addVariable;
    setResolution(width: number, height: number): void;
    setFps(fps: number): void;
    setBackground(color: string): void;
    onResolutionChange(callback: ResolutionChangeCallback): void;
    onFpsChange(callback: FpsChangeCallback): void;
    onBackgroundChange(callback: BackgroundChangeCallback): void;
    dispose(): void;
}

export declare type CaptionAsset = components["schemas"]["CaptionAsset"];

export { CaptionAssetSchema }

export declare type ChromaKey = components["schemas"]["ChromaKey"];

export declare type Clip = components["schemas"]["Clip"];

export declare type ClipAnchor = Clip["position"];

/** Clip info for interactions */
declare interface ClipInfo {
    trackIndex: number;
    clipIndex: number;
    config: ResolvedClip;
}

export declare type ClipLocation = {
    trackIndex: number;
    clipIndex: number;
};

export declare type ClipReference = ClipLocation & {
    clip: ResolvedClip;
};

/** Custom clip renderer interface */
declare interface ClipRenderer {
    /** Render custom content inside clip element */
    render(clip: ResolvedClip, element: HTMLElement): void;
    /** Optional cleanup when clip is removed */
    dispose?(element: HTMLElement): void;
}

export { ClipSchema }

declare interface ClipStats {
    videos: number;
    images: number;
    text: number;
    richText: number;
    luma: number;
    animatedClips: number;
    cachedFrames: number;
}

/**
 * Toolbar for clip-level properties (timing, linking).
 * Shows compact timing controls for start and length with:
 * - Click-to-cycle mode badges
 * - Scrubbable time values (drag to adjust)
 * - Keyboard increment/decrement (arrow keys)
 */
export declare class ClipToolbar extends BaseToolbar {
    private startControl;
    private lengthControl;
    mount(parent: HTMLElement): void;
    private mountComponents;
    private applyTimingUpdate;
    protected syncState(): void;
    protected getPopupList(): (HTMLElement | null)[];
    dispose(): void;
}

declare type ClipType = ResolvedClip;

declare type CommandContext = {
    getClips(): Player[];
    getTracks(): Player[][];
    getTrack(trackIndex: number): Player[] | null;
    getContainer(): Container;
    addPlayer(trackIdx: number, player: Player): Promise<void>;
    addPlayerToContainer(trackIdx: number, player: Player): void;
    createPlayerFromAssetType(clipConfiguration: ClipType): Player;
    queueDisposeClip(player: Player): void;
    disposeClips(): void;
    clearClipError(trackIdx: number, clipIdx: number): void;
    undeleteClip(trackIdx: number, clip: Player): void;
    setUpdatedClip(clip: Player): void;
    restoreClipConfiguration(clip: Player, previousConfig: ClipType): void;
    updateDuration(): void;
    emitEvent<T extends EditEventName>(name: T, ...args: EditEventMap[T] extends void ? [] : [EditEventMap[T]]): void;
    findClipIndices(player: Player): {
        trackIndex: number;
        clipIndex: number;
    } | null;
    getClipAt(trackIndex: number, clipIndex: number): Player | null;
    getSelectedClip(): Player | null;
    setSelectedClip(clip: Player | null): void;
    movePlayerToTrackContainer(player: Player, fromTrackIdx: number, toTrackIdx: number): void;
    getEditState(): EditType;
    propagateTimingChanges(trackIndex: number, startFromClipIndex: number): void;
    resolveClipAutoLength(clip: Player): Promise<void>;
    untrackEndLengthClip(clip: Player): void;
    trackEndLengthClip(clip: Player): void;
    getMergeFields(): MergeFieldService;
};

export declare class Controls {
    private edit;
    private seekDistance;
    private seekDistanceLarge;
    private frameTime;
    constructor(timeline: Edit);
    load(): Promise<void>;
    private shouldIgnoreKeyboardEvent;
    private handleKeyDown;
    private handleKeyUp;
}

export declare type Crop = components["schemas"]["Crop"];

export { CropSchema }

export declare type Destination = components["schemas"]["Destinations"];

export declare const DestinationSchema: z.ZodUnion<readonly [z.ZodIntersection<z.ZodObject<{
    destinations: z.ZodOptional<z.ZodLiteral<"shotstackDestination_ShotstackDestination">>;
}, z.core.$strip>, z.ZodObject<{
    provider: z.ZodDefault<z.ZodString>;
    exclude: z.ZodOptional<z.ZodBoolean>;
}, z.core.$strip>>, z.ZodIntersection<z.ZodObject<{
    destinations: z.ZodOptional<z.ZodLiteral<"muxDestination_MuxDestination">>;
}, z.core.$strip>, z.ZodObject<{
    provider: z.ZodDefault<z.ZodString>;
    options: z.ZodOptional<z.ZodObject<{
        playbackPolicy: z.ZodOptional<z.ZodArray<z.ZodEnum<{
            public: "public";
            signed: "signed";
        }>>>;
        passthrough: z.ZodOptional<z.ZodString>;
    }, z.core.$strip>>;
}, z.core.$strip>>, z.ZodIntersection<z.ZodObject<{
    destinations: z.ZodOptional<z.ZodLiteral<"s3Destination_S3Destination">>;
}, z.core.$strip>, z.ZodObject<{
    provider: z.ZodDefault<z.ZodString>;
    options: z.ZodOptional<z.ZodObject<{
        region: z.ZodString;
        bucket: z.ZodString;
        prefix: z.ZodOptional<z.ZodString>;
        filename: z.ZodOptional<z.ZodString>;
        acl: z.ZodOptional<z.ZodString>;
    }, z.core.$strip>>;
}, z.core.$strip>>, z.ZodIntersection<z.ZodObject<{
    destinations: z.ZodOptional<z.ZodLiteral<"googleCloudStorageDestination_GoogleCloudStorageDestination">>;
}, z.core.$strip>, z.ZodObject<{
    provider: z.ZodDefault<z.ZodString>;
    options: z.ZodOptional<z.ZodObject<{
        bucket: z.ZodString;
        prefix: z.ZodOptional<z.ZodString>;
        filename: z.ZodOptional<z.ZodString>;
    }, z.core.$strip>>;
}, z.core.$strip>>, z.ZodIntersection<z.ZodObject<{
    destinations: z.ZodOptional<z.ZodLiteral<"googleDriveDestination_GoogleDriveDestination">>;
}, z.core.$strip>, z.ZodObject<{
    provider: z.ZodDefault<z.ZodString>;
    options: z.ZodObject<{
        folderId: z.ZodString;
        filename: z.ZodOptional<z.ZodString>;
    }, z.core.$strip>;
}, z.core.$strip>>, z.ZodIntersection<z.ZodObject<{
    destinations: z.ZodOptional<z.ZodLiteral<"vimeoDestination_VimeoDestination">>;
}, z.core.$strip>, z.ZodObject<{
    provider: z.ZodDefault<z.ZodString>;
    options: z.ZodOptional<z.ZodObject<{
        name: z.ZodOptional<z.ZodString>;
        description: z.ZodOptional<z.ZodString>;
        privacy: z.ZodOptional<z.ZodObject<{
            view: z.ZodOptional<z.ZodEnum<{
                anybody: "anybody";
                nobody: "nobody";
                contacts: "contacts";
                password: "password";
                unlisted: "unlisted";
            }>>;
            embed: z.ZodOptional<z.ZodEnum<{
                public: "public";
                private: "private";
                whitelist: "whitelist";
            }>>;
            comments: z.ZodOptional<z.ZodEnum<{
                anybody: "anybody";
                nobody: "nobody";
                contacts: "contacts";
            }>>;
        }, z.core.$strip>>;
        folderUri: z.ZodOptional<z.ZodString>;
    }, z.core.$strip>>;
}, z.core.$strip>>, z.ZodIntersection<z.ZodObject<{
    destinations: z.ZodOptional<z.ZodLiteral<"tiktokDestination_TiktokDestination">>;
}, z.core.$strip>, z.ZodObject<{
    provider: z.ZodDefault<z.ZodString>;
    options: z.ZodOptional<z.ZodObject<{
        title: z.ZodOptional<z.ZodString>;
        privacyLevel: z.ZodOptional<z.ZodEnum<{
            public: "public";
            friends: "friends";
            private: "private";
        }>>;
        disableDuet: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
        disableStitch: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
        disableComment: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
    }, z.core.$strip>>;
}, z.core.$strip>>]>;

export declare class Edit extends Entity {
    private static readonly ZIndexPadding;
    assetLoader: AssetLoader;
    events: EventEmitter<EditEventMap & InternalEventMap>;
    private edit;
    private tracks;
    private clipsToDispose;
    private clips;
    private commandHistory;
    private commandIndex;
    playbackTime: number;
    totalDuration: number;
    private cachedTimelineEnd;
    private endLengthClips;
    private isBatchingEvents;
    private isLoadingEdit;
    private syncCorrectionCount;
    private toolbarButtons;
    private canvas;
    private lumaMaskController;
    private clipErrors;
    /**
     * Create an Edit instance from a template configuration.
     *
     * @param template - The Edit JSON configuration (aligns with Shotstack API contract)
     *
     * @example
     * ```typescript
     * const edit = new Edit(template);
     * await edit.load();
     *
     * const canvas = new Canvas(edit);
     * await canvas.load();
     * ```
     */
    constructor(template: Edit_2);
    load(): Promise<void>;
    /**
     * Initialize players and timing from the document.
     * Called during initial load() and can be called again via loadEdit() for hot-reload.
     * @param source - The source identifier for events (default: "load")
     */
    private initializeFromDocument;
    private updateViewportMask;
    play(): void;
    pause(): void;
    seek(target: number): void;
    stop(): void;
    /**
     * Reload the edit with a new configuration (hot-reload).
     * Uses smart diffing to only update what changed when possible.
     *
     * For initial loading, use the constructor + load() pattern instead:
     * ```typescript
     * const edit = new Edit(template);
     * await edit.load();
     * ```
     *
     * @param edit - The new Edit configuration to load
     */
    loadEdit(edit: Edit_2): Promise<void>;
    private loadSoundtrack;
    getEdit(): Edit_2;
    /**
     * Validates an edit configuration without applying it.
     * Use this to pre-validate user input before calling loadEdit().
     *
     * @param edit - The edit configuration to validate
     * @returns Validation result with valid boolean and any errors
     */
    validateEdit(edit: unknown): {
        valid: boolean;
        errors: Array<{
            path: string;
            message: string;
        }>;
    };
    getResolvedEdit(): ResolvedEdit;
    /**
     * Get the original parsed edit configuration.
     * Unlike getResolvedEdit(), this returns the edit as originally parsed,
     * with all clips present regardless of loading state.
     */
    getOriginalEdit(): ResolvedEdit | null;
    addClip(trackIdx: number, clip: Clip): void | Promise<void>;
    getClip(trackIdx: number, clipIdx: number): Clip | null;
    /**
     * Get the error state for a clip that failed to load.
     * Returns null if the clip loaded successfully.
     */
    getClipError(trackIdx: number, clipIdx: number): {
        error: string;
        assetType: string;
    } | null;
    /**
     * Clear the error for a deleted clip and shift indices for remaining errors.
     * Called when a clip is deleted to keep error indices in sync.
     */
    private clearClipErrorAndShift;
    getPlayerClip(trackIdx: number, clipIdx: number): Player | null;
    /** Get the exportable asset for a clip, preserving merge field templates */
    getOriginalAsset(trackIndex: number, clipIndex: number): unknown | undefined;
    deleteClip(trackIdx: number, clipIdx: number): void;
    splitClip(trackIndex: number, clipIndex: number, splitTime: number): void;
    addTrack(trackIdx: number, track: Track): Promise<void>;
    getTrack(trackIdx: number): Track | null;
    deleteTrack(trackIdx: number): void;
    getTotalDuration(): number;
    getMemoryStats(): {
        clipCounts: Record<string, number>;
        totalClips: number;
        richTextCacheStats: {
            clips: number;
            totalFrames: number;
        };
        textPlayerCount: number;
        lumaMaskCount: number;
        commandHistorySize: number;
        trackCount: number;
    };
    getComprehensiveMemoryStats(): {
        textureStats: {
            videos: {
                count: number;
                totalMB: number;
                avgDimensions: string;
            };
            images: {
                count: number;
                totalMB: number;
                avgDimensions: string;
            };
            text: {
                count: number;
                totalMB: number;
            };
            richText: {
                count: number;
                totalMB: number;
            };
            luma: {
                count: number;
                totalMB: number;
            };
            animated: {
                count: number;
                frames: number;
                totalMB: number;
            };
            totalTextures: number;
            totalMB: number;
        };
        assetDetails: Array<{
            id: string;
            type: "video" | "image" | "text" | "rich-text" | "luma" | "audio" | "html" | "shape" | "caption" | "unknown";
            label: string;
            width: number;
            height: number;
            estimatedMB: number;
        }>;
        systemStats: {
            clipCount: number;
            trackCount: number;
            commandCount: number;
        };
    };
    private estimateTextureMB;
    private getAssetLabel;
    getPlaybackHealth(): {
        activePlayerCount: number;
        totalPlayerCount: number;
        videoMaxDrift: number;
        audioMaxDrift: number;
        syncCorrections: number;
    };
    recordSyncCorrection(): void;
    undo(): void;
    redo(): void;
    updateClip(trackIdx: number, clipIdx: number, updates: Partial<Clip>): void;
    /**
     * Update clip timing mode and/or values.
     * Supports manual values, "auto", and "end" timing modes.
     * @param trackIdx - Track index
     * @param clipIdx - Clip index within track
     * @param params - Timing update parameters (start and/or length in milliseconds)
     */
    updateClipTiming(trackIdx: number, clipIdx: number, params: TimingUpdateParams): void;
    executeEditCommand(command: EditCommand): void | Promise<void>;
    protected executeCommand(command: EditCommand): void | Promise<void>;
    /**
     * Emits a unified `edit:changed` event after any state mutation.
     * Consumers can subscribe to this single event instead of tracking 31+ granular events.
     */
    protected emitEditChanged(source: string): void;
    /**
     * Detects merge field placeholders in the raw edit before substitution.
     * Returns a map of clip keys ("trackIdx-clipIdx") to their merge field bindings.
     * Each binding maps a property path to its placeholder and resolved value.
     */
    private detectMergeFieldBindings;
    /**
     * Recursively walks an object to find merge field placeholders.
     * Returns a map of property paths to their bindings.
     */
    private detectBindingsInObject;
    /**
     * Checks if edit has structural changes requiring full reload.
     * Structural = track count, clip count, or asset type changed.
     */
    private hasStructuralChanges;
    /**
     * Applies granular changes without full reload (preserves undo history, no flash).
     * Only called when structure is unchanged (same track/clip counts).
     */
    private applyGranularChanges;
    protected createCommandContext(): CommandContext;
    private queueDisposeClip;
    protected disposeClips(): void;
    /**
     * Remove fonts from timeline.fonts that are no longer referenced by any clip.
     * This keeps the document clean and prevents accumulation of unused font URLs.
     */
    private cleanupUnusedFonts;
    /**
     * Extract the filename (without extension) from a font URL.
     * e.g., "https://fonts.gstatic.com/s/inter/v20/UcCO3Fwr...Bg-4.ttf" → "UcCO3Fwr...Bg-4"
     */
    private extractFilenameFromUrl;
    private disposeClip;
    private unloadClipAssets;
    protected clearClips(): void;
    private updateTotalDuration;
    private resolveAllTiming;
    propagateTimingChanges(trackIndex: number, startFromClipIndex: number): void;
    resolveClipAutoLength(clip: Player): Promise<void>;
    private addPlayerToContainer;
    private movePlayerToTrackContainer;
    private createPlayerFromAssetType;
    private addPlayer;
    selectClip(trackIndex: number, clipIndex: number): void;
    clearSelection(): void;
    isClipSelected(trackIndex: number, clipIndex: number): boolean;
    getSelectedClipInfo(): {
        trackIndex: number;
        clipIndex: number;
        player: Player;
    } | null;
    /**
     * Copy a clip to the internal clipboard
     */
    copyClip(trackIdx: number, clipIdx: number): void;
    /**
     * Paste the copied clip at the current playhead position
     */
    pasteClip(): void;
    /**
     * Check if there is a clip in the clipboard
     */
    hasCopiedClip(): boolean;
    findClipIndices(player: Player): {
        trackIndex: number;
        clipIndex: number;
    } | null;
    getClipAt(trackIndex: number, clipIndex: number): Player | null;
    selectPlayer(player: Player): void;
    isPlayerSelected(player: Player): boolean;
    /**
     * Move the selected clip by a pixel delta.
     * Used for keyboard arrow key positioning.
     */
    moveSelectedClip(deltaX: number, deltaY: number): void;
    setExportMode(exporting: boolean): void;
    isInExportMode(): boolean;
    setCanvas(canvas: Canvas): void;
    getCanvasZoom(): number;
    setOutputSize(width: number, height: number): void;
    setOutputFps(fps: number): void;
    getOutputFps(): number;
    setOutputFormat(format: string): void;
    getOutputFormat(): string;
    setOutputDestinations(destinations: Destination[]): void;
    getOutputDestinations(): Destination[];
    getTimelineFonts(): Array<{
        src: string;
    }>;
    /**
     * Remove any fonts from timeline.fonts that are no longer used by clips.
     * Call this after changing a clip's font to clean up the old font.
     */
    pruneUnusedFonts(): void;
    setTimelineBackground(color: string): void;
    getTimelineBackground(): string;
    /**
     * @deprecated Use `ui.registerButton()` instead.
     */
    registerToolbarButton(config: ToolbarButtonConfig_2): void;
    /**
     * @deprecated Use `ui.unregisterButton()` instead.
     */
    unregisterToolbarButton(id: string): void;
    /**
     * @deprecated Use `ui.getButtons()` instead.
     */
    getToolbarButtons(): ToolbarButtonConfig_2[];
    /** Get the exportable clip (with merge field placeholders restored) */
    protected getTemplateClip(trackIndex: number, clipIndex: number): ResolvedClip | null;
    /** Get the text content from the template clip (with merge field placeholders) */
    getTemplateClipText(trackIdx: number, clipIdx: number): string | null;
    /** Map of content player → luma player for attachment tracking */
    private lumaAttachments;
    /** Map of asset src → original asset type (for reliable luma detachment) */
    private originalAssetTypes;
    /**
     * Attach a luma mask to a specific clip.
     * Creates a luma clip on the same track with synchronized timing.
     *
     * @param trackIndex - Track index of the content clip
     * @param clipIndex - Clip index of the content clip
     * @param lumaSrc - URL of the luma mask asset (video or image)
     */
    attachLumaToClip(trackIndex: number, clipIndex: number, lumaSrc: string): Promise<void>;
    /**
     * Detach the luma mask from a clip.
     * Removes the luma clip from the track.
     *
     * @param trackIndex - Track index of the content clip
     * @param clipIndex - Clip index of the content clip
     */
    detachLumaFromClip(trackIndex: number, clipIndex: number): Promise<void>;
    /**
     * Get the luma mask attached to a clip, if any.
     *
     * @param trackIndex - Track index of the content clip
     * @param clipIndex - Clip index of the content clip
     * @returns Luma info or null if no luma attached
     */
    getClipLuma(trackIndex: number, clipIndex: number): {
        src: string;
        clipIndex: number;
    } | null;
    /**
     * Check if a clip has a luma mask attached.
     *
     * @param trackIndex - Track index of the content clip
     * @param clipIndex - Clip index of the content clip
     */
    hasLumaMask(trackIndex: number, clipIndex: number): boolean;
    /**
     * Register a luma attachment in the Edit Session's map.
     * This is called when a luma is attached to a content clip (e.g., during drag-drop).
     * The map is used by syncAttachedLuma() to coordinate timing between attached clips.
     */
    registerLumaAttachment(contentTrackIndex: number, contentClipIndex: number, lumaTrackIndex: number, lumaClipIndex: number): void;
    /**
     * Transform a clip to luma type (for attachment).
     * Recreates the player with luma asset type while preserving the src.
     *
     * @param trackIndex - Track index of the clip
     * @param clipIndex - Clip index of the clip
     */
    transformToLuma(trackIndex: number, clipIndex: number): void;
    /**
     * Transform a luma clip back to its original type (for detachment).
     * Uses stored original type for reliability, with URL extension fallback.
     *
     * @param trackIndex - Track index of the luma clip
     * @param clipIndex - Clip index of the luma clip
     */
    transformFromLuma(trackIndex: number, clipIndex: number): void;
    private setupIntentListeners;
}

declare type Edit_2 = components["schemas"]["Edit"];

declare type EditCommand = {
    execute(context?: CommandContext): void | Promise<void>;
    undo?(context?: CommandContext): void | Promise<void>;
    readonly name: string;
};

/** Alias for Edit type to avoid conflicts with SDK's Edit class */
export declare type EditConfig = Edit_2;

export declare const EditEvent: {
    readonly PlaybackPlay: "playback:play";
    readonly PlaybackPause: "playback:pause";
    readonly TimelineUpdated: "timeline:updated";
    readonly TimelineBackgroundChanged: "timeline:backgroundChanged";
    readonly ClipAdded: "clip:added";
    readonly ClipSplit: "clip:split";
    readonly ClipSelected: "clip:selected";
    readonly ClipUpdated: "clip:updated";
    readonly ClipDeleted: "clip:deleted";
    readonly ClipRestored: "clip:restored";
    readonly ClipCopied: "clip:copied";
    readonly ClipLoadFailed: "clip:loadFailed";
    readonly SelectionCleared: "selection:cleared";
    readonly EditChanged: "edit:changed";
    readonly EditUndo: "edit:undo";
    readonly EditRedo: "edit:redo";
    readonly TrackAdded: "track:added";
    readonly TrackRemoved: "track:removed";
    readonly DurationChanged: "duration:changed";
    readonly OutputResized: "output:resized";
    readonly OutputFpsChanged: "output:fpsChanged";
    readonly OutputFormatChanged: "output:formatChanged";
    readonly OutputDestinationsChanged: "output:destinationsChanged";
    readonly MergeFieldRegistered: "mergefield:registered";
    readonly MergeFieldUpdated: "mergefield:updated";
    readonly MergeFieldRemoved: "mergefield:removed";
    readonly MergeFieldChanged: "mergefield:changed";
    readonly MergeFieldApplied: "mergefield:applied";
    readonly TranscriptionProgress: "transcription:progress";
    readonly TranscriptionCompleted: "transcription:completed";
    readonly TranscriptionFailed: "transcription:failed";
    readonly LumaAttached: "luma:attached";
    readonly LumaDetached: "luma:detached";
};

export declare type EditEventMap = {
    [EditEvent.PlaybackPlay]: void;
    [EditEvent.PlaybackPause]: void;
    [EditEvent.TimelineUpdated]: {
        current: ResolvedEdit;
    };
    [EditEvent.TimelineBackgroundChanged]: {
        color: string;
    };
    [EditEvent.ClipAdded]: ClipLocation;
    [EditEvent.ClipSplit]: {
        trackIndex: number;
        originalClipIndex: number;
        newClipIndex: number;
    };
    [EditEvent.ClipSelected]: ClipReference;
    [EditEvent.ClipUpdated]: {
        previous: ClipReference;
        current: ClipReference;
    };
    [EditEvent.ClipDeleted]: ClipLocation;
    [EditEvent.ClipRestored]: ClipLocation;
    [EditEvent.ClipCopied]: ClipLocation;
    [EditEvent.ClipLoadFailed]: ClipLocation & {
        error: string;
        assetType: string;
    };
    [EditEvent.SelectionCleared]: void;
    [EditEvent.EditChanged]: {
        source: string;
        timestamp: number;
    };
    [EditEvent.EditUndo]: {
        command: string;
    };
    [EditEvent.EditRedo]: {
        command: string;
    };
    [EditEvent.TrackAdded]: {
        trackIndex: number;
        totalTracks: number;
    };
    [EditEvent.TrackRemoved]: {
        trackIndex: number;
    };
    [EditEvent.DurationChanged]: {
        duration: number;
    };
    [EditEvent.OutputResized]: {
        width: number;
        height: number;
    };
    [EditEvent.OutputFpsChanged]: {
        fps: number;
    };
    [EditEvent.OutputFormatChanged]: {
        format: string;
    };
    [EditEvent.OutputDestinationsChanged]: {
        destinations: unknown[];
    };
    [EditEvent.MergeFieldRegistered]: {
        field: MergeField_2;
    };
    [EditEvent.MergeFieldUpdated]: {
        field: MergeField_2;
    };
    [EditEvent.MergeFieldRemoved]: ClipLocation & {
        propertyPath: string;
        fieldName: string | null;
    };
    [EditEvent.MergeFieldChanged]: {
        fields: MergeField_2[];
    };
    [EditEvent.MergeFieldApplied]: ClipLocation & {
        propertyPath: string;
        fieldName: string;
    };
    [EditEvent.TranscriptionProgress]: {
        clipAlias: string;
        message?: string;
    };
    [EditEvent.TranscriptionCompleted]: {
        clipAlias: string;
        cueCount: number;
    };
    [EditEvent.TranscriptionFailed]: {
        clipAlias: string;
        error: string;
    };
    [EditEvent.LumaAttached]: ClipLocation & {
        lumaSrc: string;
        lumaClipIndex: number;
    };
    [EditEvent.LumaDetached]: ClipLocation;
};

export declare type EditEventName = (typeof EditEvent)[keyof typeof EditEvent];

export { EditSchema }

declare type EditType = ResolvedEdit;

declare abstract class Entity {
    private readonly container;
    constructor();
    abstract load(): Promise<void>;
}

declare class EventEmitter<TEventPayloadMap extends EventPayloadMap = EventPayloadMap> {
    private readonly events;
    constructor();
    on<TEventName extends keyof TEventPayloadMap>(name: TEventName, listener: Listener<TEventPayloadMap[TEventName]>): () => void;
    once<TEventName extends keyof TEventPayloadMap>(name: TEventName, listener: Listener<TEventPayloadMap[TEventName]>): () => void;
    off<TEventName extends keyof TEventPayloadMap>(name: TEventName, listener: Listener<TEventPayloadMap[TEventName]>): void;
    clear(name: keyof TEventPayloadMap): void;
    emit<TEventName extends keyof TEventPayloadMap>(name: TEventName, ...args: TEventPayloadMap[TEventName] extends void ? [] : [TEventPayloadMap[TEventName]]): void;
}

declare type EventPayloadMap<TPayload = any> = Record<string, TPayload>;

/** SDK-extended CaptionAsset with stroke, width, height, alignment */
export declare type ExtendedCaptionAsset = CaptionAsset & {
    stroke?: {
        width: number;
        color: string;
    };
    width?: number;
    height?: number;
    alignment?: {
        horizontal?: "left" | "center" | "right";
        vertical?: "top" | "center" | "bottom";
    };
};

export declare type Font = components["schemas"]["Font"];

declare type FpsChangeCallback = (fps: number) => void;

export declare const HexColorSchema: z.ZodString;

export declare type HtmlAsset = components["schemas"]["HtmlAsset"];

export declare type HtmlAssetPosition = NonNullable<HtmlAsset["position"]>;

export { HtmlAssetSchema }

export declare type ImageAsset = components["schemas"]["ImageAsset"];

export { ImageAssetSchema }

export declare class Inspector extends Entity {
    private static readonly Width;
    private static readonly Height;
    fps: number;
    playbackTime: number;
    playbackDuration: number;
    isPlaying: boolean;
    clipStats: ClipStats | null;
    systemStats: SystemStats | null;
    playbackHealth: PlaybackHealth | null;
    clipCounts: Record<string, number>;
    totalClips: number;
    commandHistorySize: number;
    trackCount: number;
    private background;
    private text;
    private historySamples;
    private readonly maxSamples;
    private lastSampleTime;
    private readonly sampleInterval;
    private frameTimes;
    private readonly frameTimeWindow;
    private readonly jankThreshold;
    constructor();
    load(): Promise<void>;
    update(_: number, deltaMS: number): void;
    private trackFrameTime;
    private getFrameStats;
    private getFrameTimeSparkline;
    private addHistorySample;
    private getJsHeapSparkline;
    private renderStats;
    private getSyncStatusIcon;
    draw(): void;
    dispose(): void;
    private formatClipCounts;
    private getMemoryInfo;
    private bytesToMegabytes;
}

declare type InternalEventMap = {
    "canvas:clipClicked": {
        player: Player;
    };
    "canvas:backgroundClicked": void;
    "font:capabilitiesChanged": {
        supportsBold: boolean;
    };
    "toolbar:buttonsChanged": {
        buttons: ToolbarButtonConfig_2[];
    };
};

declare type Keyframe_2 = Tween;
export { Keyframe_2 as Keyframe }

declare type Listener<TPayload = any> = (payload: TPayload) => void;

export declare type LumaAsset = components["schemas"]["LumaAsset"];

export { LumaAssetSchema }

export declare class MediaToolbar extends BaseToolbar {
    private showMergeFields;
    private assetType;
    constructor(edit: Edit, options?: MediaToolbarOptions);
    /** Get the edit as ShotstackEdit if it has merge field capabilities */
    private getShotstackEdit;
    private currentFit;
    private currentVolume;
    private transitionPanel;
    private effectPanel;
    private opacitySlider;
    private scaleSlider;
    private fitBtn;
    private opacityBtn;
    private scaleBtn;
    private volumeBtn;
    private transitionBtn;
    private effectBtn;
    private advancedBtn;
    private audioFadeBtn;
    private fitPopup;
    private opacityPopup;
    private scalePopup;
    private volumePopup;
    private transitionPopup;
    private effectPopup;
    private advancedPopup;
    private audioFadePopup;
    private fitLabel;
    private volumeSlider;
    private volumeValue;
    private volumeSection;
    private visualSection;
    private audioSection;
    private dynamicToggle;
    private dynamicPanel;
    private dynamicInput;
    private audioFadeEffect;
    private isDynamicSource;
    private dynamicFieldName;
    private originalSrc;
    mount(parent: HTMLElement): void;
    /**
     * Mount composite UI components into their placeholder elements.
     */
    private mountCompositeComponents;
    private setupEventListeners;
    private togglePopupByName;
    protected closeAllPopups(): void;
    protected getPopupList(): (HTMLElement | null)[];
    protected syncState(): void;
    private handleFitChange;
    private handleOpacityChange;
    private handleScaleChange;
    private handleVolumeChange;
    private applyTransitionUpdate;
    private applyEffect;
    private handleAudioFadeSelect;
    private applyAudioFade;
    private updateAudioFadeUI;
    private applyClipUpdate;
    private setupDynamicSourceHandlers;
    private applyDynamicUrl;
    private showUrlError;
    private clearUrlError;
    private clearDynamicSource;
    private updateDynamicSourceUI;
    private updateFitDisplay;
    private updateOpacityDisplay;
    private updateScaleDisplay;
    private updateVolumeDisplay;
    private updateFitActiveState;
    /**
     * Show the toolbar for a specific clip.
     * Derives assetType from the clip's asset configuration.
     */
    show(trackIndex: number, clipIndex: number): void;
    dispose(): void;
}

declare interface MediaToolbarOptions {
    mergeFields?: boolean;
}

export declare type MergeField = components["schemas"]["MergeField"];

/**
 * Merge field types for the Shotstack Studio SDK.
 *
 * Merge fields allow dynamic content substitution using {{ FIELD_NAME }} syntax.
 * Values are replaced at render time, enabling template-based video generation.
 */
/**
 * A merge field definition used throughout the SDK.
 */
declare interface MergeField_2 {
    /** Field identifier (uppercase convention: MY_FIELD) */
    name: string;
    /** Default value used for preview when no runtime value is provided */
    defaultValue: string;
    /** Optional description for UI display */
    description?: string;
}

/**
 * Tracks a merge field binding for a specific property path.
 * Used to restore placeholders on export for properties that haven't changed.
 */
declare interface MergeFieldBinding {
    /** The original placeholder string, e.g., "{{ HERO_IMAGE }}" */
    placeholder: string;
    /** The resolved value at binding time, used for change detection */
    resolvedValue: string;
}

declare class MergeFieldService {
    private fields;
    private events;
    constructor(events: EventEmitter);
    /**
     * Register or update a merge field.
     * @param field The merge field to register
     * @param options.silent If true, suppresses event emission (for command-based operations)
     */
    register(field: MergeField_2, options?: {
        silent?: boolean;
    }): void;
    /**
     * Remove a merge field by name.
     * @param name The field name to remove
     * @param options.silent If true, suppresses event emission (for command-based operations)
     */
    remove(name: string, options?: {
        silent?: boolean;
    }): boolean;
    /** Get a merge field by name */
    get(name: string): MergeField_2 | undefined;
    /** Get all registered merge fields */
    getAll(): MergeField_2[];
    /** Clear all merge fields */
    clear(): void;
    /**
     * Apply merge field substitutions to a string.
     * Replaces {{ FIELD_NAME }} patterns with their default values.
     */
    resolve(input: string): string;
    /**
     * Check if a string contains unresolved merge fields.
     * Returns true if any {{ FIELD_NAME }} patterns remain after resolution.
     */
    hasUnresolved(input: string): boolean;
    /**
     * Extract the first merge field name from a string.
     * Returns null if no merge field pattern is found.
     */
    extractFieldName(input: string): string | null;
    /** Check if a string is a merge field template (contains {{ FIELD }}) */
    isMergeFieldTemplate(input: string): boolean;
    /** Create a merge field template string from a field name */
    createTemplate(fieldName: string): string;
    /** Export fields in Shotstack API format ({ find, replace }) */
    toSerializedArray(): SerializedMergeField[];
    /** Import fields from Shotstack API format (does not emit event - called during loadEdit) */
    loadFromSerialized(fields: SerializedMergeField[]): void;
    /** Generate a unique field name with a given prefix (e.g., MEDIA_1, MEDIA_2) */
    generateUniqueName(prefix: string): string;
}

export declare interface NumericKeyframe {
    start: number;
    length: number;
    from: number;
    to: number;
    interpolation?: Tween["interpolation"];
    easing?: Tween["easing"];
}

export declare type Offset = components["schemas"]["Offset"];

export { OffsetSchema }

export declare type Output = components["schemas"]["Output"];

export declare const OutputFormatSchema: z.ZodEnum<{
    mp4: "mp4";
    gif: "gif";
    mp3: "mp3";
    jpg: "jpg";
    png: "png";
    bmp: "bmp";
}>;

export declare const OutputFpsSchema: z.ZodUnion<readonly [z.ZodLiteral<12>, z.ZodLiteral<15>, z.ZodLiteral<23.976>, z.ZodLiteral<24>, z.ZodLiteral<25>, z.ZodLiteral<29.97>, z.ZodLiteral<30>, z.ZodLiteral<48>, z.ZodLiteral<50>, z.ZodLiteral<59.94>, z.ZodLiteral<60>]>;

export { OutputSchema }

export declare const OutputSizeSchema: z.ZodObject<{
    width: z.ZodOptional<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>>;
    height: z.ZodOptional<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodNumber>>;
}, z.core.$strip>;

declare interface PlaybackHealth {
    activePlayerCount: number;
    totalPlayerCount: number;
    videoMaxDrift: number;
    audioMaxDrift: number;
    syncCorrections: number;
}

/**
 * Base class for all visual content players in the canvas.
 *
 * Player is responsible for rendering clip content (video, image, text, etc.)
 * and applying keyframe animations. It does NOT handle selection UI or
 * drag/resize/rotate interactions - those are handled by SelectionHandles
 * when registered via UIController.
 *
 * This separation allows Canvas to be used as a pure preview renderer
 * without any interactive overlays.
 */
declare abstract class Player extends Entity {
    private static readonly DiscardedFrameCount;
    layer: number;
    shouldDispose: boolean;
    readonly playerType: PlayerType;
    protected edit: Edit;
    clipConfiguration: ResolvedClip;
    private timingIntent;
    private resolvedTiming;
    private positionBuilder;
    private offsetXKeyframeBuilder?;
    private offsetYKeyframeBuilder?;
    private scaleKeyframeBuilder?;
    private opacityKeyframeBuilder?;
    private rotationKeyframeBuilder?;
    private maskXKeyframeBuilder?;
    private wipeMask;
    protected contentContainer: pixi.Container;
    /**
     * Tracks which properties came from merge field templates.
     * Key: property path (e.g., "asset.src"), Value: binding info
     */
    private mergeFieldBindings;
    constructor(edit: Edit, clipConfiguration: ResolvedClip, playerType: PlayerType);
    reconfigureAfterRestore(): void;
    /**
     * Reload the asset for this player (e.g., when asset.src changes).
     * Override in subclasses that have loadable assets (image, video).
     * Default implementation is a no-op.
     */
    reloadAsset(): Promise<void>;
    protected configureKeyframes(): void;
    load(): Promise<void>;
    update(_: number, __: number): void;
    private updateWipeMask;
    draw(): void;
    dispose(): void;
    getStart(): Seconds;
    getLength(): Seconds;
    getEnd(): Seconds;
    getTimingIntent(): TimingIntent;
    setTimingIntent(intent: Partial<TimingIntent>): void;
    getResolvedTiming(): ResolvedTiming;
    setResolvedTiming(timing: ResolvedTiming): void;
    convertToFixedTiming(): void;
    /**
     * Set a merge field binding for a property path.
     * Called when a property is resolved from a merge field template.
     */
    setMergeFieldBinding(path: string, binding: MergeFieldBinding): void;
    /**
     * Get the merge field binding for a property path, if any.
     */
    getMergeFieldBinding(path: string): MergeFieldBinding | undefined;
    /**
     * Remove a merge field binding (e.g., when user changes the value).
     */
    removeMergeFieldBinding(path: string): void;
    /**
     * Get all merge field bindings for this player.
     */
    getMergeFieldBindings(): Map<string, MergeFieldBinding>;
    /**
     * Bulk set bindings during player initialization.
     */
    setInitialBindings(bindings: Map<string, MergeFieldBinding>): void;
    /**
     * Get the exportable clip configuration with merge field placeholders restored.
     * For properties that haven't changed from their resolved value, the original
     * placeholder (e.g., "{{ HERO_IMAGE }}") is restored for export.
     */
    getExportableClip(): Clip;
    /**
     * Get the playback time relative to clip start, in seconds.
     * Used for keyframe animation calculations.
     */
    getPlaybackTime(): number;
    abstract getSize(): Size;
    /**
     * Returns the source content dimensions (before fit scaling).
     * Override in subclasses that have different source vs output sizes.
     * Default implementation returns getSize().
     */
    getContentSize(): Size;
    getOpacity(): number;
    getPosition(): Vector;
    getPivot(): Vector;
    protected getFitScale(): number;
    getScale(): number;
    protected getContainerScale(): Vector;
    getRotation(): number;
    isActive(): boolean;
    shouldDiscardFrame(): boolean;
    /**
     * Handle pointer down - emit click event for selection handling.
     * All drag/resize/rotate interaction is handled by SelectionHandles.
     */
    private onPointerDown;
    private clipHasKeyframes;
    protected applyFixedDimensions(): void;
    protected applyAnchorPositioning(anchor: string, clipWidth: number, clipHeight: number, sprite: pixi.Sprite): void;
    /**
     * Override in subclasses to enable edge resize handles for dimension changes.
     * When true, edge handles will be shown instead of corner scale handles.
     */
    supportsEdgeResize(): boolean;
    /**
     * Called when dimensions change via edge resize. Override in subclasses to handle re-rendering.
     */
    protected onDimensionsChanged(): void;
    /**
     * Public wrapper for notifying dimension changes.
     * Called by SelectionHandles after edge resize operations.
     */
    notifyDimensionsChanged(): void;
}

declare enum PlayerType {
    Video = "video",
    Image = "image",
    Audio = "audio",
    Text = "text",
    RichText = "rich-text",
    Luma = "luma",
    Html = "html",
    Shape = "shape",
    Caption = "caption",
    Svg = "svg"
}

declare type ResolutionChangeCallback = (width: number, height: number) => void;

declare type ResolvedClip = Omit<Clip, "start" | "length"> & {
    start: Seconds;
    length: Seconds;
};

declare type ResolvedEdit = Omit<Edit_2, "timeline"> & {
    timeline: Omit<Edit_2["timeline"], "tracks"> & {
        tracks: ResolvedTrack[];
    };
};

/**
 * Resolved timing values in seconds.
 * Matches the external @shotstack/schemas unit convention.
 * Conversion to milliseconds happens only in the Player layer for pixi rendering.
 */
declare interface ResolvedTiming {
    start: Seconds;
    length: Seconds;
}

declare type ResolvedTrack = {
    clips: ResolvedClip[];
};

export declare type RichTextAsset = components["schemas"]["RichTextAsset"];

export { RichTextAssetSchema }

export declare class RichTextToolbar extends BaseToolbar {
    private showMergeFields;
    private fontPopup;
    private fontPreview;
    private fontPicker;
    private sizeInput;
    private sizePopup;
    private weightDropdown;
    private weightPopup;
    private weightPreview;
    private spacingPopup;
    private spacingPanel;
    private anchorTopBtn;
    private anchorMiddleBtn;
    private anchorBottomBtn;
    private alignIcon;
    private transformBtn;
    private underlineBtn;
    private linethroughBtn;
    private textEditPopup;
    private textEditArea;
    private textEditDebounceTimer;
    private autocompletePopup;
    private autocompleteItems;
    private autocompleteVisible;
    private autocompleteFilter;
    private autocompleteStartPos;
    private selectedAutocompleteIndex;
    private borderPopup;
    private borderWidthSlider;
    private borderWidthValue;
    private borderColorInput;
    private borderOpacitySlider;
    private borderOpacityValue;
    private borderRadiusSlider;
    private borderRadiusValue;
    private backgroundPopup;
    private backgroundColorPicker;
    private paddingPopup;
    private paddingTopSlider;
    private paddingTopValue;
    private paddingRightSlider;
    private paddingRightValue;
    private paddingBottomSlider;
    private paddingBottomValue;
    private paddingLeftSlider;
    private paddingLeftValue;
    private fontColorPopup;
    private fontColorPicker;
    private colorDisplay;
    private animationPopup;
    private animationDurationSlider;
    private animationDurationValue;
    private animationStyleSection;
    private animationDirectionSection;
    private transitionPopup;
    private transitionPanel;
    private effectPopup;
    private effectPanel;
    private stylePopup;
    private stylePanel;
    private boundHandleClick;
    constructor(edit: Edit, options?: RichTextToolbarOptions);
    private getShotstackEdit;
    mount(parent: HTMLElement): void;
    private handleClick;
    private getCurrentAsset;
    private updateSize;
    private static readonly FONT_WEIGHTS;
    private static readonly CHECKMARK_SVG;
    /** Single source of truth for weight normalization - handles string, number, or object */
    private normalizeWeight;
    private getWeightName;
    private toggleWeightPopup;
    /** Build popup once at mount - uses event delegation (no per-item listeners) */
    private buildWeightPopup;
    /** Update active state without rebuilding DOM */
    private updateWeightPopupState;
    private setFontWeight;
    private toggleSizePopup;
    private buildSizePopup;
    private applyManualSize;
    private toggleSpacingPopup;
    private toggleAnimationPopup;
    private toggleFontColorPopup;
    private toggleFontPopup;
    private toggleTextEditPopup;
    private debouncedApplyTextEdit;
    private applyTextEdit;
    private checkAutocomplete;
    private showAutocomplete;
    private hideAutocomplete;
    private insertVariable;
    private insertSelectedVariable;
    private getFilteredFieldCount;
    private buildFontPicker;
    private getDisplayName;
    private selectFont;
    private updateVerticalAlign;
    private cycleAlignment;
    private updateAlignment;
    private updateAlignIcon;
    private cycleTransform;
    private toggleUnderline;
    private toggleLinethrough;
    private updateBorderProperty;
    private updateShadowProperty;
    private updateAnimationProperty;
    private updateAnimationSections;
    private updateBackgroundProperty;
    private updatePaddingProperty;
    private updateFontColorProperty;
    private updateClipProperty;
    private applyClipUpdate;
    protected getPopupList(): (HTMLElement | null)[];
    protected syncState(): void;
    dispose(): void;
}

declare interface RichTextToolbarOptions {
    mergeFields?: boolean;
}

/**
 * A number representing time in seconds.
 * Used at API/configuration boundaries where users specify timing.
 */
declare type Seconds = number & {
    readonly [SecondsSymbol]: typeof SecondsSymbol;
};

declare const SecondsSymbol: unique symbol;

export declare class SelectionHandles implements CanvasOverlayRegistration {
    private edit;
    private container;
    private outline;
    private handles;
    private edgeHandles;
    private app;
    private positionBuilder;
    private selectedPlayer;
    private selectedTrackIndex;
    private selectedClipIndex;
    private isHovering;
    private isDragging;
    private dragOffset;
    private scaleDirection;
    private edgeDragDirection;
    private edgeDragStart;
    private originalDimensions;
    private isRotating;
    private rotationStart;
    private initialRotation;
    private rotationCorner;
    private initialClipConfiguration;
    private onClipSelectedBound;
    private onSelectionClearedBound;
    private onPointerDownBound;
    private onPointerMoveBound;
    private onPointerUpBound;
    constructor(edit: Edit);
    mount(parent: pixi.Container, app: pixi.Application): void;
    update(_deltaTime: number, _elapsed: number): void;
    draw(): void;
    dispose(): void;
    private onClipSelected;
    private onSelectionCleared;
    private syncToPlayer;
    private drawOutline;
    private drawHandles;
    private drawEdgeHandles;
    private getUIScale;
    private onPointerDown;
    private onPointerMove;
    private onPointerUp;
    private startDrag;
    private handleDrag;
    private startCornerResize;
    private handleCornerResize;
    private startEdgeResize;
    private handleEdgeResize;
    private startRotation;
    private handleRotation;
    private captureOriginalDimensions;
    private getContentCenter;
    private getRotationCorner;
    private getCornerResizeCursor;
    private updateHoverState;
    private resetDragState;
    private hasStateChanged;
}

/**
 * Serialized format for JSON export (matches Shotstack API).
 * The replace value can be any type - strings, numbers, booleans, objects.
 */
declare interface SerializedMergeField {
    find: string;
    replace: unknown;
}

export declare type ShapeAsset = components["schemas"]["ShapeAsset"];

export { ShapeAssetSchema }

declare type Size = {
    width: number;
    height: number;
};

export declare type Soundtrack = components["schemas"]["Soundtrack"];

declare interface SystemStats {
    clipCount: number;
    trackCount: number;
    commandCount: number;
}

export declare type TextAsset = components["schemas"]["TextAsset"];

export { TextAssetSchema }

export declare class TextToolbar extends BaseToolbar {
    private textEditBtn;
    private textEditPopup;
    private textEditArea;
    private textEditDebounceTimer;
    private sizeInput;
    private sizePopup;
    private fontBtn;
    private fontPopup;
    private fontPreview;
    private boldBtn;
    private fontColorBtn;
    private fontColorPopup;
    private fontColorInput;
    private colorDisplay;
    private spacingBtn;
    private spacingPopup;
    private spacingPanel;
    private anchorTopBtn;
    private anchorMiddleBtn;
    private anchorBottomBtn;
    private alignBtn;
    private alignIcon;
    private backgroundBtn;
    private backgroundPopup;
    private bgColorInput;
    private bgOpacitySlider;
    private bgOpacityValue;
    private strokeBtn;
    private strokePopup;
    private strokeWidthSlider;
    private strokeWidthValue;
    private strokeColorInput;
    private transitionBtn;
    private transitionPopup;
    private transitionPanel;
    private effectBtn;
    private effectPopup;
    private effectPanel;
    private boundHandleClick;
    private getShotstackEdit;
    mount(parent: HTMLElement): void;
    private bindElements;
    private setupEventListeners;
    private mountCompositePanels;
    private handleClick;
    protected getPopupList(): (HTMLElement | null)[];
    private buildFontPopup;
    private buildSizePopup;
    private getCurrentAsset;
    private updateAssetProperty;
    private debouncedApplyTextEdit;
    private adjustSize;
    private setSize;
    private applyManualSize;
    private setFont;
    private updateFontActiveState;
    private toggleBold;
    private handleFontColorChange;
    private setVerticalAnchor;
    private updateAnchorActiveState;
    private cycleAlignment;
    private updateAlignmentIcon;
    private handleBackgroundChange;
    private handleStrokeChange;
    private applyClipUpdate;
    protected syncState(): void;
    dispose(): void;
}

/** HTML/CSS-based Timeline component extending TimelineEntity for SDK consistency */
export declare class Timeline extends TimelineEntity {
    private readonly edit;
    private readonly container;
    private readonly stateManager;
    private features;
    private clipRenderers;
    private thumbnailGenerator;
    private mediaThumbnailRenderer;
    private toolbar;
    private rulerTracksWrapper;
    private ruler;
    private trackList;
    private playhead;
    private playheadGhost;
    private feedbackLayer;
    private interactionController;
    private animationFrameId;
    private isRenderLoopActive;
    private lastFrameTime;
    private isInteracting;
    private isLoaded;
    private readonly handleTimelineUpdated;
    private readonly handlePlaybackPlay;
    private readonly handlePlaybackPause;
    private readonly handleClipSelected;
    private readonly handleClipLoadFailed;
    constructor(edit: Edit, container: HTMLElement, options?: TimelineOptions);
    /** Initialize and mount the timeline */
    load(): Promise<void>;
    /** Update component state (called each frame during active rendering) */
    update(_deltaTime: number, _elapsed: number): void;
    /** Render/draw component to DOM (called each frame after update) */
    draw(): void;
    /** Clean up and unmount the timeline */
    dispose(): void;
    private setupEventListeners;
    private removeEventListeners;
    /** Start continuous render loop (during playback or interaction) */
    private startRenderLoop;
    /** Stop continuous render loop */
    private stopRenderLoop;
    /** Animation frame callback */
    private tick;
    /** Request a single render (used when idle and data changes) */
    private requestRender;
    /** Mark interaction as started (enables render loop) */
    beginInteraction(): void;
    /** Mark interaction as ended (may stop render loop) */
    endInteraction(): void;
    private buildComponents;
    private disposeComponents;
    setZoom(pixelsPerSecond: number): void;
    zoomIn(): void;
    zoomOut(): void;
    scrollTo(time: number): void;
    /** Recalculate size from container and re-render */
    resize(): void;
    selectClip(trackIndex: number, clipIndex: number): void;
    clearSelection(): void;
    enableFeature(feature: keyof TimelineFeatures): void;
    disableFeature(feature: keyof TimelineFeatures): void;
    registerClipRenderer(type: string, renderer: ClipRenderer): void;
    getEdit(): Edit;
    findClipAtPosition(x: number, y: number): ClipInfo | null;
}

/**
 * Base class for HTML-based timeline components.
 * Mirrors the Entity pattern used by PixiJS components (load/update/draw/dispose lifecycle).
 */
declare abstract class TimelineEntity {
    readonly element: HTMLElement;
    protected children: TimelineEntity[];
    constructor(tagName?: keyof HTMLElementTagNameMap, className?: string);
    /** Initialize the component and its children */
    abstract load(): Promise<void>;
    /** Update component state (called each frame during active rendering) */
    abstract update(deltaTime: number, elapsed: number): void;
    /** Render/draw component to DOM (called each frame after update) */
    abstract draw(): void;
    /** Clean up resources and remove from DOM */
    abstract dispose(): void;
    /** Add a child entity */
    protected addChild(child: TimelineEntity): void;
    /** Remove a child entity */
    protected removeChild(child: TimelineEntity): void;
    /** Remove all children */
    protected removeAllChildren(): void;
    /** Load all children */
    protected loadChildren(): Promise<void>;
    /** Update all children */
    protected updateChildren(deltaTime: number, elapsed: number): void;
    /** Draw all children */
    protected drawChildren(): void;
    /** Dispose all children */
    protected disposeChildren(): void;
}

/** Feature toggles for Timeline */
export declare interface TimelineFeatures {
    /** Show toolbar with playback controls */
    toolbar?: boolean;
    /** Show time ruler */
    ruler?: boolean;
    /** Show playhead indicator */
    playhead?: boolean;
    /** Enable snap-to-grid/clips */
    snap?: boolean;
    /** Show timing intent badges on clips */
    badges?: boolean;
    /** Enable multi-select with shift/ctrl+click */
    multiSelect?: boolean;
}

/** Interaction configuration */
declare interface TimelineInteractionConfig {
    /** Minimum pixels to move before starting drag */
    dragThreshold?: number;
    /** Snap distance in pixels */
    snapThreshold?: number;
    /** Width of resize zone at clip edges */
    resizeZone?: number;
    /** Callback to request timeline re-render */
    onRequestRender?: () => void;
}

/** Configuration options for Timeline */
export declare interface TimelineOptions {
    /** Feature toggles */
    features?: TimelineFeatures;
    /** Interaction configuration */
    interaction?: TimelineInteractionConfig;
    /** Initial pixels per second (zoom level) */
    pixelsPerSecond?: number;
    /** Track height in pixels */
    trackHeight?: number;
}

export { TimelineSchema }

export declare interface TimelineTheme {
    timeline: {
        background: number;
        divider: number;
        toolbar: {
            background: number;
            surface: number;
            hover: number;
            active: number;
            divider: number;
            icon: number;
            text: number;
            height: number;
        };
        ruler: {
            background: number;
            text: number;
            markers: number;
            height: number;
        };
        tracks: {
            surface: number;
            surfaceAlt: number;
            border: number;
            height: number;
        };
        clips: {
            video: number;
            audio: number;
            image: number;
            text: number;
            "rich-text": number;
            shape: number;
            html: number;
            luma: number;
            default: number;
            selected: number;
            radius: number;
        };
        playhead: number;
        snapGuide: number;
        dropZone: number;
        trackInsertion: number;
    };
}

export declare interface TimelineThemeInput {
    timeline: {
        background: string;
        divider: string;
        toolbar: {
            background: string;
            surface: string;
            hover: string;
            active: string;
            divider: string;
            icon: string;
            text: string;
            height?: number;
        };
        ruler: {
            background: string;
            text: string;
            markers: string;
            height?: number;
        };
        tracks: {
            surface: string;
            surfaceAlt: string;
            border: string;
            height?: number;
        };
        clips: {
            video: string;
            audio: string;
            image: string;
            text: string;
            shape: string;
            html: string;
            luma: string;
            default: string;
            selected: string;
            radius?: number;
        };
        playhead: string;
        snapGuide: string;
        dropZone: string;
        trackInsertion: string;
    };
}

/**
 * Stores the original timing intent as specified by the user.
 * This is preserved even after resolution to numeric values.
 * All numeric values are in seconds.
 */
declare interface TimingIntent {
    start: Seconds | "auto";
    length: TimingValue;
}

/**
 * Command parameters for timing updates.
 * Values in milliseconds (for UI convenience).
 */
declare interface TimingUpdateParams {
    start?: number | "auto";
    length?: number | "auto" | "end";
}

/**
 * A timing value can be a numeric value (in seconds) or a special string.
 * - "auto" for start: position after previous clip on track
 * - "auto" for length: asset's intrinsic duration
 * - "end" for length: extend to timeline end
 */
declare type TimingValue = Seconds | "auto" | "end";

export declare type TitleAsset = components["schemas"]["TitleAsset"];

/**
 * Configuration for a toolbar button.
 */
export declare interface ToolbarButtonConfig {
    /** Unique identifier for the button (used in event names) */
    id: string;
    /** SVG icon markup */
    icon: string;
    /** Tooltip text shown on hover */
    tooltip: string;
    /** Whether to show a divider before this button */
    dividerBefore?: boolean;
}

declare interface ToolbarButtonConfig_2 {
    id: string;
    icon: string;
    tooltip: string;
    event: string;
    dividerBefore?: boolean;
}

export declare type Track = components["schemas"]["Track"];

export { TrackSchema }

export declare class TranscriptionIndicator extends Entity {
    private background;
    private spinner;
    private statusText;
    private spinnerAngle;
    private isVisible;
    private currentMessage;
    load(): Promise<void>;
    show(message: string): void;
    hide(): void;
    getIsVisible(): boolean;
    update(deltaTime: number, _elapsed: number): void;
    draw(): void;
    private redraw;
    setPosition(x: number, y: number): void;
    getWidth(): number;
    dispose(): void;
}

export declare type Transformation = components["schemas"]["Transformation"];

export { TransformationSchema }

export declare type Transition = components["schemas"]["Transition"];

export { TransitionSchema }

export declare type Tween = components["schemas"]["Tween"];

export { tweenSchema as KeyframeSchema }
export { tweenSchema as TweenSchema }

/**
 * Controller for managing UI elements (toolbars, utilities) separately from Canvas.
 *
 * This enables:
 * - Pure preview mode (Canvas without UI)
 * - Custom toolbar registration
 * - Optional UI element loading
 *
 * @example
 * ```typescript
 * // Standard setup with all toolbars
 * const ui = UIController.create(edit, canvas, { mergeFields: true });
 *
 * // Minimal setup for custom toolbars
 * const ui = UIController.minimal(edit, canvas);
 * ui.registerToolbar('text', new CustomTextToolbar(edit));
 * ```
 */
export declare class UIController {
    private toolbars;
    private utilities;
    private canvasOverlays;
    private container;
    private canvas;
    private isDisposed;
    /** Whether merge fields UI is enabled (Variables panel, autocomplete) */
    readonly mergeFieldsEnabled: boolean;
    /** Whether selection handles are enabled for drag/resize/rotate */
    private readonly selectionHandlesEnabled;
    private clipToolbar;
    private toolbarMode;
    private currentAssetType;
    private currentTrackIndex;
    private currentClipIndex;
    private onKeyDownBound;
    private buttonRegistry;
    private buttonEvents;
    private assetToolbar;
    private canvasToolbar;
    /**
     * Create a UIController with all standard toolbars pre-registered.
     * This is the recommended way to create a UIController for most use cases.
     *
     * @param edit - The Edit instance
     * @param canvas - The Canvas instance
     * @param options - Configuration options
     * @returns A fully configured UIController
     *
     * @example
     * ```typescript
     * const ui = UIController.create(edit, canvas, { mergeFields: true });
     * ui.registerButton({ id: "text", icon: "...", tooltip: "Add Text" });
     * ui.on("button:text", ({ position }) => { ... });
     * ```
     */
    static create(edit: Edit, canvas: Canvas, options?: UIControllerOptions): UIController;
    /**
     * Create a minimal UIController without pre-registered toolbars.
     * Use this when you want full control over which toolbars are registered.
     *
     * @param edit - The Edit instance
     * @param canvas - Optional Canvas instance
     * @returns A minimal UIController ready for custom configuration
     *
     * @example
     * ```typescript
     * const ui = UIController.minimal(edit, canvas);
     * ui.registerToolbar('text', new CustomTextToolbar(edit));
     * ui.registerToolbar('video', new CustomVideoToolbar(edit));
     * ```
     */
    static minimal(edit: Edit, canvas?: Canvas): UIController;
    /**
     * Private constructor - use UIController.create() or UIController.minimal() instead.
     */
    private constructor();
    private readonly edit;
    /**
     * Subscribe to edit events. Called by factory methods.
     */
    private subscribeToEvents;
    /**
     * Register all standard toolbars. Called by create() factory.
     */
    private registerStandardToolbars;
    /**
     * Register a toolbar for one or more asset types.
     * When a clip of that type is selected, the toolbar will be shown.
     *
     * @param assetTypes - Single type or array of types (e.g., 'text', ['video', 'image'])
     * @param toolbar - The toolbar component implementing UIRegistration
     * @returns this (for chaining)
     */
    registerToolbar(assetTypes: string | string[], toolbar: UIRegistration): this;
    /**
     * Register a utility component (Inspector, TranscriptionIndicator, etc.).
     * Utilities are mounted but not tied to clip selection.
     *
     * @param component - The utility component implementing UIRegistration
     * @returns this (for chaining)
     */
    registerUtility(component: UIRegistration): this;
    /**
     * Register a PixiJS-based canvas overlay (SelectionHandles, AlignmentGuides, etc.).
     * Overlays render on the canvas and receive update/draw calls each frame.
     *
     * @param overlay - The overlay component implementing CanvasOverlayRegistration
     * @returns this (for chaining)
     */
    registerCanvasOverlay(overlay: CanvasOverlayRegistration): this;
    /**
     * Mount all registered UI components to a container.
     * Should be called after all registrations are complete.
     *
     * @param container - The DOM element to mount UI components into
     */
    mount(container: HTMLElement): void;
    /**
     * Update all canvas overlays. Called by Canvas each tick.
     */
    updateOverlays(deltaTime: number, elapsed: number): void;
    /**
     * Update toolbar positions to be adjacent to the canvas content.
     * Uses position: fixed with screen coordinates for complete independence from parent CSS.
     * Called by Canvas after zoom, pan, or resize operations.
     */
    updateToolbarPositions(): void;
    /**
     * Dispose all registered UI components and clean up event listeners.
     */
    dispose(): void;
    /**
     * Get the toolbar registered for a specific asset type.
     */
    getToolbar(assetType: string): UIRegistration | undefined;
    /**
     * Check if a toolbar is registered for an asset type.
     */
    hasToolbar(assetType: string): boolean;
    /**
     * Register a toolbar button.
     * Buttons appear in the left toolbar and trigger events when clicked.
     *
     * @example
     * ```typescript
     * ui.registerButton({
     *   id: "text",
     *   icon: `<svg>...</svg>`,
     *   tooltip: "Add Text"
     * });
     *
     * ui.on("button:text", ({ position }) => {
     *   edit.addTrack(0, { clips: [{ ... }] });
     * });
     * ```
     *
     * @param config - Button configuration
     * @returns this (for chaining)
     */
    registerButton(config: ToolbarButtonConfig): this;
    /**
     * Unregister a toolbar button.
     *
     * @param id - Button ID to remove
     * @returns this (for chaining)
     */
    unregisterButton(id: string): this;
    /**
     * Get all registered toolbar buttons.
     */
    getButtons(): ToolbarButtonConfig[];
    /**
     * Subscribe to a button click event.
     *
     * @example
     * ```typescript
     * ui.on("button:text", ({ position, selectedClip }) => {
     *   console.log("Text button clicked at position:", position);
     * });
     * ```
     *
     * @param event - Event name in format `button:${buttonId}`
     * @param handler - Callback function
     * @returns Unsubscribe function
     */
    on<K extends `button:${string}`>(event: K, handler: (payload: ButtonClickPayload) => void): () => void;
    /**
     * Unsubscribe from a button click event.
     */
    off<K extends `button:${string}`>(event: K, handler: (payload: ButtonClickPayload) => void): void;
    /**
     * Set the toolbar mode and update visibility accordingly.
     * @param mode - "asset" shows asset-specific toolbar, "clip" shows ClipToolbar
     */
    private setToolbarMode;
    /**
     * Hide all registered toolbars.
     */
    private hideAllToolbars;
    /**
     * Update toolbar visibility based on current mode and selection.
     */
    private updateToolbarVisibility;
    /**
     * Check if any toolbar is currently visible (clip is selected).
     */
    private hasVisibleToolbar;
    /**
     * Check if an input element is focused (to avoid intercepting typing).
     */
    private isInputFocused;
    /**
     * Handle backtick (`) key to toggle between asset and clip mode.
     * Backtick is the video editor convention for mode/view toggling (Premiere, After Effects).
     */
    private onKeyDown;
    private onClipSelected;
    private onSelectionCleared;
}

/**
 * Options for UIController configuration.
 */
export declare interface UIControllerOptions {
    /** Enable selection handles for drag/resize/rotate interactions. Default: true */
    selectionHandles?: boolean;
    /** Enable merge fields UI (Variables panel, autocomplete). Default: false (vanilla video editor) */
    mergeFields?: boolean;
}

/**
 * Interface for HTML/DOM UI components that can be registered with UIController.
 * Toolbars, inspectors, and other UI elements should implement this interface.
 */
export declare interface UIRegistration {
    /** Mount the component to a parent container */
    mount(container: HTMLElement): void;
    /** Show the component for a specific clip (optional - utilities may not need this) */
    show?(trackIndex: number, clipIndex: number): void;
    /** Hide the component */
    hide?(): void;
    /** Clean up resources */
    dispose(): void;
}

declare type Vector = {
    x: number;
    y: number;
};

export declare const VERSION: string;

export declare type VideoAsset = components["schemas"]["VideoAsset"];

export { VideoAssetSchema }

export declare class VideoExporter {
    private readonly edit;
    private readonly canvas;
    private readonly app;
    private isExporting;
    private videoProcessor;
    private audioProcessor;
    private progressUI;
    private exportCommand;
    constructor(edit: Edit, canvas: Canvas);
    export(filename?: string, fps?: number): Promise<void>;
    private processFrames;
    private handleKeyDown;
    dispose(): void;
    private prepareConfig;
    private saveEditState;
    private restoreEditState;
    private isVideoPlayer;
    private waitForPendingTranscriptions;
}

export { }
