import { Quaternion, Vector2, Vector3, Vector4 } from "three";
declare type Vector = Vector2 | Vector3 | Vector4 | Quaternion;
import { type Context } from "./engine_context.js";
import { type SourceIdentifier } from "./engine_types.js";
/** @internal */
export declare const nameofFactory: <T>() => (name: keyof T) => keyof T;
/** @internal */
export declare function nameof<T>(name: keyof T): keyof T;
type ParseNumber<T> = T extends `${infer U extends number}` ? U : never;
export type EnumToPrimitiveUnion<T> = `${T & string}` | ParseNumber<`${T & number}`>;
/** @internal */
export declare function isDebugMode(): boolean;
/**
 * The circular buffer class can be used to cache objects that don't need to be created every frame.
 * This structure is used for e.g. Vector3 or Quaternion objects in the engine when calling `getTempVector3` or `getTempQuaternion`.
 *
 * @example Create a circular buffer that caches Vector3 objects. Max size is 10.
 * ```typescript
 * const buffer = new CircularBuffer(() => new Vector3(), 10);
 * const vec = buffer.get();
 * ```
 *
 * @example Create a circular buffer that caches Quaternion objects. Max size is 1000.
 * ```typescript
 * const buffer = new CircularBuffer(() => new Quaternion(), 1000);
 * const quat = buffer.get();
 * ```
 */
export declare class CircularBuffer<T> {
    private _factory;
    private _cache;
    private _maxSize;
    private _index;
    constructor(factory: () => T, maxSize: number);
    get(): T;
}
export declare function getUrlParams(): URLSearchParams;
type Param<T extends string> = string | boolean | number | T;
/** Checks if a url parameter exists.
 * Returns true if it exists but has no value (e.g. ?help)
 * Returns false if it does not exist
 * Returns false if it's set to 0 e.g. ?debug=0
 * Returns the value if it exists e.g. ?message=hello
 */
export declare function getParam<T extends string>(paramName: T): Param<T>;
export declare function setParam(paramName: string, paramValue: string): void;
/** Sets an URL parameter without reloading the website */
export declare function setParamWithoutReload(paramName: string, paramValue: string | null, appendHistory?: boolean): void;
/** Sets or adds an URL query parameter */
export declare function setOrAddParamsToUrl(url: URLSearchParams, paramName: string, paramValue: string | number): void;
/** Adds an entry to the browser history. Internally uses `window.history.pushState` */
export declare function pushState(title: string, urlParams: URLSearchParams, state?: any): void;
/** Replaces the current entry in the browser history. Internally uses `window.history.replaceState` */
export declare function setState(title: string, urlParams: URLSearchParams, state?: any): void;
/** Generates a random id string of the given length */
export declare function makeId(length: any): string;
/** Generates a random number
 * @deprecated use Mathf.random(min, max)
 */
export declare function randomNumber(min: number, max: number): number;
/** Generates a random id string from a list of adjectives and nouns */
export declare function makeIdFromRandomWords(): string;
export declare function sanitizeString(str: any): string;
/**
 * @param globalObjectIdentifier The guid of the object to find
 * @param obj The object to search in
 * @param recursive If true the search will be recursive
 * @param searchComponents If true the search will also search components
 * @returns the first object that has the globalObjectIdentifier as a guid */
export declare function tryFindObject(globalObjectIdentifier: string, obj: any, recursive?: boolean, searchComponents?: boolean): any;
declare type deepClonePredicate = (owner: any, propertyName: string, current: any) => boolean;
/** Deep clones an object
 * @param obj The object to clone
 * @param predicate A function that can be used to skip certain properties from being cloned
 * @returns The cloned object
 * @example
 * const clone = deepClone(obj, (owner, propertyName, current) => {
 *    if (propertyName === "dontCloneMe") return false;
 *   return true;
 * });
 * */
export declare function deepClone(obj: any, predicate?: deepClonePredicate): any;
/** Wait for a specific amount of milliseconds to pass
 * @returns a promise that resolves after a certain amount of milliseconds
 * @example
 * ```typescript
 * await delay(1000);
 * ```
*/
export declare function delay(milliseconds: number): Promise<void>;
/** Will wait for a specific amount of frames to pass
 * @param frameCount The amount of frames to wait for
 * @param context The context to use, if not provided the current context will be used
 * @returns a promise that resolves after a certain amount of frames
 * @example
 * ```typescript
 * await delayForFrames(10);
 * ```
*/
export declare function delayForFrames(frameCount: number, context?: Context): Promise<void>;
export declare const relativePathPrefix = "rel:";
/** @deprecated use resolveUrl instead */
export declare function getPath(source: SourceIdentifier | undefined, uri: string): string;
/**
 * Use to resolve a url serialized in a glTF file
 * @param source The uri of the loading file
 * @param uri The uri of the file to resolve, can be absolute or relative
 * @returns The resolved uri
 */
export declare function resolveUrl(source: SourceIdentifier | undefined, uri: string): string;
export type WriteCallback = (data: any, prop: string) => void;
export interface IWatch {
    subscribeWrite(callback: WriteCallback): any;
    unsubscribeWrite(callback: WriteCallback): any;
    apply(): any;
    revoke(): any;
    dispose(): any;
}
export declare class Watch implements IWatch {
    private readonly _watches;
    constructor(object: object, str: string[] | string);
    subscribeWrite(callback: WriteCallback): void;
    unsubscribeWrite(callback: WriteCallback): void;
    apply(): void;
    revoke(): void;
    dispose(): void;
}
/** Subscribe to an object being written to
 * Currently supporting Vector3
 */
export declare function watchWrite(vec: Vector, cb: Function): boolean;
export declare function unwatchWrite(vec: Vector, cb: Function): void;
declare global {
    interface NavigatorUAData {
        platform: string;
    }
    interface Navigator {
        userAgentData?: NavigatorUAData;
    }
}
/**
 * Utility functions to detect certain device types (mobile, desktop), browsers, or capabilities.
 */
export declare namespace DeviceUtilities {
    /** @returns `true` for MacOS or Windows devices. `false` for Hololens and other headsets. */
    function isDesktop(): boolean;
    /** @returns `true` if it's a phone or tablet */
    function isMobileDevice(): boolean;
    /** @deprecated use {@link isiPad} instead */
    function isIPad(): boolean;
    /** @returns `true` if we're currently on an iPad */
    function isiPad(): boolean;
    /** @returns `true` if we're currently on an Android device */
    function isAndroidDevice(): boolean;
    /** @returns `true` if we're currently using the Mozilla XR Browser (only available for iOS) */
    function isMozillaXR(): boolean;
    /** @returns `true` for MacOS devices */
    function isMacOS(): boolean;
    /** @returns `true` for VisionOS devices */
    function isVisionOS(): boolean;
    /** @returns `true` for iOS devices like iPad, iPhone, iPod... */
    function isiOS(): boolean;
    /** @returns `true` if we're currently on safari */
    function isSafari(): boolean;
    /** @returns `true` for Meta Quest devices and browser. */
    function isQuest(): boolean;
    /** @returns `true` if the browser has `<a rel="ar">` support, which indicates USDZ QuickLook support. */
    function supportsQuickLookAR(): boolean;
    /** @returns `true` if the user allowed to use the microphone */
    function microphonePermissionsGranted(): Promise<boolean>;
    function getiOSVersion(): string | null;
    function getChromeVersion(): string | null;
}
/**
 * @deprecated use {@link DeviceUtilities.isDesktop} instead
 */
export declare function isDesktop(): boolean;
/**
 * @deprecated use {@link DeviceUtilities.isMobileDevice} instead
 */
export declare function isMobileDevice(): boolean;
/** @deprecated use {@link DeviceUtilities.isiPad} instead */
export declare function isIPad(): boolean;
/** @deprecated use {@link DeviceUtilities.isiPad} instead */
export declare function isiPad(): boolean;
/** @deprecated use {@link DeviceUtilities.isAndroidDevice} instead */
export declare function isAndroidDevice(): boolean;
/** @deprecated use {@link DeviceUtilities.isMozillaXR} instead */
export declare function isMozillaXR(): boolean;
/** @deprecated use {@link DeviceUtilities.isMacOS} instead */
export declare function isMacOS(): boolean;
/** @deprecated use {@link DeviceUtilities.isiOS} instead */
export declare function isiOS(): boolean;
/** @deprecated use {@link DeviceUtilities.isSafari} instead */
export declare function isSafari(): boolean;
/** @deprecated use {@link DeviceUtilities.isQuest} instead */
export declare function isQuest(): boolean;
/** @deprecated use {@link DeviceUtilities.microphonePermissionsGranted} instead */
export declare function microphonePermissionsGranted(): Promise<boolean>;
export declare function getIpCloudflare(): Promise<string | null>;
/** Gets the public IP address of this device.
 * @returns IP address, or `undefined` when it can't be determined.
*/
export declare function getIp(): Promise<string | undefined>;
/**
 * Contains information about public IP, continent, country, state, city.
 * This information may be affected by VPNs, proxies, or other network configurations.
 */
export type IpAndLocation = {
    ipAddress: string;
    continentCode: string;
    continentName: string;
    countryCode: string;
    countryName: string;
    stateProv: string;
    city: string;
};
/** Gets the public IP address, location, and country data of this device.
 * @returns an object containing {@link IpAndLocation} data, or `undefined` when it can't be determined.
*/
export declare function getIpAndLocation(): Promise<IpAndLocation | undefined>;
declare type AttributeChangeCallback = (value: string | null) => void;
/**
 * Register a callback when an {@link HTMLElement} attribute changes.
 * This is used, for example, by the Skybox component to watch for changes to the environment-* and skybox-* attributes.
*/
export declare function addAttributeChangeCallback(domElement: HTMLElement, name: string, callback: AttributeChangeCallback): void;
/**
 * Unregister a callback previously registered with {@link addAttributeChangeCallback}.
*/
export declare function removeAttributeChangeCallback(domElement: HTMLElement, name: string, callback: AttributeChangeCallback): void;
/** Used by `PromiseAllWithErrors` */
export declare class PromiseErrorResult {
    readonly reason: string;
    constructor(reason: string);
}
/** Can be used to simplify Promise error handling and if errors are acceptable.
 * Promise.all will just fail if any of the provided promises fails and not return or cancel pending promises or partial results
 * Using Promise.allSettled (or this method) instead will return a result for each promise and not automatically fail if any of the promises fails.
 * Instead it will return a promise containing information if any of the promises failed
 * and the actual results will be available as `results` array
 **/
export declare function PromiseAllWithErrors<T>(promise: Promise<T>[]): Promise<{
    anyFailed: boolean;
    results: Array<T | PromiseErrorResult>;
}>;
/** Generates a QR code HTML image using https://github.com/davidshimjs/qrcodejs
 * @param args.text The text to encode
 * @param args.width The width of the QR code
 * @param args.height The height of the QR code
 * @param args.colorDark The color of the dark squares
 * @param args.colorLight The color of the light squares
 * @param args.correctLevel The error correction level to use
 * @param args.domElement The dom element to append the QR code to. If not provided a new div will be created and returned
 * @returns The dom element containing the QR code
 */
export declare function generateQRCode(args: {
    domElement?: HTMLElement;
    text: string;
    width?: number;
    height?: number;
    colorDark?: string;
    colorLight?: string;
    correctLevel?: any;
}): Promise<HTMLElement>;
export {};
