type SkuData = {
    category?: AssetCategory;
    arUrl?: string;
    arEnvUrl?: string;
    arDiamondEnvUrl?: string;
    arToneMapping?: ToneMapping;
    arToneMappingExposure?: number;
    arBloomEnabled?: boolean;
    arBloomStrength?: number;
    arBloomRadius?: number;
    arBloomThreshold?: number;
    arKey?: string;
    arPromptEnabled?: boolean;
    arPromptText?: string;
    arPromptImage?: string;
    previewUrl?: string;
    previewEnvUrl?: string;
    previewDiamondEnvUrl?: string;
    previewToneMapping?: ToneMapping;
    previewToneMappingExposure?: number;
    previewBloomEnabled?: boolean;
    previewBloomStrength?: number;
    previewBloomRadius?: number;
    previewBloomThreshold?: number;
    previewPosterUrl?: string;
    cameraErrorText?: string;
    qrPromptText?: string;
};
declare const ASSET_CATEGORIES: readonly ["Glasses", "Shoes", "Watches", "Bracelets", "Handbags", "Rings", "Bottles", "Scarves", "Hats", "Necklaces", "Earrings"];
type AssetCategory = typeof ASSET_CATEGORIES[number];
declare const TONE_MAPPINGS: readonly ["ACES", "Linear", "Neutral"];
type ToneMapping = typeof TONE_MAPPINGS[number];

declare const strings_: {
    'loading.ar': string;
    'prompt.ar.shoes': string | undefined;
    'prompt.ar.glasses': string | undefined;
    'prompt.ar.watches': string | undefined;
    'prompt.ar.bracelets': string | undefined;
    'prompt.ar.scarves': string | undefined;
    'prompt.ar.hats': string | undefined;
    'prompt.ar.necklaces': string | undefined;
};
type Strings = typeof strings_;

/**
 * Truescale output measurements
 */
type FaceMeasurement = {
    /**
     * Face width in millimeters.
     */
    faceWidth: number;
    /**
     * Interpupillary distance in millimeters.
     */
    IPD: number;
};
/**
 * Type that wraps face position and orientation.
 */
type FacePose = {
    /**
     * Face position in uncalibrated 3D space.
     */
    translation: number[];
    /**
     * Face rotation represented as Tait-Bryan angles (nautical angles).
     *
     * Sequence of fields in this array is yaw, pitch, roll (heading, elevation, bank).
     */
    rotation: number[];
};
/**
 * Plugin controller.
 */
type Plugin = {
    /**
     * Launches the AR view.
     * Set to `undefined` if AR is not supported for given SKU.
     *
     * @returns A promise that resolves when AR is launched.
     */
    launchAR?: () => Promise<void>;
    /**
     * Launches the 3D view.
     * Set to `undefined` if 3D is not supported for given SKU.
     *
     * @returns A promise that resolves when 3D is launched.
     */
    launch3D?: () => Promise<void>;
    /**
     * Closes the AR view.
     * Set to `undefined` if AR is not supported for given SKU.
     *
     * @returns A promise that resolves when AR is closed.
     */
    closeAR?: () => Promise<void>;
    /**
     * Closes the 3D view.
     * Set to `undefined` if 3D is not supported for given SKU.
     *
     * @returns A promise that resolves when 3D is closed.
     */
    close3D?: () => Promise<void>;
    /**
     * Closes the AR or 3D view.
     * Set to `undefined` if neither AR nor 3D are supported for given SKU.
     *
     * @returns A promise that resolves when AR or 3D is closed.
     */
    close?: () => Promise<void>;
    /**
     * Returns the current user interactivity value.
     *
     * @returns `true` is user interactivity is enabled and `false` otherwise.
     */
    isInteractive: () => boolean;
    /**
     * Sets user interactivity to the provided value. Set to `false` to ignore input events.
     *
     * @param value The provided value.
     */
    setInteractive: (interactive: boolean) => void;
    /**
     * Zooms the 3D view in.
     * The magnification is multiplied by `2^power`, so a power of 1 doubles the magnification.
     * Has no effect if the 3D view is not currently active.
     * Set to `undefined` if 3D is not supported for given SKU.
     *
     * @param power The exponent applied to the zoom. Each unit doubles the magnification.
     */
    zoomIn3D?: (power: number) => void;
    /**
     * Zooms the 3D view out.
     * The magnification is divided by `2^power`, so a power of 1 halves the magnification.
     * Has no effect if the 3D view is not currently active.
     * Set to `undefined` if 3D is not supported for given SKU.
     *
     * @param power The exponent applied to the zoom. Each unit halves the magnification.
     */
    zoomOut3D?: (power: number) => void;
    /**
     * Rotates the 3D model horizontally by the specified number of degrees.
     * The initial animation is stopped on the first call.
     * Has no effect if the 3D view is not currently active.
     * Set to `undefined` if 3D is not supported for given SKU.
     *
     * @param degrees The rotation angle in degrees. Positive values rotate the model right, negative values rotate left.
     */
    rotateHorizontally3D?: (degrees: number) => void;
    /**
     * Rotates the 3D model vertically by the specified number of degrees.
     * The initial animation is stopped on the first call.
     * Has no effect if the 3D view is not currently active.
     * Set to `undefined` if 3D is not supported for given SKU.
     *
     * @param degrees The rotation angle in degrees. Positive values rotate the model up, negative values rotate down.
     */
    rotateVertically3D?: (degrees: number) => void;
};
/**
 * Vision plugin controller
 */
type VisionPlugin = {
    /**
     * Register a face pose callback which will be called if face is detected.
     */
    registerFacePoseListener?: (facePoseListener: (facePose: FacePose) => void) => void;
    /**
     * Register a face measurement callback which will be called if face is detected.
     */
    registerFaceMeasurementListener?: (faceMeasurementListener: (faceMeasurement: FaceMeasurement) => void) => void;
    /**
     * Switch the AR effect for preview
     *
     * This call is a thin wrapper around DeepAR.switchEffect API.
     *
     * @param arUrl A path to the AR effect file
     * @returns Promise that resolves when an effect start rendering
     */
    switchEffect?: (arUrl: string) => Promise<void>;
    /**
     * Clear the AR effect
     *
     * Call this after switchEffect to clear the loaded effect.
     * @returns void
     */
    clearEffect?: () => void;
    /**
     * Closes the vision plugin and releases the camera.
     *
     * @returns A promise that resolves when AR is closed.
     */
    close?: () => void;
};

type ArVideoConfig = {
    video: HTMLVideoElement;
    mirror: boolean;
};

/** Preview state values. */
declare const PREVIEW_STATES: readonly ["AR", "3D"];
/** Preview state type. */
type PreviewState = typeof PREVIEW_STATES[number];
/**
 * Configuration of an animation key frame at the specified time point.
 */
type KeyFrameConfig = {
    /** Timestamp (in ms). */
    time: number;
    /** Vertical angle of rotation (in degrees). */
    pitch?: number;
    /** Horizontal angle of rotation (in degrees). */
    yaw?: number;
    /** Camera's field of view (in degrees). */
    fov?: number;
    /**
     * Easing function used for interpolating the values between this and the next key frame.
     *
     * Supported options are:
     * - `'hold'`: maintain the current value without interpolation.
     * - `'linear'`: linear interpolation.
     * - `'sine'`: sine wave interpolation.
     * - `'ease'`: starts slowly, accelerates sharply and slows gradually towards the end.
     * - `'ease-in'`: starts slowly, progressively speeds up until the end, at which point it stops abruptly.
     * - `'ease-out'`: starts abruptly and progressively slows down towards the end.
     * - `'ease-in-out'`: smooth start and end with gradual acceleration and decceleration.
     *
     * Additionally, it's possible to specify a custom Bézier function:
     * - `'cubic-bezier(x1, y1, x2, y2)'`: define two 2D points for a custom interpolation curve.
     *
     * @default 'ease-in-out'
     */
    interpolation?: string;
};
/**
 * Options used for the plugin setup.
 */
type SetupOptions = {
    /** API key found in the ShopAR dashboard. */
    apiKey: string;
    /** Product identifier. */
    sku: string;
    /**
     * If provided, the API call is skipped and this SKU data is used instead.
     */
    skuData?: SkuData;
    /**
     * The element to inflate with ShopAR UI.
     *
     * @remarks If using default UI, its CSS position property must be either 'static' or 'relative'.
     */
    targetElement: HTMLElement;
    /**
     * If provided, defines which preview type the plugin initializes to.
     */
    initialState?: PreviewState;
    /**
     * If provided, defines where the additional ShopAR plugin files are fetched from.
     *
     * @default `https://cdn.jsdelivr.net/npm/shopar-plugin@${version}/`
     */
    baseUrl?: string;
    /**
     * If provided and set to `false`, disables the default UI such as buttons, loading and error views.
     *
     * When the default UI is disabled, use the returned object as a controller:
     * ```js
     * const shopAR = await ShopAR.plugin.setup({
     *   // ...
     *   defaultUI: false,
     * });
     * shopAR.launchAR();
     * ```
     *
     * @default true
     */
    defaultUI?: boolean;
    /**
     * If provided and set to `false`, disables user interactivity by ignoring input events.
     *
     * @default true
     */
    interactive?: boolean;
    /**
     * If provided, the corresponding touch scroll behavior will be used in 3D.
     *
     * Supported values are:
     * - `none`: Touch gestures are never interpreted as scrolling. This might be useful if 3D occupies the whole viewport.
     * - `pan-x`: Touch gestures that start horizontally are interpreted as scrolling.
     * - `pan-y`: Touch gestures that start vertically are interpreted as scrolling.
     *
     * @default 'pan-y'
     */
    touchAction?: 'none' | 'pan-x' | 'pan-y';
    /**
     * If provided and set to `false`, disables zoom in 3D by ignoring mouse scroll or pinch touch events.
     *
     * @default true
     */
    zoomEnabled?: boolean;
    /**
     * If provided, it will be used as the minimum zoom level in 3D.
     *
     * @default 0.625
     */
    minZoom?: number;
    /**
     * If provided, it will be used as the maximum zoom level in 3D.
     *
     * @default 5
     */
    maxZoom?: number;
    /**
     * If provided and set to `true`, transparent background will always be used in 3D.
     *
     * This overrides the default behaviour which uses the transparent background only for models **without** transmissive materials.
     *
     * WARNING:
     * Opaque background is intentionally used for models with transmission to avoid the associated rendering issues.
     * When using this feature, please make sure that the transmissive parts of the model look as desired.
     *
     * @default false
     */
    alwaysTransparentBackground?: boolean;
    strings?: Partial<Strings>;
    /**
     * If provided, replaces the default interactivity animation in 3D with a custom one.
     *
     * Two formats are supported: `KeyFrameConfig[]` and `string`.
     * For more information on the `KeyFrameConfig[]` format, see {@link KeyFrameConfig}.
     *
     * The `string` format is interpreted as a plain-text table. Empty lines and comments are ignored.
     * First line defines the columns and all subsequent lines define data per key frame.
     *
     * Supported columns are:
     * - `time`: timestamp of the key frame.
     * - `pitch`: vertical angle of rotation.
     * - `yaw`: horizontal angle of rotation.
     * - `fov`: camera's field of view.
     * - `interpolation`: easing function used for interpolating the values between this and the next key frame.
     * See {@link KeyFrameConfig.interpolation} for supported options.
     *
     * Timestamps are specified with or without a unit (`ms` or `s`). When not specified, milliseconds are used.
     *
     * Angles are specified with or without a unit (`deg` or `rad`). When not specified, degrees are used.
     *
     * @example
     * `
     * # Empty lines and comments are ignored.
     *
     * time pitch yaw    fov   interpolation
     * 0s   45deg 60deg  25deg hold
     * 1s   45deg 60deg  25deg ease-in-out
     * 2s   60deg -60deg 20deg hold
     * 3s   60deg -60deg 20deg ease-in-out
     * 4s   90deg 90deg  40deg hold
     * 5s   90deg 90deg  40deg ease-in-out
     * 6s   45deg 420deg 25deg hold
     * `
     *
     * @example
     * [
     *   { time: 0,    pitch: 45, yaw: 60,  fov: 25, interpolation: 'hold' },
     *   { time: 1000, pitch: 45, yaw: 60,  fov: 25, interpolation: 'ease-in-out' },
     *   { time: 2000, pitch: 60, yaw: -60, fov: 20, interpolation: 'hold' },
     *   { time: 3000, pitch: 60, yaw: -60, fov: 20, interpolation: 'ease-in-out' },
     *   { time: 4000, pitch: 90, yaw: 90,  fov: 40, interpolation: 'hold' },
     *   { time: 5000, pitch: 90, yaw: 90,  fov: 40, interpolation: 'ease-in-out' },
     *   { time: 6000, pitch: 45, yaw: 420, fov: 25, interpolation: 'hold' },
     * ]
     */
    initialAnimation?: KeyFrameConfig[] | string;
    /**
     * If provided, it will be called the first time the user's subject is detected in AR (e.g. face, feet, wrist).
     * It fires only once per setup.
     */
    onFirstAREngagement?: () => void;
    /**
     * If provided, it will be called the first time the user engages with the 3D view (rotate, pan or zoom).
     * It fires only once per setup.
     */
    onFirst3DEngagement?: () => void;
    /**
     * If provided, it will be used as the debounce duration for debounced AR engagement tracking.
     *
     * @default 2000
     * @see onDebouncedAREngagement
     */
    debounceAREngagementMs?: number;
    /**
     * If provided, it will get called with the engagement duration on every (debounced) AR engagement.
     *
     * AR engagement is measured as the time spent by the user virtually trying out the product in AR.
     * The callback is called after engagement stops for the specified debounce duration.
     * Additionally, any outstanding engagement duration is flushed when AR is closed.
     *
     * @param durationMs Engagement duration in milliseconds.
     * @see debounceAREngagementMs
     */
    onDebouncedAREngagement?: (durationMs: number) => void;
    /**
     * If provided, it will be used as the debounce duration for debounced 3D engagement tracking.
     *
     * @default 2000
     * @see onDebounced3DEngagement
     */
    debounce3DEngagementMs?: number;
    /**
     * If provided, it will be called with the engagement duration on every (debounced) 3D engagement.
     *
     * 3D engagement is measured as the time spent by the user rotating, panning or zooming the product in 3D.
     * The callback is called after engagement stops for the specified debounce duration.
     * Additionally, any outstanding engagement duration is flushed when 3D is closed.
     *
     * @param durationMs Engagement duration in milliseconds.
     * @see debounce3DEngagementMs
     */
    onDebounced3DEngagement?: (durationMs: number) => void;
    /**
     * If provided, it will be called when the maximum zoom level (`maxZoom`) is reached in 3D.
     */
    onMaxZoomEnter?: () => void;
    /**
     * If provided, it will be called when the zoom level moves away from the maximum (`maxZoom`) in 3D.
     */
    onMaxZoomLeave?: () => void;
    /**
     * If provided, it will be called when the minimum zoom level (`minZoom`) is reached in 3D.
     */
    onMinZoomEnter?: () => void;
    /**
     * If provided, it will be called when the zoom level moves away from the minimum (`minZoom`) in 3D.
     */
    onMinZoomLeave?: () => void;
    /**
     * If provided, it will be called when the minimum vertical angle is reached in 3D.
     * This corresponds to the camera being positioned at the top of the orbit, looking down at the object.
     */
    onMinVerticalAngleEnter?: () => void;
    /**
     * If provided, it will be called when the vertical angle moves away from the minimum in 3D.
     * The camera is no longer at the top of the orbit.
     */
    onMinVerticalAngleLeave?: () => void;
    /**
     * If provided, it will be called when the maximum vertical angle is reached in 3D.
     * This corresponds to the camera being positioned at the bottom of the orbit, looking up at the object.
     */
    onMaxVerticalAngleEnter?: () => void;
    /**
     * If provided, it will be called when the vertical angle moves away from the maximum in 3D.
     * The camera is no longer at the bottom of the orbit.
     */
    onMaxVerticalAngleLeave?: () => void;
    /**
     * If provided, it will be used as the video source for AR instead of the default camera used by plugin.
     *
     * Example of loading HTMLVideoElement:
     * ```js
     * function loadVideo(src) {
     *   const video = document.createElement('video');
     *   video.src = src;
     *   video.muted = true;
     *   video.setAttribute("playsinline", "playsinline");
     *   video.load();
     *   video.onloadedmetadata = () => {
     *     video.play();
     *   };
     *
     *   return video;
     * }
     * ```
     */
    customArVideo?: ArVideoConfig;
    /**
     * If provided, it will be used as the true scale face width, in millimeters, for AR glasses.
     *
     * If not provided, the value is determined by ShopAR True Scale technology.
     */
    customTrueScaleFaceWidth?: number;
    _internalOptions?: any;
};
/**
 * Options used for the vision plugin setup.
 */
type VisionOptions = {
    /** API key found in the ShopAR dashboard. */
    apiKey: string;
    /**
     * The element to inflate with camera canvas.
     */
    targetElement: HTMLElement;
    /**
     * If provided, defines where the additional ShopAR plugin files are fetched from.
     *
     * @default `https://cdn.jsdelivr.net/npm/shopar-plugin@${version}/`
     */
    baseUrl?: string;
};

/**
 * Base error class for all ShopAR plugin errors.
 */
declare class PluginError extends Error {
    constructor(message: string);
}
/**
 * Error thrown when setup or option validation fails.
 */
declare class ValidationError extends PluginError {
    constructor(message: string);
}
/**
 * Error thrown when the ShopAR API call fails.
 */
declare class ApiError extends PluginError {
    status: number | undefined;
    constructor(message: string, status?: number);
}
/**
 * Error thrown when SKU data sanitization fails.
 */
declare class SanitizationError extends PluginError {
    constructor(message: string);
}
/**
 * Error thrown when 3D fails to launch.
 */
declare class Launch3DError extends PluginError {
    constructor(message?: string);
}
/**
 * Error thrown when AR fails to launch.
 */
declare class LaunchARError extends PluginError {
    constructor(message?: string);
}
/**
 * Error thrown when the user denies camera permissions.
 */
declare class CameraPermissionDeniedError extends LaunchARError {
    constructor(message?: string);
}
/**
 * Error thrown when QR code launch fails.
 */
declare class QRError extends LaunchARError {
    constructor(message?: string);
}

/**
 * ShopAR vision plugin.
 *
 * @example
 * Using CDN:
 * ```html
 * <script src="../../shopar-plugin/shopar-plugin.js"></script>
 * <script>
 *   const vision = ShopAR.vision.setup({ ... });
 * </script>
 * ```
 *
 * @example
 * Using a module bundler:
 * ```js
 * import { ShopAR } from 'shopar-plugin';
 *
 * const vision = ShopAR.vision.setup({ ... });
 * ```
 */
declare const vision: {
    /**
     * Initializes vision modules and renderes deepar canvas.
     *
     * If successful, function returns a handle to the VisionPlugin. This component alows for lower level control
     * over DeepAR and truescale components.
     *
     * @param options Setup options.
     */
    setup: (options: VisionOptions) => Promise<VisionPlugin>;
};
/**
 * The ShopAR plugin.
 *
 * @example
 * Using CDN:
 * ```html
 * <script src="../../shopar-plugin/shopar-plugin.js"></script>
 * <script>
 *   ShopAR.plugin.setup({ ... });
 * </script>
 * ```
 *
 * @example
 * Using a module bundler:
 * ```js
 * import { ShopAR } from 'shopar-plugin';
 *
 * ShopAR.plugin.setup({ ... });
 * ```
 */
declare const plugin: {
    /**
     * Fetches the specified product from the ShopAR API and renders the ShopAR UI.
     *
     * Optionally, you can provide a `skuData` object to bypass the API call and use the provided SKU data directly.
     *
     * @param options Setup options.
     */
    setup: (options: SetupOptions) => Promise<Plugin>;
    /** Plugin version. */
    version: string;
};

export { ApiError, CameraPermissionDeniedError, Launch3DError, LaunchARError, PREVIEW_STATES, PluginError, QRError, SanitizationError, ValidationError, plugin, vision };
export type { ArVideoConfig, FaceMeasurement, FacePose, KeyFrameConfig, Plugin, PreviewState, SetupOptions, SkuData, VisionOptions, VisionPlugin };
