# Generated public API

Generated from the public exports and TypeScript declarations. Relative imports retain their original context. The standalone script also exposes the THREE namespace.

| Export | Kind | Entry points |
| --- | --- | --- |
| `ARAnimationOptions` | Type | `webar-facil` |
| `ARComponentsOptions` | Type | `webar-facil` |
| `ARDiagnostics` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `AREventMap` | Type | `webar-facil/core`, `webar-facil` |
| `ARModelElement` | Type | `webar-facil` |
| `ARModelLoadOptions` | Type | `webar-facil` |
| `ARModelOptions` | Type | `webar-facil` |
| `ARPose` | Type | `webar-facil/core`, `webar-facil` |
| `ARSceneElement` | Type | `webar-facil` |
| `ARSceneOptions` | Type | `webar-facil` |
| `ARVideoElement` | Type | `webar-facil` |
| `ARVideoOptions` | Type | `webar-facil` |
| `CalibrationReport` | Type | `webar-facil/core`, `webar-facil` |
| `CalibrationSession` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `CameraFrame` | Type | `webar-facil/core`, `webar-facil` |
| `CameraIntrinsics` | Type | `webar-facil/core`, `webar-facil` |
| `CameraManager` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `CameraManagerOptions` | Type | `webar-facil/core`, `webar-facil` |
| `CameraMetrics` | Type | `webar-facil/core`, `webar-facil` |
| `ChromaKeyOptions` | Type | `webar-facil` |
| `CompilerOptions` | Type | `webar-facil/core`, `webar-facil` |
| `DEVICE_TEST_PROTOCOL` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `DeviceTestCase` | Type | `webar-facil/core`, `webar-facil` |
| `DeviceTestResult` | Type | `webar-facil/core`, `webar-facil` |
| `DiagnosticConfiguration` | Type | `webar-facil/core`, `webar-facil` |
| `DiagnosticContext` | Type | `webar-facil/core`, `webar-facil` |
| `DiagnosticOptions` | Type | `webar-facil/core`, `webar-facil` |
| `DiagnosticRendererMetrics` | Type | `webar-facil/core`, `webar-facil` |
| `DiagnosticReport` | Type | `webar-facil/core`, `webar-facil` |
| `DiagnosticStats` | Type | `webar-facil/core`, `webar-facil` |
| `EngineOptions` | Type | `webar-facil/core`, `webar-facil` |
| `EngineState` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `ExperimentalMetricScale` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `FrameQuality` | Type | `webar-facil/core`, `webar-facil` |
| `ImageCompiler` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `ImageObservation` | Type | `webar-facil/core`, `webar-facil` |
| `ImageTargetMetadata` | Type | `webar-facil/core`, `webar-facil` |
| `ImageTargetOptions` | Type | `webar-facil/core`, `webar-facil` |
| `ImageTargetResult` | Type | `webar-facil/core`, `webar-facil` |
| `ImageTrackingProfile` | Type | `webar-facil/core`, `webar-facil` |
| `LIBRARY_BUILD` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `LIBRARY_VERSION` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `MarkerCompiler` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `MarkerFeatures` | Type | `webar-facil/core`, `webar-facil` |
| `MarkerQuality` | Type | `webar-facil/core`, `webar-facil` |
| `MetricScaleDiagnostics` | Type | `webar-facil/core`, `webar-facil` |
| `OdometryBackend` | Type | `webar-facil/core`, `webar-facil` |
| `OdometryConfig` | Type | `webar-facil/core`, `webar-facil` |
| `OdometryEstimate` | Type | `webar-facil/core`, `webar-facil` |
| `OdometryMapSnapshot` | Type | `webar-facil/core`, `webar-facil` |
| `OdometryModule` | Type | `webar-facil/core`, `webar-facil` |
| `OdometryScanHint` | Type | `webar-facil/core`, `webar-facil` |
| `OpticalFlowOptions` | Type | `webar-facil/core`, `webar-facil` |
| `OpticalFlowSLAM` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `PlacementState` | Type | `webar-facil` |
| `projectionFromIntrinsics` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `registerAFrameComponent` | Value and/or type | `webar-facil` |
| `registerAFrameModelComponent` | Value and/or type | `webar-facil` |
| `registerAFrameVideoComponent` | Value and/or type | `webar-facil` |
| `registerARComponents` | Value and/or type | `webar-facil` |
| `rotateIntrinsics` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `scaleIntrinsics` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `SLAMManager` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `SLAMMapSnapshot` | Type | `webar-facil/core`, `webar-facil` |
| `SLAMOptions` | Type | `webar-facil/core`, `webar-facil` |
| `SurfaceTransitionOptions` | Type | `webar-facil/core`, `webar-facil` |
| `SurfaceTransitionResult` | Type | `webar-facil/core`, `webar-facil` |
| `TargetFoundEvent` | Type | `webar-facil/core`, `webar-facil` |
| `TargetLostEvent` | Type | `webar-facil/core`, `webar-facil` |
| `TargetVisibilityEvent` | Type | `webar-facil/core`, `webar-facil` |
| `ThreeARGroup` | Value and/or type | `webar-facil` |
| `ThreeARModel` | Value and/or type | `webar-facil` |
| `ThreeARScene` | Value and/or type | `webar-facil` |
| `ThreeARVideo` | Value and/or type | `webar-facil` |
| `ThreeCameraBackground` | Value and/or type | `webar-facil` |
| `Tracker` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `TrackerOptions` | Type | `webar-facil/core`, `webar-facil` |
| `TrackingIssue` | Type | `webar-facil/core`, `webar-facil` |
| `TrackingQualityEvent` | Type | `webar-facil/core`, `webar-facil` |
| `TrackingResult` | Type | `webar-facil/core`, `webar-facil` |
| `validateIntrinsics` | Value and/or type | `webar-facil/core`, `webar-facil` |
| `VisualReferenceResult` | Type | `webar-facil/core`, `webar-facil` |
| `WebAREngine` | Value and/or type | `webar-facil/core`, `webar-facil` |

See [WebAREngine](api-engine.md) and [the advanced API](advanced.md) for integration guidance.

## Pose.d.ts

```ts
export interface ARPose {
    targetId?: string;
    backend: 'image' | 'webxr' | 'optical-flow';
    timestampMs: number;
    scale: 'metric' | 'relative';
    scaleSource?: 'experimental-inertial';
    matrix: Float32Array;
    worldMatrix: Float32Array;
    viewMatrix: Float32Array;
    projectionMatrix: Float32Array | null;
    projectionSource?: 'calibrated' | 'estimated' | 'webxr';
    surfaceDetected?: boolean;
    diagnostics?: {
        processingMs: number;
        inliers: number;
        reprojectionErrorPx: number;
        relocalized?: boolean;
        keyframeCorrected?: boolean;
    };
}
export interface CameraIntrinsics {
    width: number;
    height: number;
    fx: number;
    fy: number;
    cx: number;
    cy: number;
    distortion?: readonly number[];
}
```

## WebAREngine.d.ts

```ts
import { type CameraManagerOptions, type CameraMetrics } from './camera/CameraManager.js';
import { type TrackerOptions } from './tracking/Tracker.js';
import { type MarkerQuality } from './tracking/ImageCompiler.js';
import { type OpticalFlowOptions } from './slam/OpticalFlowSLAM.js';
import type { ExperimentalMetricScale } from './slam/ExperimentalMetricScale.js';
import type { ARPose, CameraIntrinsics } from './Pose.js';
import type { OdometryMapSnapshot, VisualReferenceResult } from './slam/OdometryBackend.js';
import type { AREventMap } from './tracking/events.js';
export declare enum EngineState {
    Idle = "Idle",
    Camera = "Camera",
    TrackingImage = "TrackingImage",
    TrackingSurface = "TrackingSurface",
    Disposed = "Disposed"
}
export interface EngineOptions {
    experimentalMetricScale?: ExperimentalMetricScale;
    keyframeCorrection?: boolean;
    imageLossGraceMs?: number;
    keepContentOnLost?: boolean;
    imageSmoothingMs?: number;
    camera?: Omit<CameraManagerOptions, 'onFrame' | 'onError'>;
    tracker?: TrackerOptions;
    opencvURL?: string | URL;
    calibration?: CameraIntrinsics;
    fallback?: OpticalFlowOptions | false;
    attachXRSession?: (session: XRSession) => Promise<void>;
    getXRContext?: () => WebGL2RenderingContext;
    overlayRoot?: HTMLElement;
}
export interface ImageTargetOptions {
    physicalWidthMeters?: number;
    maxDimension?: number;
}
export interface ImageTargetMetadata {
    format: 'WART';
    version: 2;
    width: number;
    height: number;
    physicalWidthMeters: number;
    extractorId: number;
    quality: MarkerQuality;
}
export interface ImageTargetResult {
    buffer: ArrayBuffer;
    metadata: ImageTargetMetadata;
}
export interface SurfaceTransitionOptions {
    targetId?: string;
    backend?: 'auto' | 'webxr' | 'optical-flow';
    placement?: 'auto' | 'preserve' | 'hit-test';
    initializationTimeoutMs?: number;
}
export interface SurfaceTransitionResult {
    backend: 'webxr' | 'optical-flow';
    placement: 'preserved' | 'scan-marker' | 'select-surface' | 'scan-floor';
}
export interface SLAMMapSnapshot {
    version: 1;
    map: OdometryMapSnapshot;
    anchor: Float32Array | null;
    targetId: string;
}
export declare class WebAREngine {
    constructor(options?: EngineOptions);
    get state(): EngineState;
    get videoElement(): HTMLVideoElement;
    get cameraSettings(): MediaTrackSettings | null;
    get calibration(): CameraIntrinsics | undefined;
    setFocus(mode: 'continuous' | 'manual', distance?: number): Promise<boolean>;
    onPose(fn: (matrix: Float32Array, pose: ARPose) => void): () => void;
    onStatus(fn: (message: string) => void): () => void;
    onError(fn: (error: Error) => void): () => void;
    onSurface(fn: (matrix: Float32Array) => void): () => void;
    onMetrics(fn: (metrics: CameraMetrics) => void): () => void;
    get targetIds(): readonly string[];
    on<K extends keyof AREventMap>(name: K, listener: (event: AREventMap[K]) => void): () => void;
    onTargetFound(listener: (event: AREventMap['targetFound']) => void): () => void;
    onTargetLost(listener: (event: AREventMap['targetLost']) => void): () => void;
    onTrackingQuality(listener: (event: AREventMap['trackingQuality']) => void): () => void;
    onTargetVisibility(listener: (event: AREventMap['targetVisibility']) => void): () => void;
    setKeepContentOnLost(value: boolean, targetId?: string): void;
    checkSLAMVisualReference(action: 'capture' | 'verify', id: string): Promise<VisualReferenceResult>;
    exportSLAMMap({ includeCurrentView }?: {
        includeCurrentView?: boolean;
    }): Promise<SLAMMapSnapshot>;
    importSLAMMap(snapshot: SLAMMapSnapshot): Promise<void>;
    startCamera(): Promise<void>;
    loadTarget(url: string | URL): Promise<void>;
    addTarget(id: string, url: string | URL): Promise<void>;
    loadImageTarget(source: Blob | string | URL, options?: ImageTargetOptions): Promise<ImageTargetResult>;
    addImageTarget(id: string, source: Blob | string | URL, options?: ImageTargetOptions): Promise<ImageTargetResult>;
    removeTarget(id: string): Promise<void>;
    enableSLAM(options?: SurfaceTransitionOptions): Promise<SurfaceTransitionResult>;
    stop(): Promise<void>;
    dispose(): void;
}
```

## build-info.d.ts

```ts
export declare const LIBRARY_VERSION: string;
export declare const LIBRARY_BUILD = "1c906eb944d9f8f4";
```

## calibration/CalibrationSession.d.ts

```ts
import type { CalibrationCapture, CalibrationReport } from './types.js';
export declare class CalibrationSession {
    constructor(options?: {
        workerFactory?: () => Worker;
    });
    initialize(opencvURL: string, signal?: AbortSignal): Promise<void>;
    addFrame(frame: ImageData, signal?: AbortSignal): Promise<CalibrationCapture>;
    board(): Promise<{
        data: Uint8ClampedArray;
        width: number;
        height: number;
    }>;
    solve(): Promise<CalibrationReport>;
    reset(): Promise<void>;
    dispose(): void;
}
```

## calibration/types.d.ts

```ts
import type { CameraIntrinsics } from '../Pose.js';
export interface CalibrationObservation {
    width: number;
    height: number;
    objectPoints: Float32Array;
    imagePoints: Float32Array;
}
export interface CalibrationReport {
    calibration: CameraIntrinsics;
    rmsPx: number;
    perViewErrorsPx: number[];
    views: number;
    coverage: number;
    warnings: string[];
}
export interface CalibrationCapture {
    accepted: boolean;
    corners: Float32Array;
    views: number;
    reason: string;
}
```

## camera/CameraManager.d.ts

```ts
import type { ImageTrackingProfile } from '../tracking/profile.js';
import type { TrackingQualityEvent } from '../tracking/events.js';
export interface CameraFrame {
    imageData: ImageData;
    timestampMs: number;
    mediaTimeSeconds: number;
    sessionId: number;
    sourceWidth: number;
    sourceHeight: number;
}
export interface CameraManagerOptions {
    onFrame: (frame: CameraFrame, signal: AbortSignal) => void | Promise<void>;
    onError?: (error: Error) => void;
    onStatus?: (status: 'camera-requesting' | 'camera-granted' | 'camera-playing') => void;
    playbackContainer?: HTMLElement;
    performance?: 'auto' | 'balanced' | 'battery' | 'quality';
    width?: number;
    height?: number;
    facingMode?: 'environment' | 'user';
    deviceId?: string;
    fps?: number;
    maxFrameWidth?: number;
    maxFramePixels?: number;
    focusMode?: 'continuous' | 'manual' | 'none';
    focusDistance?: number;
    adaptive?: boolean;
    minFrameWidth?: number;
    onMetrics?: (metrics: CameraMetrics) => void;
    onSuspend?: () => void;
    onResume?: () => void;
}
export interface CameraMetrics {
    tracking?: ImageTrackingProfile;
    odometry?: import('../slam/OdometryBackend.js').OdometryTimings;
    consumerMs?: number;
    processedFrames: number;
    skippedFrames: number;
    readbackMs: number;
    processingMs: number;
    averageProcessingMs: number;
    analysisWidth: number;
    targetAnalysisFPS: number;
    analysisHeight?: number;
    performance?: CameraManagerOptions['performance'];
}
export declare class CameraManager {
    constructor(options: CameraManagerOptions);
    get state(): 'idle' | 'starting' | 'running' | 'paused' | 'disposed';
    get videoElement(): HTMLVideoElement;
    get settings(): MediaTrackSettings | null;
    setAdaptiveResolution(enabled: boolean): void;
    setTrackingFeedback(qualities: readonly TrackingQualityEvent[], frameWidth?: number): void;
    setAnalysisWidth(width: number): void;
    setFocus(mode: 'continuous' | 'manual', distance?: number): Promise<boolean>;
    start(): Promise<void>;
    stop({ retainDevice }?: {
        retainDevice?: boolean;
    }): void;
    dispose(): void;
}
```

## diagnostics/ARDiagnostics.d.ts

```ts
import { TRACKING_STAGES, TRACKING_COUNTS } from '../tracking/profile.js';
import type { WebAREngine } from '../WebAREngine.js';
import type { CameraMetrics } from '../camera/CameraManager.js';
import { ODOMETRY_STAGES } from '../slam/OdometryBackend.js';
export type DeviceTestResult = 'pending' | 'pass' | 'fail' | 'not-supported';
export interface DiagnosticContext {
    platform?: 'ios' | 'android' | 'desktop' | 'other';
    execution?: 'unspecified' | 'automated' | 'physical-user-reported';
    deviceModel?: string;
    osVersion?: string;
    browserVersion?: string;
    scenario?: string;
}
export interface DiagnosticConfiguration {
    mode?: string;
    backend?: string;
    performance?: string;
    maxFramePixels?: number;
    analysisWidth?: number;
    requestedFPS?: number;
    lossGraceMs?: number;
    keepContentOnLost?: boolean;
    manualPlacement?: boolean;
    keyframeCorrection?: boolean;
    renderPixelRatio?: number;
    antialias?: boolean;
}
export interface DiagnosticOptions {
    context?: DiagnosticContext;
    configuration?: DiagnosticConfiguration;
    sampleLimit?: number;
    now?: () => number;
}
export interface DiagnosticStats {
    count: number;
    mean: number | null;
    min: number | null;
    max: number | null;
    p50: number | null;
    p95: number | null;
    quantileSamples: number;
}
export interface DiagnosticRendererMetrics {
    drawCalls: number;
    triangles: number;
    geometries: number;
    textures: number;
    drawingBufferWidth: number;
    drawingBufferHeight: number;
    pixelRatio: number;
}
export interface DiagnosticReport {
    schemaVersion: 1;
    kind: 'webar-diagnostics';
    sdk: {
        version: string;
        build: string;
    };
    createdAt: string;
    durationMs: number;
    recording: boolean;
    context: Required<DiagnosticContext>;
    configuration: DiagnosticConfiguration;
    environment: {
        userAgent: string;
        secureContext: boolean;
        cameraAPI: boolean;
        webgl2API: boolean;
        xrAPI: boolean;
        immersiveAR: boolean | null;
    };
    camera: Record<string, string | number | boolean>;
    state: string;
    targets: Record<string, {
        found: number;
        lost: number;
        ended: number;
        firstFoundMs: number | null;
        recoveriesMs: number[];
    }>;
    poses: {
        count: number;
        backends: Record<string, number>;
        scales: Record<string, number>;
        projectionSources: Record<string, number>;
        relocalized: number;
        keyframeCorrected: number;
        firstPoseMs: number | null;
    };
    quality: {
        samples: Record<string, number>;
        issues: Record<string, number>;
        diagnosis: 'heuristic';
    };
    metrics: {
        processingMs: DiagnosticStats;
        readbackMs: DiagnosticStats;
        consumerMs: DiagnosticStats;
        renderLoopMs: DiagnosticStats;
        poseStepTranslation: DiagnosticStats;
        poseStepRotationDegrees: DiagnosticStats;
        reprojectionErrorPx: DiagnosticStats;
        latestCamera: CameraMetrics | null;
    };
    odometry: {
        frames: number;
        stages: Record<typeof ODOMETRY_STAGES[number], DiagnosticStats>;
    };
    tracking: {
        frames: number;
        stages: Record<typeof TRACKING_STAGES[number], DiagnosticStats>;
        paths: Record<typeof TRACKING_COUNTS[number], number>;
    };
    renderer: {
        latest: DiagnosticRendererMetrics | null;
        peakDrawCalls: number;
        peakTriangles: number;
    };
    timeline: {
        atMs: number;
        event: string;
        detail: string;
    }[];
    observations: {
        atMs: number;
        testId: string;
        result: DeviceTestResult;
        notes: string;
    }[];
    limits: {
        sampleLimit: number;
        timelineLimit: number;
        observationLimit: number;
        quantiles: 'latest bounded samples';
        poseSteps: 'not physical jitter or drift';
        renderLoop: 'callback interval, not completed GPU frames';
        physicalValidation: 'operator-declared, not independently certified';
    };
}
type Source = Pick<WebAREngine, 'state' | 'cameraSettings' | 'targetIds' | 'onPose' | 'onStatus' | 'onError' | 'onMetrics' | 'onTargetFound' | 'onTargetLost' | 'onTrackingQuality'>;
export declare class ARDiagnostics {
    constructor(source: Source, options?: DiagnosticOptions);
    setContext(context: DiagnosticContext): void;
    mark(event: string, detail?: string): void;
    observe(testId: string, result: DeviceTestResult, notes?: string): void;
    recordError(error: Error): void;
    recordRenderer(input: DiagnosticRendererMetrics): void;
    recordRenderFrame(): void;
    probeCapabilities(): Promise<void>;
    stop(): void;
    snapshot(): DiagnosticReport;
    download(filename?: string): void;
}
export {};
```

## diagnostics/device-protocol.d.ts

```ts
export interface DeviceTestCase {
    id: string;
    title: string;
    instructions: string;
    seconds: number;
    modes: readonly ('image' | 'flow' | 'transition' | 'webxr')[];
}
export declare const DEVICE_TEST_PROTOCOL: readonly DeviceTestCase[];
```

## slam/ExperimentalMetricScale.d.ts

```ts
type WindowRejection = 'visualCoverage' | 'sensorCoverage' | 'sensorGap' | 'weakVisualMotion' | 'weakInertialMotion';
type Interruption = 'poseGap' | 'trackingLost' | 'relocalized' | 'keyframeCorrection' | 'mapReset';
type AxisValues = {
    x: number;
    y: number;
    z: number;
};
interface MotionSignal {
    windows: number;
    deviceAccelerationRmsMps2: AxisValues;
    worldAccelerationRmsMps2: AxisValues;
    integratedRmsMeters: AxisValues;
    meanAbsoluteIntegralMeters: AxisValues;
}
interface GuidedPhaseDiagnostics {
    visualPoses: number;
    visualDisplacementUnits: number | null;
    visualDisplacementMeters: number | null;
    visualCoverageMs: number;
    stationaryPoses: number;
    maxExcursionUnits: number | null;
    durationMs: number;
    samples: number;
    usableSamples: number;
    accelerationPeakMps2: AxisValues | null;
    accelerationRmsMps2: AxisValues | null;
    accelerationStdDevMps2: AxisValues | null;
    integratedWindows: number;
    weakWindows: number;
}
export interface MetricScaleDiagnostics {
    permission: 'idle' | 'listening' | 'denied' | 'unavailable';
    motionEvents: number;
    samples: number;
    usableSamples: number;
    medianIntervalMs: number | null;
    largestGapMs: number;
    visualFrames: number;
    medianVisualIntervalMs: number | null;
    pairedWindows: number;
    relativeResidual: number | null;
    metersPerUnit: number | null;
    windowsEvaluated: number;
    windowsAccepted: number;
    rejectedWindows: Record<WindowRejection, number>;
    interruptions: Record<Interruption, number>;
    fitState: 'waiting' | 'inconsistent' | 'accepted';
    fitAttempts: number;
    timing: {
        comparableWindows: number;
        estimatedOffsetMs: number | null;
        zeroOffsetResidual: number | null;
        bestResidual: number | null;
    };
    lastTimingFit: MetricScaleDiagnostics['timing'] | null;
    motionSignal: {
        all: MotionSignal | null;
        weak: MotionSignal | null;
        guided: MotionSignal | null;
        guidedWeak: MotionSignal | null;
    };
    guidedPhases: Record<string, GuidedPhaseDiagnostics>;
}
export declare class ExperimentalMetricScale {
    start(): Promise<boolean>;
    stop(): void;
    setGuidedMotionCapture(active: boolean): void;
    hasStableVisualTracking(now?: number): boolean;
    pauseGuidedMotionPhase(): void;
    setGuidedMotionPhase(id: string): void;
    diagnostics(): MetricScaleDiagnostics;
    guidedReturnError(outboundId: string, inboundId: string): number | null;
    resetMap(): void;
    interrupt(reason?: Interruption): void;
    observe(time: number, worldFromCamera: Float32Array, stationary?: boolean): number | null;
}
export {};
```

## slam/OdometryBackend.d.ts

```ts
import type { CameraIntrinsics } from '../Pose.js';
import type { ImageObservation } from '../tracking/types.js';
export interface OdometryConfig {
    intrinsics: CameraIntrinsics;
    opencvURL?: string;
    seed?: ImageObservation;
    keyframeCorrection?: boolean;
    floorROI: {
        x: number;
        y: number;
        width: number;
        height: number;
    };
}
export interface OdometryMapSnapshot {
    version: 1;
    intrinsics: CameraIntrinsics;
    scale: 'relative' | 'metric';
    mapId: string;
    keyframes: {
        descriptors: Uint8Array;
        points: Float32Array;
        view: Float32Array;
    }[];
    groundPlane?: {
        worldFromPlane: Float32Array;
        inliers: number;
    };
    currentViewCaptured?: boolean;
}
export declare const ODOMETRY_STAGES: readonly [
    "grayMs",
    "cornersMs",
    "flowMs",
    "flowNormalMs",
    "flowWideMs",
    "flowRetryMs",
    "initializationMs",
    "poseMs",
    "mapUpdateMs",
    "keyframesMs",
    "planeMs",
    "planeFitMs",
    "planeConsensusMs",
    "relocalizationMs",
    "workerMs"
];
export type OdometryTimings = Partial<Record<typeof ODOMETRY_STAGES[number], number>>;
export declare const ODOMETRY_SCAN_HINTS: readonly [
    "low-texture",
    "move-sideways",
    "map-initializing",
    "plane-unverified",
    "return-to-map",
    "map-matches-insufficient",
    "map-pose-unverified",
    "map-pose-confirming",
    "surface-ready"
];
export type OdometryScanHint = typeof ODOMETRY_SCAN_HINTS[number];
export type OdometryEstimate = ({
    status: 'initializing' | 'lost';
    mapId: string;
} | {
    status: 'tracked';
    mapId: string;
    worldFromCamera: Float32Array;
    projectionMatrix: Float32Array;
    scale: 'relative' | 'metric';
    trackedPoints: number;
    environmentReady?: boolean;
    processingMs?: number;
    reprojectionErrorPx?: number;
    relocalized?: boolean;
    keyframeCorrected?: boolean;
    stationary?: boolean;
    groundPlane?: {
        worldFromPlane: Float32Array;
        inliers: number;
    };
}) & {
    timings?: OdometryTimings;
    scanHint?: OdometryScanHint;
};
export interface OdometryBackend {
    processFrame(frame: {
        rgba: Uint8ClampedArray;
        width: number;
        height: number;
        timestampMs: number;
    }): OdometryEstimate | Promise<OdometryEstimate>;
    reset(): void | Promise<void>;
    exportMap?(includeCurrentView?: boolean): OdometryMapSnapshot;
    importMap?(snapshot: OdometryMapSnapshot): void;
    checkVisualReference?(action: 'capture' | 'verify', id: string, timestampMs: number): VisualReferenceResult;
}
export type VisualReferenceResult = {
    status: 'captured';
    points: number;
} | {
    status: 'verified';
    inliers: number;
    reprojectionErrorPx: number;
    medianImageShiftPx: number;
    directReturnUnits: number;
    trajectoryDeltaUnits: number;
} | {
    status: 'unavailable' | 'insufficient-support' | 'missing-reference';
};
export interface OdometryModule {
    createOdometryBackend(config: OdometryConfig): Promise<OdometryBackend>;
}
```

## slam/OpticalFlowSLAM.d.ts

```ts
import type { CameraFrame } from '../camera/CameraManager.js';
import type { OdometryConfig, OdometryEstimate, OdometryMapSnapshot, VisualReferenceResult } from './OdometryBackend.js';
export interface OpticalFlowOptions extends OdometryConfig {
    moduleURL?: URL;
    workerFactory?: () => Worker;
}
export declare class OpticalFlowSLAM {
    constructor(options: OpticalFlowOptions);
    start(signal?: AbortSignal): Promise<void>;
    processFrame(frame: CameraFrame, signal?: AbortSignal): Promise<OdometryEstimate | null>;
    checkVisualReference(action: 'capture' | 'verify', referenceId: string, signal?: AbortSignal): Promise<VisualReferenceResult>;
    exportMap(signal?: AbortSignal, includeCurrentView?: boolean): Promise<OdometryMapSnapshot>;
    importMap(snapshot: OdometryMapSnapshot, signal?: AbortSignal): Promise<void>;
    stop(): void;
    dispose(): void;
}
```

## slam/SLAMManager.d.ts

```ts
import type { ARPose } from '../Pose.js';
import type { CameraFrame } from '../camera/CameraManager.js';
import type { CameraIntrinsics } from '../Pose.js';
export interface SLAMOptions {
    attachSession: (session: XRSession) => Promise<void>;
    overlayRoot?: HTMLElement;
    onPose: (pose: ARPose) => void;
    onSurface?: (matrix: Float32Array) => void;
    onLost?: () => void;
    onEnd?: () => void;
    onError?: (error: Error) => void;
    getGLContext?: () => WebGL2RenderingContext;
    requireCameraAccess?: boolean;
    onCameraFrame?: (frame: CameraFrame, worldFromCamera: Float32Array, intrinsics: CameraIntrinsics, referenceEpoch: number) => Promise<void>;
    onAlignmentUnavailable?: (error: Error) => void;
}
export declare class SLAMManager {
    get imageAlignmentAvailable(): boolean;
    get hasPlacement(): boolean;
    get referenceEpoch(): number;
    constructor(options: SLAMOptions);
    static isSupported(): Promise<boolean>;
    start(signal?: AbortSignal): Promise<void>;
    switchToSLAM(currentMatrix: Float32Array, alignedWorldFromCamera?: Float32Array): void;
    stop(): Promise<void>;
}
```

## tools/MarkerCompiler.d.ts

```ts
import type { MarkerQuality } from '../tracking/ImageCompiler.js';
export declare class MarkerCompiler {
    constructor(options?: {
        workerFactory?: () => Worker;
    });
    compile(file: Blob, options: {
        physicalWidthMeters: number;
        opencvURL: string;
        maxDimension?: number;
    }, signal?: AbortSignal): Promise<{
        buffer: ArrayBuffer;
        quality: MarkerQuality;
    }>;
    dispose(): void;
}
```

## tracking/ImageCompiler.d.ts

```ts
export declare const TARGET_HEADER_BYTES = 48;
export declare const TARGET_MAX_BYTES: number;
export declare const TARGET_MAX_FEATURES = 100000;
export declare const ORB_DESCRIPTOR_BYTES = 32;
export interface MarkerFeatures {
    width: number;
    height: number;
    keypoints: Float32Array;
    descriptors: Uint8Array;
}
export interface CompiledMarker extends MarkerFeatures {
    simulated: boolean;
    physicalWidthMeters: number;
    extractorId: number;
}
export interface DecodedImage {
    data: Uint8ClampedArray;
    width: number;
    height: number;
}
export interface CompilerOptions {
    affineViews?: boolean;
    physicalWidthMeters: number;
    opencvURL?: string;
    extractorId?: number;
    maxDimension?: number;
    simulate?: boolean;
    extract?: (encoded: Uint8Array) => Promise<MarkerFeatures>;
    decode?: (encoded: Uint8Array) => Promise<DecodedImage>;
}
export interface MarkerQuality {
    featureCount: number;
    coverage: number;
    duplicateRatio: number;
    usable: boolean;
    warnings: string[];
}
export declare function crc32(bytes: Uint8Array): number;
export declare function analyzeFeatures(features: MarkerFeatures): MarkerQuality;
export declare class ImageCompiler {
    compile(source: Uint8Array | Blob, options: CompilerOptions): Promise<ArrayBuffer>;
    compileRGBA(image: DecodedImage, options: CompilerOptions): Promise<ArrayBuffer>;
}
export declare function decodeImageBrowser(encoded: Uint8Array, max: number): Promise<DecodedImage>;
export declare function encodeMarker(features: MarkerFeatures, options: CompilerOptions, simulated?: boolean): ArrayBuffer;
export declare function decodeMarker(buffer: ArrayBuffer): CompiledMarker;
```

## tracking/Tracker.d.ts

```ts
import { type ImageTrackingProfile } from './profile.js';
import type { CameraFrame } from '../camera/CameraManager.js';
import type { CameraIntrinsics } from '../Pose.js';
import type { TrackingResult, TrackingBatchResult } from './types.js';
export type { TrackingResult, ImageObservation } from './types.js';
export interface TrackerOptions {
    opencvURL?: string | URL;
    calibration?: CameraIntrinsics;
    allowEstimatedCalibration?: boolean;
    timeoutMs?: number;
    workerFactory?: () => Worker;
}
export declare class Tracker {
    get latestProfile(): ImageTrackingProfile | null;
    constructor(options?: TrackerOptions);
    get state(): 'idle' | 'busy' | 'disposed';
    get hasTarget(): boolean;
    loadTarget(buffer: ArrayBuffer, signal?: AbortSignal, targetId?: string): Promise<void>;
    get targetIds(): readonly string[];
    loadTargets(targets: readonly {
        id: string;
        buffer: ArrayBuffer;
    }[], signal?: AbortSignal): Promise<void>;
    processFrame(frame: CameraFrame, signal?: AbortSignal, calibrationOverride?: CameraIntrinsics): Promise<TrackingResult | null>;
    processTargetsFrame(frame: CameraFrame, signal?: AbortSignal): Promise<TrackingBatchResult | null>;
    dispose(): void;
}
```

## tracking/events.d.ts

```ts
import type { ARPose } from '../Pose.js';
import type { OdometryScanHint } from '../slam/OdometryBackend.js';
export type TrackingIssue = 'low-texture' | 'small-target' | 'blur' | 'high-motion' | 'insufficient-matches' | 'occlusion-or-out-of-view' | 'device-load';
export interface FrameQuality {
    gradient: number;
    laplacianVariance: number;
    motionPixels: number;
    targetSizePx: number;
    featureCount: number;
    inliers: number;
    reprojectionErrorPx: number;
}
export interface TrackingQualityEvent extends FrameQuality {
    targetId: string;
    timestampMs: number;
    state: 'tracking' | 'recovering' | 'lost';
    score: number;
    processingMs: number;
    issues: TrackingIssue[];
    diagnosis: 'heuristic';
}
export interface TargetFoundEvent {
    targetId: string;
    timestampMs: number;
    pose: ARPose;
}
export interface TargetLostEvent {
    targetId: string;
    timestampMs: number;
    retained: boolean;
    reason: 'lost' | 'removed' | 'stopped';
}
export interface TargetVisibilityEvent {
    targetId: string;
    visible: boolean;
    reason: 'tracked' | 'recovering' | 'lost' | 'removed' | 'stopped' | 'policy';
}
export interface AREventMap {
    scanGuidance: {
        hint: OdometryScanHint;
        timestampMs: number;
    };
    targetFound: TargetFoundEvent;
    targetLost: TargetLostEvent;
    trackingQuality: TrackingQualityEvent;
    targetVisibility: TargetVisibilityEvent;
}
```

## tracking/profile.d.ts

```ts
export declare const TRACKING_STAGES: readonly [
    "grayMs",
    "qualityMs",
    "supportMs",
    "opticalFlowMs",
    "flowValidationMs",
    "orbMs",
    "matchingMs",
    "homographyMs",
    "poseMs",
    "workerMs",
    "roundTripMs",
    "transportAndSchedulingMs"
];
export declare const TRACKING_COUNTS: readonly [
    "flowAttempts",
    "flowAccepted",
    "redetections",
    "orbExtractions",
    "flowInputPoints",
    "cachedAttempts",
    "fullDetections",
    "matchingQueryDescriptors",
    "flowReliable",
    "redetectMissing",
    "redetectWeakSupport",
    "redetectDeadline",
    "redetectVerification",
    "globalDeferred",
    "flowSparseReliable",
    "weakDistribution",
    "weakReprojection",
    "weakRetention",
    "cacheConflicts",
    "exactMatchingCalls",
    "opencvMatchingCalls",
    "emptyMatchingCalls"
];
export interface ImageTrackingProfile {
    timings: Record<typeof TRACKING_STAGES[number], number>;
    counts: Record<typeof TRACKING_COUNTS[number], number>;
}
export declare function createTrackingProfile(): ImageTrackingProfile;
export declare function copyTrackingProfile(value: unknown): ImageTrackingProfile | null;
export declare function measureTracking<T>(profile: ImageTrackingProfile, key: typeof TRACKING_STAGES[number], run: () => T): T;
```

## tracking/types.d.ts

```ts
import type { CameraIntrinsics } from '../Pose.js';
import type { ImageTrackingProfile } from './profile.js';
import type { FrameQuality } from './events.js';
export interface ImageObservation {
    rgba: ArrayBuffer;
    width: number;
    height: number;
    timestampMs: number;
    sessionId: number;
    intrinsics: CameraIntrinsics;
    projectionSource?: 'calibrated' | 'estimated';
    cameraFromMarker: Float32Array;
    imagePoints: Float32Array;
    objectPoints: Float32Array;
    markerCorners: Float32Array;
}
export type TrackingResult = {
    sessionId: number;
    timestampMs: number;
    processingMs: number;
    quality?: FrameQuality;
    targetId?: string;
    profile?: ImageTrackingProfile;
} & ({
    status: 'not-found';
    matrix: null;
} | {
    status: 'tracked';
    matrix: Float32Array;
    projectionMatrix: Float32Array;
    projectionSource: 'calibrated' | 'estimated';
    inliers: number;
    reprojectionErrorPx: number;
    reference: ImageObservation;
});
export interface TrackingFrameRequest {
    type: 'FRAME' | 'FRAME_BATCH';
    id: number;
    buffer: ArrayBuffer;
    width: number;
    height: number;
    sessionId: number;
    timestampMs: number;
    intrinsics: CameraIntrinsics;
    projectionSource: 'calibrated' | 'estimated';
}
export interface TrackingBatchResult {
    results: TrackingResult[];
    processingMs: number;
    profile?: ImageTrackingProfile;
}
```

## vision/calibration.d.ts

```ts
import type { CameraIntrinsics } from '../Pose.js';
export declare function validateIntrinsics(k: CameraIntrinsics): void;
export declare function scaleIntrinsics(k: CameraIntrinsics, width: number, height: number): CameraIntrinsics;
export declare function estimateIntrinsics(width: number, height: number, verticalFovDegrees?: number): CameraIntrinsics;
export declare function projectionFromIntrinsics(k: CameraIntrinsics, near?: number, far?: number): Float32Array;
export declare function rotateIntrinsics(k: CameraIntrinsics, degrees: 0 | 90 | 180 | 270): CameraIntrinsics;
export declare function normalizedPixel(x: number, y: number, k: CameraIntrinsics): [
    number,
    number
];
```

## wrappers/SurfacePlacement.d.ts

```ts
import { RingGeometry, MeshBasicMaterial, Mesh } from 'three';
import type { ARPose } from '../Pose.js';
export type PlacementState = 'idle' | 'scanning' | 'surface-found' | 'placed' | 'lost';
export declare class SurfacePlacement {
    readonly reticle: Mesh<RingGeometry, MeshBasicMaterial, import("three").Object3DEventMap>;
    constructor(manual: boolean, changed: (state: PlacementState) => void, now?: () => number, onStale?: () => void, showGrid?: boolean);
    get state(): PlacementState;
    get canConfirm(): boolean;
    begin(): void;
    status(message: string): void;
    observeSurface(matrix: Float32Array): void;
    observePose(pose: ARPose): void;
    confirm(): void;
    tick(): void;
    dispose(): void;
}
```

## wrappers/ThreeARGroup.d.ts

```ts
import { Group } from 'three';
import type { ARPose } from '../Pose.js';
import type { WebAREngine } from '../WebAREngine.js';
export declare class ThreeARGroup extends Group {
    constructor();
    bind(engine: WebAREngine, targetId?: string): this;
    unbind(): void;
    dispose(): void;
    update(matrix: Float32Array, pose?: ARPose): void;
}
```

## wrappers/ThreeARModel.d.ts

```ts
import { Group } from 'three';
export interface ARModelOptions {
    dracoDecoderPath?: string | URL;
    maxBytes?: number;
}
export interface ARModelLoadOptions {
    fitSize?: number | false;
    autoplay?: boolean;
    signal?: AbortSignal;
}
export interface ARAnimationOptions {
    loop?: 'repeat' | 'once' | 'pingpong';
    repetitions?: number;
    speed?: number;
    crossFadeSeconds?: number;
    clampWhenFinished?: boolean;
}
export declare class ThreeARModel extends Group {
    constructor(options?: ARModelOptions);
    get model(): Group | null;
    load(source: Blob | string | URL, options?: ARModelLoadOptions): Promise<this>;
    update(deltaSeconds: number): void;
    setSize(size: number | false): void;
    playAnimation(nameOrIndex?: string | number, options?: ARAnimationOptions): void;
    configureAnimation(options: ARAnimationOptions): void;
    pauseAnimations(): void;
    resumeAnimations(): void;
    get animationState(): {
        name: string;
        time: number;
        paused: boolean;
        speed: number;
        running: boolean;
    } | null;
    onAnimationFinished(listener: (name: string) => void): () => void;
    stopAnimations(): void;
    unload(): void;
    dispose(): void;
}
```

## wrappers/ThreeARScene.d.ts

```ts
import { Scene, PerspectiveCamera, WebGLRenderer, type Object3D } from 'three';
import { WebAREngine, type EngineOptions } from '../WebAREngine.js';
import { ThreeARGroup } from './ThreeARGroup.js';
export interface ARSceneOptions {
    container: HTMLElement;
    engineOptions?: EngineOptions;
    maxPixelRatio?: number;
    lighting?: boolean;
    fit?: 'contain' | 'cover';
    antialias?: boolean;
}
export declare class ThreeARScene {
    readonly engine: WebAREngine;
    readonly scene: Scene;
    readonly camera: PerspectiveCamera;
    readonly renderer: WebGLRenderer;
    constructor(options: ARSceneOptions);
    getAnchor(targetId?: string): ThreeARGroup;
    addContent(targetId: string, content: Object3D): void;
    removeContent(content: Object3D): void;
    onRender(callback: (deltaSeconds: number) => void): () => void;
    onAfterRender(callback: () => void): () => void;
    dispose(): Promise<void>;
}
```

## wrappers/ThreeARVideo.d.ts

```ts
import { Group, Mesh, PlaneGeometry, ShaderMaterial, type ColorRepresentation } from 'three';
export interface ChromaKeyOptions {
    color?: ColorRepresentation;
    similarity?: number;
    smoothness?: number;
    spill?: number;
}
export interface ARVideoOptions {
    width?: number;
    orientation?: 'flat' | 'upright';
    muted?: boolean;
    loop?: boolean;
    chromaKey?: ChromaKeyOptions | false;
}
export declare class ThreeARVideo extends Group {
    readonly videoElement: HTMLVideoElement;
    readonly mesh: Mesh<PlaneGeometry, ShaderMaterial>;
    constructor(options?: ARVideoOptions);
    setChromaKey(options: ChromaKeyOptions | false): void;
    setWidth(width: number): void;
    setOrientation(orientation: 'flat' | 'upright'): void;
    setSource(source: Blob | string | URL): Promise<void>;
    play(): Promise<void>;
    pause(): void;
    dispose(): void;
}
```

## wrappers/ThreeCameraBackground.d.ts

```ts
import { Mesh } from 'three';
import type { CameraIntrinsics } from '../Pose.js';
export declare class ThreeCameraBackground {
    readonly object3D: Mesh;
    constructor(video: HTMLVideoElement, calibration?: CameraIntrinsics);
    setCalibration(calibration?: CameraIntrinsics): void;
    dispose(): void;
}
```

## wrappers/aframe-component.d.ts

```ts
import type { Object3D, Camera } from 'three';
import type { WebAREngine } from '../WebAREngine.js';
import { ThreeCameraBackground } from './ThreeCameraBackground.js';
interface ComponentInstance {
    data: {
        target: string;
        physicalWidth: number;
        targetId: string;
    };
    el: HTMLElement & {
        object3D: Object3D;
        sceneEl?: {
            camera?: Camera;
            object3D?: Object3D;
        };
    };
    unsubscribe?: () => void;
    originalAutoUpdate?: boolean;
    originalVisible?: boolean;
    removed?: boolean;
    camera?: Camera;
    cameraAutoUpdate?: boolean;
    background?: ThreeCameraBackground;
    releaseBackground?: () => void;
    releaseCamera?: () => void;
}
interface AFrameRegistry {
    registerComponent(name: string, definition: {
        schema: {
            target: {
                type: 'string';
                default: string;
            };
            physicalWidth: {
                type: 'number';
                default: number;
            };
            targetId: {
                type: 'string';
                default: string;
            };
        };
        init(this: ComponentInstance): void;
        update(this: ComponentInstance, previous: {
            target?: string;
            physicalWidth?: number;
            targetId?: string;
        }): void;
        remove(this: ComponentInstance): void;
    }): unknown;
}
export declare function registerAFrameComponent(AFRAME: AFrameRegistry, engine: WebAREngine): void;
export {};
```

## wrappers/aframe-model.d.ts

```ts
import type { Object3D } from 'three';
import { ThreeARModel, type ARModelOptions } from './ThreeARModel.js';
interface Instance {
    data: {
        src: string;
        fitSize: number;
        autoplay: boolean;
    };
    el: HTMLElement & {
        object3D: Object3D;
    };
    model?: ThreeARModel;
    generation?: number;
}
interface Registry {
    registerComponent(name: string, definition: {
        schema: {
            src: {
                type: 'string';
                default: string;
            };
            fitSize: {
                type: 'number';
                default: number;
            };
            autoplay: {
                type: 'boolean';
                default: boolean;
            };
        };
        init(this: Instance): void;
        update(this: Instance, previous: Partial<Instance['data']>): void;
        tick(this: Instance, time: number, delta: number): void;
        remove(this: Instance): void;
    }): unknown;
}
export declare function registerAFrameModelComponent(AFRAME: Registry, options?: ARModelOptions): void;
export {};
```

## wrappers/aframe-video.d.ts

```ts
import type { Object3D } from 'three';
import { ThreeARVideo } from './ThreeARVideo.js';
interface Instance {
    data: {
        src: string;
        width: number;
        chromaKey: boolean;
        keyColor: string;
        similarity: number;
        smoothness: number;
        spill: number;
        muted: boolean;
        loop: boolean;
    };
    el: HTMLElement & {
        object3D: Object3D;
    };
    video?: ThreeARVideo;
    generation?: number;
}
interface Registry {
    registerComponent(name: string, definition: {
        schema: Record<string, {
            type: string;
            default: string | number | boolean;
        }>;
        init(this: Instance): void;
        update(this: Instance, previous: Partial<Instance['data']>): void;
        remove(this: Instance): void;
    }): unknown;
}
export declare function registerAFrameVideoComponent(AFRAME: Registry): void;
export {};
```

## wrappers/web-components.d.ts

```ts
import { ThreeARScene } from './ThreeARScene.js';
import { ThreeARModel, type ARAnimationOptions } from './ThreeARModel.js';
import { ThreeARVideo } from './ThreeARVideo.js';
import { type PlacementState } from './SurfacePlacement.js';
import { ARDiagnostics, type DiagnosticReport } from '../diagnostics/ARDiagnostics.js';
import type { WebAREngine, SurfaceTransitionOptions, SurfaceTransitionResult } from '../WebAREngine.js';
export interface ARComponentsOptions {
    assetBase?: string | URL;
}
export interface ARSceneElement extends HTMLElement {
    readonly app: ThreeARScene | null;
    readonly engine: WebAREngine | null;
    readonly updateComplete: Promise<void>;
    readonly diagnostics: ARDiagnostics | null;
    readonly placementState: PlacementState;
    confirmPlacement(): void;
    getDiagnosticsReport(): DiagnosticReport | null;
    downloadDiagnostics(): void;
    start(): Promise<void>;
    stop(): Promise<void>;
    refresh(): Promise<void>;
    enableSLAM(options?: SurfaceTransitionOptions): Promise<SurfaceTransitionResult>;
}
export interface ARModelElement extends HTMLElement {
    readonly model: ThreeARModel | null;
    readonly updateComplete: Promise<void>;
    reload(): Promise<void>;
    playAnimation(nameOrIndex: string | number, options?: ARAnimationOptions): void;
    pauseAnimations(): void;
    resumeAnimations(): void;
    stopAnimations(): void;
}
export interface ARVideoElement extends HTMLElement {
    readonly video: ThreeARVideo | null;
    readonly updateComplete: Promise<void>;
    reload(): Promise<void>;
    play(): Promise<void>;
    pause(): void;
}
export declare function registerARComponents(options?: ARComponentsOptions): void;
```


## Autoría / Credits

**Creador / Creator:** IngCarlosReina. - Realidad Aumentada Empezando Desde Cero

- [Web](https://realidad-aumentada.com.co)
- [Blog](https://blog.realidad-aumentada.com.co)
- [YouTube](https://www.youtube.com/@carlosreinamcr)
